Wednesday, July 30, 2014

Advanced Cisco Routing: GRE Tunnels

Suppose you had a network that spanned an untrusted carrier's network -- say, the Internet, for example. A wise admin probably would not be comfortable broadcasting company data across this untrusted network; any number of common LAN protocols, such as POP3, CIFS, HTTP, Telnet, etc. could potentially leak confidential data, like user names and passwords, to anyone who happened to be listening in. Even on relatively trustworthy networks such as leased lines or Metro-Ethernet E-Line or E-Tree services, a simple configuration error could result in propagating company data to other organizations on that network.

One solution to this problem is "tunneling" -- that is, encapsulating the raw TCP/IP traffic into another format. This is often used to create VPN's, or "Virtual Private Networks." A tunnel does not necessarily have to be encrypted, although it frequently is.

One protocol that is used on Cisco devices to create tunnels is GRE, which will be the focus of today's post.

Consider the following network:

In this example, I have created two LAN segments, one in Anchorage (R3 and R5) and one in Bethel(R4 and R6), connected by a service provider's network (R1 and R2). The configuration on R1 and R2 are very straightforward: turn up the necessary network interfaces, set up OSPF to share routes between R1 and R2, then configure BGP to peer with the Anchorage and Bethel routers (R3 and R4), all of which we've done before. R5 and R6 are also very straightforward: turn up FA1/0 on both routers, assign the appropriate IP addresses to each router, then set up a default route through R3 for R5 and through R4 for R6. As usual, these two routers are simply simulating PCs on the internal LAN.

R3 and R4 are the routers that where the magic happens in this lab. Essentially, a tunnel interface is just a logical interface on the router that is configured much like a physical interface. For GRE, the interface name is "Tunnel1" and the IP address of the tunnel interface is configured exactly like the IP address of any other interface on the router. On R3...:
interface Tunnel1
ip address 10.255.255.1 255.255.255.252


R4, of course, is configured with a tunnel IP address of 10.255.255.2/30.

Next, you must configure a tunnel source and a tunnel destination. That is, you must tell the router what interface you want the tunnel to terminate at on the local router ("tunnel source") and what router the far end of the interface should exist upon ("tunnel destination"). On R3, also under the "interface Tunnel1" configuration...:
tunnel source 172.16.0.2
tunnel destination 172.16.1.2


There is one additional caveat to consider, and this is one that is easy to forget. On TCP/IP networks, there is a parameter known as MTU size. Essentially, this is the largest size of a packet that a network device can forward without having to break the packet into smaller pieces. Consider it like this: if you have a shipment that is delivered to you in a semi truck, but you need to carry that shipment in your pickup truck, you will have to make several trips to deliver the load, right? Same thing in networking. If one network device can handle a 1500 byte packet, but the next device can only handle a 1400 byte packet, then the second network device will have to break the packet into a 1400 byte chunk, then send the remaining 100 bytes in a second chunk. This is called "fragmentation." MTU size becomes an issue with GRE tunnels, because GRE adds several bytes to the packet size when it encapsulates a TCP packet. Consequently, if your network can only support 1500 byte MTUs, and you are receiving 1500 byte packets from, say, a LAN interface, then you will have a GRE-encapsulated packet that is larger than 1500 bytes exiting through your WAN interface. You can avoid this by setting the MTU size and adjusting the maximum packet size that the tunnel will encapsulate. This is done with two commands in the tunnel interface setting:
ip mtu 1460
ip tcp adjust-mss 1420


The complete tunnel interface configuration looks like this:
interface Tunnel1
ip address 10.255.255.1 255.255.255.252
ip mtu 1460
ip tcp adjust-mss 1420
tunnel source 172.16.0.2
tunnel destination 172.16.1.2

There is one last factor to consider. Since tunnels are used to isolate certain types of traffic, for example, LAN traffic, you probably don't want to advertise all of your routes when tunneling between two networks. In this lab, I modeled a very common scenario: two LAN networks with a tunnel to allow them to communicate over a public, untrusted network. This is, in fact, exactly how a network I manage in my day job is built: two LAN networks with a VPN tunnel across the Internet to bridge them together. Obviously, I don't want to advertise routes to my internal, RFC-1918 networks to the Internet, nor do I want the entire Internet routing tables stored on my LAN routers. To address this, I set up BGP peering between R3 and R1, and between R4 and R2, to provide routes to public (Internet) hosts (note: yes, I'm using private IP space on all of these hosts. Just pretend that 192.168.0.0/16 is private IP space, but 10.0.0.0/8 and 172.16.0.0/12 are public for this lab). Then, I set up OSPF to advertise routes to my LAN networks only across the GRE tunnel. R3 and R4 are NOT sharing their OSPF routes with R1 or R2.

To do this, I first created the access list and route map to match the LAN network on each router. The config is identical on R3 and R4:
access-list 10 permit 192.168.0.0 0.0.255.255
!
route-map lan permit 10
match ip address 10

Then, I applied the route maps to the OSPF configuration on each router. On R3:
router ospf 2112
router-id 10.255.255.1
log-adjacency-changes
redistribute connected subnets route-map lan
network 10.255.255.0 0.0.0.3 area 0

...and on R4:
router ospf 2112
router-id 10.255.255.2
log-adjacency-changes
redistribute connected subnets route-map lan
network 10.255.255.0 0.0.0.3 area 0

For BGP, R3 and R4 are essentially set up to receive routes only. On R3:
router bgp 64513
bgp log-neighbor-changes
neighbor 172.16.0.1 remote-as 64512
!
address-family ipv4
neighbor 172.16.0.1 activate
no auto-summary
no synchronization
exit-address-family

...and on R4:
router bgp 64515
bgp log-neighbor-changes
neighbor 172.16.1.1 remote-as 64514
!
address-family ipv4
neighbor 172.16.1.1 activate
no auto-summary
no synchronization
exit-address-family

With that, I have a virtual connection from R3 to R4, as shown by the traceroute from R5 to R6:
R5#traceroute 192.168.1.2

Type escape sequence to abort.
Tracing the route to 192.168.1.2

1 192.168.0.1 0 msec 0 msec 8 msec
2 10.255.255.2 28 msec 24 msec 40 msec
3 192.168.1.2 32 msec 24 msec *
R5#

Notice that the traceroute does not show that it crossed 172.16.0.0/30, 10.0.0.0/30 or 172.16.1.0/30? It appears to go directly from R3 to R4. That is due to the tunnel that bridges R3 and R4 together. Even though, in reality, the traffic is indeed passing through the "ISP" network, to the LAN hosts, it is as if R3 has a direct physical connection to R4.

Monday, July 14, 2014

Advanced Cisco Routing -- Route Maps

So far, all of our routing examples have been pretty straight-forward: to reach network "A" you take route "A," and to reach network "B" you take route "B," etc. Suppose, however, that you need to filter routes between different WAN sites? Specifically, consider the following list of requirements:

  1. Multiple WAN sites with RFC-1918 IP space on the inside of the networks;
  2. Direct Nat'ed Internet links at each WAN site;
  3. Point-to-Point links (T1's, VPN tunnels, etc.) between WAN sites to route the internal LANs together;
  4. OSPF routing between internal LAN subnets.


In this case, you can use a route map to filter what networks OSPF is advertising. Here's how you do it:

First, here is the network topology for our example:
In this drawing, we'll use router R1 as our Anchorage router, R2 as our Fairbanks router, R4 and R5 will be random hosts on the internal LANs of R1 and R2 (respectively), and R3 will represent the Internet network between R1 and R2. Here is the basic configuration for R1 (the Anchorage router):

interface FastEthernet0/0
description LAN
ip address 192.168.1.1 255.255.255.0
ip nat inside
duplex auto
speed auto
!
interface FastEthernet1/0
description Inet
ip address 169.254.1.10 255.255.255.192
ip nat outside
duplex auto
speed auto
!
interface FastEthernet2/0
description OVPN to Fairbanks
ip address 172.16.1.1 255.255.255.252
ip nat inside
duplex auto
speed auto
!
ip nat inside source list 1 interface FastEthernet1/0 overload
no ip http server
no ip http secure-server
ip classless
ip route 0.0.0.0 0.0.0.0 169.254.1.1
!
access-list 1 permit 192.168.1.0 0.0.0.255
access-list 1 permit 172.16.1.0 0.0.0.3
!

As you can see, we have set up NAT to map addresses on the two internal interfaces to the external IP address of 169.254.1.10, and we have created a default route to the Internet router at 169.254.1.1. At this point, any hosts on the internal network should be able to reach any publicly-accessible IP address.

Similarly, here is the basic configuration for the Fairbanks router:

interface FastEthernet0/0
description LAN
ip address 192.168.3.1 255.255.255.0
ip nat inside
duplex auto
speed auto
!
interface FastEthernet1/0
description Inet
ip address 169.254.2.10 255.255.255.192
ip nat outside
duplex auto
speed auto
!
interface FastEthernet2/0
description OVPN to Anch
ip address 172.16.1.2 255.255.255.252
ip nat inside
duplex auto
speed auto
!
ip nat inside source list 1 interface FastEthernet1/0 overload
no ip http server
no ip http secure-server
ip classless
ip route 0.0.0.0 0.0.0.0 169.254.2.1
!
access-list 1 permit 192.168.3.0 0.0.0.255
access-list 1 permit 172.16.1.0 0.0.0.3
!

With this configuration, R4 should be able to ping the outside interface on R2, and R5 should be able to ping the outside interface on R1 (assuming that R3, R4 and R5 have been configured with the appropriate IP addresses on their respective interfaces, and that R4 and R5 have default routes through R1 and R2, respectively). However, if you try to ping R5 from R4 or vice versa, you will find that the pings fail, because R1 and R2 are not yet advertising routes to their internal networks. You could create static routes on these routers to solve this problem, but that's why we have dynamic routing protocols -- to reduce the network admin's workload.

However, you don't want to send routes to public IP addresses over your internal-only links, and even more importantly, you don't want to advertise your RFC-1918 IP addresses on the public Internet (your service provider should already be filtering these, but...). Therefore, we want to make sure OSPF is only advertising our private LAN addresses over the point-to-point link, so we'll create a route map on R1 and R2 to filter what routes OSPF advertises.

The first step in creating a route map is creating the access control list (ACL) to identify the traffic we want OSPF to allow. On R1...:

access-list 10 permit 192.168.3.0 0.0.0.255
access-list 10 permit 192.168.1.0 0.0.0.255
access-list 10 permit 172.16.1.0 0.0.0.3
!

...and on R2...:
access-list 10 permit 192.168.3.0 0.0.0.255
access-list 10 permit 192.168.1.0 0.0.0.255
access-list 10 permit 172.16.1.0 0.0.0.3
!

Note: If you don't fully understand the ACL's we have created here, check out CCNA Lesson 12 for a more in-depth explanation of ACL's on a Cisco router.

Next, we create the route-map to allow the networks filtered by these access lists (configuration is the same on both R1 and R2):
route-map inside-ospf permit 10
match ip address 10
!

Finally, we create our OSPF configuration, referencing the route maps. On R1:

router ospf 42
router-id 192.168.1.1
log-adjacency-changes
redistribute connected subnets route-map inside-ospf
network 172.16.1.0 0.0.0.3 area 0.0.0.0
!

...and on R2:

router ospf 42
router-id 192.168.3.1
log-adjacency-changes
redistribute connected subnets route-map inside-ospf
network 172.16.1.0 0.0.0.3 area 0.0.0.0
!


Here's what's happening in the router. We are creating the ACL to match our internal LAN traffic (192.168.1.0/24, 192.168.3.0/24, and 172.16.1.0/30). Then, we are creating a route map called "inside-ospf" to match the networks defined in ACL 10. Finally, OSPF is redistributing the networks referenced in the route-map "inside-ospf." If a network does not match the ACL, for example 169.254.1.0/26 (the network attached to fa1/0 on router R1), OSPF does not forward that route to other OSPF-enabled routers in that area. You can verify that this is working by tracing routes to various networks from R4 or R5. Here is an example of two traceroutes from R5:

Router#traceroute 192.168.1.2

Type escape sequence to abort.
Tracing the route to 192.168.1.2

1 192.168.3.1 8 msec 8 msec 8 msec
2 172.16.1.1 24 msec 8 msec 16 msec
3 192.168.1.2 28 msec 16 msec *
Router#traceroute 169.254.1.10

Type escape sequence to abort.
Tracing the route to 169.254.1.10

1 192.168.3.1 8 msec 4 msec 8 msec
2 169.254.2.1 16 msec 12 msec 8 msec
3 169.254.1.10 28 msec 25 msec *
Router#

You can see the traceroute follows the P-t-P link from R2 to R1 to reach 192.168.1.2, but follows the "Internet" link to reach the outside interface of R1, which is exactly what we wanted.

Reference:Cisco's "Route Maps for IP Routing Protocol Redistribution Configuration" web page.

Tuesday, June 3, 2014

Advanced Cisco Routing -- BGP and OSPF

If you wish to configure network gear for Service Provider networks, or even for Enterprise networks in large enough companies, you will eventually need to understand BGP. While I have worked for Service Providers for my entire professional career, I have never had the opportunity to work with BGP. However, due to some changes in my current work environment, I realized that I would need to come up to speed on BGP in the fairly near future, so I decided it was time to start playing with that particular routing protocol.

First, a little background. In my earlier Cisco and Juniper posts, we've discussed setting up and configuring OSPF, RIP, and EIGRP, so it might be reasonable to ask, what's so different about BGP? Without getting into too much detail, the bottom line is that the other routing protocols are designed for use within a single provider's network. You might have a lot of routers and a lot of routes, but the Internet's routing tables (for example) are much, much larger than your internal routing tables -- far too big, in fact, to fit on just about any router if you are using one of these protocols. BGP is the answer to this problem. It was designed to efficiently store and share very, very large routing tables on service provider networks. Consequently, you most often (but not exclusively!) see BGP on routers that are sharing publicly accessible routes on the Internet. It is important to note that BGP comes in two flavors: iBGP (internal BGP) that is used to share routes among your own networks, much like the routing protocols we have alread discussed; and eBGP (external BGP), which is used to share routes among other organizations. For this post, we will be discussing eBGP exclusively.

So, let's get started!

Here is the network that I created in GNS3:
Why GNS3 rather than a real hardware network? Well, first, I built this while at work (it was a slow day, and it is work-related learning), and second, because I have had to tear down my Cisco lab at home for reasons I'm sure you don't want to read about now :) Besides...I tried to get GNS3 to work a little while ago and failed, so I figured it was time to figure out how to make this puppy sing! It really wasn't all that difficult, but it did require some non-intuitive experimentation with settings until I got everything working.

Anyway, here's the description of the topology:

R1 and R2 are my core routers on this network -- they are the ones doing the BGP peering with each other. R1 is using AS64512 and R2 is using AS64513. Those AS numbers are not entirely random; they are, in fact, the first two private, reserved AS numbers according to the RFC's (think RFC-1918 for BGP autonomous system numbers, and you'll be pretty close). In GNS3, it doesn't really matter, but if you want to build BGP routers with real iron that might ever be connected to the Internet, you should probably use an AS number in the range 64512 - 65535 until/unless you get a real AS number from ARIN.

R3 and R4 are edge routers connected to R1; R5 and R6 are likewise edge routers connected to R2. R1, R3 and R4 make up the autonomous system in OSPF area 42. R2, R5 and R6 make up the autonomous system in OSPF area 51.

Finally, these are the networks connected to each router:
Router Interface IP Address Subnet Mask Description
R1 fa0/0 10.0.0.1 255.255.255.252 Uplink to R2
R1 fa1/0 192.168.1.1 255.255.255.0 Uplink to R3
R1 fa3/0 192.168.2.1 255.255.255.0 Uplink to R4
R2 fa0/0 10.0.0.2 255.255.255.252 Uplink to R1
R2 fa1/0 172.16.1.1 255.255.255.252 Uplink to R5
R2 fa2/0 172.16.20.1 255.255.255.252 Uplink to R6
R3 e0/0 192.168.10.1 255.255.255.0 LAN
R3 fa1/0 192.168.1.2 255.255.255.0 Uplink to R1
R4 e0/0 192.168.20.1 255.255.255.0 LAN
R4 fa1/0 192.168.2.2 255.255.255.0 Uplink to R1
R5 e0/0 172.16.10.1 255.255.255.0 LAN
R5 fa1/0 172.16.1.2 255.255.255.252 Uplink to R1
R6 e0/0 172.16.20.1 255.255.255.0 LAN
R6 fa1/0 172.16.2.2 255.255.255.252 Uplink to R1


I started by configuring OSPF on R1, R3 and R4:
R1#sho run | begin router ospf 42
router ospf 42
router-id 10.0.0.1
log-adjacency-changes
network 192.168.1.0 0.0.0.255 area 0
network 192.168.2.0 0.0.0.255 area 0
!

R3#sho run | begin router ospf 42
router ospf 42
router-id 192.168.10.1
log-adjacency-changes
redistribute connected subnets
network 192.168.1.0 0.0.0.255 area 0
!

R4#sho run | begin router ospf 42
router ospf 42
router-id 192.168.20.1
log-adjacency-changes
redistribute connected subnets
network 192.168.2.0 0.0.0.255 area 0
!

Once I had verified that I was routing between these three routers, I configured OSPF on R2, R5 and R6:
R2#sho run | begin ospf 51
router ospf 51
router-id 10.0.0.2
log-adjacency-changes
network 172.16.1.0 0.0.0.3 area 0
network 172.16.2.0 0.0.0.3 area 0
!

R5#sho run | begin ospf 51
router ospf 51
router-id 172.16.10.1
log-adjacency-changes
redistribute connected subnets
network 172.16.1.0 0.0.0.3 area 0
network 172.16.10.0 0.0.0.255 area 0
!

R6#sho run | begin router ospf 51
router ospf 51
router-id 172.16.20.1
log-adjacency-changes
redistribute connected subnets
network 172.16.2.0 0.0.0.3 area 0
network 172.16.20.0 0.0.0.255 area 0
!


...and checked to make sure that I had routing between these three routers, which I did.
Note: if any of this does not look familiar to you, I'd highly recommend you take a look at my blog entries on OSPF here and here to come up to speed on OSPF before digging into BGP.

Next, I configured the BGP routing process between R1 and R2:
R1#sho run | begin router bgp
router bgp 64512
bgp log-neighbor-changes
neighbor 10.0.0.2 remote-as 64513
address-family ipv4
neighbor 10.0.0.2 activate
no auto-summary
no synchronization
exit-address-family
!

R2#sho run | begin router bgp
router bgp 64513
bgp log-neighbor-changes
neighbor 10.0.0.1 remote-as 64512
address-family ipv4
neighbor 10.0.0.1 activate
no auto-summary
no synchronization
exit-address-family
!


First, note the AS numbers I mentioned earlier in the "router bgp..." command. In OSPF, we provide a process ID for the OSPF process; in BGP, we provide the AS number that we are advertising with BGP. We use those AS numbers on the very next line on the peer router to specify who we wish to be sharing routes with. Unlike OSPF, with BGP we specify the neighbor router(s) that we want to peer with. After that, we tell BGP what address family (IPv4, IPv6, etc.) that we will be advertising, and then we tell BGP to activate the peering session with our peer at <IP Address>. The rest of the lines were defaults automatically populated by IOS.

Unfortunately, at this point, I didn't see routes propagating between routers like I expected. After a little quality time with Google, I discovered that I hadn't told BGP what routes I wanted to share. Adding the line, "redistribute ospf 42 match internal external 1 external 2" on R1 and "redistribute ospf 51" on R2 solved that problem -- I was now able to see OSPF routes from the BGP peer showing up on R1 and R2.

Note: notice that R1 includes some extra syntax that R2 is missing on the "redistribute ospf..." statement. I don't have time right now to explain why that is necessary, but I'll try to add a post later to discuss what is different about the two networks.

However, all was not well in Mudville. When I got on the console for R6, I found that I could not ping R3 or R4. I ran "sho ip route" and found that, even though BGP had propagated routes from R1 onto R2 and vice versa, R2 hadn't shared those routes with R5 and R6, nor had R1 shared the routes learned through BGP with R3 and R4. That was because, even though I had told BGP to share OSPF routes (which it had), I hadn't told OSPF to share BGP routes! On R1, I added "redistribute bgp 64512 subnets" to the OSPF config, and on R2, I added "redistribute bgp 64513 subnets" which solved the problem. I could now ping any of the six routers from any of the five remaining routers.

Thursday, April 10, 2014

JNCIA -- Backing up Config Files

Okay, this is cool. You've set up your JunOS device (switch, router, whatever) just the way you want it, so you really should make a copy of the config so that, if the device ever fails, you can restore the configuration to replacement hardware with minimal effort (that whole, "the best sys admin is a lazy sys admin" thing again). Sure, after committing a config, you can always issue the commands to copy the config to an FTP server on your network, but, show of hands,...have you ever forgotten to do it? Look around -- everyone who didn't raise their hands is either very, very new to networking, or is lying ;)

Because we are all human, JunOS provides a very cool feature to work around the human limitation: a setting that dumps your config to an FTP server when you commit the config. Here's how you do it:

[edit]
root@branch-3200# edit system archival configuration

[edit system archival configuration]
root@branch-3200# transfer-on-commit;

[edit system archival configuration]
root@branch-3200# archive-sites {

[edit system archival configuration archive-sites]
"ftp://username:password@myftphost.example.com";


Of course, the ability to save your configuration is not terribly useful without the ability to restore it, so JunOS provides that ability, as well (natch):

[edit] root@branch-3200# edit system archival configuration

[edit system archival configuration]
root@branch-3200# load merge ftp://username:password@myftphost.example.com/branch-3200.conf.gz_20140410_111217

load complete

[edit system archival configuration]
root@branch-3200#


Wednesday, December 11, 2013

Configuring Port Security on a Foundry/Brocade FastIron Switch

I recently spoke with a user at a remote site on my network who was running into trouble getting on-line. During the troubleshooting session, I asked him to retrieve his IP address, and he gave me an address that was on a different subnet than I expected for his location. Puzzled, I asked a few follow-up questions, and found that he had connected a wireless router to my LAN switch at the remote site, a violation of our corporate compliance policies. In general, I'm not a fan of "Big Brother" IT/MIS policies, but in this case, I got a little torqued. This user is not MIS, he is not the guy who will get called out on the carpet if our network is breached because he didn't properly secure his wireless access point, and therefore, he is not supposed to be connecting wireless devices without explicit approval and knowledge of either me or one of the other network admins.

Unfortunately, this is not an uncommon occurrence. Fortunately, the Foundry FES2402 switches that we are using at these remote sites gives the network admin(s) some tools to help prevent users from connecting unauthorized devices to our networks.

The first tool is a simple MAC filter. In this case, there is a fixed number of devices that are supposed to be connected to our network, the MAC addresses of these devices are known, and therefore, we can create a filter to allow only these MAC addresses on a given port(s). Alternatively, if there is a known MAC address (or multiple addresses) that we *don't* want connected to a given port, we can create a filter to disallow it (or them). Here's how you do it:

  conf t
  mac filter 1 deny 0015.c507.ae6b ffff.ffff.ffff any
  mac filter 128 permit any any
    interface ethernet 7
      mac filter-group 1 128
      mac filter-group log-enable

This filter denies access from MAC address 0015.c507.ae6b to eth7, but allows access from all other MAC addresses.

Keep in mind that there are a few tips and a couple of "gotchas" in the simple MAC filter. First, just as when creating an Access Control List (ACL) or firewall rule for an IP address, you can filter for a portion of the MAC address, if you like:

  conf t
    mac filter 1 deny 0015.c507.ae6b ffff.0000.0000 any
    mac filter 128 permit any any
    interface ethernet 7
      mac filter-group 1 128
      mac filter-group log-enable

This will only match the "0015" portion of the given MAC address.

For a "gotcha," while there are many interface parameters that you can set using a range of Ethernet ports on a Foundry/Brocade switch, this isn’t one of them. For example, this…:

  conf t
  int eth 1 to 24
    mac filter-group 1 128
    mac filter-group log-enable

…doesn’t work. You can only apply a filter to a single interface at a time.

Another "gotcha" is that if you create multiple filters, then when applying the filters to an interface, you MUST include all of the filter groups on one line. If you try to put the filter groups on multiple lines, you will only get the LAST filter:

  conf t
  mac filter 1 deny 0015.c507.ae6b ffff.ffff.ffff any
  mac filter 128 permit any any
  int eth 7
      mac filter-group 1
      mac filter-group 128
      mac filter-group log-enable

This will result in ONLY filter 128 ("permit any any") being applied to the interface -- NOT AT ALL what you (presumably) intended.

The second tool is a lock that allows the admin to limit the number of devices that can access a given port on the switch. Unfortunately, this only sends an SNMP trap for a violation -- it does not actually disable the port or drop traffic from an unauthorized MAC address. Here's how you do it:

  conf t
  lock ethernet 15 addr-count 1

This applies a "lock" to allow only a single MAC address to eth 15 on a FES2402 switch. However, this isn't a terribly useful tool, as it only notifies the admin when someone attempts to attach an unauthorized device.

However, there is a third tool that takes the "lock" concept and gives it some teeth, so to speak. This is the MAC Port Security feature, and it can be applied either globally or directly to an Ethernet interface. Here is how you apply the MAC Port Security feature to a specific interface:

  conf t
  int eth 0/1/15
    port security
      enable
      maximum 1
      age 5
      violation restrict

In this example, we applied Port Security to Ethernet 0/1/15, enabled port security, set a maximum of 1 authorized IP address to this port, set the aging timer to drop the authorized IP address after 5 minutes (that is, if five minutes elapse without receiving a frame from a device, it will clear the MAC address entries for the interface, allowing a new device to connect), and telling the port to drop frames from any unrecognized device. You can set up to a maximum of 64 known MAC addresses per port. The aging timer can be set from zero (never time out a recognized MAC address) to 1440 minutes. The admin can choose between "restrict" and "shutdown" when a violation occurs; restrict will simply drop frames from an unknown device, whereas shutdown will disable the Ethernet interface for a specified period. If you choose "shutdown", then the next parameter is a number between 0 and 1440, where zero means shut down the port permanently, and any other number is the time to shut down the port, in minutes.

In addtion, you can manually specify allowed MAC addresses on the port, or you can configure to automatically discover and save allowed MAC addresses to the startup configuration. To manually specify an allowed MAC address:

  conf t
  int eth 0/1/15
    port security
      enable
      secure 0123.4567.89ab

This configuration manually specifies that only the device with the MAC address "0123.4567.89ab" should be allowed to access the port.

Alternatively, to have the Foundry auto-discover an allowed device, then write the MAC address to the startup configuration:

  conf t
  int eth 0/1/15
    port security
      enable
      autosave 60

This will automatically detect the MAC address of the device connected to the port and write its MAC address to the startup configuration every 60 minutes. Only that device will be allowed to connect from then on.

Wednesday, December 4, 2013

Brocade BCNP Resources

I recently found this post containing links to a number of resources for Brocade BCNP test preparation. I used the Brocade IP Primer to prepare for my BCNE, so I can verify that it's a great resource.

Thursday, November 14, 2013

JNCIA Lesson 4 1/2 -- More on Routing Policies and Firewall Filtering

One of the concepts that I have struggled with the most while trying to learn JunOS is the filtering language used on Juniper devices. That's a pretty significant problem too, because the filtering language is basically a core feature of JunOS, cropping up in Class of Service/Quality of Service, routing policies, and, of course, basic firewall/security on JunOS devices. It's pretty safe to say that if you don't understand this core concept, you will not be proficient in JunOS, and therefore, I decided I needed to spend a little while playing with the filtering syntax so I can understand it better. In it's most basic form, the filtering rules follow the pattern, "match-action" -- that is, you define a pattern to match, then upon a match, you perform some action on incoming packets -- and then you apply the filter to an interface or VLAN. There are three important concepts to keep in mind when trying to compose a filter rule:
  1. Within a single term, match rules are logical-AND'ed together. That is, if you put a rule to match a source IP address inside a term, then put a second rule to match a destination port, the filter will only match packets from that particular source IP address AND to that particular destination port (i.e., from 192.168.1.17, to port 23). If you want to logically OR rules, you have to create separate terms in the firewall rule-set;
  2. Packets are compared to each term from the top down, and the firewall stops comparing the packet to the firewall rules when it finds a match. In other words, if you put an "allow any" rule as the first term in your match rules, then put specific "deny ..." rules below, all packets will match against the "allow any" and no packet will ever be compared against the "deny ..." rules;
  3. There is an implicit "deny all" at the very end of the firewall rules, even though it is not shown in the configuration. Therefore, you must always make sure that you include rules to match all of the traffic that you want to allow. For example, suppose you are seeing brute-force password guessing attacks through SSH from the IP address 1.2.3.4, so you create a rule to drop traffic matching the source address of 1.2.3.4 and destination port 22. Unless you configure a rule to allow everything else, the implicit "deny all" rule will drop all traffic coming in on the interface or VLAN to which you applied the firewall rule.


Let's start with a simple example: suppose I have a switch on the 192.168.1.0/24 network, I have a host at 192.168.1.1, and on my switch, I want to block ICMP messages from that host with an "ICMP Administratively Prohibited" notification, while allowing any other protocol from 192.168.1.1 or all traffic from other source addresses.

root@branch-3200# set firewall family inet filter no-icmp term drop-icmp from source-address 192.168.1.1

[edit]
root@branch-3200# set firewall family inet filter no-icmp term drop-icmp from protocol icmp

[edit]
root@branch-3200# set firewall family inet filter no-icmp term drop-icmp then reject administratively-prohibited

[edit]
root@branch-3200# commit
commit complete

[edit]
root@branch-3200#


If we attempt to ping 192.168.1.2 (the EX3200 switch) from 192.168.1.1 at this point, we will find the firewall isn't particularly effective:

root@main3200> ping 192.168.1.2
PING 192.168.1.2 (192.168.1.2): 56 data bytes
64 bytes from 192.168.1.2: icmp_seq=0 ttl=64 time=3.630 ms
64 bytes from 192.168.1.2: icmp_seq=1 ttl=64 time=2.408 ms
64 bytes from 192.168.1.2: icmp_seq=2 ttl=64 time=2.395 ms
^C
--- 192.168.1.2 ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max/stddev = 2.395/2.811/3.630/0.579 ms

root@main3200>


Since we haven't applied the firewall to an interface or VLAN yet, no incoming packets are being compared against the firewall rules, and therefore all inbound traffic is still allowed. Let's take care of that, now:

root@branch-3200# set interfaces vlan unit 0 family inet filter input no-icmp

[edit]
root@branch-3200# commit
commit complete

[edit]
root@branch-3200#


To create our firewall, we started by adding a rule that drops traffic only if the source address is 192.168.1.1. However, we only want to drop ICMP traffic, so we then added a second rule (with the same term name, namely "drop-icmp") that drops ICMP traffic. Since the terms are cumulative, we've essentially created a rule that says, "if the source address matches 192.168.1.1 AND the protocol is ICMP..." Then, we created an action to reject matching packets with the "administratively prohibited" message. Let's see how it works:

root@main3200> ping 192.168.1.2
PING 192.168.1.2 (192.168.1.2): 56 data bytes
36 bytes from 192.168.1.2: Communication prohibited by filter
Vr HL TOS  Len   ID Flg  off TTL Pro  cks      Src      Dst
4  5  00 0054 d4e0   0 0000  40  01 2275 192.168.1.1  192.168.1.2
<...snip...>
^C
--- 192.168.1.2 ping statistics ---
3 packets transmitted, 0 packets received, 100% packet loss
root@main3200>


Good, good...

root@main3200> telnet 192.168.1.2
Trying 192.168.1.2...
telnet: connect to address 192.168.1.2: Operation timed out
telnet: Unable to connect to remote host

root@main3200>


Hrmmm...Well, we're half-way there. We are successfully blocking ICMP, but apparently, we are also blocking telnet. Remember, JunOS adds an implicit "deny all" at the end of the firewall rules. Since we create a rule to block ICMP from 192.168.1.1, but we didn't include a rule to allow any packets, we are actually blocking ALL packets on vlan.0. To fix this, we have to add a new term to allow anything that isn't ICMP and from 192.168.1.1:

root@branch-3200# set firewall family inet filter no-icmp term everything-else source 0.0.0.0/0

[edit]
root@branch-3200# set firewall family inet filter no-icmp term everything-else then accept

[edit]
root@branch-3200# commit
commit complete

[edit]
root@branch-3200#


Let's see if that solves the problem:

root@main3200> ping 192.168.1.2
PING 192.168.1.2 (192.168.1.2): 56 data bytes
36 bytes from 192.168.1.2: Communication prohibited by filter
Vr HL TOS  Len   ID Flg  off TTL Pro  cks      Src      Dst
4  5  00 0054 2f4c   0 0000  40  01 c809 192.168.1.1  192.168.1.2

36 bytes from 192.168.1.2: Communication prohibited by filter
Vr HL TOS  Len   ID Flg  off TTL Pro  cks      Src      Dst
4  5  00 0054 2f76   0 0000  40  01 c7df 192.168.1.1  192.168.1.2

36 bytes from 192.168.1.2: Communication prohibited by filter
Vr HL TOS  Len   ID Flg  off TTL Pro  cks      Src      Dst
4  5  00 0054 2f9c   0 0000  40  01 c7b9 192.168.1.1  192.168.1.2

^C
--- 192.168.1.2 ping statistics ---
3 packets transmitted, 0 packets received, 100% packet loss

root@main3200> telnet 192.168.1.2
Trying 192.168.1.2...
Connected to 192.168.1.2.
Escape character is '^]'.

branch-3200 (ttyp0)

login:
telnet> quit
Connection closed.

root@main3200>


That's more better :) We are now successfully blocking ICMP from 192.168.1.1 while still allowing other protocols, such as TCP/23 (telnet) to the switch.

However, looking at the firewall rules, something doesn't seem to be right. We have two rules to block source-address 192.168.1.1 and protocol ICMP, but the allow rule only specifies a source-address. How does this rule work?

Keep in mind that JunOS firewall rules work from top down, and they stop looking for matches as soon as a packet matches a term. Consequently, any packet originating from 192.168.1.1 and using the ICMP protocol matches our "reject ..." rule. However, if the packet comes from another source address or is a protocol other than ICMP, JunOS continues comparing the packet with the firewall rules. Therefore, anything not matching the "drop-icmp" term is compared to the "everything-else" term. The "everything-else" term tries to match the packet against the source-address of 0.0.0.0/0 -- in other words, against all possible source IP addresses. Since this second term will match a packet coming from any IP address, it is essentially an "allow any" rule. Therefore, our rule effectively reads, "if the packet matches 192.168.1.1 and matches the ICMP protocol, then reject it with the 'administratively-prohibited' message. If it is anything else, allow it."