ASA firewall in multiple context mode

In our previous blog, we saw that the ASA can be virtualized into many virtual firewalls or contexts. Now, we will see how.

We will use this topology:

 

We will focus on ASA1 physical box and set it up. Let’s forget about ASA2 for now, because we will use it in a failover scenario later on.

Most often (or should I say always?) the ASA is in a single context mode. We bought it like that or was in production for some time in a single mode. Be that as it may, we need to switch it to a multiple mode. This requires a reboot and a valid license already installed.

ciscoasa#
ciscoasa# show mode
Security context mode: single
ciscoasa#
ciscoasa# conf t
ciscoasa(config)# mode multi
WARNING: This command will change the behavior of the device
WARNING: This command will initiate a Reboot
Proceed with change mode? [confirm]
Convert the system configuration? [confirm]
!
The old running configuration file will be written to flash

Converting the configuration – this may take several minutes for a large configuration

The admin context configuration will be written to flash

The new running configuration file was written to flash
Security context mode: multiple

***
*** — SHUTDOWN NOW —
***
*** Message to all terminals:
***
***   change mode

!!!
!!! Lines omitted while rebooting
!!!

ciscoasa#
ciscoasa# show mode
Security context mode: multiple
ciscoasa#

Now our box is in multiple mode. Like said in previous blog, our running config is split into two parts: a device configuration (interfaces up/down, VLANs, speed, duplex, failover, …) is stored as a system execution space in the NVRAM. A network part of running configuration (IP addressing and routing for a physical box, AAA servers, …) is saved into a file called “admin.cfg” on a flash disk. When we issue a “show run” from a console prompt, we will see commands from a system execution space:

ciscoasa#
ciscoasa# show run
: Saved
:
ASA Version 8.4(2) <system>
!
hostname ciscoasa
enable password 8Ry2YjIyt7RRXU24 encrypted
no mac-address auto
!
interface GigabitEthernet0
shutdown
!
interface GigabitEthernet1
shutdown
!
interface GigabitEthernet2
shutdown
!
interface GigabitEthernet3
shutdown
!
class default
limit-resource All 0
limit-resource ASDM 5
limit-resource SSH 5
limit-resource Telnet 5
!

ftp mode passive
pager lines 24
no failover
no asdm history enable
arp timeout 14400
console timeout 0

admin-context admin
context admin
config-url disk0:/admin.cfg
!

prompt hostname context
no call-home reporting anonymous
call-home
profile CiscoTAC-1
no active
destination address http https://tools.cisco.com/its/service/oddce/services/DDCEService
destination address email callhome@cisco.com
destination transport-method http
subscribe-to-alert-group diagnostic
subscribe-to-alert-group environment
subscribe-to-alert-group inventory periodic monthly
subscribe-to-alert-group configuration periodic monthly
subscribe-to-alert-group telemetry periodic daily
crashinfo save disable
Cryptochecksum:4e19f052af151a6bfa3bc9627a51cd5f
: end
ciscoasa#

Similar to this, we can see a network part by issuing “more disk0:/admin.cfg”:

ciscoasa#
ciscoasa# more disk0:/admin.cfg
: Saved
: Written by enable_15 at 12:17:16.969 UTC Thu Aug 9 2012
ASA Version 8.4(2)
hostname ciscoasa
enable password 8Ry2YjIyt7RRXU24 encrypted
passwd 2KFQnbNIdI.2KYOU encrypted
names
pager lines 24
icmp unreachable rate-limit 1 burst-size 1
no asdm history enable
arp timeout 14400
timeout xlate 3:00:00
timeout conn 1:00:00 half-closed 0:10:00 udp 0:02:00 icmp 0:00:02
timeout sunrpc 0:10:00 h323 0:05:00 h225 1:00:00 mgcp 0:05:00 mgcp-pat 0:05:00
timeout sip 0:30:00 sip_media 0:02:00 sip-invite 0:03:00 sip-disconnect 0:02:00
timeout sip-provisional-media 0:02:00 uauth 0:05:00 absolute
timeout tcp-proxy-reassembly 0:01:00
timeout floating-conn 0:00:00
user-identity default-domain LOCAL
no snmp-server location
no snmp-server contact
telnet timeout 5
ssh timeout 5
no threat-detection statistics tcp-intercept
: end

ciscoasa#

And our old running config is saved in a file called “old_running.cfg” on a flash, in case we want to revert back to a single mode scenario:

ciscoasa#
ciscoasa# dir disk0:

Directory of disk0:/

5      drwx  4096         13:16:00 Aug 07 2012  log
14     drwx  4096         13:16:04 Aug 07 2012  coredumpinfo
37     -rwx  196          13:16:04 Aug 07 2012  upgrade_startup_errors_201208071316.log
38     -rwx  196          13:18:54 Aug 07 2012  upgrade_startup_errors_201208071318.log
39     -rwx  196          13:27:52 Aug 07 2012  upgrade_startup_errors_201208071327.log
40     -rwx  196          13:37:42 Aug 07 2012  upgrade_startup_errors_201208071337.log
28     -rwx  0            14:00:54 Aug 07 2012  nat_ident_migrate
41     -rwx  1871         12:17:16 Aug 09 2012  old_running.cfg
42     -rwx  825          12:17:16 Aug 09 2012  admin.cfg

268136448 bytes total (267739136 bytes free)
ciscoasa#

The next step is to set up and bring up needed interfaces. This is done from a system execution space. We can tell that we are in this space from a prompt that contains only a hostname, not a slash sign followed by a context name:

ciscoasa#
ciscoasa# conf t
ciscoasa(config)# int gi1
ciscoasa(config-if)# no shut
ciscoasa(config-if)# int gi1.26
ciscoasa(config-subif)# vlan 26
ciscoasa(config-subif)# exit
ciscoasa(config)# int gi1.27
ciscoasa(config-subif)# vlan 27
ciscoasa(config-subif)# exit
ciscoasa(config)# int gi0
ciscoasa(config-if)# no shut
ciscoasa(config-if)# exit
ciscoasa(config)# exit
ciscoasa#

We are using a scenario with a separate inside sub-interfaces and a shared outside interface. This is the most common scenario.

Next, we need to create and/or initialize our contexts. For now, we will leave the admin context alone and create two user contexts. What ever we do inside these user contexts is applicable to the admin context. From the traffic flow perspective. The only conceptual difference is that the admin context is used to access to and from the box itself. It can be used as an ordinary context, but this is not recommended.

Let’s go ahead and create and initialize two user contexts:

ciscoasa#
ciscoasa# conf t
ciscoasa(config)# context Cust1
Creating context ‘Cust1’… Done. (3)
ciscoasa(config-ctx)# config-url disk0:/Cust1.cfg

WARNING: Could not fetch the URL disk0:/Cust1.cfg
INFO: Creating context with default config
ciscoasa(config-ctx)# allocate-interface gi1.26 INSIDE
ciscoasa(config-ctx)# allocate-interface gi0 OUTSIDE
ciscoasa(config-ctx)# exit
ciscoasa(config)#
ciscoasa(config)#
ciscoasa(config)# context Cust2
Creating context ‘Cust2’… Done. (4)
ciscoasa(config-ctx)# config-url disk0:/Cust2.cfg

WARNING: Could not fetch the URL disk0:/Cust2.cfg
INFO: Creating context with default config
ciscoasa(config-ctx)# allocate-interface gi1.27 INSIDE
ciscoasa(config-ctx)# allocate-interface gi0 OUTSIDE
ciscoasa(config-ctx)# exit
ciscoasa(config)# exit
ciscoasa#

So what just happened? Well, we created a context named “Cust1”. Then we said where the config for this context will be stored. For, now we must use local disk as a storage for this config file, because if we wanted to store it on a network, the admin context must be initialized first. Remember that the physical ASA uses admin context for communication.

After we say where to store a configuration, we allocate two interfaces for this context. One dedicated interface Gi1.26 that we called INSIDE and one shared interface Gi0, called OUTSIDE.

We then created a Cust2 context in a similar fashion.

Now we can switch to a context and see what’s inside:

ciscoasa#
ciscoasa# changeto context Cust1
ciscoasa/Cust1# show run
: Saved
:
ASA Version 8.4(2) <context>
!
hostname Cust1
enable password 8Ry2YjIyt7RRXU24 encrypted
passwd 2KFQnbNIdI.2KYOU encrypted
names
!
interface INSIDE
no nameif
no security-level
no ip address
!
interface OUTSIDE
no nameif
no security-level
no ip address
!
pager lines 24
icmp unreachable rate-limit 1 burst-size 1
no asdm history enable
arp timeout 14400
timeout xlate 3:00:00
timeout conn 1:00:00 half-closed 0:10:00 udp 0:02:00 icmp 0:00:02
timeout sunrpc 0:10:00 h323 0:05:00 h225 1:00:00 mgcp 0:05:00 mgcp-pat 0:05:00
timeout sip 0:30:00 sip_media 0:02:00 sip-invite 0:03:00 sip-disconnect 0:02:00
timeout sip-provisional-media 0:02:00 uauth 0:05:00 absolute
timeout tcp-proxy-reassembly 0:01:00
timeout floating-conn 0:00:00
user-identity default-domain LOCAL
no snmp-server location
no snmp-server contact
telnet timeout 5
ssh timeout 5
no threat-detection statistics tcp-intercept
!
class-map inspection_default
match default-inspection-traffic
!
!
policy-map type inspect dns preset_dns_map
parameters
message-length maximum client auto
message-length maximum 512
policy-map global_policy
class inspection_default
inspect dns preset_dns_map
inspect ftp
inspect h323 h225
inspect h323 ras
inspect ip-options
inspect netbios
inspect rsh
inspect rtsp
inspect skinny
inspect esmtp
inspect sqlnet
inspect sunrpc
inspect tftp
inspect sip
inspect xdmcp
!
service-policy global_policy global
Cryptochecksum:16d90e04d010a86b06d9ff471fe5ce96
: end
ciscoasa/Cust1#

Classic empty ASA configuration. I would like to pint out to interface names. By giving names INSIDE and OUTSIDE, we hide real interface names.

Let’s do a very basic setup from here and then allow Cust1 admin to go from there:

ciscoasa/Cust1#
ciscoasa/Cust1# conf t
ciscoasa/Cust1(config)# int INSIDE
ciscoasa/Cust1(config-if)# ip addr 192.168.26.1 255.255.255.0
ciscoasa/Cust1(config-if)# nameif inside
INFO: Security level for “inside” set to 100 by default.
ciscoasa/Cust1(config-if)# no shut
ciscoasa/Cust1(config-if)# exit
ciscoasa/Cust1(config)#
ciscoasa/Cust1(config)#
ciscoasa/Cust1(config)# telnet 0 0 INSIDE
ciscoasa/Cust1(config)# exit
ciscoasa/Cust1#
ciscoasa/Cust1# ping 192.168.26.2
Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 192.168.26.2, timeout is 2 seconds:
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 10/22/50 ms
ciscoasa/Cust1#

We gave the INSIDE interface an IP address and a security level. We brought it up, enabled a telnet access and verified connectivity to router CUSTOMER1. From now, we act as a Cust1 admin.

CUSTOMER1#
CUSTOMER1#ping 192.168.26.1

Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 192.168.26.1, timeout is 2 seconds:
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 8/26/44 ms
CUSTOMER1#
CUSTOMER1#192.168.26.1
Trying 192.168.26.1 … Open

User Access Verification

Password:
Type help or ‘?’ for a list of available commands.
ciscoasa/Cust1>
ciscoasa/Cust1> en
Password:
ciscoasa/Cust1#

As we can see, the Cust1 admin has successfully logged into his/her firewall. From here, without a clue that he/she is in a virtual firewall, he/she will continue to set this firewall according to a security policy. For demonstration purposes, he/she will set up basic routing and a NAT, so Cust1 users can access the Internet:

ciscoasa/Cust1(config)#
ciscoasa/Cust1(config)# int OUTSIDE
ciscoasa/Cust1(config-if)# ip addr 172.16.1.1 255.255.255.0
ciscoasa/Cust1(config-if)# nameif outside
INFO: Security level for “outside” set to 0 by default.
ciscoasa/Cust1(config-if)# no shut
ciscoasa/Cust1(config-if)# exit
ciscoasa/Cust1(config)# exit
ciscoasa/Cust1#

ciscoasa/Cust1#
ciscoasa/Cust1# conf t
ciscoasa/Cust1(config)# route outside 0 0 172.16.1.2
ciscoasa/Cust1(config)# ping 4.2.2.2
Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 4.2.2.2, timeout is 2 seconds:
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 1/8/10 ms
ciscoasa/Cust1(config)#
ciscoasa/Cust1(config)# exit
ciscoasa/Cust1#

So we now have a connectivity from Cust1 to the Internet. The 4.2.2.2 is the address of a loopback interface on router INTERNET.

Now we need to set up a NAT and ICMP inspection in order to allow Cust1 users to access the Internet:

ciscoasa/Cust1#
ciscoasa/Cust1# show run object
object network CUST1_LAN_1
subnet 192.168.26.0 255.255.255.0
ciscoasa/Cust1#
ciscoasa/Cust1# show run nat
nat (inside,outside) source dynamic CUST1_LAN_1 interface
ciscoasa/Cust1#

ciscoasa/Cust1(config)#
ciscoasa/Cust1(config)# fixup proto icmp
INFO: converting ‘fixup protocol icmp ‘ to MPF commands
ciscoasa/Cust1(config)#
ciscoasa/Cust1#

It is time to check this out. From CUSTOMER1 router:

CUSTOMER1#
CUSTOMER1#ping 4.2.2.2

Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 4.2.2.2, timeout is 2 seconds:
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 16/49/116 ms
CUSTOMER1#

And indeed we did go across the ASA, virtual firewall Cust1:

ciscoasa/Cust1#
ciscoasa/Cust1# show local-host
Interface outside: 0 active, 1 maximum active, 0 denied
Interface inside: 0 active, 1 maximum active, 0 denied
ciscoasa/Cust1#
ciscoasa/Cust1# show local-host
Interface outside: 0 active, 1 maximum active, 0 denied
Interface inside: 1 active, 1 maximum active, 0 denied
local host: <192.168.26.2>,
TCP flow count/limit = 0/unlimited
TCP embryonic count to host = 0
TCP intercept watermark = unlimited
UDP flow count/limit = 0/unlimited

Xlate:
ICMP PAT from inside:192.168.26.2/1 to outside:172.16.1.1/42255 flags ri idle 0:00:04 timeout 0:00:30
ciscoasa/Cust1#

Finally, don’t forget a “wr m”:

ciscoasa/Cust1#
ciscoasa/Cust1# wr
Building configuration…
Cryptochecksum: 9039f3df 9ddaeb79 e36cb066 7ecfae1b

1898 bytes copied in 1.890 secs (1898 bytes/sec)
[OK]
ciscoasa/Cust1#

We as an ISP admin, should also do a “wr” to save system execution space, do a “wr” from admin context to save network portion of configuration, or use a “wr m all” from system execution space to save everything: system execution space, admin context and all user contexts:

ciscoasa/Cust1#
ciscoasa/Cust1# changeto system
ciscoasa#
ciscoasa# wr m all
Building configuration…
Saving context :           system : (000/003 Contexts saved)
Cryptochecksum: c513a3b0 4b7b6b18 a3fba56d 8951067f

1560 bytes copied in 1.270 secs (1560 bytes/sec)
Saving context :            admin : (001/003 Contexts saved)
Cryptochecksum: c5234796 86327e1a 5320a6d0 fbd35d92

892 bytes copied in 1.390 secs (892 bytes/sec)
Saving context :            Cust1 : (002/003 Contexts saved)
Cryptochecksum: 9039f3df 9ddaeb79 e36cb066 7ecfae1b

1898 bytes copied in 1.500 secs (1898 bytes/sec)
Saving context :            Cust2 : (003/003 Contexts saved)
Cryptochecksum: 1ad968a5 2b5b535b 20d8b4d2 56db3ff2

1572 bytes copied in 1.650 secs (1572 bytes/sec)
[OK]
ciscoasa#

Please make a note of “changeto system” command. This way we switch from one context to system execution space. Of course, admins from user context are not able to do so:

ciscoasa/Cust1#
ciscoasa/Cust1# changeto system
Command not valid in current execution space
ciscoasa/Cust1#
ciscoasa/Cust1# changeto context Cust2
Command not valid in current execution space
ciscoasa/Cust1#

Now it’s time to set up a Cust2 context. We will not go through the whole process, because it’s the same. We will only list a full Cust2 config:

!
hostname Cust2
enable password 8Ry2YjIyt7RRXU24 encrypted
passwd 2KFQnbNIdI.2KYOU encrypted
names
!
interface INSIDE
nameif inside
security-level 100
ip address 192.168.27.1 255.255.255.0
!
interface OUTSIDE
nameif outside
security-level 0
ip address 172.16.1.11 255.255.255.0
!
object network CUST2_LAN_1
subnet 192.168.27.0 255.255.255.0
pager lines 24
mtu inside 1500
mtu outside 1500
icmp unreachable rate-limit 1 burst-size 1
no asdm history enable
arp timeout 14400
nat (inside,outside) source dynamic CUST2_LAN_1 interface
route outside 0.0.0.0 0.0.0.0 172.16.1.2 1
timeout xlate 3:00:00
timeout conn 1:00:00 half-closed 0:10:00 udp 0:02:00 icmp 0:00:02
timeout sunrpc 0:10:00 h323 0:05:00 h225 1:00:00 mgcp 0:05:00 mgcp-pat 0:05:00
timeout sip 0:30:00 sip_media 0:02:00 sip-invite 0:03:00 sip-disconnect 0:02:00
timeout sip-provisional-media 0:02:00 uauth 0:05:00 absolute
timeout tcp-proxy-reassembly 0:01:00
timeout floating-conn 0:00:00
user-identity default-domain LOCAL
no snmp-server location
no snmp-server contact
telnet 0.0.0.0 0.0.0.0 inside
telnet timeout 5
ssh timeout 5
no threat-detection statistics tcp-intercept
!
class-map inspection_default
match default-inspection-traffic
!
!
policy-map type inspect dns preset_dns_map
parameters
message-length maximum client auto
message-length maximum 512
policy-map global_policy
class inspection_default
inspect dns preset_dns_map
inspect ftp
inspect h323 h225
inspect h323 ras
inspect ip-options
inspect netbios
inspect rsh
inspect rtsp
inspect skinny
inspect esmtp
inspect sqlnet
inspect sunrpc
inspect tftp
inspect sip
inspect xdmcp
inspect icmp
!
service-policy global_policy global

If we now initiate separate telnet sessions from CUSTOMER1 and CUSTOMER2 to INTERNET router, we will see that the two contexts behave like separate firewalls:

ciscoasa/Cust1#
ciscoasa/Cust1# show local-host
Interface outside: 1 active, 1 maximum active, 0 denied
local host: <4.2.2.2>,
TCP flow count/limit = 1/unlimited
TCP embryonic count to host = 0
TCP intercept watermark = unlimited
UDP flow count/limit = 0/unlimited

Conn:
TCP outside 4.2.2.2:23 inside 192.168.26.2:23365, idle 0:00:24, bytes 110, flags UIO
Interface inside: 1 active, 1 maximum active, 0 denied
local host: <192.168.26.2>,
TCP flow count/limit = 1/unlimited
TCP embryonic count to host = 0
TCP intercept watermark = unlimited
UDP flow count/limit = 0/unlimited

Xlate:
TCP PAT from inside:192.168.26.2/23365 to outside:172.16.1.1/13746 flags ri idle 0:00:27 timeout 0:00:30

Conn:
TCP outside 4.2.2.2:23 inside 192.168.26.2:23365, idle 0:00:24, bytes 110, flags UIO
ciscoasa/Cust1#

ciscoasa/Cust2#
ciscoasa/Cust2# show local-host
Interface outside: 1 active, 1 maximum active, 0 denied
local host: <4.2.2.2>,
TCP flow count/limit = 1/unlimited
TCP embryonic count to host = 0
TCP intercept watermark = unlimited
UDP flow count/limit = 0/unlimited

Conn:
TCP outside 4.2.2.2:23 inside 192.168.27.2:26391, idle 0:01:00, bytes 110, flags UIO
Interface inside: 1 active, 1 maximum active, 0 denied
local host: <192.168.27.2>,
TCP flow count/limit = 1/unlimited
TCP embryonic count to host = 0
TCP intercept watermark = unlimited
UDP flow count/limit = 0/unlimited

Xlate:
TCP PAT from inside:192.168.27.2/26391 to outside:172.16.1.11/30213 flags ri idle 0:01:02 timeout 0:00:30

Conn:
TCP outside 4.2.2.2:23 inside 192.168.27.2:26391, idle 0:01:00, bytes 110, flags UIO
ciscoasa/Cust2#

And INTERNET router sees both connections NATed to respective outside interfaces:

INTERNET#
INTERNET#who
Line       User       Host(s)              Idle       Location
*  0 con 0                idle                 00:00:00
98 vty 0                idle                 00:01:27 172.16.1.1
99 vty 1                idle                 00:01:20 172.16.1.11

Interface    User               Mode         Idle     Peer Address

INTERNET#

Next time we will try to put this multi context ASA into failover cluster.

Advertisements
This entry was posted in ASA, Cisco, Virtualization and tagged , , , , . Bookmark the permalink.

3 Responses to ASA firewall in multiple context mode

  1. adilmhaisker says:

    Amazing post.
    Although, I tried to telnet from outside interface of Customer context, and I am not able to do so, (I can ping and all) even when I allow manually it in the context configuration.
    Any reasons for the same???

    • Sasa says:

      Make sure you are actually getting to the right context. Use debugs or shows, or perhaps forbid the icmp for testing purposes. If you are hitting the right place with icmp and telnet is allowed, it should work.

  2. sindhuja says:

    while doing in failover in multle context mode where we have to write the failover configs that means in system , admin or context as well as i want to copy asdm image ..so where i have to copy in system,admin or context ?

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s