Here’s a scenario that you may have experienced first-hand. Imagine you’re the IT manager of a small business. The management approaches you and says, “We need to secure our network with a firewall.” Typically, such impulsive announcements from the management come after they’ve taken some seminar or read a trending article on best business practices for security.
In such cases, you have to (very patiently and with a steady calm voice) explain to the administration in wording that they can understand, what such an endeavor entails. You have to explain the complex interrelationships between the functionality, the services running on your network, the various possibilities of extra features such as VPNs, the necessity of high availability, and the often extensive network redesign that may be necessary to accommodate a firewall.
And all of this has to be put into the context of money: “How much will each possible design permutation cost?
So, a simple statement like this can quickly become an unwieldy project that may take, at best, the better part of a day, or at worst, several days for you to work out. And that comes on top of all the other important things you have to do…
Low budget firewall options
Well, fear not. If your company has invested in Cisco, it is more than likely that your edge device is a Cisco IOS router. If this is indeed the case, you have several options for enabling various firewall-like security features on your router without the need for network redesigns, and without any purchase of additional, often expensive devices, which is arguably the most attractive result for management.
The specific features that we’ll be looking at are:
- The use of the established parameter on extended access lists
- Reflexive access lists
- Zone-based firewall feature
- Context Based Access Control (CBAC)
These features are very useful, and can substantially enhance the security of the edge of your network. However, keep in mind that these deliver only a subset of the security features and level of security that are provided by dedicated firewall appliances and solutions such as Cisco’s FirePower or ASA devices, or other firewalls such as Pfsense. I urge you to ensure that the level of security provided by these features is indeed at the level that you require before implementing them on a production network. If you require more robust security, consider migrating to a full-blown firewall solution.
For the purposes of demonstrating these features, we’ll be using the following topology:
R2 is the router where all of the security features will be applied. R1 will be considered the inside host, while R3 is some host found on the Internet to which we want to connect, or from which we want to protect our internal network.
ACL Established Parameter
Any self-respecting network engineer will ensure that their edge router has employed at least the access lists required for rudimentary security, filtering out bogons, and multicast addresses from the Internet as well as all public IP addresses that belong to your organization (your address space should never be the source of packets incoming from the Internet). However, one further thing that you can do to enhance the security of your network edge ACLs is to make use of the established keyword.
How do you implement the established keyword?
For example, you can configure the following entry in an ACL and apply it in an incoming direction on the Internet-facing interface:
R1(config)#access-list 102 permit tcp any any established R1(config)#access-list 102 deny any any
established keyword goes on the end of the ACL entry. I’ve added the explicit deny that exists for all access lists at the end just to keep in mind that it is always there.
What does the established keyword do?
To understand how this ACL entry behaves, let’s first take a look at what would happen if the established keyword wasn’t used. It would look something like this:
R1(config)#access-list 102 permit tcp any any R1(config)#access-list 102 deny any any
This entry essentially allows any packets that are part of a TCP session to pass through, regardless of source or destination IP address. So, when applied in an incoming direction on the Internet-facing interface, it will allow all incoming TCP sessions, even those initiated from the Internet, to pass through. Needless to say, we don’t want this.
If we add the
established keyword, then it will only allow such communication to packets that are part of a response to a TCP session initiated by an internal device. In other words, the packet must be part of an established TCP session that was already initiated by an internal host. In a sense, this gives us a very rudimentary stateful firewall.
What does the ACL actually look for in incoming packets to determine if they are part of an established TCP session? They examine whether the ACK or RST bits are set in the TCP header. Set ACK or RST bits indicate that the packet is not the first in the session, and therefore the packet belongs to an already established session initiated from inside.
Refining the solution
We can refine this solution further by doing the following:
R1(config)#access-list 102 permit tcp any any gt 1023 established
This ACL entry will permit incoming communications that are part of established TCP sessions that have a destination TCP port of greater than 1023. This would be useful if you only have client PCs internally on your network, which will always use ports greater than 1023 for their communications with the Internet. Thus, any return traffic should use destination ports greater than 1023. Since most of the well-known TCP ports for IP services have values less than 1023, you can ensure greater protection for these services.
However, we may want to let some of those through if you have an internal web server on port 80 or 443 for example, and you want Internet users to access it. In such a case, you must further refine your access list to permit other port values and ranges of your choice.
There are certain things to remember when using this method of edge network security. The most crucial is that the
established keyword can only be used for TCP sessions. The UDP protocol has no concept of sessions, so it is “immune” to this type of configuration. Other communications that don’t use TCP will also be unaffected by this configuration, so you must take those into account in other ways.
Reflexive Access Lists
Implementing a reflexive access list similar to using the established parameter, but it is a major step up. Reflexive access lists provide a truer form of session filtering which is more difficult to spoof because more filter criteria must be matched before a packet is permitted through.
How it works
As seen in the previous example, a Cisco IOS router that employs ACLs doesn’t keep track of any connections. The only thing it cares about when applying an ACL is if an incoming packet matches a statement or not. Once matched, it will perform the configured action, either permit or deny. If it doesn’t match, it will simply check the next statement and so on until it gets to the end of the ACL, where it meets the implicit deny statement.
Employing reflexive access-lists will enable your router to keep track of outgoing connections so that return traffic will automatically be permitted. Specifically, reflexive access lists examine the source and destination IP address and port numbers, not just ACK and RST bits. They also dynamically create and remove temporary filters as needed.
Normal access-list behavior
Let’s take a look at our diagram once again:
Let’s create and apply an access list denying all traffic from the Outside:
R2(config)#ip access-list extended 100 R2(config-ext-nacl)#deny ip any any R2(config-ext-nacl)#exit R2(config)#interface fastEthernet 0/1 R2(config-if)#ip access-group 100 in
This access list applied incoming on Fa0/1 of R2 will drop all traffic from R3 (as well as from any other host on the Internet.) Now let’s say that R3 is a web server and R1 wants to view a web page. It will successfully reach R3, but all return traffic will be dropped due to the above ACL.
Employing a reflexive access list
Using the following configuration on R2, you can create and apply a reflexive access list:
R2(config)#ip access-list extended OUTBOUND R2(config-ext-nacl)#permit ip any any reflect EVALUATE R2(config-ext-nacl)#exit R2(config)#interface fastEthernet 0/1 R2(config-if)#ip access-group OUTBOUND out
The access list called OUTBOUND is applied in an outbound direction on the Fa0/1 interface of R1. It permits everything, so it doesn’t actually do any filtering. Its purpose is to keep track of all outbound packets and to create a temporary access list called EVALUATE based on that outbound traffic. The EVALUATE access list will dynamically maintain statements to allow return traffic.
So far we haven’t filtered anything. To filter inbound traffic “reflexively” so to speak, we must do the following:
R2(config)#ip access-list extended INBOUND R2(config-ext-nacl)#evaluate EVALUATE R2(config-ext-nacl)#exit R2(config)#interface fastEthernet 0/1 R2(config-if)#ip access-group INBOUND in
This access list called INBOUND will examine the EVALUATE temporary access list to determine if incoming traffic is return traffic and if it should be permitted. This access list is applied inbound on the Fa0/1 interface, ensuring that incoming traffic is filtered based on this reflexive access list. Only return traffic will be allowed while all other traffic will be implicitly denied.
This feature is preferred compared to the established parameter because its usage is not limited to TCP sessions. UDP as well as other upper-layer protocols can be used in conjunction with reflexive access lists. However, some applications that use port numbers that change during a session may be disrupted. For example, reflexive access lists may cause disruption to applications such as FTP or VoIP, both of which use changing port numbers to operate. In addition, if there is any asymmetric routing or load sharing across multiple routers, this solution won’t work unless you take care to ensure that traffic is going through the same device in both directions.
This feature is the most advanced method of stateful firewall that can be configured on a Cisco IOS device and is actually quite elegant in its implementation.
How it works
Instead of creating multiple access lists and applying them to specific interfaces, you can create zones, and apply security policies to each zone pair. For example, take a look at this modified topology:
Here we have three zones: Inside, Outside, and DMZ. The interfaces of R2 are assigned to the zone we want, and we can apply policies that affect the traffic between zones. For the above topology, there are six zone pairs:
- Inside to Outside
- Inside to DMZ
- Outside to Inside
- Outside to DMZ
- DMZ to Inside
- DMZ to Outside
For each of these zone pairs, specific security policies can be applied.
Let’s go back to our original topology for simplicity:
Let’s create our zones and assign each interface to the appropriate zone.
R2(config)#zone security INSIDE R2(config)#zone security OUTSIDE R2(config)#interface fastEthernet 0/0 R2(config-if)#zone-member security INSIDE R2(config-if)#interface fastEthernet 0/1 R2(config-if)#zone-member security OUTSIDE
Now let’s take a look at the current status of our zones:
R2#show zone security zone self Description: System defined zone zone INSIDE Member Interfaces: FastEthernet0/0 zone OUTSIDE Member Interfaces: FastEthernet0/1
Great! We’ve got two zones, and one interface assigned to each.
Configuring zone pairs and policies
Once zones are configured, you can then configure the zone pairs like so:
R2(config)#zone-pair security INSIDE-TO-OUTSIDE source INSIDE destination OUTSIDE R2(config-sec-zone-pair)#description INSIDE-TO-OUTSIDE TRAFFIC R2(config-sec-zone-pair)#exit R2(config)#zone-pair security OUTSIDE-TO-INSIDE source OUTSIDE destination INSIDE R2(config-sec-zone-pair)#description OUTSIDE-TO-INSIDE TRAFFIC
By default, once configured, communication between zones is prohibited. If you try to ping R3 from R1, the ping will fail. To allow specific types of traffic, you must configure and apply security policies for each zone pair. These are implemented using policy maps. There are three actions that can be applied to matched traffic:
- Pass – where traffic is permitted
- Drop – where traffic is denied
- Inspect – where traffic is permitted and inspected so that return traffic will be passed
Here is an example of a policy that allows ICMP traffic from Inside to Outside:
R2(config)#class-map type inspect ICMP R2(config-cmap)#match protocol icmp R2(config-cmap)#exit R2(config)#policy-map type inspect INSIDE-TO-OUTSIDE R2(config-pmap)#class type inspect ICMP R2(config-pmap-c)#inspect
A class-map will match ICMP traffic, and a policy map will assign an action of “inspect” to that class map. This will allow traffic from Inside to Outside but will also allow return traffic due to the inspect action in the policy map. Now we can apply this policy map to our zone pair:
R2(config)#zone-pair security INSIDE-TO-OUTSIDE R2(config-sec-zone-pair)#service-policy type inspect INSIDE-TO-OUTSIDE
The result is that ICMP traffic can now traverse the R2 router from R1 to R3:
R1#ping 192.168.23.3 Type escape sequence to abort. Sending 5, 100-byte ICMP Echos to 192.168.23.3, timeout is 2 seconds: !!!!! Success rate is 100 percent (5/5), round-trip min/avg/max = 8/9/12 ms
But no other traffic, from any zone to any zone, can pass through! For more information about class maps and policy maps, take a look at this Cisco Documentation.
Context Based Access Control is most similar to reflexive access lists, but with a twist. Where reflexive ACLs inspect up to Layer 4, CBAC is able to inspect up to Layer 7 of the OSI model. Thus, it is able to filter traffic based on the application being served.
The problem being solved is the same as that described in the reflexive ACL section. The solution using CBAC is implanted as follows.
How it works
Let’s look at our topology again.
Because you don’t want traffic from the Internet entering your network, you apply the following access list:
R2(config)#ip access-list extended DENY_ALL_FROM_OUTSIDE R2(config-ext-nacl)#deny ip any any R2(config-ext-nacl)#exit R2(config)#interface fastEthernet 0/1 R2(config-if)#ip access-group DENY_ALL_FROM_OUTSIDE in
Let’s say R3 is a web server and R1 wants to reach that web server, but we want to ensure that R2 blocks all other traffic from the Internet. Using CBAC, we can do the following:
R2(config)#ip inspect name MY_FIREWALL http
We create what is called a CBAC inspect rule called MY_FIREWALL and tell it to inspect HTTP traffic. In other words, check to see if the Layer 7 protocol being used is HTTP. We then apply this inspect rule to an interface:
R2(config)#interface fastEthernet 0/1 R2(config-if)#ip inspect MY_FIREWALL out
Specifically, it is applied on Fa0/1 in R2 in an outbound direction. What does this do? It tells the router to keep track of all outbound communications that are using the HTTP protocol at Layer 7, and to allow return traffic that uses this protocol to pass through as an exemption to the applied access list. Remember, this occurs in addition to matching the source and destination IP addresses and ports, so it is applied specifically to sessions originating internally.
It is possible to create less restrictive rules that apply to more general categories of traffic types such as the following, which for the most part should be self-explanatory:
R2(config)#ip inspect name MY_FIREWALL tcp R2(config)#ip inspect name MY_FIREWALL udp R2(config)#ip inspect name MY_FIREWALL icmp
If you do have a Cisco IOS router on the edge of your network, and there are many businesses that do, these are some highly sophisticated security solutions that can be implemented almost immediately without any additional cost. To get more familiar with them, I suggest you experiment with them on a network emulator to learn their intricacies more intimately and to find out which one is the best for you. As always, make sure to implement them on your production network only during a maintenance window to ensure minimum downtime.