Statistics
| Branch: | Tag: | Revision:

root / docs / index.rst @ ab4ee460

History | View | Annotate | Download (7.5 kB)

1
.. nfdhcpd documentation master file, created by
2
   sphinx-quickstart on Mon Jan 20 18:25:17 2014.
3
   You can adapt this file completely to your liking, but it should at least
4
   contain the root `toctree` directive.
5

    
6
Welcome to nfdhcpd's documentation!
7
===================================
8

    
9
nfdhcpd is a userspace server written in python and based on NFQUEUE [1].  The
10
administrator can enable processing of DHCP, NS, RS, DHCPv6 requests on
11
individual TAP interfaces by injecting nfdhcpd in the processing pipeline for
12
IP packets dynamically (by mangling the corresponding packet types and redirect
13
them to the appropriate nfqueue).
14

    
15
The daemon runs on the host and is controlled by manipulating files under its
16
state directory. Creation of a new file under this directory ("binding file")
17
instructs the daemon to reply on the requests arriving on the specified TAP
18
interface.
19

    
20
nfdhcpd vs. dnsmasq
21
-------------------
22

    
23
a) The service can be activated dynamically, per-interface, by manipulating
24
iptables accordingly. There is no need to restart the daemon, or edit
25
(potentially read-only) configuration files, you only need to drop a file
26
containing the required info under /var/lib/nfdhcpd.
27

    
28
b) There is no interference to existing DHCP servers listening to port
29
67. Everything happens directly via NFQUEUE.
30

    
31
c) The host doesn't even need to have an IP address on the interfaces
32
where DHCP replies are served, making it invisible to the VMs. This
33
may be beneficial from a security perspective. Similarly, it doesn't
34
matter if the TAP interface is bridged or routed.
35

    
36
d) Binding files provide a TAP-MAC mapping. In other words, requests coming
37
from unregistered TAP interfaces (without a binding file) are ignored, and
38
packet processing happens as if nfdhcpd didn't exist in the first place.
39
Requests coming from a registered device with but with different are considered
40
as snooping attempts and are dropped.
41

    
42
e) nfdhcpd is written in pure Python and uses scapy for packet
43
processing. This has proved super-useful when trying to troubleshooting
44
networking problems in production.
45

    
46
A simple scenario
47
-----------------
48

    
49
a) nfdhcpd starts. Upon initialization, it creates an NFQUEUE (e.g., 42,
50
configurable), and listens on it for incoming DHCP requests. It also begins to
51
watch its state directory, `/var/lib/nfdhcpd` via inotify().
52

    
53
b) A new VM gets created, let's assume its NIC has address mac0, lives on TAP
54
interface tap0, and is to receive IP address ip0 via DHCP.
55

    
56
c) Someone (e.g., a Ganeti KVM ifup script, or in our case snf-network [2]
57
creates a new binding file informing nfdhcpd that it is to reply to DHCP
58
requests from MAC mac0 on TAP interface tap0, and include IP ip0 in the DHCP
59
reply.
60

    
61
d) The ifup script or the administrator injects nfdhcpd in the processing
62
pipeline for packets coming from tap0, using iptables:
63

    
64
.. code-block:: console
65

    
66
  # iptables -t mangle -A PREROUTING -i tap0 -m udp -p udp --dport 67 -j NFQUEUE --queue-num 42
67

    
68
e) From now on, whenever a DHCP request is sent out by the VM, the
69
iptables rule will forward the packet to nfdhcpd, which will consult
70
its bindings database, find the entry for tap0, verify the source MAC,
71
and inject a DHCP reply for the corresponding IP address into tap0.
72

    
73
Binding file
74
------------
75

    
76
A binding file in nfdhcpd's state directory is named after the
77
physical interface where the daemon is to receive incoming DHCP requests
78
from, and defines at least the following variables:
79

    
80
* ``INSTANCE``: The instance name related to this inteface
81

    
82
* ``INDEV``: The logical interface where the packet is received on. For
83
  bridged setups, the bridge interface, e.g., br0. Otherwise, same as
84
  the file name.
85

    
86
* ``MAC``: The MAC address where the DHCP request must be originating from
87

    
88
* ``IP``: The IPv4 address to be returned in DHCP replies
89

    
90
* ``SUBNET``: The IPv4 subnet to be returned in DHCP replies in CIDR form
91

    
92
* ``GATEWAY``: The IPv4 gateway to be returned in DHCP replies
93

    
94
* ``SUBNET6``: The IPv6 network prefix
95

    
96
* ``GATEWAY6``: The IPv6 network gateway
97

    
98
* ``EUI64``: The IPv6 address of the instance
99

    
100

    
101
nfdhcpd.conf
102
------------
103

    
104
The configuration file for nfdhcp is `/etc/nfdhpcd/nfdhcpd.conf`. Three
105
sections are defined: general, dhcp, ipv6.
106

    
107
Note that nfdhcpd can run as nobody. This and other options related to
108
its execution environment are defined in general section.
109

    
110
In the dhcp section we define the options related to DHCP responses.
111
Specifically:
112

    
113
* ``enable_dhcp`` to globally enable/disable DHCP
114

    
115
* ``server_ip`` a dummy IP that the VMs will as src IP of the response
116

    
117
* ``dhcp_queue`` the a NFQUEUE number to listen on for DHCP requests
118

    
119
| Please not that this queue *must* be used in iptables mangle rule.
120

    
121
* ``nameservers`` IPv4 nameservers to include in DHCP responses
122

    
123
* ``domain`` the domain to serve with the replies (optional)
124

    
125
| If not given the instance's name (hostname) will be used instead.
126

    
127
In the ipv6 section we define the options related to IPv6 responses.  Currently
128
nfdhcpd supports IPv6 stateless configuration [3]. The instance will get an
129
auto-generated IPv6 (MAC to eui64) based on the IPv6 prefix exported by Router
130
Advertisements (O flag set, M flag unset). This kind of RA will make instance
131
query for nameservers and domain search list via DHCPv6 request.
132
nfdhcpd, currently and in case of IPv6, is supposed to work on a routed setup
133
where the instances are not on the same collision domain with the external
134
router and thus any RA/NA should be served locally. Specifically:
135

    
136
* ``enable_ipv6`` to globally enable/disable IPv6 responses
137

    
138
* ``ra_period`` to define how often nfdhcpd will send RAs to TAPs with IPv6
139

    
140
* ``rs_queue`` the NFQUEUE number to listen on for router solicitations
141

    
142
* ``ns_queue`` the NFQUEUE number to listen on for neighbor solicitations
143

    
144
* ``dhcp_queue`` the NFQUEUE number to listen on for DHCPv6 request
145

    
146
* ``nmeservers`` the IPv6 nameservers
147

    
148
| They can be send using the RDNSS option of the RA [4].
149
| Since it is not supported by Windows we serve them via DHCPv6 responses
150

    
151
* ``domains`` the domain search list
152

    
153
| If not given the instance's name (hostname) will be used instead.
154

    
155
iptables
156
--------
157

    
158
In order nfdhcpd to be able to process incoming requests you have to mangle
159
the corresponding packages. Please note that in case of bridged setup the
160
kernel understands that the packets are coming from the bridge (logical indev)
161
and not from the tap (physical indev). Specifically:
162

    
163
* **DHCP**: ``iptables -t mangle -A PREROUTING -i tap+ -p udp --dport 67 -j NFQUEUE --queue-num 42``
164

    
165
* **RS**: ``ip6tables -t mangle -A PREROUTING -i tap+ -p icmpv6 --icmpv6-type router-solicitation -j NFQUEUE --queue-num 43``
166

    
167
* **NS**: ``ip6tables -t mangle -A PREROUTING -i tap+ -p icmpv6 --icmpv6-type neighbour-solicitation -j NFQUEUE --queue-num 44``
168

    
169
* **DHCPv6**: ``ip6tables -t mangle -A PREROUTING -i tap+ -p udp --dport 547 -j NFQUEUE --queue-num 45``
170

    
171
For a bridged setup replace tap+ with br+ in case of DHCP. Using nfdhcpd
172
for IPv6 in a bridged setup does not make any sense. The above rules are
173
included in `/etc/ferm/nfdhcpd.ferm` .
174
In case you use ferm, this file should be included in `/etc/ferm/ferm.conf`.
175
Otherwise an `rc.local` script can be used to issue those rules upon boot.
176

    
177

    
178
debug
179
-----
180

    
181
A useful way to see the clients registered in nfdhpcd runtime context one can
182
send SIGUSR1 and see the list in the logfile:
183

    
184
.. code-block:: console
185

    
186
 # kill -SIGUSR1 $(cat /var/run/nfdhcpd/nfdhpcd.pid) && tail -n 100 /var/log/nfdhcpd/nfdhpcd.log
187

    
188

    
189
| [1] https://www.wzdftpd.net/redmine/projects/nfqueue-bindings/wiki/
190
| [2] https://code.grnet.gr/projects/snf-network/
191
| [3] https://tools.ietf.org/html/rfc4862
192
| [4] https://tools.ietf.org/html/rfc5006