SLAACer - Accountability with IPv6
SLAACer primary objective is to place a second option on the table for network sysadmin's when they deploy IPv6 in their organisation. So far the mass consenus generally has bee that you must roll out DHCPv6 if you want to be able to map your IPv6 addresses back to MAC addresses; and do not wish to poll via SNMP/CLI all your routers.
SLAACer embraces that in the IPv6 world, unlike the IPv4 world, multiple IP assignment to a node should be encouraged if not actually be considered the norm:
EUI-64 - subnet + MAC address
- static - manual assignment
Mobile IPv6 - non-local
link-local - fe80::/64
Much like NAT, I have the opinion that DHCP has become one of those 'latent' efforts that sysadmins have become use to deploying in the IPv4 world when in actual fact they do require some degree of effort (especially to make highly available) which can be completely engineered away in the IPv6 world. Some might argue that DHCP can also be used to give TFTP, NTP, LDAP, etc servers in their payload, I personally feel that using DNS SRV records and multicast SLP are far more appropriate methods.
Either way and whatever your view, SLAACer now permits network sysadmin's to choose to use either DHCPv6 or SLAAC depending on their needs. A situation with options should always be considered preferable over a sitation where you are forced to embrace one method/vendor.
N.B. SLAACer is not the solution but should tie us all over until something better comes along (lets hope vendors give us something like SNMP traps for changes to the IPv6 to MAC mapping events).
Overview
In it's ugliest form, SLAACer requires that you port-mirror every workstation edge switch port in your network into it. This is actually not as bad as it sounds as to stop things getting out of control you can use filters on the port-mirror'ing to capture only the traffic SLAACer is interested in (ICMPv6 NS/NA traffic), ingress only traffic and a number of other tricks discussed later.
All this traffic is sent to a dedicated Ethernet interface that the 'slaacer' daemon listens on (using libpcap). 'slaacer' digests the traffic and sends out syslog messages depending on what it sees. A syslog server collects these messages (additionally you can process the syslog traffic from your IPv4 ISC DHCP server too) to write to a text file as well as parsing the contents and creating an SQL query calling an function that records the information in an easy to use format.
Requirements
perl 5.10 with Net::Pcap install
- one of the follow syslog daemon's
- an SQL server
a network infrastructure that supports remote port-mirroring (Cisco call this 'RSPAN')
Usage
Once deployed and you have all your data trickling into your SQL server, data is recorded as the column 'start' indicating when the IP address (either IPv4 or IPv6) was first seen and 'last' when it was last recorded1.
You can now start to make queries such as "what addresses has the MAC address 00-17-42-87-ce-f7 used since the beginning of March 2011?":
user@host:~$ echo "SELECT * FROM mac2addr WHERE mac = '00-17-42-87-ce-f7' AND last > '2011-03-01' ORDER BY last DESC" | psql --host=%SQL-SERVER% %DATABASE% %USERNAME% Password for user %USERNAME%: id | mac | addr | start | last -------+-------------------+--------------------------------------+------------------------+------------------------ 6609 | 00-17-42-87-ce-f7 | fe80::217:42ff:fe87:cef7 | 2011-02-23 10:06:23+00 | 2011-04-08 14:55:33+01 31403 | 00-17-42-87-ce-f7 | 2001:630:1b:8000:c4b:c8fa:d360:5b3 | 2011-04-07 08:32:43+01 | 2011-04-08 14:44:06+01 10185 | 00-17-42-87-ce-f7 | 10.150.72.38 | 2011-03-07 08:23:02+00 | 2011-04-08 07:41:30+01 30027 | 00-17-42-87-ce-f7 | 2001:630:1b:8000:c161:3cde:da18:9caa | 2011-04-04 08:28:22+01 | 2011-04-06 15:58:03+01 29489 | 00-17-42-87-ce-f7 | 2001:630:1b:8000:51bc:41fe:62de:99da | 2011-04-01 08:23:21+01 | 2011-04-01 20:11:08+01 (5 rows)
The most useful request is, in the case of abuse reports, to ask "who was using the IP address 2001:630:1b:8000:c4b:c8fa:d360:5b3 at 2011-04-07 22:00?":
user@host:~$ echo "SELECT * FROM mac2addr WHERE addr = '2001:630:1b:8000:c4b:c8fa:d360:5b3' AND start <= '2011-04-07 22:00' AND last >= '2011-04-07 22:00'" | psql --host=%SQL-SERVER% %DATABASE% %USERNAME% Password for user ac56: id | mac | addr | start | last -------+-------------------+------------------------------------+------------------------+------------------------ 31403 | 00-17-42-87-ce-f7 | 2001:630:1b:8000:c4b:c8fa:d360:5b3 | 2011-04-07 08:32:43+01 | 2011-04-08 14:44:06+01 (1 row)
All the IPv6 information 2 is obtained from the syslog messages that are generated by 'slaacer':
Apr 11 08:25:26: 00-17-42-87-ce-f7 2001:630:1b:8000:7c1a:d241:3902:b982 [SOLICIT,dad] Apr 11 08:25:27: 00-17-42-87-ce-f7 2001:630:1b:8000:217:42ff:fe87:cef7 [SOLICIT,dad] Apr 11 08:26:12: 00-17-42-87-ce-f7 2001:630:1b:8000:7c1a:d241:3902:b982 [ADVERT,solicited,override] Apr 11 08:56:10: 00-17-42-87-ce-f7 fe80::217:42ff:fe87:cef7 [ADVERT,solicited] Apr 11 08:56:11: 00-17-42-87-ce-f7 2001:630:1b:8000:7c1a:d241:3902:b982 [ADVERT,solicited] Apr 11 08:57:10: 00-17-42-87-ce-f7 fe80::217:42ff:fe87:cef7 [ADVERT,solicited]
SLAACer
'slaacer' supports a number of parameters when being called (in addition to '--help, -h' and '--man'):
--interface, -i: listen for IPv6 ICMP packets on a particular interface (required)
--debug, -d: enable verbose debugging
--nofork, -n: do not fork into background
--record=path, -R path: path to place recordings in (default: /tmp)
--playback=filename, -P filename: playback a former recording and exit (implies 'nofork' but does no syslog'ing)
Whilst running, 'slaacer' supports receiving and acting on the following signals (ie. 'pkill -USR1 -x slaacer'):
SIGTERM/SIGINT: cleanly shutdown
SIGUSR1: write out traffic being received by the daemon to a PCAP compatible file ('/path/specified/for/record/slaacer.%Y-%m-%dT%TZ') and when signaled when already recording, stop recording and close the file
Download
The git tree for hopefully everything you need can be found at:
git://git.wormnet.eu/alex/slaacer.git - web browsable at http://git.wormnet.eu/?p=alex/slaacer.git
For those unfamiliar with git, if you have installed it, all you need to type is:
user@host:~$ git clone git://git.wormnet.eu/alex/slaacer.git user@host:~$ cd slaacer user@host:~/slaacer$ ls -l total 16 -rwxr-xr-x 1 user group 12882 Apr 10 15:09 slaacer drwxr-xr-x 2 user group 18 Apr 10 15:09 sql drwxr-xr-x 2 user group 22 Apr 10 15:09 syslog user@host:~/slaacer$
Installation
There are four componments that need to be configured:
- SQL server
- central syslog server
- port mirroring
- the SLAACer daemon
Throughout, we will assume that:
your central syslog server you administrate lives at '1.2.3.4'
the SQL server is at 'sql.example.com'
N.B. make sure you are careful to replace all the placeholders ('%...%')
SQL
This should be just a simple case of just replacing the place holders '%DATABASE%', '%USERNAME%' and '%PASSWORD%' in the included 'sql' directory for your particular SQL server and loading it in.
PostgreSQL
sql:~# cat <<'EOF' >> /etc/postgresql/8.3/main/pg_hba.conf host %DATABASE% mac2addr 1.2.3.4/32 md5 EOF sql:~# /etc/init.d/postgresql-8.3 reload sql:~# su - postgres postgres@sql:~$ psql -f /path/to/slaacer/sql/pqsql %DATABASE%
syslog
Like for the SQL case, it should be just a simple case of replacing the place holders '%SQL-SERVER%', '%DATABASE%', '%USERNAME%' and '%PASSWORD%' in the included
syslog-ng
Make sure you have the 'psql' (Debian package 'postgresql-client') tool installed and that you insert the 'syslog/syslog-ng' file into your syslog-ng configuration (additionally you might wish to add 'syslog/syslog-ng.ipv4-dhcp-hook' to record you IPv4 allocations too).
syslog:~# cat <<'EOF' >> /etc/syslog-ng/pgpass sql.example.com:5432:%DATABASE%:mac2addr:%PASSWORD% EOF syslog:~# chown root:root /etc/syslog-ng/pgpass syslog:~# chmod 600 /etc/syslog-ng/pgpass syslog:~# /etc/init.d/syslog-ng reload
Port Mirror
This section is more than likely the most difficult part and so to try and help out I have broken it up into two chunks. The "quick'n'dirty" approach that gets you going without any thought about the quantity of traffic flooding your LAN but should just work, the second part lists constraints and approaches to make you feel less dirty in regards to the deployment.
N.B. as a helpful aid to track bandwidth usage on your LAN, I strongly recommend Torrus. It is trivial to set up and it gives you RRD graphs for every switchport on your network.
Cisco
You need to create a single global VLAN than spans your entire LAN (in our example we shall use VLAN ID '300'). The VLAN should be trunked up to every switch stack and you will need to type the following on either your VTP master, or each of your switch stacks:
vlan 300 name v6span-nd remote-span
At all your L3 router source(s)3, assuming all your IPv6 traffic comes off VLAN 33, we want to only capture ingress (received) traffic:
monitor session 8 source vlan 33 rx monitor session 8 destination remote vlan 300
N.B. if you are fortunate enough to have 3750X/3560X's at your access layer, then you can use FRSPAN (Filter RSPAN) to capture just then neighbour discovery traffic. If you be a simple case of just adding 'monitor session 8 filter ipv6 ...' and the necessary access list.
On the switch that the SLAACer server connects to (assuming it's monitoring port, 'eth1' is on 'Gi1/0/1'), type:
monitor session 8 source remote vlan 300 monitor session 8 destination interface Gi1/0/1
Improving
Remote SPAN'ing functions by creating a VLAN that has MAC learning disabled, this unfortunately means that every packet is turned into a broadcast packet, this becomes a nasty problem as the number of edge switch stacks increase. You can control the problem by creating a unique RSPAN VLAN for each edge switchstack which would effectively uni-directionalise the traffic.
The most powerful feature you need to look into is VACL's which enable you to apply filters to the RSPAN VLAN to control what traffic is actually passed around. There are a number of unfortunate appliable constraints when dealing with VACL's and IPv6 traffic:
- C3750 will not VACL RSPAN sources
C3750/C6500 will not VACL with IPv6 ACLs
- C3750 will not VACL IPv6 Ethernet frames with MAC ACLs
- C6500 with even a single DFC3A will not VACL Ethernet frames with MAC ACLs (no 'mac classify-packet' command)
IOS versions pre-12.2(55) on a C3750 are affected by CSCtd72626 where an RSPAN does not include multicast IPv6 traffic (MAC address destination 33:33:ww:xx:yy:zz) that prevents catching NS-DAD packets
My organisation's network is made up of C3750's at the edge (configured in L3 'at the edge') feeding back to two C6500's (with DFC3A modules) using port-channels. The SLAACer daemon sits on a Linux box hanging off a C3750E that pipes back to the C6500 core. With this topology some of those contraints are a royal pain...fortunately at peak most of those port-channels peak at around 5% utilisation.
So far, what I am currently using is the following (the C6500 will prune all IPv4 traffic whilst the C3750E prunes off the ARP traffic):
6500#show ip access-lists slaacer-v4
Extended IP access list slaacer-v4
10 permit ip any any
6500#show vlan access-map slaacer
Vlan access-map "slaacer" 10
match: ip address slaacer-v4
action: drop
6500#show vlan filter
VLAN Map slaacer:
Configured on VLANs: 300
Active on VLANs: 3003750E#show access-lists slaacer
Extended MAC access list slaacer
permit any any lsap 0xAAAA 0x0
permit any any lsap 0x4242 0x0
3750E#show vlan access-map slaacer
Vlan access-map "slaacer" 10
Match clauses:
mac address: slaacer
Action:
forward
Vlan access-map "slaacer" 20
Match clauses:
Action:
drop
3750E#show vlan filter
VLAN Map slaacer is filtering VLANs:
300
SLAACer
'slaacer' is placed on the system that is the destination for all the port mirror'ed traffic you are collecting (lets assume the interface is 'eth1'). We first need to configure the system to send the 'slaacer' generated syslog traffic to your central syslog server. We do this, assuming you run 'rsyslog' on the system, by adding the following to send the traffic over TCP (if you want UDP, replace '@@' with '@'):
root@slaacer:~# cat <<'EOF' > /etc/rsyslog.d/local-slaacer.conf if $programname == 'slaacer' then @@1.2.3.4 & ~ EOF root@slaacer:~# /etc/init.d/rsyslog reload
For now, initially call 'slaacer' in a screen session:
# slaacer -i eth1 -n
'slaacer' will now parse traffic coming in over 'eth1' and print to stderr (as well as syslog) a message describing the traffic it sees. The syslog messages will be processed by your central syslog server and the SQL table 'mac2addr' will be updated with this live information.
Future Development
Do contact me if you want to contribute patches, send feedback or just generally have a chat about SLAACer. Currently on the roadmap are the following changes that I can think of:
- improve Perl POD documentation for the daemon
- improvements to filtering port-mirroring to mirror only the traffic we are interested in (including developments into SPF loopback approaches)
configuration examples for other syslog servers such as rsyslog
- record and process ICMPv6 RA packets to track down mis-configured hosts
Links
SLAACers - IPv6 Accountability without DHCPv6 (Networkshop 39) - presentation
warning: especially in the case of DHCP leases, 'last' and when the host was last using that address is only accurate to the last timestamp a DHCP renew request, or IPv6 NA packet, was sent (1)
the IPv4 DHCP entries come from the regular ISC DHCP syslog messages (2)
If you have your IP addresses assigned at your core routers ('L2 to the edge'), then you RSPAN source on those core routers. If you have your IP addressing at your access layer ('L3 to the edge') then you need to RSPAN source from there, yes 48 ports per switch is what we have to do, but it works (3)