What is it ?
aclcheck is Cisco ACL syntax checker. It can be mainly used for
For maintaining complex security policies with large ACLs, it may be suitable to store ACLs in repository. (cvs or the like) Every change of ACLs must be done in the repository. Commits into the repository can be set up to generate e-mails of every change. The e-mails can contain differences to previous versions of ACLs. This can make security administration more transparent.
ACLs can be then loaded from repository directly to Cisco boxes. Before that, they should be checked they are syntactically correct. This is what aclcheck does.
aclcheck can also be used for Cisco extended ACL syntax learning. To make some idea how IOS ACL syntax looks, you can see command hints here.
License
aclcheck is written under the terms of GNU general public license.
Download section
Changelog
Installation process
aclcheck can be installed either by hand from build/ directory after doing make install or by make install from source directory. aclcheck is installed to /usr/local/bin/aclcheck by default. Packages for *BSD and linux would be naturally better, lend a hand and create some if aclcheck has gotten your interest.
Usage
aclcheck FE-0-1-0-ingress.acl
(supposing aclcheck is in search path)
If the file is syntactically correct, aclcheck ends silently with error code 0. For more verbose output, use -v flag, which can be cumulated in order to get more verbose output.
sample extended ACL:
access-list 133 remark HUE-HUE-(lada)==OUT
! access-list 129 permit tcp any eq 80 host 195.113.1.2
access-list 111 deny udp any eq 80 host 12.13.14.15 range 1 4444
! precedence
access-list 123 permit igrp host 5.6.7.8 any precedence immediate
! icmp qualifier
access-list 123 permit icmp any any 3 0
access-list 156 permit icmp any 1.2.3.0 0.0.0.255 packet-too-big
Note: colored output above was created using vim editor with Cisco ACL syntax highlighting.
Notes
When configuring e.g. icmp protocol qualifier, cisco command line interface suggests (via '?') keywords which are breaking original syntax of extended access lists but produce valid results. Results of this behavior can be however unexpected.
e.g. When we enter
access-list 123 permit icmp any any 0 3
it produces the same line in running-config output. However, if we enter
access-list 123 permit icmp any any 0 3 1 2
it produces following line:
access-list 123 permit icmp any any 1 2
Some of the specifiers can be written in arbitrary order.
E.g. following lines are equivalent and in running-config appear "normalized" - as the first line.
access-list 123 permit gre any any precedence routine tos normal
log
access-list 123 permit gre any any tos normal precedence routine log
When specifying icmp message type and code, it is possible to enter bogus numbers.
e.g.
access-list 123 deny icmp host 1.2.3.4 any 3 26
There is no such code 26 for ICMP unreachable message type. aclcheck is more strict in this sense - it does not allow invalid message types and codes.
When network address or network mask is specified incorrectly, it is fixed (maybe only in some IOS versions, e.g. 12.1(22)E1 and 12.3(6a) work) in resulting rule:
c10.ipv6(config)# access-list 133 permit tcp 172.20.0.208 0.0.0.63 host 10.0.0.1 eq 22 c10.ipv6(config)# c10.ipv6(config)#^Z c10.ipv6#sh running-config | incl list 133 access-list 133 permit tcp 172.20.0.192 0.0.0.63 host 10.0.0.1 eq 22 c10.ipv6#
We tried to configure rule for network 172.20.0.208 0.0.0.63
(172.20.0.208/26), which is not possible - the netmask and
network address does not match.
This fixup suggests, that we want something other, in this case
172.20.0.208 0.0.0.15 (172.20.0.208/28).
(208 in binary is 11010000,
this is 24+4 fixed bits)
This kind of behavior can be easily detected by comparing stored version of generated ACL with ACL extracted from router config.
When higher port is specified first in range keyword, in the configuration it appears reversed:
access-list 2311 permit udp host 192.168.1.34 host 172.20.1.52 range 8000 3300becomes
access-list 2311 permit udp host 192.168.1.34 host 172.20.1.52 range 3300 8000TCP flags can be specified in a list, e.g.
access-list 129 permit tcp any any eq 23 syn fin urg ackBut some additional rules apply: