Hi everyone, and welcome to this article in our network reliability series. In the previous article, we explored network redundancy in ASA firewalls by using Cisco’s active/standby failover mechanism. You can read the article here. In this article, we will further explore network reliability in Cisco firewalls by exploring the active/active failover mechanism.
I’ll start off by issuing a disclaimer here: Cisco’s ASA failover mechanism is an active/standby mechanism. This means that, at every point, only one firewall can be active in a failover group. So how can we create a scenario where we have active/active failover? We simply use more than one failover group. That sounds easy, right? Well, not exactly. The issue is that a “firewall” can only be a member of one failover group. So how do we get a firewall to join more than one group? We can do that by creating multiple virtual firewalls within the firewall. And this virtualization concept is called security contexts.
ASA Security Contexts
Security contexts are instances of an ASA that are created on the physical firewall. A typical reason to do this is if you have multiple customers with different addressing spaces and different security policies (assuming you are a service provide or a large enterprise organization) and you do not want to purchase multiple firewalls to serve this purpose. However, you should be aware that some of the cool features of the physical ASA are sacrificed to enable this kind of virtualization. With multiple contexts, you cannot:
Enable multicast routing
Enable IPv6 (OSPFv3) routing
Support remote access VPNs (until recently, site-to-site VPNs were also unsupported)
Enable threat detection
As you can see from the list above, the unsupported features (except remote access VPNs) are not frequently required on firewalls anyway, so you might get away with deploying multiple contexts in your network without any issues.
So how does this work? Once an ASA is converted to multiple context mode, the ASA will keep a separate configuration file for each of the contexts and a common system configuration file for system administration purposes (adding contexts, allocating interfaces to contexts, etc.).
From a management perspective, you can log into different contexts separately, but one of the contexts is the admin context, from which you can access the system configuration to manage all other contexts. You can assign interfaces to unique contexts and interfaces can be shared between different contexts. I will not dive into the details of various multiple context designs in this article, since the focus is actually setting up active/active failover using multiple contexts. Let us set up a simple multiple context scenario and configure active/active failover.
Configuring Multiple Contexts
The first step in creating security contexts is to enable the firewall to function in multiple-context mode. BY default, ASA’s are in single-context mode. You can enable this multiple context using the command:
FW1(config)# mode multiple
Once this command is entered, two configuration files are created: The system configuration file and a new admin.cfg, which is the configuration file for the administrative context. The running config before the multiple context would be saved as old_running.cfg in the flash memory. This is useful, in case you want to revert to single mode. In that case, you can just copy the old running config to startup config, change mode to single, and reload the device.
The next step is to create contexts using the “context” command. Once this is done, you are placed in a context configuration mode, in which you can assign interfaces to the context and allocate other resources to the context. In this case, let’s create a context ctx_A and assign interfaces Gig0/0 and G0/1 to that context.
FW1(config)# context ctx_A FW1(config-ctx)# allocate-interface Gig0/0 int1 FW1(config-ctx)# allocate-interface Gig0/1 int2
TIP: If you don’t want to use shared interfaces in your contexts, you can create sub-interfaces in the system configuration and then assign these sub-interfaces to individual contexts. By doing this, you can reuse the same physical interface as different logical entities without sharing them.
You can specify the administrative context by using the command:
FW1(config)# admin context
You can also specify URLs to download the context configurations from; in that case, the firewall will download the configuration for that context from the URL. The URL specified must be reachable from the admin context.
To switch between contexts and to the system configuration, you can use the “changeto” command. For example, to change to the context we just created, I’d issue the command:
FW1(config)# changeto context ctx_A FW1/ctx_A(config)#
Notice the prompt change when you switch inside the context. This is useful to administrators so they can know what part of the firewalls they are configuring. To go back to the system configuration space, just issue the “changeto system” command.
Once you drop to the context level, you can configure the “virtual firewall” as though it was a physical firewall, barring the features that are unsupported (of course). Now let’s look at how we can leverage on multiple contexts to design active/active failover scenarios.
Active/Active Failover Using Multiple Contexts
For active/active failover, firewalls with multiple contexts are configured in failover groups. Then contexts are assigned to these different failover groups. One firewall is configured as active for the first failover group and the other firewall is configured as active for the second group. This way, both firewalls can pass traffic at the same time.
The firewall in the active state in a failover group is responsible for the configuration of the context in that group. The system configuration is always managed from failover group 1. This is the same with the admin context. Now, I know all this might sound a bit more complex than it actually is, so let us see how this is configured on the command line:
Configure the primary (physical device) with IP addresses and other relevant security policies. Remember to use the “changeto context” command to go under the context for context-specific configuration. When configuring interfaces with IP addresses, use the standby command to configure the IP address for the standby peer of that interface:
FW1/ctx_A (config)# interface int1 FW1/ctx_A (config-if)# nameif outside FW1/ctx_A (config-if)# ip address 18.104.22.168 255.255.255.0 standby 22.214.171.124 FW1/ctx_A (config-if)# no shutdown FW1/ctx_A (config-if)# exit FW1/ctx_A (config)#
Next step is to configure the failover characteristics. This is done from the system. So remember to changeto system first:
FW1/ctx_A (config)# changeto system FW1(config)# failover lan unit primary FW1(config)# failover lan interface intense_school Ethernet0/5 FW1(config)# failover interface ip intense_school 192.168.0.1 255.255.255.0 standby 192.168.0.2 FW1(config)# interface Ethernet0/5 FW1(config-if)# no shutdown FW1(config-if)# exit FW1(config)#
The commands above specify that FW1 is the primary failover unit. It also that specifies interface Ethernet0/5 is the failover link and gives it an IP address. Finally, we enable the failover link using the no shutdown command.
The next step is to specify the interface for LAN-based failover. In this case, we would just use the same interface (Ethernet0/5):
FW1(config)# failover link intense_school Ethernet0/2
Now, we can go ahead and create our failover groups and determine which failover groups will be active on this firewall:
FW1(config)# failover group 1 FW1(config-fover-group)# primary FW1(config-fover-group)# exit FW1(config)# failover group 2 FW1(config-fover-group)# secondary FW1(config-fover-group)# exit
Next step is to assign the contexts to failover groups:
FW1(config)# context ctx_A FW1(config-context)# join-failover-group 1 FW1(config-context)# exit FW1(config)# context ctx_B FW1(config-context)# join-failover-group 2 FW1(config-context)# exit
Next step is to enable failover on this link:
Whew, that was a lot of commands. On the secondary firewall, we only need to configure the failover-related commands. We don’t need to configure context-specific commands at the beginning (despite the fact that it will become the active peer for one of those contexts);
FW2(config)# failover lan unit secondary FW2(config)# failover lan interface intense_school Ethernet0/5 FW2(config)# failover interface ip intense_school 192.168.0.1 255.255.255.0 standby 192.168.0.2 FW2(config)# interface Ethernet0/5 FW2(config-if)# no shutdown FW2(config-if)# exit FW2(config)#
Notice that we did not create failover groups or assign contexts on the secondary firewall. This is because that is automatically done for us (along with other parts of the config) when we replicate the configuration using the failover command:
At this point, we save the configuration and check the status of the failover. In some cases, both contexts might be stuck in active on FW1 because it came up first. There are two things we can do in this scenario. We can force the primary firewall to stop being active for the second failover group:
FW1# no failover active group 2
We can also configure preemption to ensure that the right device takes over the failover group when it comes online:
FW1(config)#)# failover group 1 FW1(config-fover-group)# preempt FW1(config)# failover group 2 FW1(config-fover-group)# preempt
Clearly, active/active redundancy improves reliability of systems while optimizing return on investments. However, with Cisco ASA firewalls, it takes careful design and optimization to ensure that we integrate all of the technologies involved to get this running. There are other bits of optimization that can be enabled to make this scenario even more resilient (and I will write about them if I get some time!), but this article is a good start to configuring resilient firewalls. I hope you enjoyed reading it as much as I enjoyed writing it.
Thank you very much for reading and I look forward to writing more articles soon!
Multiple Contexts on the ASA:
Active/Active Failover on ASA: