Chapter 19. Access Lists

19.0. Introduction

An Access Control List (ACL) is generically a method for doing pattern matching based on protocol information. There are many reasons for doing this type of pattern matching, such as restricting access for security reasons or restricting routing tables for performance reasons.

Cisco has several different general kinds of access lists. The most common are the numbered ACLs, which are summarized in Table 19-1. But there are also named access lists, reflexive access lists, context-based access lists, and rate-limit access lists. There are even timed access lists that can have different effects at different times of day, although we will not cover them in this book. Within each of these general categories, there are many different types of ACLs that match on different protocol information. When working with route filtering, it is often easiest to work with prefix lists, which are another type of ACL discussed in more detail in Chapters Chapter 6, Chapter 7, Chapter 8, and Chapter 9.

You can apply an ACL in many different ways. Applied to an interface, you can use it to accept or reject incoming or outgoing packets based on protocol information such as source or destination address, port number, protocol number, and so forth. Applied to a routing protocol, this same ACL might prevent the router from sharing information about a particular route. And, applied to a route map, the ACL could just identify packets that need to be tagged or treated differently.

Table 19-1 shows all of the current ranges for numbered access lists. Cisco periodically adds new ranges to this list, so earlier IOS levels may not support all of these ACL types. Also bear in mind that if your IOS feature set doesn’t support a particular protocol such as IPX, XNS, or AppleTalk, the corresponding ACL type will also be unavailable.

Table 19-1. Numbered access list types

Numeric range

Access list type

1 - 99

Standard IP ACL

100 - 199

Extended IP ACL

200 - 299

Ethernet type code ACL

300 - 399

DECNET ACL

400 - 499

XNS ACL

500 - 599

Extended XNS ACL

600 - 699

AppleTalk ACL

700 - 799

48-bit MAC address ACL

800 - 899

IPX ACL

900 - 999

Extended IPX ACL

1000 - 1099

IPX service advertisement protocol

1100 - 1199

Extended 48-bit MAC address ACL

1200 - 1299

IPX NLSP ACL

1300 - 1999

Standard IP ACL, expanded range

2000 - 2699

Extended IP ACL, expanded range

2700 - 2999

SS7 (Voice) ACL

Clearly many of these ranges deal with protocols or technologies that are beyond the scope of this book. This book’s primary focus is on IP-based technologies, so this chapter will not discuss ACL types that are intended for use with other protocols.

A named ACL is really just another way of writing either a standard or extended IP ACL. Named ACLs can make your configuration files considerably easier to read. Some commands that use an ACL for pattern matching will not accept named ACLs, but, for the most part, named ACLs are interchangeable with normal IP ACLs. Their chief advantage is that you can nest other ACLs inside of a named ACL for greater flexibility.

Reflexive ACLs are more sophisticated objects that can contain temporary entries. Reflexive ACLs need to be nested inside of named ACLs. A reflexive ACL has two parts that are generally nested in two different named ACLs. One part watches for packets of a particular type using normal extended IP ACL syntax. As soon as the router sees this packet, it activates a matching rule in another ACL. This allows you to do things like permitting inbound traffic of a particular type only after the router sees an initial outbound packet of the matching type.

However, reflexive ACLs are somewhat limited in their scope because they are not able to read into the payloads of IP packets. Many applications have more complicated behavior, such as using dynamically generated port numbers. To handle this type of situation, Cisco has developed another type of ACL called Context-Based Access Control (CBAC).

Like reflexive ACLs, CBAC works by turning on and off temporary access list rules. However, CBAC actively monitors applications using a stateful inspection algorithm that allows the router to react to the application and dynamically create new ACL rules. It can also watch for unusual application behavior and dynamically disable the corresponding temporary ACL rules.

You should always remember that every ACL ends with an implicit deny all clause. This means that if you are matching items (packets, for example) with an ACL, and the item fails to match any of the explicitly listed clauses of the ACL and falls off the end, it is the same as if the item matched an explicit deny clause. For this reason, if you are trying to block certain unwanted packets (for example), but want to allow all others to pass, you must remember to include a permit all statement at the end of the ACL.

For more information on ACLs in general, refer to Cisco IOS Access Lists (O’Reilly).

19.1. Filtering by Source or Destination IP Address

Problem

You want to block packets to or from certain IP addresses.

Solution

You can use standard access lists to block packets from specified IP source addresses:

Router1#configure terminal
Enter configuration commands, one per line.  End with CNTL/Z.
Router1(config)#access-list 50 deny host 10.2.2.2
Router1(config)#access-list 50 permit any
Router1(config)#interface Serial0/1
Router1(config-if)#ip access-group 50 in
Router1(config-if)#end
Router1#

You can filter packets based on both the source and destination addresses with an extended access list:

Router1#configure terminal
Enter configuration commands, one per line.  End with CNTL/Z.
Router1(config)#access-list 150 deny ip host 10.2.2.2 host 172.25.25.1
Router1(config)#access-list 150 permit ip any any
Router1(config)#interface Serial0/1
Router1(config-if)#ip access-group 150 in
Router1(config-if)#end
Router1#

Discussion

The most obvious use for access lists is traffic filtering. The two examples in this recipe both show how to use access control lists for filtering inbound packets. The first example uses the following access list:

Router1(config)#access-list 50 deny host 10.2.2.2
Router1(config)#access-list 50 permit any

This is a numbered ACL with a value between 1 and 99, making it a standard access list. Using standard ACLs like this allows you to filter based only on the source IP address. In the example, we have chosen to deny a single host address, 10.2.2.2. All other packets are permitted. This is a somewhat artificial thing to do, of course. It is more likely that you would want to allow only a limited group of devices and block all of the others. For example, you might want to allow all of the devices on 10.2.2.0/24, except the host 10.2.2.2, and drop packets from any other devices. You could do this with the following standard ACL:

Router1(config)#access-list 50 deny host 10.2.2.2
Router1(config)#access-list 50 permit 10.2.2.0 0.0.0.255
Router1(config)#access-list 50 deny any

The order of the statements in an access list is critical. Consider what would have happened if we had put a line that permitted 10.2.2.0/24 before the line that denied the specific host (10.2.2.2). Then, each time the router receives a packet from the forbidden host, it compares it to the ACL. Because this host is part of the permitted range, the router would accept the packet and not look any further.

Also, because the router will stop processing an ACL as soon as it finds a match, you can save the processor a lot of work by putting the most common rules near the top. You want the router to find a match as early as possible while parsing the ACL. All of the examples in this chapter are relatively short, but if you have an ACL that is several hundred lines long, good ordering so that most of your packets match early lines in the ACL can make a significant improvement in processing time. Ordering will affect router CPU load and can also improve jitter and latency issues.

The other important thing to look out for when constructing an ACL like this is the fact that they use wildcard bits (rather than netmask format) when defining ranges of addresses. In this example, we wanted to specify the range 10.2.2.0/24. This means that we want to fix all of the bits in the first three octets of the address and allow any pattern of bits in the last octet. We can achieve this with a wildcard pattern of 0.0.0.255. Refer to Recipe 5.3 for a more detailed discussion of the differences between wildcards and netmasks.

The basic notation is an IP address followed by a wildcard pattern. But there are two special cases. Suppose you want to match on a single IP address for a particular device, such as 10.2.2.2. You can write this as follows:

Router1(config)#access-list 50 deny 10.2.2.2 0.0.0.0

This wildcard pattern means that there are no free bits in the address, so we are looking for an exact match. Alternatively, you can use the more intuitive version that we used earlier in this recipe, with the host keyword:

Router1(config)#access-list 50 deny host 10.2.2.2

The two forms have an identical effect. In fact, for standard IP ACLs like this one, the router will replace both of these with the following:

Router1(config)#access-list 50 deny 10.2.2.2

The host keyword is not redundant, however, for extended IP ACLs, which we will discuss later.

Alternatively, if you want to match any device, you could write this:

Router1(config)#access-list 50 deny 0.0.0.0 255.255.255.255

Because all of the wildcard bits in this pattern are set, it means that any bit may have a value of either 0 or 1. Therefore, this pattern will match any IP address. The router will rewrite this ACL with the following simpler form:

Router1(config)#access-list 50 deny any

As we mentioned in the introduction to this chapter, there are many different ways to apply an ACL. In this case, we want to apply this ACL to filter IP packets received on a particular router interface. To do so, we use the ip access-group command on the interface that will receive the data stream that we want to filter:

Router1(config)#interface Serial0/1
Router1(config-if)#ip access-group 50 in

In this command, the keyword in tells the router to apply the filter to inbound packets, that is, packets received by this interface. In some cases, you might want to filter outbound packets instead. The router will even let you apply a different ACL to inbound and outbound packets:

Router1(config)#interface Serial0/1
Router1(config-if)#ip access-group 50 in
Router1(config-if)#ip access-group 51 out

The outbound access-group command has an interesting quirk that you should be aware of. This command will not filter packets that originate on the router itself. This is important because if you apply an outbound filter and then try to test it with a ping or telnet from the router, your rule will appear not to work. Make sure to do these tests from a downstream device.

It’s also important to remember that the router originates packets in several less obvious situations. For example, if you are using tunnels, the tunnel packets themselves originate on the router—even if the router is encapsulating IP packets from downstream devices. The same is true when the router acts as a gateway for other protocols, such as SNA or X.25.

This also has security implications: if somebody can convince the router to originate packets for them, they will bypass the rule. So, while the outbound access-group command is extremely useful, you need to be careful about how you use it, or it might be less effective than you expect.

The second example in the solution section of this recipe does a similar kind of filtering, except that this time we have used an extended ACL:

Router1(config)#access-list 150 deny ip host 10.2.2.2 host 172.25.25.1
Router1(config)#access-list 150 permit ip any any

The syntax of the extended IP ACL is somewhat more involved than that of the standard ACL. It includes the same permit or deny keywords as the standard IP ACL. The next keyword in this example selects the IP protocol. Refer to Recipe 19.3 for a discussion of other options.

Extended IP ACLs always include two IP addresses. The first is the source address, and the second is the destination. In the first line of the example, we have specified two host addresses for the source and destination, while the second line matches any address in either the source or the destination fields of the IP packet.

You can use the same wildcard matching systems for IP addresses that we discussed earlier. Suppose, for example, that we want to allow any device on the 10.2.2.0/24 segment to access any destination device, but we want to specifically prevent the host, 10.2.2.2 from reaching 172.25.25.1, and we want to drop all packets from any other devices. We could do this with the following extended IP ACL:

Router1(config)#access-list 150 deny ip host 10.2.2.2 host 172.25.25.1
Router1(config)#access-list 150 permit ip 10.2.2.0 0.0.0.255 any
Router1(config)#access-list 150 deny ip any any

Note that the last line explicitly denies everything that wasn’t matched in one of the previous lines. This is actually not necessary because every ACL implicitly ends with a deny all, whether you include it or not. However, including an explicit permit all or deny all clause at the end of an ACL is generally a good practice because it makes things more clear. Also, when you look at an ACL with the show access-list command, it gives you a breakdown of how many times each rule found a match:

Router1#show access-list 150
Extended IP access list 150
    deny ip host 10.2.2.2 host 172.25.25.1 (422 matches)
    permit ip 10.2.2.0 0.0.0.255 any (743 matches)
    deny ip any any (387 matches)
Router1#

Including an explicit deny all rule at the end of this ACL allows you to tell exactly how many packets were affected.

As we discuss in Recipe 19.8, you can configure this line to log exactly which packets reach all the way to the end of the ACL without matching one of the earlier rules.

Finally, we need to mention one of the most annoying problems involved in managing large ACLs. If you add a new rule to an ACL, it will always go at the very end of the list. This is not always what you want. Worst of all, there is no way to remove individual lines from an ACL without removing the entire list.

We have found that the easiest way to get around this problem is to use the show running-config command to get a complete listing of the ACL you want to edit. Copy this into a text editor of some kind on your local workstation. Then you can use any common text editor to create the modified ACL. Delete the old ACL and copy in the new one. As we mentioned in Chapter 1, if you use TFTP to transfer the new commands into the router, it will not make the change until the transfer is complete. This is particularly important for ACLs, where you could enter the first line and then find yourself locked out of the router by the implicit deny all that follows it.

19.2. Adding a Comment to an ACL

Problem

You want to add a human-readable comment to an ACL to help other engineers understand what you have done.

Solution

You can add a comment to any standard or extended IP ACL using the remark keyword:

Router1#configure terminal
Enter configuration commands, one per line.  End with CNTL/Z.
Router1(config)#access-list 50 remark Authorizing thy trespass with compare
Router1(config)#access-list 50 deny host 10.2.2.2
Router1(config)#access-list 50 permit 10.2.2.0 0.0.0.255
Router1(config)#access-list 50 permit any

Discussion

This command can be quite useful when you have to keep track of many different ACLs on a router, particularly when several of them look similar. The comment field can be up to 100 characters long. If you require more space, simply add more remark lines to the ACL:

Router1(config)#access-list 50 remark Authorizing thy trespass with compare
Router1(config)#access-list 50 remark My self corrupting salving thy amiss,
Router1(config)#access-list 50 remark Excusing thy sins more than thy sins are
Router1(config)#access-list 50 remark Shakespeare, Sonnet 35

When you display this ACL using the show access-list command, it will not show the remark lines:

Router1#show access-list 50
Standard IP access list 50
    deny   10.2.2.2
    permit 10.2.2.0, wildcard bits 0.0.0.255
    permit any
Router1#

The only way to see these comments is to look at the router’s configuration file:

Router1#show running-config | include access-list 50
access-list 50 remark Authorizing thy trespass with compare
access-list 50 remark My self corrupting salving thy amiss,
access-list 50 remark Excusing thy sins more than thy sins are
access-list 50 remark Shakespeare, Sonnet 35
access-list 50 deny   10.2.2.2
access-list 50 permit 10.2.2.0 0.0.0.255
access-list 50 permit any
access-list 50 remark
Router1#

Note that the router does not reorder the remark lines in the ACL, so you can use this feature to explain line-by-line what each command does:

Router1(config)#access-list 50 remark loathsome canker
Router1(config)#access-list 50 deny host 10.2.2.2
Router1(config)#access-list 50 remark sweetest bud
Router1(config)#access-list 50 permit 10.2.2.0 0.0.0.255
Router1(config)#access-list 50 permit any

See Also

Complete Sonnets, William Shakespeare (Dover)

19.3. Filtering by Application

Problem

You want to filter access to certain applications.

Solution

Extended IP access lists can also filter based on application information such as protocol and port numbers:

Router1#configure terminal
Enter configuration commands, one per line.  End with CNTL/Z.
Router1(config)#access-list 151 permit tcp any any eq www
Router1(config)#access-list 151 deny tcp any any gt 1023
Router1(config)#access-list 151 permit icmp any any
Router1(config)#access-list 151 permit udp any any eq ntp
Router1(config)#access-list 151 deny ip any any
Router1(config)#interface Serial0/1
Router1(config-if)#ip access-group 151 in
Router1(config-if)#end
Router1#

Discussion

This example shows how to construct an extended IP ACL to filter traffic based on applications. In Recipe 19.1, we showed how to use extended IP ACLs to match on any combination of source and/or destination IP addresses. But the extended IP ACL also allows you to match on just about anything in the IP packet header.

The first argument after the permit or deny keyword represents the IP protocol type:

Router1(config)#access-list 151 permit tcp any any eq www

In this case, we want to match a TCP-based application, so we have used the keyword tcp in this position. This field represents the IP protocol number, which is an 8-bit value. TCP is protocol number 6, UDP is 17, and ICMP uses protocol number 1. The IANA has registered 134 different protocol numbers. You can find the complete list of registered IP protocols online at http://www.iana.org/assignments/protocol-numbers. Cisco supplies helpful mnemonics for several of these protocols, such as the tcp, udp, and icmp keywords used in the example, so you don’t have to remember the protocol numbers. Table 19-2 shows all of the IP protocols for which Cisco supplies mnemonic keywords. You can always use the protocol number in decimal form if you prefer, but the router will replace it with the mnemonic (if one exists) in its configuration file.

Table 19-2. IP protocol numbers and their extended ACL keywords

Protocol number

Keyword

Description

1

icmp

Internet Control Message Protocol

2

igmp

Internet Gateway Message Protocol

4

ipinip

IP-in-IP tunnel protocol

6

tcp

Transmission Control Protocol

9

igrp

Interior Gateway Routing Protocol

17

udp

User Datagram Protocol

21

nos

KA9Q tunnel protocol

47

gre

Generic Routing Encapsulation tunnel protocol

50

esp

IPSec Encapsulation Security Payload

51

ahp

IPSec Authenticating Header Protocol

88

eigrp

Enhanced Interior Gateway Routing Protocol

89

ospf

Open Shortest Path First routing protocol

103

pim

Protocol Independent Multicast protocol

108

pcp

IP Payload Compression Protocol

As we showed in Recipe 19.1, you can match on any IP protocol number by simply using the keyword ip.

The source and destination IP addresses come after the IP protocol number or keyword. We described how to use these fields in Recipe 19.1. Remember that the address keyword any is shorthand that stands for an address of 0.0.0.0 with a wildcard pattern of 255.255.255.255.

Following each address is an optional field in which you can specify particular protocol information such as port numbers. In the following example, we match on TCP port 80, which is used by the HTTP protocol.

There are many possible mnemonic keywords for different TCP port numbers:

Router1(config)#access-list 151 permit tcp any eq ?
  <0-65535>    Port number
  bgp          Border Gateway Protocol (179)
  chargen      Character generator (19)
  cmd          Remote commands (rcmd, 514)
  daytime      Daytime (13)
  discard      Discard (9)
  domain       Domain Name Service (53)
  echo         Echo (7)
  exec         Exec (rsh, 512)
  finger       Finger (79)
  ftp          File Transfer Protocol (21)
  ftp-data     FTP data connections (20)
  gopher       Gopher (70)
  hostname     NIC hostname server (101)
  ident        Ident Protocol (113)
  irc          Internet Relay Chat (194)
  klogin       Kerberos login (543)
  kshell       Kerberos shell (544)
  login        Login (rlogin, 513)
  lpd          Printer service (515)
  nntp         Network News Transport Protocol (119)
  pim-auto-rp  PIM Auto-RP (496)
  pop2         Post Office Protocol v2 (109)
  pop3         Post Office Protocol v3 (110)
  smtp         Simple Mail Transport Protocol (25)
  sunrpc       Sun Remote Procedure Call (111)
  syslog       Syslog (514)
  tacacs       TAC Access Control System (49)
  talk         Talk (517)
  telnet       Telnet (23)
  time         Time (37)
  uucp         Unix-to-Unix Copy Program (540)
  whois        Nicname (43)
  www          World Wide Web (HTTP, 80)

Router1#

As with the IP protocol numbers listed in Table 19-2, you can substitute the decimal numerical value for any of these keywords, and the router will replace it with the keyword. For any other applications not included in this list, you must use the decimal port number.

In our example, the mnemonic for port 80 is www:

Router1(config)#access-list 151 permit tcp any any eq www

Note that the keywords eq www appear after the destination IP address, rather than the source IP address. This is because we are looking for the destination TCP port number. If you need to match on a source port number instead, you could simply move these keywords to follow the source IP address:

Router1(config)#access-list 151 permit tcp any eq www any

Of course, you can always match on both:

Router1(config)#access-list 151 permit tcp any eq www any eq www

Note, however, that this ACL will score a correct match only if both source and destination TCP port numbers match. If you wanted to match HTTP traffic between any two devices, but didn’t know which device had initiated the TCP session, you would need to include two separate lines like this:

Router1(config)#access-list 151 permit tcp any any eq www
Router1(config)#access-list 151 permit tcp any eq www any

The IANA reserves the TCP port numbers 1024 and above for local and temporary applications. Many TCP implementations use these high-numbered ports for source port numbers, and for temporary or ephemeral purposes. So it is relatively common to see ACLs that restrict the use of these ports. We included an example ACL rule in this recipe:

Router1(config)#access-list 151 deny tcp any any gt 1023

This command will block all packets that have a destination port number greater than 1023 (that is, ports 1024 through 65,535). Remember that TCP applications often use these high port numbers for source ports, so you need to be careful about traffic direction when you apply such an ACL.

There is a similar set of port numbers for UDP applications:

Router1(config)#access-list 151 permit udp any eq ?
  <0-65535>    Port number
  biff         Biff (mail notification, comsat, 512)
  bootpc       Bootstrap Protocol (BOOTP) client (68)
  bootps       Bootstrap Protocol (BOOTP) server (67)
  discard      Discard (9)
  dnsix        DNSIX security protocol auditing (195)
  domain       Domain Name Service (DNS, 53)
  echo         Echo (7)
  isakmp       Internet Security Association and Key Management Protocol (500)
  mobile-ip    Mobile IP registration (434)
  nameserver   IEN116 name service (obsolete, 42)
  netbios-dgm  NetBios datagram service (138)
  netbios-ns   NetBios name service (137)
  netbios-ss   NetBios session service (139)
  ntp          Network Time Protocol (123)
  pim-auto-rp  PIM Auto-RP (496)
  rip          Routing Information Protocol (router, in.routed, 520)
  snmp         Simple Network Management Protocol (161)
  snmptrap     SNMP Traps (162)
  sunrpc       Sun Remote Procedure Call (111)
  syslog       System Logger (514)
  tacacs       TAC Access Control System (49)
  talk         Talk (517)
  tftp         Trivial File Transfer Protocol (69)
  time         Time (37)
  who          Who service (rwho, 513)
  xdmcp        X Display Manager Control Protocol (177)

Router1#

For example, you could block all Sun RPC traffic, which includes important but chatty applications such as Network File System (NFS):

Router1(config)#access-list 151 deny udp any eq sunrpc any
Router1(config)#access-list 151 deny udp any any eq sunrpc

This will block RPC traffic going in either direction because we applied the UDP port number file separately to the source and destination ports.

Like TCP, UDP port number values from 1024 through 65,535 are often used for temporary purposes such as source port numbers. You can control the use of these port numbers with a similar rule:

Router1(config)#access-list 151 deny udp any any gt 1023

You can also create an access list to look for specific types of ICMP messages in exactly the same way that we matched on TCP and UDP port numbers. The difference for ICMP message types is that each ICMP packet has only a single type field, rather than a source and destination port. You specify the type after the addresses on an Extended ACL, as follows:

Router1(config)#access-list 190 permit icmp any any echo

This ACL looks for ICMP echo request packets, such as those sent by the ping utility. This feature allows you to treat these ping packets differently than, for example, an ICMP unreachable message. In fact, this command allows you to look for any ICMP message type number between 0 and 255 either by the decimal number, or by mnemonic:

Router1(config)#access-list 190 permit icmp any any ?
  <0-255>                      ICMP message type
  administratively-prohibited  Administratively prohibited
  alternate-address            Alternate address
  conversion-error             Datagram conversion
  dod-host-prohibited          Host prohibited
  dod-net-prohibited           Net prohibited
  dscp                         Match packets with given dscp value
  echo                         Echo (ping)
  echo-reply                   Echo reply
  fragments                    Check non-initial fragments
  general-parameter-problem    Parameter problem
  host-isolated                Host isolated
  host-precedence-unreachable  Host unreachable for precedence
  host-redirect                Host redirect
  host-tos-redirect            Host redirect for TOS
  host-tos-unreachable         Host unreachable for TOS
  host-unknown                 Host unknown
  host-unreachable             Host unreachable
  information-reply            Information replies
  information-request          Information requests
  log                          Log matches against this entry
  log-input                    Log matches against this entry, including input
                               interface
  mask-reply                   Mask replies
  mask-request                 Mask requests
  mobile-redirect              Mobile host redirect
  net-redirect                 Network redirect
  net-tos-redirect             Net redirect for TOS
  net-tos-unreachable          Network unreachable for TOS
  net-unreachable              Net unreachable
  network-unknown              Network unknown
  no-room-for-option           Parameter required but no room
  option-missing               Parameter required but not present
  packet-too-big               Fragmentation needed and DF set
  parameter-problem            All parameter problems
  port-unreachable             Port unreachable
  precedence                   Match packets with given precedence value
  precedence-unreachable       Precedence cutoff
  protocol-unreachable         Protocol unreachable
  reassembly-timeout           Reassembly timeout
  redirect                     All redirects
  router-advertisement         Router discovery advertisements
  router-solicitation          Router discovery solicitations
  source-quench                Source quenches
  source-route-failed          Source route failed
  time-exceeded                All time exceededs
  time-range                   Specify a time-range
  timestamp-reply              Timestamp replies
  timestamp-request            Timestamp requests
  tos                          Match packets with given TOS value
  traceroute                   Traceroute
  ttl-exceeded                 TTL exceeded
  unreachable                  All unreachables
  <cr>

Note that not all of the range of possible ICMP message types have been officially allocated. Please refer to the Internet Assigned Numbers Authority (IANA) web site for a complete listing of standard ICMP message types: http://www.iana.org/assignments/icmp-parameters.

19.4. Filtering Based on TCP Header Flags

Problem

You want to filter based on the flag bits in the TCP header.

Solution

The following ACL blocks contain several illegal combinations of TCP header flags:

Router1#configure terminal
Enter configuration commands, one per line.  End with CNTL/Z.
Router1(config)#access-list 161 deny tcp any any ack fin psh rst syn urg
Router1(config)#access-list 161 deny tcp any any rst syn
Router1(config)#access-list 161 deny tcp any any rst syn fin
Router1(config)#access-list 161 deny tcp any any rst syn fin ack
Router1(config)#access-list 161 deny tcp any any syn fin
Router1(config)#access-list 161 deny tcp any any syn fin ack
Router1(config)#end
Router1#

Discussion

There are six flag bits in the TCP header that the devices use to control the session:

ACK

Acknowledgement.

SYN

Synchronize sequence numbers.

FIN

Terminate the session.

RST

Reset the session.

PSH

Push this data to the application immediately. This usually means that all of the data has been sent.

URG

Look at the Urgent pointer later in the packet.

TCP uses a so-called three-way handshake to set up sessions. To start a session, the client device sends a packet with the SYN bit, which is an instruction to synchronize sequence numbers. The server device responds with a packet that has both SYN and ACK bits set, which the first device then acknowledges with an ACK to complete the handshake process.

The session teardown procedure is similar, but it actually uses four packets instead of three. One device sends the other a packet with the FIN bit set. The second device then responds to this with an ACK. Then, in a separate packet, the second device sends its own FIN, which the first device responds to with an ACK to terminate the session.

Devices use the RST flag for a few different reasons, but one of the most common is the so-called abortive close. This happens when one device can’t wait around for the other device to acknowledge the end of the session using the normal FIN and ACK pattern. So, it simply sends a packet that has both the RST and ACK bits set to end the session. There is no need for the other device to respond to this packet.

Obviously, some combinations of these bits are not valid, however. For example, it makes no sense to have a single packet with both the SYN and FIN bits set. And, in defining test cases for TCP implementations, RFC 1025 defines a packet with all 6 bits set as a nastygram (or a kamikaze packet, Christmas tree packet, or lamp test segment). The first line in the example ACL blocks nastygrams:

Router1(config)#access-list 161 deny tcp any any ack fin psh rst syn urg

The remaining lines block other illegal combinations of flags.

See Also

RFC 1025

19.5. Restricting TCP Session Direction

Problem

You want to filter TCP sessions so that only the client device may initiate the application.

Solution

You can use the established keyword to restrict which device is allowed to initiate the session. In the following example, we want to allow the client device to telnet to the server, but not the other way around:

Router1#configure terminal
Enter configuration commands, one per line.  End with CNTL/Z.
Router1(config)#access-list 148 permit tcp any eq telnet any established
Router1(config)#access-list 148 deny ip any any
Router1(config)#interface FastEthernet0/0
Router1(config-if)#ip access-group 148 in
Router1(config-if)#end
Router1#

Discussion

In this example, the interface will accept incoming TCP packets only if they have a TCP source port number of 23 (Telnet) and this TCP session is already established. It does not restrict the destination port number; it would be whatever random high-numbered port the initiating device had originally selected for its source port when it started the session.

The router considers an established TCP connection to be one that has either the RST or ACK bits set. We discuss these TCP header flags in more detail in Recipe 19.4. Because this does not include packets with only the SYN bit set in particular, it is impossible to create a new TCP connection.

Note that you could actually write the same thing explicitly as two rules:

Router1(config)#access-list 148 permit tcp any eq telnet any ack
Router1(config)#access-list 148 permit tcp any eq telnet any rst

The combination of these two rules is identical to the version in the example:

Router1(config)#access-list 148 permit tcp any eq telnet any established

But the version with the established keyword executes more efficiently. Note that putting both RST and ACK in the same rule would match packets with both RST and ACK set, not one or the other.

To see why the established keyword is sometimes necessary, imagine what would happen if it were not present. The interface would accept any inbound TCP packets that happened to have a source port of 23. But this could be literally anything. A moderately clever hacker who knew how to set the source port on his Telnet application could easily initiate a connection to any device on the other side of the router.

So, if you are using ACLs to control TCP applications for security reasons, you should consider using the established keyword.

See Also

Recipe 19.4

19.6. Filtering Multiport Applications

Problem

You want to filter an application that uses more than one TCP or UDP port.

Solution

This example shows how to filter both FTP control and data sessions:

Router1#configure terminal
Enter configuration commands, one per line.  End with CNTL/Z.
Router1(config)#access-list 152 permit tcp any any eq ftp
Router1(config)#access-list 152 permit tcp any any eq ftp-data established
Router1(config)#interface FastEthernet0/0
Router1(config-if)#ip access-group 152 in
Router1(config-if)#end
Router1#

Discussion

Some protocols use multiple ports. A classic example is FTP, which is shown in the example. It is worthwhile to review how the FTP protocol works. For more details, please consult RFC 959.

When a client device wants to connect to a server to upload or download files, it makes a TCP connection on port 21. This port 21 connection carries all of the interactive user traffic such as usernames and passwords, as well as commands to move around to different directories. FTP also uses this control session to tell the server what port number it wants to use for transferring data. This will typically be a high-numbered temporary TCP port.

When the user wants to transfer a file, he traditionally types a put or get command on the server. We say traditionally because this is not quite how things work when your FTP client software is driven through a web browser, as we discuss in Recipe 19.12.

The server then makes a new TCP connection to the high-numbered port on the client device that it previously learned about through the control session. The source port for this connection is the well-known FTP data port number 20. This is backwards from most TCP connections in which the client device connects to the server using a well-known destination port number. Here, the server connects to the client using a well-known source port number.

The client and server exchange the file, then disconnect this FTP data connection, leaving the FTP control connection on port 21 active. The server will actually use the FTP data connection to transfer any bulk data, including directory listings as well as files. You can match both the control and data traffic streams using the ACL shown in this recipe.

In this example, we assume that the client device is connected to the router’s FastEthernet0/0 interface, perhaps through other downstream routers. And, for the sake of the example, we assume that this is the only data that we want to allow.

The router will receive a TCP packet from client device as it initiates the FTP session with destination port 21. We match this connection with the following extended IP ACL:

Router1(config)#access-list 152 permit tcp any any eq ftp

Note that we have used the keyword ftp in this ACL to mean TCP port 21.

Then, when there is data to exchange, the server will make a connection back to the client device on port number 20. The ACL keyword for this port is ftp-data:

Router1(config)#access-list 152 permit tcp any any eq ftp-data established

It’s important to note that the access group is applied inbound to packets received on the client FastEthernet port. So this ACL will not apply to any of the packets sent from the server to the client device, only those sent from the client to the server. However, this is sufficient because the devices cannot establish a TCP session unless they can both send packets.

For a more generic multiport TCP application, you can specify a range of ports in the ACL with the range keyword:

Router1(config)#access-list 153 permit tcp any any range 6000 6063

This example matches any packets whose destination port is between 6000 and 6063 inclusive, which is the range commonly used by the X Window System. You can also specify open-ended ranges. For example, to match any TCP port number greater than 1023, use the gt keyword:

Router1(config)#access-list 153 permit tcp any any gt 1023

There are similar “less than” and “not equal to” operators for port numbers:

Router1(config)#access-list 153 permit tcp any any lt 1024
Router1(config)#access-list 153 permit tcp any any neq 666

As an aside, TCP port number 666 is used by the Doom interactive network game, making it an excellent candidate for filtering.

These same operations also apply identically for UDP port numbers:

Router1(config)#access-list 154 permit udp any any range 6000 6063
Router1(config)#access-list 155 deny udp any any gt 1023
Router1(config)#access-list 156 permit udp any any lt 1024
Router1(config)#access-list 157 permit udp any any neq 666

19.7. Filtering Based on DSCP and TOS

Problem

You want to filter based on IP QoS information.

Solution

You can filter packets based on the contents of the Differentiated Services Control Point (DSCP) field using the dscp keyword:

Router1#configure terminal
Enter configuration commands, one per line.  End with CNTL/Z.
Router1(config)#access-list 162 permit ip any any dscp af11
Router1(config)#end

Similarly, to filter based on TOS, you can use the tos keyword:

Router1#configure terminal
Enter configuration commands, one per line.  End with CNTL/Z.
Router1(config)#access-list 162 permit ip any any tos max-reliability
Router1(config)#end

And you can filter based on IP Precedence using the precedence keyword:

Router1#configure terminal
Enter configuration commands, one per line.  End with CNTL/Z
Router1(config)#access-list 162 permit ip any any precedence flash
Router1(config)#end

Discussion

In Chapter 11 and Appendix B we discuss the DSCP, IP TOS, and IP Precedence fields in more detail. Chapter 11 also includes several examples of ACLs that filter based on this information. Please refer to these sections for more information.

The first example looks for packets that have a DSCP field value of AF11, which has a bit pattern of 001010, or a decimal value of 10. The second example matches packets with a TOS value of maximum reliability, which has a decimal value of 2.

Note that you can use the decimal numerical values for any TOS, Precedence, or DSCP field, and the router will simply replace it with the mnemonic keyword, if one exists. For example, we could have written the second example as follows:

Router1(config)#access-list 162 permit ip any any tos 2

In this case, the router would have replaced the number 2 with the max-reliability keyword. However, there is no mnemonic keyword corresponding to the TOS value, 3. The router will accept values that do not have well-known names such as this, but it will leave them as numerical values in the configuration file.

19.8. Logging when an Access List Is Used

Problem

You want to know when the router invokes an access list.

Solution

Access lists can generate log messages. The following example will allow all packets to pass, but will record them:

Router1#configure terminal
Enter configuration commands, one per line.  End with CNTL/Z.
Router1(config)#access-list 150 permit ip any any log
Router1(config)#interface Serial0/1
Router1(config-if)#ip access-group 150 in
Router1(config-if)#end
Router1#

In this example, we use the log-input keyword to include additional information about where the packets came from:

Router1#configure terminal
Enter configuration commands, one per line.  End with CNTL/Z.
Router1(config)#access-list 150 permit tcp any any log-input
Router1(config)#access-list 150 permit ip any any
Router1(config)#interface Serial0/1
Router1(config-if)#ip access-group 150 in
Router1(config-if)#end
Router1#

Discussion

The first example uses the log keyword to record a log message every time the ACL makes a match. Here are some log messages generated by this command:

Feb  6 13:01:19: %SEC-6-IPACCESSLOGRP: list 150 permitted ospf 10.1.1.1 ->
  224.0.0.5, 9 packets
Feb  6 13:01:19: %SEC-6-IPACCESSLOGDP: list 150 permitted icmp 10.1.1.1 ->
  10.1.1.2 (0/0), 4 packets

You can also get a breakdown of how many matches each line in the ACL has recorded with the show access-list command:

Router1#show access-list 150
Extended IP access list 150
    permit ip any any log (15 matches)
Router1#

The second form, with the log-input keyword, causes the router to include other useful data in the log messages. With this option, the log messages will include the port where the packet was received:

Feb  6 13:08:31: %SEC-6-IPACCESSLOGP: list 150 permitted tcp 10.1.1.1(0)
  (Serial0/1 ) -> 10.1.1.2(0), 80 packets
Feb  6 13:08:38: %SEC-6-IPACCESSLOGP: list 150 permitted tcp 10.2.2.2(0)
  (Serial0/1 ) -> 172.25.26.5(0), 1 packet
Feb  6 13:10:29: %SEC-6-IPACCESSLOGP: list 150 permitted tcp 10.2.2.2(0)
  (Serial0/1 ) -> 172.20.100.1(0), 1 packet

If we apply this ACL on an Ethernet or Token Ring port, the log messages will also include MAC address information:

Feb  6 14:56:34: %SEC-6-IPACCESSLOGP: list 150 permitted tcp 172.25.1.1(0)
(FastEthernet0/0.1 0010.4b09.5700) -> 172.25.25.1(0), 1 packet
Router1#
Feb  6 14:58:20: %SEC-6-IPACCESSLOGP: list 150 permitted tcp 172.25.1.7(0)
(FastEthernet0/0.1 0000.0c92.bc6a) -> 172.25.1.5(0), 1 packet

The only problem with these commands is that they tend to produce huge numbers of log messages. To be really useful, we recommend using this feature in conjunction with a remote log server, as described in Chapter 18. Then you can store and analyze all of the messages without worrying that you will lose information when the router’s internal log buffer overwrites itself. We offer a useful script for analyzing the messages and look for important patterns in Recipe 19.10.

In general, we recommend logging all denied packets, because they tend to represent the rejected traffic that is not part of the normal functioning of the network.

While all of the examples in this recipe used extended ACLs, the log keyword is also available with standard ACLs:

Router1(config)#access-list 77 permit any log

However, the log-input option is available only for extended ACLs.

19.9. Logging TCP Sessions

Problem

You want to log the total number of TCP sessions.

Solution

You can configure the router to log the total number of TCP sessions, rather than just the number of packets, with the following set of commands:

Router1#configure terminal
Enter configuration commands, one per line.  End with CNTL/Z.
Router1(config)#access-list 122 permit tcp any any eq telnet established
Router1(config)#access-list 122 permit tcp any any eq telnet
Router1(config)#access-list 122 permit ip any any
Router1(config)#interface Serial0/0
Router1(config-if)#ip access-group 122 in
Router1(config-if)#end
Router1#

Here is an alternative method that will also work:

Router1#configure terminal
Enter configuration commands, one per line.  End with CNTL/Z.
Router1(config)#access-list 121 permit tcp any any eq telnet syn
Router1(config)#access-list 121 permit tcp any any eq telnet
Router1(config)#access-list 121 permit ip any any
Router1(config)#interface Serial0/0
Router1(config-if)#ip access-group 121 in
Router1(config-if)#end
Router1#

Discussion

When you configure an access list, the router counts the total number of times it finds something that matches each line in the ACL. While this information is often useful, it does not tell you whether these counters are recording a thousand packets on a single session, or a single packet from each of a thousand sessions. The ACLs in this recipe count the number of TCP sessions, as well as the total number of packets.

In the first example, the first line in the ACL permits all established Telnet packets to pass through the access list, as we did in Recipe 19.5. The second line then matches all of the Telnet packets that the first one does not, which mainly means the initial SYN packet that starts the TCP session. As we mentioned in Recipe 19.4, the first packet of a TCP session contains the SYN bit. And, as we discussed in Recipe 19.5, an ACL that includes the established keyword will not match any packets that have the SYN bit set.

So, the second line catches the initial session establishment, while the first line matches all of the other packets in the session. Therefore, the second line will give us a way to count the total number of TCP sessions that pass through the router. Note that these sessions can be between any two devices—as long as they communicate through this router, we can count them. Of course, the ACL in the example counts only Telnet sessions, that is, sessions on TCP port number 23. However, it is easy enough to change the port number in the ACL to monitor other TCP-based applications.

When you apply this ACL to an interface, the show access-list command shows a running count of the number of Telnet sessions that have occurred:

Router1#show access-list 122
Extended IP access list 122
    permit tcp any any eq telnet established (3843 matches)
    permit tcp any any eq telnet (6 matches)
    permit ip any any (31937 matches)
Router1#

Six separate Telnet sessions have passed through the interface where we applied this ACL. If you want to know the total number of Telnet packets, you can simply add the first two lines together: 3843+6=3849 packets.

The second example uses a slightly different method for counting the number of sessions. In this case, the first line of the access list matches only Telnet packets with the SYN bit set, as discussed in Recipe 19.4:

Router1(config)#access-list 121 permit tcp any any eq telnet syn

The only packets that have this bit set are the packets from the initial TCP three-phase handshake that establishes the session. So this also gives us a way of counting the total number of Telnet sessions. The second line of this ACL captures the remaining Telnet packets:

Router1#show access-list 121
Extended IP access list 121
    permit tcp any any eq telnet syn (7 matches)
    permit tcp any any eq telnet (3057 matches)
    permit ip any any (9404 matches)
Router1#

This ACL has counted seven separate Telnet sessions: 7+3057=3064 total Telnet packets.

We can take the counting functionality of these ACLs a step further by adding the log keyword to the ACL lines that count the sessions:

Router1#configure terminal
Enter configuration commands, one per line.  End with CNTL/Z.
Router1(config)#access-list 121 permit tcp any any eq telnet syn log
Router1(config)#access-list 121 permit tcp any any eq telnet
Router1(config)#access-list 121 permit ip any any
Router1(config)#end
Router1#

Including the log keyword like this allows us to keep a log of every TCP session, without needing to log all of the packets in these sessions. This can be useful for security records and audits:

Router1#show logging | include list 121
Feb  7 15:36:13: %SEC-6-IPACCESSLOGP: list 121 permitted tcp 172.25.1.1(3886)
-> 10.2.2.2(23), 1 packet
Feb  7 15:36:39: %SEC-6-IPACCESSLOGP: list 121 permitted tcp 172.25.1.1(3887)
-> 10.2.2.2(23), 1 packet
Feb  7 15:38:32: %SEC-6-IPACCESSLOGP: list 121 permitted tcp 172.25.1.1(3888)
-> 10.2.2.2(23), 1 packet
Feb  8 07:48:20: %SEC-6-IPACCESSLOGP: list 121 permitted tcp 172.25.1.1(4332)
 -> 10.2.2.2(23), 1 packet
Feb  8 07:49:35: %SEC-6-IPACCESSLOGP: list 121 permitted tcp 172.25.1.1(4333)
-> 10.2.2.2(23), 1 packet
Feb  8 08:08:57: %SEC-6-IPACCESSLOGP: list 121 permitted tcp 172.25.1.1(4339)
-> 10.2.2.2(23), 1 packet
Router1#

For more information about logging, see Chapter 18.

19.10. Analyzing ACL Log Entries

Problem

You want to analyze the log entries created by logging ACLs.

Solution

The Perl script in Example 19-1 parses a router syslog file and builds a detailed report of packets that were denied by logging ACLs. By default, the script will parse every ACL log message that it finds in the syslog file on a server. You can also look for messages associated with a particular ACL by specifying the ACL number or name as a command-line argument.

Example 19-1. logscan.pl
#!/usr/local/bin/perl
#
#       logscan.pl -- a script to extract ACL logs from a syslog file.
#
# Set behaviour
$log="/var/log/cisco.log";
$ntop=10;
#
chomp ($acl=$ARGV[0]);
if ($acl =  = "") { $acl=".*"};

open(LOG , "<$log") or die;
while (<LOG>) {
 if (/IPACCESSLOGP: list $acl denied ([tcpud]+) ([0-9.]+)(([0-9]+)) ->
   ([0-9.]+)(([0-9]+)), ([0-9]+) /) {

   $x=$6;
   $srca{$2}+=$x;
   $foo=sprintf("%16s  -> %16s  %3s port %-6s",$2,$4,$1,$5);
   $moo=sprintf("%3s port %-6s",$1,$5);
   $quad{$foo}+=$x;
   $port{$moo}+=$x;
 }
}
$n=0;
printf ("Connection Summary:
");
foreach $i (sort { $quad{$b} <=> $quad{$a} } keys %quad) {
   if ($n++ >= $ntop) { last };
   printf ("%6s:%s
", $quad{$i},$i);
}
$n=0;
printf ("
Destination Port Summary:
");
foreach $i ( sort { $port{$b} <=> $port{$a} } keys %port) {
   if ($n++ >= $ntop) { last };
   printf ("%6s: %s
", $port{$i},$i);
}
$n=0;
printf ("
Source Address Summary:
");
foreach $i ( sort { $srca{$b} <=> $srca{$a} } keys %srca) {
   if ($n++ >= $ntop) { last };
   printf ("%6s: %s
", $srca{$i},$i);
}

Note that we have had to split the line that begins “if (/IPACCESSLOGP: list” across two lines so that it will fit on the page. If you decide to use this script, please type this as a single line.

Discussion

It’s a good idea configure your access lists so that they log all of the packets that they deny. This is particularly true for security-related ACLs. You can then use these log messages for security or audit purposes. Unfortunately, this level of logging can create a large number of messages, which makes analysis difficult. This Perl script automates the most difficult part of this analysis by parsing a large file of ACL log messages and building a report that can help to identify potential problems.

The report produced by the script has three sections that summarize connections, destination ports, and source IP addresses. The connection report displays the top 10 most common connection denied attempts including the source address, destination source, and destination port number. The destination port summary displays the top 10 most frequently denied destination ports. Finally, the source address summary displays the 10 hosts whose connection attempts were most frequently denied. In each case, the script looks at both TCP and UDP ports.

The following is a sample report:

Freebsd%./logscan.pl
Connection Summary:
   195:      172.25.1.1  ->     172.20.100.1  tcp port 23
    13:      172.25.1.1  ->     172.20.100.1  tcp port 22
     8:      172.20.1.2  ->       172.25.1.3  udp port 53
     6:      172.20.1.2  ->       172.25.1.1  udp port 123
     6:      172.25.1.1  ->         10.2.2.2  tcp port 23
     4:      172.20.1.2  ->       172.25.1.1  udp port 162
     4:      172.25.1.1  ->     172.20.100.1  tcp port 21
     4:      172.20.1.2  ->       172.25.1.1  udp port 53
     3:      172.25.1.1  ->     172.20.100.1  tcp port 80
     2:      172.20.1.2  ->       172.25.1.3  udp port 123

Destination Port Summary:
   206: tcp port 23
    14: tcp port 22
    12: udp port 53
     8: udp port 123
     4: tcp port 80
     4: udp port 162
     4: tcp port 21
     2: tcp port 443
     1: tcp port 6000
     1: tcp port 79

Source Address Summary:
   222: 172.25.1.1
    24: 172.20.1.2
     3: 172.25.1.6
     1: 192.168.4.217
     1: 172.25.1.9
     1: 10.2.3.134
     1: 172.25.1.4
     1: 172.22.1.9
     1: 10.23.55.121
     1: 172.25.1.3
Freebsd%

This report can help identify troubling behavior that warrants further investigation. For instance, address 172.25.1.1 has attempted to telnet to 172.20.100.1 195 times. This may not have been evident by scanning the log file by hand.

The script can also build a report based on the messages received from a particular ACL number or name:

Freebsd%./logscan.pl 122
Connection Summary:
     2:      172.25.1.6  ->         10.2.2.2  tcp port 443
     1:   192.168.4.217  ->         10.2.2.2  tcp port 23
     1:      172.22.1.9  ->         10.2.2.2  tcp port 6000
     1:      10.2.3.134  ->         10.2.2.2  tcp port 23
     1:      172.25.1.9  ->         10.2.2.2  tcp port 23
     1:    10.23.55.121  ->         10.2.2.2  tcp port 79
     1:      172.25.1.1  ->         10.2.2.2  tcp port 22
     1:      172.25.1.6  ->         10.2.2.2  tcp port 23

Destination Port Summary:
     4: tcp port 23
     2: tcp port 443
     1: tcp port 22
     1: tcp port 6000
     1: tcp port 79

Source Address Summary:
     3: 172.25.1.6
     1: 10.2.3.134
     1: 172.22.1.9
     1: 192.168.4.217
     1: 172.25.1.1
     1: 172.25.1.9
     1: 10.23.55.121
Freebsd%

Before you can use this script you must modify the variable $log. This variable must contain the full directory and filename of the syslog file that you wish to scan. The script is then ready to launch. The only other variable you may want to modify is the $ntop variable. This variable defines how long each section of the report will be. By default, the script is set to display the top 10 matches in each category. However, you can set this number to any number you prefer. Note also that, as in the previous example, if there are fewer than $ntop matches in any category, the script will show only the matches that it actually finds.

For more information on logging and remote logging to a syslog server, please see Chapter 18.

19.11. Using Named and Reflexive Access Lists

Problem

You want to use a reflexive ACL, embedded in a named ACL.

Solution

A basic named ACL is similar to the numbered ACLs that we discussed earlier in this chapter. They can work like either standard or extended IP ACLs:

Router1#configure terminal
Enter configuration commands, one per line.  End with CNTL/Z.
Router1(config)#ip access-list standard STANDARD-ACL
Router1(config-std-nacl)#remark This is a standard ACL
Router1(config-std-nacl)#permit any log
Router1(config-std-nacl)#exit
Router1(config)#ip access-list extended EXTENDED-ACL
Router1(config-ext-nacl)#remark This is an extended ACL
Router1(config-ext-nacl)#deny tcp any any eq www
Router1(config-ext-nacl)#permit ip any any log
Router1(config-ext-nacl)#exit
Router1(config)#interface Serial0/1
Router1(config-if)#ip access-group STANDARD-ACL in
Router1(config-if)#end
Router1#

You can embed a reflexive ACL inside of a named extended IP ACL. The reflect keyword defines the reflexive ACL rule, and the evaluate command executes it. The following example filters ICMP packets so that you can initiate a ping test from one side of the network, but not the other:

Router1#configure terminal
Enter configuration commands, one per line.  End with CNTL/Z.
Router1(config)#ip access-list extended PING-OUT
Router1(config-ext-nacl)#permit icmp any any reflect ICMP-REFLECT timeout 15
Router1(config-ext-nacl)#permit ip any any
Router1(config-ext-nacl)#exit
Router1(config)#ip access-list extended PING-IN
Router1(config-ext-nacl)#evaluate ICMP-REFLECT
Router1(config-ext-nacl)#deny icmp any any log
Router1(config-ext-nacl)#permit ip any any
Router1(config-ext-nacl)#exit
Router1(config)#interface Serial0/1
Router1(config-if)#ip access-group PING-OUT out
Router1(config-if)#ip access-group PING-IN in
Router1(config-if)#end
Router1#

Discussion

The first example in this recipe demonstrates how to use named ACLs. There is very little difference between this example and the one shown in Recipe 19.1, except that here we have used a different type of ACL to accomplish the same thing. One useful difference between the two versions is that you can delete an individual rule from a named ACL:

Router1#show access-list EXTENDED-ACL
Extended IP access list EXTENDED-ACL
    deny tcp any any eq www
    permit ip any any log
Router1#configure terminal
Enter configuration commands, one per line.  End with CNTL/Z.
Router1(config)#ip access-list extended EXTENDED-ACL
Router1(config-ext-nacl)#no deny tcp any any eq www
Router1(config-ext-nacl)#end
Router1#show access-list EXTENDED-ACL
Extended IP access list EXTENDED-ACL
    permit ip any any log
Router1#

However, as with numbered ACLs, you cannot add individual rules to the middle of a named ACL.

Named ACLs start to show their real value, though, when you need to use more advanced features such as reflexive ACLs, as we did in the second example. This example is similar in spirit to what we did to restrict TCP sessions in Recipe 19.5. In that case, we wanted to ensure that users on the trusted side of the network could initiate TCP connections to the untrusted side, but reject any incoming connection attempts. Here we do the same thing with ICMP packets.

Of course, because TCP is a connection-oriented protocol, it is not quite as difficult to determine which side initiated the session. But because ICMP doesn’t have the concept of a session, we have to wait until somebody on the inside sends an ICMP packet to somebody on the outside. When this happens, we tell the router that it can expect to see an appropriate ICMP response from the same IP address, so it should let that packet through.

Let’s look at the outbound ACL first:

Router1(config)#ip access-list extended PING-OUT
Router1(config-ext-nacl)#permit icmp any any reflect ICMP-REFLECT timeout 15
Router1(config-ext-nacl)#permit ip any any

The first permit command includes the keyword reflect, and defines the reflection rule name as ICMP-REFLECT. We have applied this ACL to watch for outbound packets on the interface. As soon as we send out an ICMP packet, such as a ping query, the router starts looking for the reflected version of this packet—in this case, a ping response.

We have also included the timeout keyword at the end of the line with an argument of 15. This tells the router that it should not wait more than 15 seconds after the last outbound packet for additional inbound packets.

The inbound rule then uses the evaluate keyword to dynamically enable the reflection rule:

Router1(config)#ip access-list extended PING-IN
Router1(config-ext-nacl)#evaluate ICMP-REFLECT
Router1(config-ext-nacl)#deny icmp any any log
Router1(config-ext-nacl)#permit ip any any

Note that this example uses the same rule name, ICMP-REFLECT, that was previously defined in the outbound ACL. If the incoming packet looks like a reflected version of whatever was defined when we created this rule, the ACL will permit the packet. If the packet doesn’t match this rule, then it will continue checking the rest of the ACL normally. In this case, we have followed the evaluate command with a command that will explicitly deny all other ICMP packets that don’t match the reflection rule.

Note that the router will check the reflected packet to ensure that it has the correct source and destination addresses, based on the outbound packet. For example, if you use reflexive ACLs to match a UDP application, the router will also check port numbers to ensure that the inbound packet is legitimate.

19.12. Dealing with Passive Mode FTP

Problem

You want to construct an ACL that can identify passive mode FTP sessions.

Solution

This example shows how to filter passive FTP control and data sessions:

Router1#configure terminal
Enter configuration commands, one per line.  End with CNTL/Z.
Router1(config)#access-list 144 permit tcp any gt 1023 any eq ftp
Router1(config)#access-list 144 permit tcp any gt 1023 any gt 1023
Router1(config)#access-list 144 deny ip any any
Router1(config)#interface Serial0/0.1
Router1(config-subif)#ip access-group 144 in
Router1(config-subif)#end
Router1#

Discussion

In Recipe 19.6, we briefly reviewed the traditional way that FTP works. However, there is another subtle variation on this process, which is commonly called passive FTP. The user connects the control session to the server on port 21, exactly as before. But in the passive FTP case, the client software issues the command PASV. This command instructs the server to listen on a new non-default data port and wait for a connection. The server selects a new port, which it tells to the client. The server then opens this port and waits for a connection. The client device initiates a new TCP connection to this temporary port number and uses that connection to transfer its data.

This may sound like an unusual way of doing things, and it probably is. However, it is actually the default mode for many web browsers that perform FTP file transfers, including Internet Explorer and Netscape. This makes passive FTP the most common FTP mode for many networks. The problem is that if you want to control this traffic using an ACL of any kind, you no longer know the source or destination TCP port numbers. For example, if you need to restrict some traffic while ensuring that passive FTP is allowed, you will need an ACL that can somehow permit the temporary port numbers. In Recipe 19.13, we demonstrate a filtering method in which the router learns about the new port by watching the control session of the FTP session.

This example takes a simpler approach and uses an extended ACL to deal with passive FTP. The trouble with this ACL is that it opens all TCP ports from 1024 and above. Clearly, this is not desirable on a router facing the Internet or some other potentially unfriendly network.

Although our example permits passive FTP to pass through, it opens up over 64,000 TCP ports in the process. Obviously, this is not the best way to permit passive FTP. In Recipe 19.13, we discuss a much more secure method of allowing passive FTP through your router.

19.13. Using Context-Based Access Lists

Problem

You want to use your router as a firewall to perform advanced filtering functionality.

Solution

The following example shows how to configure the router to perform stateful inspection of TCP or UDP packets:

Router1#configure terminal
Enter configuration commands, one per line.  End with CNTL/Z.
Router1(config)#access-list 166 deny   ip any any
Router1(config)#access-list 167 permit tcp any any eq telnet
Router1(config)#ip inspect name Telnet tcp
Router1(config)#interface Serial0/1
Router1(config-if)#ip access-group 166 in
Router1(config-if)#ip access-group 167 out
Router1(config-if)#ip inspect Telnet out
Router1(config-if)#end
Router1#

Note

Cisco’s firewall IOS feature set must be installed on a router before you can configure context-based access lists.

Discussion

CBAC has been available as part of the IOS firewall feature set since Version 11.2(P). CBAC does a stateful inspection of TCP and UDP packets to manage sessions as they pass through the router. It uses this state information to dynamically modify existing extended ACLs to control the active sessions. CBAC can also monitor and manage sessions based on application type and identify, terminate, or log any suspicious activity.

CBAC provides much greater security than a regular filtering ACL because it uses features similar to those found in dedicated firewalls. In fact, the IOS firewall feature set (including CBAC) makes an excellent firewall for small or cost-conscious organizations. Although it is not suitable for every application, CBAC’s stateful inspection does provide better security than simple packet filtering firewalls.

CBAC works by inspecting active sessions and dynamically creating temporary ACL entries to allow the return traffic through. In our example, we configured the router with an inbound ACL that denies all IP packets, which would normally prevent the router from accepting any inbound IP traffic on this interface. However, when somebody on the inside of the network initiates an outbound connection through this port, CBAC creates a temporary ACL that allows the device on the outside to respond.

We can demonstrate this by initiating an outbound Telnet session through this interface, then viewing the inbound ACL:

Router1#show ip access-list 166
Extended IP access list 166
    permit tcp host 10.2.2.2 eq telnet host 172.25.1.1 eq 1379 (22 matches)
    deny ip any any (456 matches)
Router1#

Note that the original ACL now contains a new entry to allow the return data of the Telnet session that we originated. This temporary ACL entry includes the exact source and destination IP addresses and port numbers. This ensures that our Telnet session works normally, but it prevents all other possible IP addresses from connecting to the client device’s source port. In fact, CBAC even prevents the external server from connecting to the internal device’s source port using a new session because it maintains specific session information such as source and destination port numbers and TCP sequence numbers. This temporary ACL entry will terminate when the session ends, leaving only the static deny all entry that we originally configured in ACL number 166.

This configuration will block all inbound connection attempts. A common and very simple technique used by hackers as a prelude to attacking an Internet site is to perform a port scan. This means systematically trying to start an inbound session on each port in a large range. If there is any response at all, the attacker knows that there is something listening, which presents a useful starting point for breaking in. However, because this CBAC configuration blocks all unsolicited connection attempts regardless of the port, port scanning reveals nothing useful. This is usually enough to deter all but the most sophisticated hackers.

In fact, the only effective way to get a packet past the ACL configuration shown in this recipe is to send a packet with the right source and destination addresses and port numbers as well as the right TCP sequence number. This technique is called a hijack attack, and it is almost impossible to prevent. Attackers using this technique are generally able to get a single packet past the firewall. In some cases an attacker can use this single packet to cause mischief. Fortunately for us, hijack attacks are extremely difficult to execute.

The show ip inspect sessions command lets you view information about all of the sessions that CBAC is currently watching:

Router1#show ip inspect sessions
Established Sessions
 Session 821061C0 (172.25.1.1:1379)=>(10.2.2.2:23) tcp SIS_OPEN
Router1#

The example shows how to inspect generic TCP sessions. However, one of CBAC’s greatest strengths is its ability to identify application-specific behavior and adjust its ACL entries accordingly. Table 19-3 displays the various applications that CBAC is able to monitor.

Table 19-3. CBAC application support keywords

Keyword

Application protocol

cuseeme

CU-SeeMe protocol

fragment

IP fragmented packets

ftp

File Transfer Protocol

h323

H.323 protocol

http

HTTP (Java blocking)

netshow

Microsoft’s NetShow

rcmd

Unix R-commands

realaudio

RealAudio

rpc

Sun RPC

rtsp

Microsoft’s RPC

smtp

Simple Mail Transfer Protocol

sqlnet

SQL*Net

streamworks

StreamWorks

tcp

Generic TCP

tftp

Trivial File Transfer Protocol

udp

Generic UDP

vdolive

VDOLive

Just because an application is not listed in this table doesn’t mean that CBAC will not manage its sessions. In fact, the Telnet example in this recipe used generic TCP inspection. Unless your application does something unusual in its session setup and negotiation sequences, the generic inspection should work well. For example, standard HTTP also uses standard TCP session rules. The special HTTP option for CBAC simply allows it to handle Java.

Let’s take a look at an application that doesn’t use standard TCP ports to build connections: passive FTP. As we indicated in Recipe 19.12, passive FTP is difficult to secure because the server can choose to use any of a large number of ports for its data session. The result is that both the source and destination ports are determined dynamically when the session is established. Recipe 19.12 showed a way to filter this traffic statically, but with the unfortunate side effect of leaving some 64,000 other ports open. With CBAC, this is not necessary—the router can watch the FTP control session and determine the server’s data port. This allows it to open only the required port:

Router1#configure terminal
Enter configuration commands, one per line.  End with CNTL/Z.
Router1(config)#access-list 155 permit tcp any any eq ftp
Router1(config)#access-list 155 deny ip any any
Router1(config)#ip inspect name TEST ftp
Router1(config)#interface Serial0/0
Router1(config-subif)#ip access-group 155 in
Router1(config-subif)#ip inspect TEST in
Router1(config-subif)#end
Router1#

In this example, the ftp keyword invokes FTP inspection instead of the generic TCP inspection that we showed in the previous example. Also, notice that the first line of our ACL includes the ftp keyword, which permits only the FTP control session. This is necessary so that CBAC will permit the control part of the application to pass.

Now we can connect to the FTP server using a web browser. The ACL now shows the new entries that CBAC has created for us:

Router1#show ip access-list 155
Extended IP access list 155
    permit tcp host 172.20.1.2 eq 11252 host 172.25.1.3 eq 49155 (1415 matches)
    permit tcp any any eq ftp (151 matches)
    deny ip any any (3829 matches)
Router1#

CBAC monitored the FTP control session and opened the specific FTP data ports for the passive FTP data connection. You can tell that this is a passive FTP session from the high port numbers.

CBAC inspection can also handle normal FTP. CBAC FTP inspection blocks third party connections, allowing only “safe” FTP data ports (1024–65535). CBAC monitors the FTP control session, and will not open a data port if the client authentication fails.

Although we haven’t shown an example for UDP, CBAC can also handle UDP-based applications in a similar fashion to TCP. When you send a UDP packet out through the interface, CBAC knows to expect an appropriate response. UDP is difficult to handle because it is not session oriented, but CBAC does it well.

CBAC also offers application support for TFTP, which is a feature rarely seen in commercial firewalls. The TFTP server uses the well-known UDP port 69. The client sends an initial packet to the server on this well-known port. But then the server opens a new arbitrary port greater than 1023 for the duration of the TFTP session. A standard packet filter would have to permit all UDP ports above 1023 to let TFTP work. CBAC gets around this problem by monitoring the TFTP session to determine which UDP port to open.

CBAC has a several settings that you can adjust to improve the overall performance and security of the router. We’ve listed some of the most important options in Table 19-4.

Table 19-4. Recommended CBAC settings

Setting

Description

Default

Recommended

TCP idle-time

Length of time CBAC will continue to permit an idle TCP session

1 hour

30 minutes

UDP idle-time

Length of time CBAC will continue to permit an idle UDP session

30 seconds

20 seconds

Finwait-time

Length of time CBAC will continue to permit a TCP session after the exchange of FIN packets

5 seconds

1 second

Synwait-time

Length of time that CBAC will wait after receiving a SYN packet without completing the session establishment

30 seconds

15 seconds

The following set of commands configures the timer settings of CBAC shown in Table 19-4:

Router1#configure terminal
Enter configuration commands, one per line.  End with CNTL/Z.
Router1(config)#ip inspect tcp idle-time 1800
Router1(config)#ip inspect udp idle-time 20
Router1(config)#ip inspect tcp finwait-time 1
Router1(config)#ip inspect tcp synwait-time 15
Router1(config)#end
Router1#

You can view the CBAC configuration settings with the show ip inspect config command:

Router1#show ip inspect config
Session audit trail is disabled
Session alert is enabled
one-minute (sampling period) thresholds are [400:500] connections
max-incomplete sessions thresholds are [400:500]
max-incomplete tcp connections per host is 50. Block-time 0 minute.
tcp synwait-time is 15 sec -- tcp finwait-time is 1 sec
tcp idle-time is 1800 sec -- udp idle-time is 20 sec
dns-timeout is 5 sec
Inspection Rule Configuration
  Inspection name Telnet
    tcp alert is on audit-trail is off timeout 1800

Router1#

CBAC also provides a method of logging managed sessions by enabling audit trails. You can enable an audit trail on a particular CBAC inspection command with the audit-trail keyword:

Router1#configure terminal
Enter configuration commands, one per line.  End with CNTL/Z.
Router1(config)#ip inspect name Telnet tcp audit-trail on
Router1(config)#end
Router1#

When you enable CBAC audit trails, the router will create a log entry after each session terminates. This log entry includes detailed information about the connection.

Here a sample audit trail log that the router recorded after we terminated a Telnet session:

Feb  8 14:37:24: %FW-6-SESS_AUDIT_TRAIL: tcp session initiator
(172.25.1.1:1402) sent 59 bytes -- responder (10.2.2.2:23) sent 1299

For more information on logging please see Chapter 18.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.217.190.58