|
3 years ago | |
---|---|---|
bin | 3 years ago | |
etc | 3 years ago | |
src | 3 years ago | |
Makefile | 3 years ago | |
README.md | 3 years ago |
DHCP Protect is a userspace application that filters DHCPv4 and DHCPv6 floods to protect a DHCP server. It uses the Netfilter userspace packet queuing API.
DHCP Protect receives every packet that enters the iptables NFQUEUE. It will count the number of queries sent by a client and if max_pkt_per_interval
is reached within interval
time, it will blacklist the client. While a client is blacklisted, the accounting continues, this means that when the blacklist_time
is over and if the client continued to flood the DHCP server, the client will NOT be unblacklisted. The blacklist expiration time will be pushed forward as long as the client continues to flood.
In DHCPv4 DHCP Protect will primarly look for option 82, suboption 2 (remoteID). If this is not available it will use the hardware address field.
In DHCPv6 DHCP Protect will account based on the client DUID.
sudo apt-get install git build-essential uthash-dev libnetfilter-queue-dev
git clone https://git.home.spale.com/public/dhcp_protect.git
cd dhcp_protect
make all
sudo make install
Note: the make install
will automatically create, enable and start the systemd service and the make uninstall
will stop and remove the systemd service.
iptables and ip6tables must be configured to send the DHCPv4 and/or DHCPv6 packets to DHCP Protect for forwarding decision.
Both DHCPv4 and DHCPv6 can be processed by the same instance of DHCP Protect. However, they must use the same --queue-num
as in the dhcp_protect.conf
configuration file.
The --queue-bypass
will tell iptables to continue to forward packets if DHCP Protect is not running or crashed. It is strongly recommended to keep this option.
iptables -A INPUT -p udp -m udp --dport 67 -j NFQUEUE --queue-num 67 --queue-bypass
iptables -A OUTPUT -p udp -m udp --sport 67 -j NFQUEUE --queue-num 67 --queue-bypass
(optional for accounting)
ip6tables -A INPUT -p udp -m udp --dport 547 -j NFQUEUE --queue-num 67 --queue-bypass
ip6tables -A OUTPUT -p udp -m udp --sport 547 -j NFQUEUE --queue-num 67 --queue-bypass
(optional for accounting)
The configuration file may be tuned, but the defaults should be fine.
# max_pkt_per_interval
# maximum number of packets authorised per time interval.
max_pkt_per_interval=30
# interval
# measurement time interval in seconds.
interval=30
# debug
# enable debugging, warning, very verbose
debug=0
# blacklist_time
# number of seconds this client will be ignored once
# it exceeded the max_pkt_per_interval per interval
blacklist_time=55
# queue number
# refers to the queue-num of iptables.
# -A FORWARD -p udp -m udp --dport 67 -j NFQUEUE --queue-num 67 --queue-bypass
queue=67
# dryrun
# if dryrun is set to 1 it will accept all packets no matter what.
# this can be used for testing, syslog will still display the blacklisting
# actions.
# Set to 0 for production.
dryrun=0
# stats file and interval (seconds)
# the stats file will be overwritten every n seconds
# as defined below. The counters are absolute AND
# relative (both included).
stats_file=/var/run/dhcp_protect_status.json
stats_interval=10
root@hostname:~/# systemd <start|stop|restart> dhcp_protect
The program will log every blacklisting action to syslog (also in dryrun mode).
Oct 23 16:50:18 router dhcp_protect[9706]: 00000000021b: blacklisting started
Oct 23 16:52:18 router dhcp_protect[9706]: 00000000021b: blacklisting ended
DHCP Protect will update its status in stats_file
every stats_interval
seconds. This is a JSON file containing the UNIX timestamp when the file was created/updated, absolute and relative (relative to late update) counters of all different DHCPv4/DHCPv6 messages types and the current blacklist entries.
For example:
root@dhcp:~# cat /var/run/dhcp_protect_status.json | json_pp
{
"dhcpv4" : {
"DISCOVER" : {
"abs" : 2,
"rel" : 0
},
"ACK" : {
"rel" : 0,
"abs" : 52
},
"REQUEST" : {
"rel" : 0,
"abs" : 52
},
"OFFER" : {
"rel" : 0,
"abs" : 1
}
},
"timestamp" : 1572204894,
"blacklist" : [],
"dhcpv6" : {
"RECONFIGURE-REQUEST" : {
"abs" : 61,
"rel" : 0
},
"SOLICIT" : {
"rel" : 0,
"abs" : 83
},
"RELEASE" : {
"rel" : 0,
"abs" : 6
},
"DECLINE" : {
"abs" : 61,
"rel" : 0
},
"RENEW" : {
"rel" : 0,
"abs" : 22
},
"REBIND" : {
"rel" : 0,
"abs" : 2
},
"RELAY-FORW" : {
"rel" : 0,
"abs" : 61
}
}
}
Copyright 2019 Pascal Gloor
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.