Simple IPAM reporting tool
This is a very simple IPAM (IP Address Management) reporting tool, which looks at DNS, DHCP and Arpwatch data. It produces a report of IP -> DHCP mappings, and includes info from arpwatch on when the MAC was last seen.
Some basic mismatch and parsing errors are reported.
It is mainly a reporting tool for when DNS and DHCP information has diverged over time, and for giving an overall IP/DNS report for a given subnet.
It is assumed that the DHCP entries are fixed-address hosts; i.e. clients pick up addresses via DHCP, but the entries are fixed and not from a pool.
It does not:
- operate a full IPAM system, with a managed database populating DNS and DHCP
- perform any editing or fixing of issues
- DNS entries are either:
- parsed from a file which was generated by dumping BIND-style entries (see examples below)
- OR looked up dynamically using
socket.gethostbyname()
andsocket.gethostbyaddr()
.
- DHCP entries are statically parsed from a
dhcpd.conf
file. - Arpwatch entries are statically parsed from a
arp.dat
file.
It highlights some basic errors which might creep into a non-IPAM-managed setup:
- mismatch between IP -> hostname -> IP mappings (incorrect forward/reverse RRs in DNS)
- malformed MAC address in DHCP
- hostnames in DHCP which don't resolve
- only display IP addresses for which there are no ARP entries (good for looking for old defunct entries)
- only display IP addresses for which the ARP entries are older than a given number (good for looking for old defunct entries)
It can also print a compressed report of unassigned IP addresses in the range.
$ ./ipam_lite.py -h
usage: ipam_lite.py [-h] [-v] [-d] [-e] [-u] [-n] [-N NO_ARP_DAYS] [-r] [-m]
netaddress netmask domain arp_file dhcp_file dns_file
positional arguments:
netaddress IPv4 network address
netmask IPv4 network mask, in CIDR 'slash' notation
domain default DNS domain name for hosts
arp_file the arp.dat file from arpwatch (typically
/var/lib/arpwatch/arp.dat)
dhcp_file the dhcpd.conf file (typically /etc/dhcpd/dhcpd.conf)
dns_file the dumped DNS entries (for example dumped from
'named-compilezone -f raw -F text'), forward and
reverse zones in a single file
optional arguments:
-h, --help show this help message and exit
-v, --verbose increase output verbosity
-d, --dhcp_hostnames check for hostnames in DHCP which don't resolve
-e, --errors display parsing and resolution errors
-u, --unassigned only display lists of unassigned/free IP addresses
-n, --no_arp only display list of IP addresses with no ARP entries
-N NO_ARP_DAYS, --no_arp_days NO_ARP_DAYS
only display list of IP addresses with no ARP entries
in the last N days
-r, --resolve look up hostnames on the fly, intead of reading
entries from a dumped file; ignore 'dns_file' in this
case
-m, --mismatches report any DNS forward/reverse mismatches and return
an error if any are found
$ ./ipam_lite.py 10.20.112.0 22 my.dns.domain arp/arp.dat dhcp/dhcpd.conf dns/db.ALL.txt
IPAM-Lite Report for 10.20.112.0/22
IP | Host | Host->IP | MAC (DHCP) | MAC (ARP) | Last seen (ARP)
---------------- | ------------------------ | -------- | ------------------ | ------------------ | ---------------------
10.20.112.1 | router01 | OK | - | 55:55:55:55:55:38 | 2016-08-18 [42 days]
10.20.112.2 | server01 | OK | 55:55:55:55:55:5f | 55:55:55:55:55:37 | 2016-08-18 [42 days]
10.20.112.3 | server02 | OK | [ SAME AS ARP ] | 55:55:55:55:55:38 | 2016-08-18 [42 days]
10.20.112.4 | server03 | OK | - | - | -
10.20.112.5 | server04 | OK | - | - | -
10.20.112.6 | server05 | OK | [ SAME AS ARP ] | 55:55:55:55:55:bf | 2016-08-18 [42 days]
10.20.112.7 | server06 | OK | [ SAME AS ARP ] | 55:55:55:55:55:2f | 2016-08-18 [42 days]
10.20.112.8 | server07 | OK | - | 55:55:55:55:55:cc | 2016-08-18 [42 days]
10.20.112.9 | server08 | OK | - | 55:55:55:55:55:90 | 2016-08-18 [42 days]
10.20.112.10 | server09 | OK | [ SAME AS ARP ] | 55:55:55:55:55:3a | 2016-08-18 [42 days]
10.20.112.11 | - | - | - | - | -
10.20.112.12 | node001 | OK | [ SAME AS ARP ] | 55:55:55:55:55:90 | 2016-08-18 [42 days]
10.20.112.13 | node002 | OK | [ SAME AS ARP ] | 55:55:55:55:55:cc | 2016-08-18 [42 days]
10.20.112.14 | node003 | OK | 55:55:55:55:55:5c | - | -
10.20.112.15 | node004 | OK | - | 55:55:55:55:55:f2 | 2016-08-18 [42 days]
10.20.112.16 | node005 | OK | 55:55:55:55:55:3c | - | -
10.20.112.17 | node006 | OK | - | - | -
10.20.112.18 | node007 | OK | [ SAME AS ARP ] | 55:55:55:55:55:08 | 2016-08-18 [42 days]
10.20.112.19 | node008 | OK | - | 55:55:55:55:55:b1 | 2016-08-18 [42 days]
10.20.112.20 | node009 | OK | [ SAME AS ARP ] | 55:55:55:55:55:9d | 2016-03-06 [207 days]
....
Total addresses in the range: 1022
Total addresses with hostnames: 272
Total without ARP entries: 139
Report of unassigned IP addresses (no hostnames):
$ ./ipam_lite.py 10.20.112.0 22 my.dns.domain arp/arp.dat dhcp/dhcpd.conf dns/db.ALL.txt -u
Unassigned addresses:
1: 10.20.112.11
1: 10.20.112.26
1: 10.20.112.29
1: 10.20.112.31
1: 10.20.112.41
4: 10.20.112.57 => 10.20.112.60
1: 10.20.112.64
5: 10.20.112.67 => 10.20.112.71
8: 10.20.112.73 => 10.20.112.80
9: 10.20.112.87 => 10.20.112.95
9: 10.20.112.104 => 10.20.112.112
15: 10.20.112.115 => 10.20.112.129
1: 10.20.112.198
7: 10.20.112.218 => 10.20.112.224
1: 10.20.112.227
4: 10.20.112.231 => 10.20.112.234
11: 10.20.112.246 => 10.20.113.0
1: 10.20.113.105
1: 10.20.113.171
3: 10.20.113.255 => 10.20.114.1
9: 10.20.114.55 => 10.20.114.63
9: 10.20.114.69 => 10.20.114.77
1: 10.20.114.90
11: 10.20.114.92 => 10.20.114.102
1: 10.20.114.107
7: 10.20.114.123 => 10.20.114.129
29: 10.20.114.131 => 10.20.114.159
2: 10.20.114.162 => 10.20.114.163
3: 10.20.114.168 => 10.20.114.170
28: 10.20.114.173 => 10.20.114.200
3: 10.20.114.203 => 10.20.114.205
11: 10.20.114.220 => 10.20.114.230
25: 10.20.114.232 => 10.20.115.0
1: 10.20.115.26
3: 10.20.115.32 => 10.20.115.34
8: 10.20.115.64 => 10.20.115.71
6: 10.20.115.205 => 10.20.115.210
8: 10.20.115.212 => 10.20.115.219
Total unassigned: 250 / 1022
Report of DNS forward/reverse mismatches:
$ ./ipam_lite.py 10.20.112.0 22 my.dns.domain arp/arp.dat dhcp/dhcpd.conf dns/db.ALL.txt -m
DNS Mismatch Report
IP | Host | Host->IP
---------------- | ------------------------ | --------
10.20.112.9 | host009.foo.com | 10.20.112.222
If using the dns_file
parameter (and not the -r
flag), the entries in the
file should be of the form:
machine1.foo.com. 1800 IN A 10.20.112.113
113.112.20.10.in-addr.arpa. 1800 IN PTR machine1.foo.com.
That is, it should be a single file containing a dump of forward zones
(foo.com.
) and reverse zones (112.20.10.in-addr.arpa.
).
Only PTR
and A
records are parsed; other RR types are ignored.
If using BIND, the files can be dumped from a server which stores zones in the raw binary format using something like:
named-compilezone -f raw -F text -o /tmp/db.112.20.10.txt 112.20.10.in-addr.arpa db.112.20.10
named-compilezone -f raw -F text -o /tmp/db.foo.com.txt foo.com db.foo.com
cat /tmp/db.112.20.10.txt /tmp/db.foo.com.txt > /tmp/db.ALL.txt
Similarly, if using BIND and storing zones in the text format:
named-compilezone -f text -F text -o /tmp/db.112.20.10.txt 112.20.10.in-addr.arpa db.112.20.10
named-compilezone -f text -F text -o /tmp/db.foo.com.txt foo.com db.foo.com
cat /tmp/db.112.20.10.txt /tmp/db.foo.com.txt > /tmp/db.ALL.txt
- highlight mismatch between MAC address in DHCP and last reported MAC in Arpwatch
- make the Arpwatch parts of the report optional
- IPv6 support