Describes the purpose behind IN, OUT, and IN_OUT rules, with examples
Introduction
When creating VMware NSX DFW rules, you have three choices for the Direction
setting - IN, OUT, and IN_OUT. The official documentation describes the setting: "The options are In, Out, and In/Out. The default is In/Out. This field refers to the direction of traffic from the point of view of the destination object. In means that only traffic to the object is checked, Out means that only traffic from the object is checked, and In/Out means that traffic in both directions is checked." Failing to fully grasp this setting can lead to granting unintended access to resources.
Test environment
VMs
3 Linux VMs are connected to a single NSX T1 segment
VM | IP |
---|
kremerpt-web1 | 192.168.80.62 |
kremerpt-app1 | 192.168.80.134 |
kremerpt-db1 | 192.168.80.174 |
Firewall configuration
Groups
The following groups contain virtual machine members.
Group Name | Group Members |
---|
kremerpt-app-all-members | kremerpt-web1, kremerpt-app1, kremerpt-db1 |
kremerpt-web1 | kremerpt-web1 |
kremerpt-app1 | kremerpt-app1 |
kremerpt-db1 | kremerpt-db1 |
Base rule
Deny All
A deny all rule goes at the bottom to catch all traffic that is not explicitly permitted
Rule Name | ID | Source | Dest | Service | Action | Direction |
---|
Deny All | 17431 | kremerpt-app-all-members | Any | Any | Drop | In-Out |
Tests
Test 1 - Outbound from DB1
Rule 17434 is added, granting DB1 outbound access destined for WEB1
Rule Name | ID | Source | Dest | Service | Action | Direction |
---|
db1-out-allow | 17434 | kremerpt-db1 | kremerpt-web1 | Any | Allow | Out |
Deny All | 17431 | kremerpt-app-all-members | Any | Any | Drop | In-Out |
Result
Ping from DB1 to WEB1 fails.
This is what output from the NSX Traceflow utility looks like. It shows traffic being forwarded from DB1 using rule 17434, then being blocked by the Deny All rule 17431 when it tries to reach WEB1

Test 2
Rule 17433 is added, allowing all traffic inbound into APP1.
Rule Name | ID | Source | Dest | Service | Action | Direction |
---|
db1-out-allow | 17434 | kremerpt-db1 | kremerpt-web1 | Any | Allow | Out |
app1-in | 17433 | Any | kremerpt-app1 | Any | Allow | In |
Deny All | 17431 | kremerpt-app-all-members | Any | Any | Drop | In-Out |
Result
Ping from WEB1 to APP1 fails.
Ping from DB1 to APP1 fails.
They are both blocked by the default deny 17431.
Test 3
Change rule 17434 from Out to In-Out.
Rule Name | ID | Source | Dest | Service | Action | Direction |
---|
db1-out-allow | 17434 | kremerpt-db1 | kremerpt-web1 | Any | Allow | In-Out |
app1-in | 17433 | Any | kremerpt-app1 | Any | Allow | In |
Deny All | 17431 | kremerpt-app-all-members | Any | Any | Drop | In-Out |
Result
Ping from DB1 to APP1 fails, still blocked by the default deny 17431
Ping from DB1 to WEB1 succeeds. Traceflow shows that rule 17434 is evaluated twice - once outbound from DB1, and once inbound to WEB1. It is not necessarily intuitive that the rule will be evaluated twice.
Test 4
Change rule 17433 from Out to In-Out.
Rule Name | ID | Source | Dest | Service | Action | Direction |
---|
db1-out-allow | 17434 | kremerpt-db1 | kremerpt-web1 | Any | Allow | In-Out |
app1-in | 17433 | Any | kremerpt-app1 | Any | Allow | In-Out |
Deny All | 17431 | kremerpt-app-all-members | Any | Any | Drop | In-Out |
Result
Ping from DB1 to APP1 now succeeds.
You may have thought that you controlled traffic explicitly with rule 17434, and traffic would only be allowed from DB1 to WEB1. But that is not what happens because of the In-Out direction on rule 17433. Outbound traffic from DB1 is now included in the Any
source in rule 17433, and the ping succeeds.
Conclusion
You must carefully consider the rule direction before applying it. Using In-Out without fully understanding what it does can result in an unexpected forwarding of traffic that you expect to block.