Anti Spoofing ACL's on Cisco Routers


Maintaining  ingress and egress filter lists on modern multi-interface routers can be a time consuming task. While it is generally accepted that these types of anti spoofing filters increase the level of secure communications over the internet, it seems that these filters are not maintained in general. A simple perlscript is presented that helps performing these tasks.


Cisco routers are said to have a market share of over 90% in the internet and are considered as important building blocks of it. While they support network management via SNMP, it is fairly easy to read the network routes and their associated interfaces with a tool like snmpwalk. The presented script catches the necessary information via SNMP, calculates the interfaces for the routes (if not directly available) and produces individual cisco access lists (ACL's) for each interface that will suppress unsolicited traffic on the interfaces. It supports also include files (for basic types of further packet filtering) as well as a list of blacklisted ports that can be used to filter out clearly unwanted traffic (like scans to popular trojan ports).

Possible problems

If you have configured your router to use asymmetric routing (traffic goes over different interfaces for directions in and out) the script does only half of it's job, here you have to edit the command file with the ACL's and the setup (not a very difficult task). The much more simpler method to prevent spoofing with the rpf checking command ip verify unicast rpf has the same problem.
I have seen also problems where no proper default route was configured on the boxes. The script tries to circumvent these problems but might fail. In case of that get in contact with me.


You will need to have both perl and snmpwalk (UCD-SNMP) installed on your (unix) system. Your ciscobox should run at least IOS 11.


After downloading the script and storing it in some separate directory, change to that directory give it a try with

./ myrouter
where myrouter is either the host name or the IP address of your router. It will tell you that it creates a subdir for the router named myrouter and that it tries to get the routing info via SNMP. After some delay it will hopefully print out the routing information and after that starting to create the ACLs for each interface. Finally it creates one file named myrouter.all that contains all the ACLs together with the commands to set them up.
At this point you should evaluate the ACL-file. I would look at the file first with more to see whether it looks reasonable. Compare the routing entries with the ACLs for the different interfaces.
If it looks good try to install it on router. I use a tftp server for that giving on the ciscobox while enabled the following commands:
conf net
<IP addr of your tftp server>
<path to my file>/<myrouter>.all
After that watch the log of your ciscobox (sho log) and the ACL counters (sho access-list).

Details of Operation

As mentioned above, the script creates a separate directory for each router. It will contain a file named <myrouter>-snmpwalk with all the SNMP information obtained by snmpwalk. The routing information shown will be stored in a file named <myrouter>-routes. Both files are useful for debugging. If you run the script again and there is already an snmpwalk file the script will ask whether to override it. If you did not change the routing information on the ciscobox you can safely say yes to the reuse question thereby sparing some time and network bandwidth.
The directory will also hold the individual access list files for each interface named <myrouter>.<interface>.acl.<acl-number>. Slashes ("/") in the interface names will be replaced by underbars ("_"). This is for testing purposes with ACLs on single interfaces.
Finally a file <myrouter>.all is created in the current working directory.
The script also keeps backups of the single interface ACL files in the router directory and backups of the "all" files in a directory named acl-archive.
If there exists a file named <myrouter>-inc-<interface> in the router directory this file is included into the ACL for the specific interface. So you easily can do some packet filtering here.
For instance you have a net Vlan123 on myrouter and a machine in that network from which no packet should escape so you have to setup a file named <myrouter>-inc-Vlan123 in the router directory which contains the following lines
! is blocked
access-list ACLNUMBER deny ip host any
The tag ACLNUMBER will be replaced literally by the proper number during generation of the ACL for the interface.

Theory of Operation

This script is not intended to replace firewalls although some of their aspects can be included here. The reason for this is that we want performance on the routers and so only in-filtering is done by the script.
The scheme for the ACL is the following:
  1. allow established tcp connections pass (performance)
  2. deny unwanted ports (trojans)
  3. deny unwanted network addresses (smurf)
  4. deny loopback & private addresses (reliability)
  5. deny broadcasts (smurf)
  6. process include file (see above)
  7. permit routed networks via this interface (normal operation)
  8. permit multicast
  9. deny everything else and log it (to see when something goes wrong)
The unwanted ports (@blocked_port_list) can be modified by editing the script (about line 45), I have included the two famous ports for Back Orifice and Netbus.
You also should edit the blocked network address list (@blocked_net_list).

What's left ?

The script was translated from a shell script to make it more handy and better performing. Suggestions from some perl wizard are welcome (the way I process and setup the lists used in this script comes from my translation from bourne-shell).
Also welcome are suggestions from cisco packet filtering wizards. If you have problems to get a running configuration for your router get in contact with me.
The same applies for bug reports and criticism as well as donations.
The script is GPL'd.


Improving Security on Cisco Routers
Access List Examples
Ports used by trojans
RFC 2267

  Jens Hektor, August 2000, RWTH Aachen, Germany