Showing posts with label MAC filtering. Show all posts
Showing posts with label MAC filtering. Show all posts

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.

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."

Saturday, October 5, 2013

Lesson 13 -- MAC Filtering and Port Security

In the wake of the virus incident, you do a little searching on-line and in your Cisco books, and decide perhaps it is time to implement another layer of security on your network. Cisco switches allow the network admin to configure ports to allow no more than a specified number of MAC addresses before taking some action, which on newer switches can be anything from simply dropping offending packets to logging the offence to shutting down the affected switch port entirely. Unfortunately, your 2924 switch only allows a subset of those actions, namely shutting down the port or simply sending an SNMP trap for the security violation. Still peeved that someone connected a personal laptop to your network -- in violation of example.com's corporate compliance policy -- you send out an e-mail to all employees reminding them that example.com does not yet have a BYOD policy, and that company policies currently prohibit connecting personal devices to the corporate network. Then, deciding to risk possibly becoming a bit of a BOfH, you implement port security on the 2924 switches, limiting switch ports to one MAC address per access (untagged VLAN) port, and automatically shutting down ports when a security violation is encountered.

lab2924a# conf t
lab2924a(config)# int fa0/7
lab2924a(config-if)# port security
lab2924a(config-if)# port security max-mac-count 1
lab2924a(config-if)# port security action shutdown
lab2924a(config)# int fa0/8
lab2924a(config-if)# port security
lab2924a(config-if)# port security max-mac-count 1
lab2924a(config-if)# port security action shutdown
lab2924a(config)# int fa0/9
lab2924a(config-if)# port security
lab2924a(config-if)# port security max-mac-count 1
lab2924a(config-if)# port security action shutdown
lab2924a(config)# int fa0/10
lab2924a(config-if)# port security
lab2924a(config-if)# port security max-mac-count 1
lab2924a(config-if)# port security action shutdown
<...snip...you get the idea...>


...and then repeat the config on lab2924b. To make sure everything is working as expected, you go to the server room and disconnect the cable from your port on the switch to the patch panel, then connect your laptop directly into the port. After getting a DHCP address from the server, you disconnect your laptop and connect a second laptop to the same port, and notice the link light briefly turns orange as spanning-tree reconverges, then goes out. You connect your laptop to another unused port, renegotiate an IP address with the DHCP server, then log in to the switch. You notice that the switchport to which the second laptop is still connected shows that it is "administratively down":

lab2924a# sho int fa0/9
FastEthernet0/9 is administratively down, line protocol is down
<...snip...>


You double-check the running configuration in RAM, to make sure that you plugged the second laptop into the correct port, and it shows the port is configured up -- looks like port security is working properly! To reset the port, you run "shut" on fa0/9, turn off port security, then run "no shut" and watch as the port comes up again (after a minute or so delay while spanning tree reconverges again). Since you have a spare laptop plugged into fa0/9, and that's your network port, you disconnect the second laptop, replace the cable in the patch panel, then return to your office before re-enabling port security on fa0/9.

Note: By this point, I'm starting to think that it might have been wise to spend a little more on a more modern switch for my CCNA practice. Once again, the commands I need to practice for the current CCNA exam are not supported on the switch I purchased (sigh...). On a modern switch, the procedure (in theory) goes like this:

switch(config)# int fa0/9
switch(config-if)# switchport port-security
switch(config-if)# switchport port-security mac-address 00:15:c5:08:5d:92


...to statically assign a MAC address to the port security feature,...:

switch(config)# int fa0/9
switch(config-if)# switchport port-security
switch(config-if)# switchport port-security mac-address sticky


...to have the switch automatically use the first MAC address it sees on the port, or...:

switch(config)# int fa0/9
switch(config-if)# switchport port-security
switch(config-if)# switchport port-security maximum 5


...to automatically use the first five MAC addresses the switch learns from a given port. Next, you can select from three possible actions when the switch detects a violation. I'll show examples of a port that simply discards offending traffic (fa0/9), that discards and logs offending traffic (fa0/10), and that shuts down a port entirely (fa0/11):

switch(config)# int fa0/9
switch(config-if)# switchport port-security
switch(config-if)# switchport port-security mac-address sticky
switch(config-if)# switchport port-security violations protect
switch(config)# int fa0/10
switch(config-if)# switchport port-security
switch(config-if)# switchport port-security mac-address sticky
switch(config-if)# switchport port-security violations restrict
switch(config)# int fa0/11
switch(config-if)# switchport port-security
switch(config-if)# switchport port-security mac-address sticky
switch(config-if)# switchport port-security violations shutdown


Also, on newer switches, you supposedly only have to shut/no shut the interface to clear an automatic "shutdown" on a port when a violation occurs. On my 2924, a shut/no shut didn't release the port.

Maybe with all the vast wealth that I should receive from prospective employers after earning my CCNA (yeah, right...) I'll spring for a newer switch before starting in on the CCNP ;)