A promiscuous, NFQUEUE-based DHCP, DHCPv6 and Router Advertisement server for virtual machine hosting
nfdhcpd is a userspace daemon written in python and based on
NFQUEUE meant
to process DHCP, IPv6 Neighbor Solicitations (NS), IPv6 Router Solicitations (RS)
and DHCPv6 requests. The daemon should run on the hosts of virtualization environments
in order to directly reply to VMs' requests without these leaving the hosts. An
administrator can enable processing of those requests on individual TAP interfaces
by injecting nfdhcpd in the processing pipeline for IP packets dynamically. This is
done by mangling the relevant packets on those interfaces using iptables and
redirecting them to NFQUEUE target using the appropriate queue number.
nfdhcpd is mainly targeted to be used in a routed setup where the
instances are not on the same broadcast domain with the external router,
but that does not mean it can't be used on bridged setup, even though one
might consider it a bit redundant.
nfdhcpd periodically sends Router Advertisements to all IPv6 enabled
interfaces it monitors to enable addressing through SLAAC. DHCPv6 functionality
is currently limited to supplying Other Configuration data like DNS Recursive
Name Server and Domain Search List as supplementary to Router Advertisements.
The daemon is controlled by manipulating files under its state directory. Creation of a new file under this directory ("binding file") instructs the daemon to reply to the requests arriving on the specified TAP interface. These files are meant to be created by the software managing the instances on the host.
nfdhcpd is meant to work with Ganeti and
gnt-networking. Instances inside the
cluster will obtain their configuration dynamically in a completely transparent
way without being aware of nfdhpcd's existence.
There's one binding file per network interface.
Here's a sample binding file (e.g. /var/lib/nfdhcpd/tap10):
INDEV=tap10
IP=192.0.2.100
MAC=aa:6b:39:22:33:44
HOSTNAME=testing-vm
TAGS=""
GATEWAY=192.0.2.1
SUBNET=192.0.2.0/24
GATEWAY6=2001:db8:aaaa:bbbb::1
SUBNET6=2001:db8:aaaa:bbbb::/64
EUI64=2001:db8:aaaa:bbbb:a86b:39ff:fe22:3344
PRIVATE=
MTU=
MACSPOOF=Here's a sample global configuration file (/etc/nfdhcpd/nfdhcpd.conf):
## nfdhcpd sample configuration file
## General options
[general]
pidfile = /var/run/nfdhcpd/nfdhcpd.pid
datapath = /var/lib/nfdhcpd # Where the client configuration will be read from
logdir = /var/log/nfdhcpd # Where to write our logs
user = nobody # An unprivileged user to run as
## DHCP options
[dhcp]
enable_dhcp = yes
lease_lifetime = 604800 # 1 week
lease_renewal = 3600 # 1 hour
server_ip = 192.0.2.1
server_on_link = no
dhcp_queue = 42 # NFQUEUE number to listen on for DHCP requests
# IPv4 nameservers to include in DHCP responses
nameservers = 192.0.2.2, 192.0.2.3
# Optional domain to serve with the replies
domain = example.com
## IPv6-related functionality
[ipv6]
enable_ipv6 = yes
mode = auto
ra_period = 300 # seconds
rs_queue = 43 # NFQUEUE number to listen on for router solicitations
ns_queue = 44 # NFQUEUE number to listen on for neighbor solicitations
dhcpv6_queue = 45 # NFQUEUE number to listen on for DHCPv6 Information-Requests
# IPv6 nameservers to send using the ICMPv6 RA RDNSS option (RFC 5006)
# since it is not supported by several OS we serve them to DHCPv6 replies
nameservers = 2001:db8:100::1, 2001:db8:200::2
domains = example.comTo send packets to nfdhcpd for processing, one must configure a few packet
filtering rules. To process packets coming from TAP interfaces that are members
of bridges one needs to use the -m physdev option of iptables. There's a
sample ferm ruleset in contrib/ferm directory.
iptables for DHCP:
iptables -A PREROUTING -i tap+ -p udp -m udp --dport 67 -j NFQUEUE --queue-num 42
iptables -A PREROUTING -p udp -m physdev --physdev-in tap+ -m udp --dport 67 -j NFQUEUE --queue-num 42ip6tables for RA,RS and DHCPv6:
ip6tables -A PREROUTING -i tap+ -p ipv6-icmp -m icmp6 --icmpv6-type 133 -j NFQUEUE --queue-num 43
ip6tables -A PREROUTING -i tap+ -p ipv6-icmp -m icmp6 --icmpv6-type 135 -j NFQUEUE --queue-num 44
ip6tables -A PREROUTING -i tap+ -p udp -m udp --dport 547 -j NFQUEUE --queue-num 45We provide Debian packages for Debian 7 (wheezy) & 8 (jessie) in our APT repository. To use them:
echo deb http://apt.dev.grnet.gr $(lsb_release -s -c)/ > /etc/apt/sources.list.d/apt.dev.grnet.gr.list
echo deb-src http://apt.dev.grnet.gr $(lsb_release -s -c)/ >> /etc/apt/sources.list.d/apt.dev.grnet.gr.list
curl https://dev.grnet.gr/files/apt-grnetdev.pub | apt-key add -
apt-get update
apt-get install nfdhcpdWarning: DHCPv6 functionality needs python-scapy>2.3 and one currently
needs to either get a package from Debian stretch or use the patched version found
in apt.dev.grnet.gr
PyPI:
Non PyPI-resolvable:
On a Debian/Ubuntu system you can install them using:
apt-get install python-nfqueue python-cap-ngThis codebase has been created by merging the original nfdhcpd code with snf-nfdhcpd and nfdhcpd by David Halls.