As things tend to go in the world o' networking, Friday proved immensely hectic.
I would've liked to have gotten this lab posted last night, but I made some last-minute changes to restrict SSH access to our "webserver" in the DMZ for a management subnet on the Inside security zone -- which I'm pretty pleased worked on the first attempt (save for a caveat where, when SSHing from a router (which I used as a makeshift "AdminTestHost") you have to enable SSHv2 to use it as a client).
All of that jargon aside, let's get going on what is, honestly, one of my new favorite lab implementations!
========================================================================
Above is the topology that we're using for the lab. Pretty straight-forward, with a bit of OSPF thrown in there for the sake of not having to build static routes. For testing Outside to DMZ traffic, I've hooked an Ubuntu VM in VirtualBox onto GNS3, on which we can generate some Nmap traffic to prove out ZBF config. I won't go into details on how to set that up, a) because this post is about properly building ZBF, and b) because there's plenty of guides online already for VMs/GNS3/Nmap.
I'll assume that, if you're at the point of curiosity about ZBFs, you probably already have the base knowledge required to cable/VLAN/IP address/route the topology. So, let's jump right into the ZBF config on our edge Cisco 7200 running IOS 15.0. I'll enclose comments between the sections explaining briefly what each part does.
class-map type inspect match-any DMZ-to-Outside
match protocol icmp
match protocol http
!
//Class-map is used by the Policy-Map to inspect traffic moving between defined Security Zones. An "inspect" Class-Map must be used with an "inspect" Policy-Map//
!
policy-map type inspect VLAN-10-DMZ-to-Outside
class type inspect DMZ-to-Outside
inspect
class class-default
drop log
!
//The Policy-Map is used by our Zone-Pair Service-Policy to inspect traffic matched by the Class-Map. If it matches (and we haven't specified any additional Parameter-Map to provide more granular control of traffic volume), the traffic passes. If there's no match, the traffic is dropped by default (I added the "log" for fun later)//
!
zone security VLAN10-WebServer1-DMZ
description Security zone for WebServer1
zone security Outside
description Outside to Internet
zone-pair security Outside-to-VLAN-10-DMZ source Outside destination VLAN10-WebServer1-DMZ
service-policy type inspect VLAN-10-DMZ-to-Outside
!
//Before you can define a Zone-Pair, or make interfaces Zone members, you need to define the Security Zones. Once interfaces have been made a zone-member (an interface can only belong to one zone), you can define the Zone-Pair. The pair is what controls traffic flow and applies our Policy-Map to it. You only need to define a zone-pair in one direction as traffic initiated in that direction is covered by the same Zone-Pair when we see return traffic. For security purposes, I've only created a Zone-Pair for traffic sourced from our DMZ destined for the Outside. If we needed our WebServer to hit the Internet for updates, etc., we would need to build a Zone-Pair where DMZ can source first//
!
interface FastEthernet0/0
description Outside
ip address 172.31.122.2 255.255.255.248
ip nat outside
ip virtual-reassembly
zone-member security Outside
duplex full
!
//Above and below, we add the Outside and DMZ interfaces to their respective Security Zones//
!
interface FastEthernet1/0.10
description VLAN10-WebServer-1-DMZ
encapsulation dot1Q 10
ip address 192.168.10.1 255.255.255.0
ip nat inside
ip virtual-reassembly
zone-member security VLAN10-WebServer1-DMZ
Now, let's confirm everything was built correctly:
Edge-7200#sh policy-map type inspect zone-pair sessionWe'll enable HTTP access ((config)#ip http server) on our "WebServer1" then try to Nmap our WebServer (172.31.122.3) from our Outside VM. Also, to add a bit of cool output when we run our next Nmap, I changed the policy-map class-default from "drop" to "drop log" on the edge 7200.
policy exists on zp Outside-to-VLAN-10-DMZ
Zone-pair: Outside-to-VLAN-10-DMZ
Service-policy inspect : VLAN-10-DMZ-to-Outside
Class-map: DMZ-to-Outside (match-any)
Match: protocol icmp
0 packets, 0 bytes
30 second rate 0 bps
Match: protocol udp
0 packets, 0 bytes
30 second rate 0 bps
Match: protocol tcp
0 packets, 0 bytes
30 second rate 0 bps
Inspect
Class-map: class-default (match-any)
Match: any
Drop
0 packets, 0 bytes
capn@capn-VirtualBox:~$ nmap -n 172.31.122.3
Nmap scan report for 173.31.122.3
Host is up (0.33c latency)
Not shown: 999 filtered ports
PORT STATE SERVICE
80/tcp open http
On our edge Cisco 7200, we can see the results of the Nmap against our ZBF policy where it rejects attempts over HTTPS, SMTP, and POP3:
*Feb 20 18:52:29.683: %FW-6-DROP_PKT: Dropping tcp session 192.168.56.102:48964 192.168.10.100:443 on zone-pairNow that that's all setup, we'll add an Inside zone and some rules to allow us to SSH into our WebServer from the Inside for management, but drop any attempts to do so from the Outside. First, we'll build SSH access on our router masquerading as a WebServer.
Outside-to-VLAN-10-DMZ class class-default due to DROP action found in policy-map with ip ident 0
*Feb 20 18:52:33.067: %FW-6-LOG_SUMMARY: 1 packet were dropped from 192.168.56.102:48964 => 192.168.10.100:443
(target:class)-(Outside-to-VLAN-10-DMZ:class-default)
*Feb 20 18:52:33.067: %FW-6-LOG_SUMMARY: 1 packet were dropped from 192.168.56.102:48965 => 192.168.10.100:443
(target:class)-(Outside-to-VLAN-10-DMZ:class-default)
*Feb 20 18:52:33.071: %FW-6-LOG_SUMMARY: 1 packet were dropped from 192.168.56.102:55985 => 192.168.10.100:587
(target:class)-(Outside-to-VLAN-10-DMZ:class-default)
*Feb 20 18:52:33.071: %FW-6-LOG_SUMMARY: 2 packets were dropped from 192.168.56.102:46872 => 192.168.10.100:25
(target:class)-(Outside-to-VLAN-10-DMZ:class-default)
*Feb 20 18:52:33.071: %FW-6-LOG_SUMMARY: 2 packets were dropped from 192.168.56.102:36496 => 192.168.10.100:110
!
truncated for brevity
!
WebServer1(config)#ip domain-name LabCorp.net
WebServer1(config)#username admin password root
WebServer1(config)#aaa new-model
WebServer1(config)#crypto key gen rsa
The name for the keys will be: WebServer1.LabCorp.net
Choose the size of the key modulus in the range of 360 to 2048 for your
General Purpose Keys. Choosing a key modulus greater than 512 may take
a few minutes.
How many bits in the modulus [512]: 1024
% Generating 1024 bit RSA keys, keys will be non-exportable...[OK]
WebServer1(config)#
*Mar 1 00:28:24.143: %SSH-5-ENABLED: SSH 2.0 has been enabled
WebServer1(config)#ip ssh ver 2
WebServer1(config)#line vty 0 935
WebServer1(config-line)#password root
WebServer1(config-line)#transport input ssh
WebServer1(config)#service password-encrypt
WebServer1(config)#no service password-encrypt
Just for fun, I added "match protocol ssh" to the class-map on the Edge-7200 and attempted to SSH in from the my VM on the Outside to WebServer1:
capn@capn-VirtualBox:~$ ssh -l admin 172.31.122.3
admin@172.31.122.3's password:
WebServer1>exit
Connection to 172.31.122.3 closed
Ok, we'll tear that match off the class-map now aaaand...just as we hoped, we can't SSH into WebServer1 from our Outside VM anymore!
capn@capn-VirtualBox:~$ ssh -l admin 172.31.122.3
^C
capn@capn-VirtualBox:~$
And look what appeared on our Edge-7200!
*Feb 19 16:20:31.435: %FW-6-DROP_PKT: Dropping tcp session 192.168.56.102:41216 192.168.10.100:22 on zone-pair
Outside-to-VLAN-10-DMZ class class-default due to DROP action found in policy-map with ip ident 0
Edge-7200#
*Feb 19 16:20:38.075: %FW-6-LOG_SUMMARY: 3 packets were dropped from 192.168.56.102:41216 => 192.168.10.100:22 (target:class)-(Outside-to-VLAN-10-DMZ:class-default)
For implementing our Inside with some simplicity, we'll hang our Inside LAN zone off of fa1/1 (10.1.1.1) on our Edge-7200 with an MLS and put fa1/1 of our 7200 in OSPF area 0, fa1/0.10 (192.168.10.1) of our 7200 (the gateway for our VLAN 10 WebServer1 DMZ) as a passive-int in area 0 as well, and then our Inside LAN as part of area 0 as well. It's not included below because, when I originally wrote this, I was planning on using a host connection, but the 192.168.1.0/24 off of LAN-Switch fa0/1 for AdminTestHost was also put into OSPF Area 0 as a passive-int. It's just not included in the RIB output below because that was done later. For the sake of information, LAN-Switch is advertising 192.168.1.0/24 into OSPF so WebServer traffic hitting the 7200 can find its way back to the AdminTestHost.
Let's check our RIB on our LAN-Switch:
LAN-Switch#sh ip route
Gateway of last resort is 10.1.1.1 to network 0.0.0.0
O*E2 0.0.0.0/0 [110/1] via 10.1.1.1, 00:11:58, Ethernet1/1 <--used "default-info originate always" on 7200
10.0.0.0/8 is variably subnetted, 2 subnets, 2 masks
C 10.1.1.0/30 is directly connected, Ethernet1/1
L 10.1.1.2/32 is directly connected, Ethernet1/1
O 192.168.10.0/24 [110/11] via 10.1.1.1, 00:10:24, Ethernet1/1
We can ping DMZ gateway fa1/0.10 (192.168.10.1) and Outside fa0/0 (172.31.122.2) of our 7200 from the LAN -- this is because traffic destined to a zone's interface itself won't be inspected/dropped as part of the ZBF policy. I have a suspicion that we won't be able to hit WebServer1 without a zone-pair built, and we definitely won't be able to hit R1's fa0/0 (172.31.122.1) without a NAT pool and a zone-pair.
LAN-Switch#ping 192.168.10.1
Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 192.168.10.1, timeout is 2 seconds:
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 39/40/41 ms
LAN-Switch#ping 172.31.122.2
Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 172.31.122.2, timeout is 2 seconds:
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 40/40/42 ms
LAN-Switch#ping 192.168.10.100
Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 192.168.10.100, timeout is 2 seconds:
.....
Success rate is 0 percent (0/5)
LAN-Switch#ping 172.31.122.1
Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 172.31.122.1, timeout is 2 seconds:
.....
Success rate is 0 percent (0/5)
Let's start by building the NAT pool. We'll just permit 10.1.1.0/30 to start, because our test pings from the LAN-Switch are going to be sourced from 10.1.1.2 anyways. We'll add to the ACL so the rest of Inside can get Outside later.
Edge-7200(config)#access-list 1 permit 10.1.1.0 0.0.0.3
Edge-7200(config)#ip nat inside source list 1 pool Inside-LAN-NAT-Pool overload
Edge-7200(config)#ip nat pool Inside-LAN-NAT-Pool 172.31.122.4 172.31.122.4 netmask 255.255.255.248
Edge-7200(config)#int fa1/1
Edge-7200(config-if)#ip nat inside
Ok, the NAT (or rather, PAT) pool is built. Just to prove that it's not enough to setup NAT and that we need the zone-pair as well, let's try to ping 172.31.122.1 once more:
Success rate is 0 percent (0/5)
LAN-Switch#ping 172.31.122.1
Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 172.31.122.1, timeout is 2 seconds:
.....
Success rate is 0 percent (0/5)
Yup, no luck. Let's get to building that new Inside to Outside zone-pair. Here's the additional config added. We'll start with just matching icmp for the sake of proving pings. For the sake of demonstrating class-map match-all inspects with an access-group, later we'll setup all of Inside LAN with the ability to open HTTP sessions to WebServer1, but only an admin subnet (192.168.1.0/24) with the ability to SSH from Inside to WebServer1 in the DMZ.
class-map type inspect match-any InsideToInternet
match protocol icmp
!
!
policy-map type inspect Inside-to-Outside
class type inspect InsideToInternet
inspect
class class-default
drop log
!
zone security Outside
description Outside to Internet
zone security Inside
description Inside to LabCorp LAN
!
zone-pair security Inside-LAN-to-Outside source Inside destination Outside
service-policy type inspect Inside-to-Outside
!
!
interface FastEthernet1/1
ip address 10.1.1.1 255.255.255.252
ip nat inside
ip virtual-reassembly
zone-member security Inside
Now, let's see if we can ping from our Inside LAN Switch to the Outside R1's fa0/0 and loopback1:
LAN-Switch#ping 172.31.122.1
Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 172.31.122.1, timeout is 2 seconds:
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 21/37/68 ms
LAN-Switch#ping 216.36.1.1
Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 216.36.1.1, timeout is 2 seconds:
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 19/28/52 ms
Inside to Outside access is good, so now let's get some access for users in our Inside LAN to our DMZ WebServer1, and we'll build that exclusive admin subnet SSH management access I mentioned earlier!
Edge-7200(config)#class-map type inspect match-any Inside-to-WebServer1-DMZ
Edge-7200(config-cmap)#match protocol icmp
Edge-7200(config-cmap)#match protocol http
Edge-7200(config-cmap)#match protocol https
Edge-7200(config)#class-map type inspect match-any Inside-Admins-Traffic
Edge-7200(config-cmap)#match protocol ssh
Edge-7200(config-cmap)#match protocol icmp
Edge-7200(config-cmap)#match protocol https
Edge-7200(config)#class-map type inspect match-all Inside-Admins-to-WebServer1-DMZ
Edge-7200(config-cmap)#match class-map Inside-Admins-Traffic
Edge-7200(config-cmap)#match access-group name AdminSubnet
Edge-7200(config)#ip access-list extended AdminSubnet
Edge-7200(config-ext-acl)#permit ip 192.168.1.0 0.0.0.255 host 192.168.10.100
Edge-7200(config)#policy-map type inspect Inside-to-WebServer1-DMZ
Edge-7200(config-pmap)#class type inspect Inside-to-WebServer1-DMZ
Edge-7200(config-pmap-c)#inspect
Edge-7200(config-pmap)#class type inspect Inside-Admins-to-WebServer1-DMZ
Edge-7200(config-pmap-c)#inspect
Edge-7200(config-pmap)#class class-default
Edge-7200(config-pmap-c)#drop log
Edge-7200(config)#zone-pair security Inside-to-WebServer1-DMZ source Inside destination VLAN10-WebServer1-DMZ
Edge-7200(config-sec-zone-pair)#service-policy type inspect Inside-to-WebServer1-DMZ
NOTE: Not sure if you have any background with class-maps, but the purpose of using "match-all" on the third map above, rather than the "match-any" that we've been using thus-far, is that "match-any" is an OR logic, whereas "match-all" is an AND logic. In order for the traffic to qualify for this class-map, not only does it need to be of one of the protocols we specified in "match class-map Inside-Admins-Traffic" for SSH/ICMP/HTTPS, the traffic also needs to match our Extended ACL which only permits traffic sourced from the management subnet (192.168.1.0/24) destined for the webserver (192.168.10.100).
First, let's start by pinging from our Inside router R3 to verify basic, non-admin, Inside traffic to WebServer1
R3#ping 192.168.10.100
Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 192.168.10.100, timeout is 2 seconds:
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 28/39/68 ms
Looks good. Now, let's see if we can SSH to it from non-admin Inside
R3#ssh -l admin 192.168.10.100
R3#
And we can confirm it failed on our Edge-7200
Edge-7200#
*Feb 20 20:15:30.355: %FW-6-DROP_PKT: Dropping ssh session 10.1.1.2:13309 192.168.10.100:22 on zone-pair Inside-to-WebServer1-DMZ class class-default due to DROP action found in policy-map with ip ident 0
Edge-7200#
*Feb 20 20:15:33.067: %FW-6-LOG_SUMMARY: 2 packets were dropped from 10.1.1.2:13309 => 192.168.10.100:22 (target:class)-(Inside-to-WebServer1-DMZ:class-default)
Let's try it from our AdminTestHost (R4) whose interface is 192.168.1.42
AdminTestHost#ssh -l admin 192.168.10.100
[Connection to 192.168.10.100 aborted: error status 0]
AdminTestHost#ping 192.168.10.100
Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 192.168.10.100, timeout is 2 seconds:
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 32/56/92 ms
Well, we can ping it...and the ZBF config is good...maybe we need to enable SSHv2 on our "AdminTestHost" which is actually just a router masquerading as a host. Spoiler: Yes, that was the case. Jumped through the hoops to get SSHv2 enabled on our AdminTestHost aaaaand...
AdminTestHost#ssh -l admin 192.168.10.100
Password:
WebServer1>
Success! We can officially:
- Send non-admin traffic from Inside to WebServer1 in the DMZ, but not SSH to it
- Send admin traffic from Inside to WebServer1 in the DMZ and SSH to it
- Send Inside traffic to the Outside Internet
- Nmap from the Outside to our WebServer1 in the DMZ to verify that only HTTP (port 80) is open
Below is our final ZBF config we built on our Edge-7200 to allow all this to be possible, and what a hell of a lab it's been. Go get yourself a scotch and celebrate success! Thanks for sticking with it to the end.
class-map type inspect match-any Inside-Admins-Traffic
match protocol ssh
match protocol icmp
match protocol https
class-map type inspect match-all Inside-Admins-to-WebServer1-DMZ
match class-map Inside-Admins-Traffic
match access-group name AdminSubnet
class-map type inspect match-any DMZ-to-Outside
match protocol icmp
match protocol http
class-map type inspect match-any Inside-to-WebServer1-DMZ
match protocol icmp
match protocol http
match protocol https
class-map type inspect match-any InsideToInternet
match protocol icmp
!
!
policy-map type inspect VLAN-10-DMZ-to-Outside
class type inspect DMZ-to-Outside
inspect
class class-default
drop log
policy-map type inspect Inside-to-WebServer1-DMZ
class type inspect Inside-to-WebServer1-DMZ
inspect
class type inspect Inside-Admins-to-WebServer1-DMZ
inspect
class class-default
drop log
policy-map type inspect Inside-to-Outside
class type inspect InsideToInternet
inspect
class class-default
drop log
!
zone security VLAN10-WebServer1-DMZ
description Security zone for WebServer1
zone security Outside
description Outside to Internet
zone security Inside
description Inside to LabCorp LAN
zone-pair security Outside-to-VLAN-10-DMZ source Outside destination VLAN10-WebServer1-DMZ
service-policy type inspect VLAN-10-DMZ-to-Outside
zone-pair security Inside-LAN-to-Outside source Inside destination Outside
service-policy type inspect Inside-to-Outside
zone-pair security Inside-to-WebServer1-DMZ source Inside destination VLAN10-WebServer1-DMZ
service-policy type inspect Inside-to-WebServer1-DMZ
!
!
interface FastEthernet0/0
description Outside
ip address 172.31.122.2 255.255.255.248
ip nat outside
ip virtual-reassembly
zone-member security Outside
duplex full
!
!
interface FastEthernet1/0.10
description VLAN10-WebServer-1-DMZ
encapsulation dot1Q 10
ip address 192.168.10.1 255.255.255.0
ip nat inside
ip virtual-reassembly
zone-member security VLAN10-WebServer1-DMZ
ip ospf 1 area 0
!
interface FastEthernet1/1
ip address 10.1.1.1 255.255.255.252
ip nat inside
ip virtual-reassembly
zone-member security Inside
ip ospf authentication message-digest
ip ospf message-digest-key 1 md5 LabCorpOSPF
ip ospf 1 area 0
duplex auto
speed auto
No comments:
Post a Comment