There was a question recently on the Enterasys mailing list asking how to block all traffic to a particular host (or network) except for a few particular ports. The tech who posed the question was using this service within a default “allow” role. This turns out to be more difficult to implement than it looks at first glance. Of course, it can be solved easily by changing the role from a default “allow” role to a default “deny” role, but that isn’t always practical.
Some background is necessary to understand how policy works. Each type of policy rule has a specific precedence associated with it. A packet that matches multiple rules will follow the rule with the higher precedence. Making the issue more confusing, each type of policy rule also has an attribute id. Attribute ids and precedence are inversely related: the type of rule with the highest precedence – MAC source address – has an attribute id of one.
Below is the policy rule precedence table, taken from the K-series 7.31 Configuration Guide. The rule precedence table in the Policy Manager Guide is quite a bit less detailed (and keep in mind not all switch series can use all rules).
| macsource |
Classifies based on MAC source address. |
1 |
| macdest |
Classifies based on MAC destination address. |
2 |
| ipxsource |
Classifies based on source IPX address. |
3 |
| ipxdest |
Classifies based on destination IPX address. |
4 |
| ipxsourcesocket |
Classifies based on source IPX socket. |
5 |
| ipxdestsocket |
Classifies based on destination IPX socket. |
6 |
| ipxclass |
Classifies based on transmission control in IPX. |
7 |
| ipxtype |
Classifies based on IPX packet type. |
8 |
| ipsourcesocket |
Classifies based on source IP address. |
12 |
| ipdestsocket |
Classifies based on destination IP address. |
13 |
| ip frag |
Classifies based on IP fragmentation value. |
14 |
| udpsourceportip |
Classifies based on UDP source port. |
15 |
| udpdestportip |
Classifies based on UDP destination port. |
16 |
| tcpsourceportip |
Classifies based on TCP source port. |
17 |
| tcpdestportip |
Classifies based on TCP destination port. |
18 |
| icmptype |
Classifies based on ICMP type. |
19 |
| iptos |
Classifies based on Type of Service field in IP packet. |
21 |
| ipproto |
Classifies based on protocol field in IP packet. |
22 |
| ether |
Classifies based on type field in Ethernet II packet. |
25 |
| llcDsapSsap |
Classifies based on DSAP/SSAP pair in 802.3 type packet. |
26 |
| vlantag |
Classifies based on VLAN tag. |
27 |
| tci |
Classifies based on Tag Control Information. |
28 |
| port |
Classifies based on port-string. |
31 |
A lot of the time, when designing a role, “eyeballing” precedence can be done by asking which type of rule is “more specific”, and also keeping in mind that generally, lower layers on the OSI model have higher precedence.
Let’s return to the original issue but make it more specific. In my network, I’d like to block a set of users from accessing my server 2.2.2.2, which runs several web services open to the world. However, I’d like to allow these users to access web pages on my server (tcp ports 80 and 443) Without remembering the italicized part above, it makes logical sense to create a set of rules like this:
- “Deny all traffic to 2.2.2.2″ – Layer 3 IP Address Destination rule, with IP 2.2.2.2 specified
- “Allow to tcp port 80 on 2.2.2.2″ – Layer 4 IP Port Destination rule, with port 80 and IP 2.2.2.2 specified
- “Allow to tcp port 443 on 2.2.2.2″ – Layer 4 IP Port Destination rule, with port 443 and IP 2.2.2.2 specified
The second rule intuitively feels “more specific,” so on the surface it looks like all traffic should be blocked to 2.2.2.2 except for traffic headed to ports 80 and 443. Unfortunately, that’s incorrect. With the above rules, all traffic to 2.2.2.2 will be dropped.
According to the table above, the first rule has a precedence of 13, and the second two have a precedence of 18. It doesn’t matter that the second two rules have a specific IP listed. The “more specific” part only refers to the rule type, not whether a mask for the subnet is added to it. Traffic destined to port 80 on 2.2.2.2 will match the first two rules, and the top one will take precedence, so the traffic will be dropped.
However, there is a way to deny all traffic to 2.2.2.2 and then “poke holes” through this without resorting to changing the role to deny all traffic. There’s a strange layer 3 rule that actually allows a specification for a layer 4 port. The rule set will look like this:
- “Deny all traffic to 2.2.2.2″ – Layer 3 IP Address Destination rule, with IP 2.2.2.2 specified
- “Permit traffic to port 80 on 2.2.2.2″ – Layer 3 IP Socket Destination rule, with IP 2.2.2.2 and port 80 specified
- “Permit traffic to port 443 on 2.2.2.2″ – Layer 3 IP Socket Destination rule, with IP 2.2.2.2 and port 443 specified
Now all three of these rules have a precedence of 13, according to the table above, but the second two are more specific. So, all traffic headed towards 2.2.2.2 will be dropped, except traffic to port 80 or 443, which will be allowed.
Take home message: It is possible to block all traffic to a given host except for certain ports without using a default deny role. Use Layer 3 IP socket destination rules rather than layer 4 port destination rules.