ACI Stateful Contracts¶
Estimated time to read: 7 minutes
- Originally Written: March, 2024
Info
This post uses the Nexus as Code (NaC) project which makes it very easy to configure ACI fabrics through a YAML file. More details and examples can be found at https://developer.cisco.com/docs/nexus-as-code/#!aci-introduction
ACI contracts permit communication between groups of endpoints (EPGs or ESGs). Think of them like an access control list which permits traffic between a source and destination subnet on a specific port.
A contract contains one or more subjects, each subject contains one or more filters, and each filter contains one or more entries. This provides a flexible way to build access policies.
When building contracts you may have seen the Stateful
checkbox as part of the filter entries. This is not the equivalent of a stateful firewall which performs connection tracking and other activities. In ACI it's simply a check to ensure the ACK
flag of a TCP packet is set in the direction of the consumer to the provider.
Info
To learn more about stateful firewalls see the A bit about stateful firewalls and intrusion prevention post
The example setup¶
Here's an example showing the two different scenarios, one with the stateful checkbox set to false
and one with it set to true
.
netcat
is used to send some traffic between the endpoints and the following is the Nexus as Code YAML file used to configure the ACI fabric for these scenarios.
Configuration
---
apic:
tenants:
- name: conmurph-01
managed: false
vrfs:
- name: conmurph-01.vrf-02
bridge_domains:
- name: 192.168.101.0_24
vrf: conmurph-01.vrf-02
subnets:
- ip: 192.168.101.254/24
- name: 192.168.102.0_24
vrf: conmurph-01.vrf-02
subnets:
- ip: 192.168.102.254/24
application_profiles:
- name: network-segments
managed: false
endpoint_groups:
- name: 192.168.101.0_24
alias: consumer
bridge_domain: 192.168.101.0_24
vmware_vmm_domains:
- name: hx-dev-01-vds-01
contracts:
consumers:
- permit_to_192.168.102.0
- name: 192.168.102.0_24
alias: provider
bridge_domain: 192.168.102.0_24
vmware_vmm_domains:
- name: hx-dev-01-vds-01
contracts:
providers:
- permit_to_192.168.102.0
filters:
- name: tcp-filters
entries:
- name: tcp-src-any-to-any-dst
ethertype: ip
protocol: tcp
stateful: false
contracts:
- name: permit_to_192.168.102.0
scope: tenant
subjects:
- name: permit-tcp
filters:
- filter: tcp-filters
- On the provider endpoint or server side:
sudo netcat -l 8080 <<< _hello_
- On the consumer endpoint or client side:
sudo netcat 192.168.102.10 8080
If everything is setup correctly you should see the message, _hello_
, on the consumer endpoint.
Connections both ways¶
Here is the Wireshark output showing the successful flow between source and destination taken from the provider side.
You can also run the connection in reverse i.e. the provider endpoint is connecting to the the server running on the consumer endpoint
Again here is the Wireshark output showing the successful flow between source and destination taken from the consumer side
In the simplified diagram below you can see a TCP three-way handshake where the client initiates a connection to the server. The SYN
flag is set in the first leg. The server sends a return packet with the SYN
and ACK
flags set and finally the client sends an ACK
.
sequenceDiagram
participant C as Client <br><br> 192.168.101.10
participant P as Server <br><br> 192.168.102.20
C->>P: SYN
Note over C,P: TCP three-way handshake starts
P->>C: SYN-ACK
C->>P: ACK
Note over C,P: TCP connection established
Looking at the fourth packet in the Wireshark output you can see the PSH
(push) and ACK
flags set. Once the TCP session is established (the first three packets), the data (_hello_
) is sent from the server/provider.
The TCP PSH flag
The PSH (push) flag is used to tell the receiving end that the data should be pushed up to the receiving application immediately without waiting for the buffer to fill up to its usual threshold.
An ACK
is received from the consumer/client and the TCP session is closed (FIN
, ACK
).
Note that the ACK
bit is present in all packets except for the initial connection packet which only has a SYN
.
Single direction¶
Now have a look what happens when the stateful
flag in the ACI contract is set to true
. You can reuse the Nexus as Code configuration above and just update the stateful
flag.
In this example no TCP connection can be established from the provider to the consumer. As you can see from the provider side screenshot below, the first packet is sent from the provider side with only the SYN
flag set. This is dropped by the ACI fabric and the connection is not established. You can see the retransmissions in Wireshark.
Output from the consumer endpoint showing no packets are received.
Finally, you can confirm on the ACI fabric by looking at the dropped flows and packets which can be found under the Tenant
-> Operational
tabs. Notice that the source port matches the source port found in the Wireshark outputs.
Summary¶
As you've seen in the different scenarios, the stateful checkbox in ACI is simply a check to ensure the ACK
flag of a TCP packet is set in the direction of the consumer to the provider.