- is it correct that dhclient uses some lower level API that is not processed by iptables?
Short version: yes, for some DHCP servers (isc-dhcp and early versions of dnsmasq), no for some other servers (later versions of dnsmasq).
Longer version: the origin of the matter is a raw socket
. A raw socket is, according to Wikipedia,
... an internet socket that allows direct sending and receiving of Internet Protocol packets without any protocol-specific transport layer formatting.
This ISC Wiki page (the Internet Systems Consortium is the author of the most common DHCP program) states that:
The DHCP protocol has some specific requirements to really work properly - in particular being able to transmit to and receive packets sent to the all-ones limited broadcast address (255.255.255.255), and being able to send a unicast without an ARP. It's not possible to do this via BSD/UDP sockets although dhcpd does also open a BSD/UDP socket (called the "fallback interface") that you will see in netstat.
This is interesting, because it explains why you will often find, by Googling, people trying to control DHCP requests in iptables
via the UDP ports 67 and 68. Of course, it is not that these ports are not opened, it is only that this is not the only channel thru which communication between server and client takes place.
This however cannot be fully successful: some guys have gone to the extreme of shutting out their machine completely (iptables drops everything!), yet they were unable to close themselves off to DHCP via raw packets).
Another interesting experiment is to use, once again iptables
to shut off one's pc, and then to use a raw socket for DNS, or for TCP connection: despite iptables, these communication attempts succeed.
A very authoritative comment on this can be found on the Netfilter site, where it is stated:
Raw sockets bypass the TCP/IP stack. Netfilter hooks, and
consequently iptables, sit inside the IP stack.
And the same applies to packet sniffer.
Here they also explain how to circumvent the problem: careful, it's a joke, Schaaf states
That's not a weekend project.
Lastly, I would also like to point out that the situation is different for dnsmasq: in a Debian Wiki page, dnsmasq's author Simon Kelly states:
Dnsmasq opens a raw socket but it never reads data from
the socket: instead it's used to talk to DHCP clients which are not yet
fully configured and cannot do ARP. This is not a security problem.
Later versions of dnsmasq use a different technique, and no longer have
a raw socket open.
Edit:
are there any way to reduce amount of logs from dhclient for unanswered unicast requests?
This is not trivial, because the CLI option to reduce the output from dhclient
, -q, can be invoked from the CLI, but not from dhclient.conf. Also, dhclient
is called directly not by your Network Manager in general, but by an executable, ifup
: in fact,
# strings `(which ifup)` | grep dhclient
/sbin/dhclient
/sbin/dhclient3
dhclient -v -r -pf /run/dhclient.%iface%.pid -lf /var/lib/dhcp/dhclient.%iface%.leases %iface%
dhclient3 -r -pf /run/dhclient.%iface%.pid -lf /var/lib/dhcp3/dhclient.%iface%.leases %iface%
dhclient -1 -v -pf /run/dhclient.%iface%.pid -lf /var/lib/dhcp/dhclient.%iface%.leases %iface% [[-e IF_METRIC=%metric%]]
dhclient3 -pf /run/dhclient.%iface%.pid -lf /var/lib/dhcp3/dhclient.%iface%.leases %iface% [[-e IF_METRIC=%metric%]]
dhclient -6 -r -pf /run/dhclient6.%iface%.pid -lf /var/lib/dhcp/dhclient6.%iface%.leases %iface%
dhclient -1 -6 -pf /run/dhclient6.%iface%.pid -lf /var/lib/dhcp/dhclient6.%iface%.leases %iface%
dhclient -1 -6 -S -pf /run/dhclient6.%iface%.pid -lf /var/lib/dhcp/dhclient6.%iface%.leases %iface%
As you can see, ifup
invokes dhclient
with the -v
(= verbose!) option, the opposite of what you wish.
What are your options?.
Download the source code, modify the invocation above, and recompile it for your kernel. It should be a cinch.
You can use a binary editor to convert the -v
into -q
.
You can modify a script file, /etc/init.d/networking
, by replacing the invocation of ifup
with
ifup .... > /dev/null 2>&1
A reboot, or a restart of the networking
service, will complete this modification. This is less than ideal because it throws into the garbage both useless warnings and serious error messages.
Lastly, you can carry out the following hack: move /sbin/dhclient
to /sbin/dhclient-true
, then create an executable file called /sbin/dhclient
with the following content:
#!/bin/bash
ARGS=$(echo "$@" | sed 's/ -v / /g')
exec /sbin/dhclient-true "-q" "$ARGS"