DHCP Release does not work correctly
-
Hello, when you go to the status_interfaces.php page and click the pretty "Release" button you would expect dhclient to send a DHCPRELEASE type 7 packet to the DHCP server that issued the IP address for said interface, however that is not the case. I discovered this error as I'm a nerd like that and like to fiddle around with things and see how they function. I used the tool called dhcpdump to conduct my debugging of dhclient and the DHCP server.
The scenario:
pfSense VM IP: 10.0.0.162 (08:00:27:88:45:55)
DHCP Server IP: 10.0.0.101 (b8:27:eb:5e:5e:e8) (Debian server on my network running ISC DHCPd)I began the initial debugging by running "dhcpdump -i eth0 -h ^08:00:27" on the Debian box running the DHCP server.
I click the Release button on the pfSense Interfaces page, got nothing in the dhcpdump. I should of got 1 packet, the DHCPRELEASE type 7.
I click the Renew button on the pfSense Interfaces page, got the following sequence:
DHCPREQUEST type 3 –> DHCPACK type 5 --> DHCPNAK type 6. The result, same IP as before.I decided to test a DHCP release/renew on a Debian VM using dhclient.
Debian VM IP: 10.0.0.156 (08:00:27:c5:1:8e)I did "dhclient -v -i eth0 -r" on the Debian VM to RELEASE the IP and kill the lease.
It PROPERLY sent the type 7 packet to the DHCP server. The sequence went like this
RELEASE: DHCPRELEASE type 7
RENEW: DHCPDISCOVER type 1 --> DHCPOFFER type 2 --> DHCPREQUEST type 3 --> DHCPACK type 5
I instigated the renew request using "dhclient -i eth0" on the Debian VM.The Debian VM ended up with a new IP as expected because we released resulting in the DHCP server to remove/expire the lease.
New IP: 10.0.0.170This is how the pfSense release/renew SHOULD function for dhclient. I will include the dhcpdump logs below, please also take notice of what DHCP request options the Debian dhclient sends to the DHCP server as well compared to the pfSense. For example I see NTP servers which is interesting, so if an ISP had NTP servers they would like you to use, maybe have something similar to how it handles DNS, a checkmark to allow or disallow overwriting the NTP server configuration? Anyway, I provide this feedback to improve pfSense and hope you take it into consideration.
dhcpdump debugging capture:
root@jetstream:/etc/bind# dhcpdump -i eth0 -h ^08:00:27
issued pfSense release
nothing...
issued pfSense renew
TIME: 2016-03-12 13:56:58.593
IP: 10.0.0.162 (8:0:27:88:45:55) > 255.255.255.255 (ff:ff:ff:ff:ff:ff)
OP: 1 (BOOTPREQUEST)
HTYPE: 1 (Ethernet)
HLEN: 6
HOPS: 0
XID: fff2afce
SECS: 0
FLAGS: 0
CIADDR: 0.0.0.0
YIADDR: 0.0.0.0
SIADDR: 0.0.0.0
GIADDR: 0.0.0.0
CHADDR: 08:00:27:88:45:55:00:00:00:00:00:00:00:00:00:00
SNAME: .
FNAME: .
OPTION: 53 ( 1) DHCP message type 3 (DHCPREQUEST)
OPTION: 50 ( 4) Request IP address 10.0.0.162
OPTION: 61 ( 7) Client-identifier 01:08:00:27:88:45:55
OPTION: 12 ( 5) Host name venom
OPTION: 55 ( 9) Parameter Request List 1 (Subnet mask)
28 (Broadcast address)
2 (Time offset)
121 (Classless Static Route)
3 (Routers)
15 (Domainname)
6 (DNS server)
12 (Host name)
119 (Domain Search)
TIME: 2016-03-12 13:56:58.594
IP: 10.0.0.101 (b8:27:eb:5e:5e:e8) > 10.0.0.162 (8:0:27:88:45:55)
OP: 2 (BOOTPREPLY)
HTYPE: 1 (Ethernet)
HLEN: 6
HOPS: 0
XID: fff2afce
SECS: 0
FLAGS: 0
CIADDR: 0.0.0.0
YIADDR: 10.0.0.162
SIADDR: 0.0.0.0
GIADDR: 0.0.0.0
CHADDR: 08:00:27:88:45:55:00:00:00:00:00:00:00:00:00:00
SNAME: .
FNAME: .
OPTION: 53 ( 1) DHCP message type 5 (DHCPACK)
OPTION: 54 ( 4) Server identifier 10.0.0.101
OPTION: 51 ( 4) IP address leasetime 465210 (5d9h13m30s)
OPTION: 1 ( 4) Subnet mask 255.255.255.0
OPTION: 3 ( 4) Routers 10.0.0.1
OPTION: 15 ( 13) Domainname lan.gtaxl.net
OPTION: 6 ( 4) DNS server 10.0.0.101TIME: 2016-03-12 13:56:58.993
IP: 10.0.0.1 (0:1e:c7:ce:6b:21) > 255.255.255.255 (ff:ff:ff:ff:ff:ff)
OP: 2 (BOOTPREPLY)
HTYPE: 1 (Ethernet)
HLEN: 6
HOPS: 0
XID: fff2afce
SECS: 0
FLAGS: 0
CIADDR: 0.0.0.0
YIADDR: 0.0.0.0
SIADDR: 0.0.0.0
GIADDR: 0.0.0.0
CHADDR: 08:00:27:88:45:55:00:00:00:00:00:00:00:00:00:00
SNAME: .
FNAME: .
OPTION: 53 ( 1) DHCP message type 6 (DHCPNAK)
OPTION: 54 ( 4) Server identifier 10.0.0.1Debian client VM:
root@jetstream:/etc/bind# dhcpdump -i eth0 -h ^08:00:27
issued dhcp release
TIME: 2016-03-12 14:05:12.693
IP: 10.0.0.156 (8:0:27:c5:1:8e) > 10.0.0.101 (b8:27:eb:5e:5e:e8)
OP: 1 (BOOTPREQUEST)
HTYPE: 1 (Ethernet)
HLEN: 6
HOPS: 0
XID: 675c8a56
SECS: 0
FLAGS: 0
CIADDR: 10.0.0.170
YIADDR: 0.0.0.0
SIADDR: 0.0.0.0
GIADDR: 0.0.0.0
CHADDR: 08:00:27:c5:01:8e:00:00:00:00:00:00:00:00:00:00
SNAME: .
FNAME: .
OPTION: 53 ( 1) DHCP message type 7 (DHCPRELEASE)
OPTION: 54 ( 4) Server identifier 10.0.0.101
OPTION: 12 ( 12) Host name debian-serv1issued dhcp renew
TIME: 2016-03-12 14:05:55.393
IP: 0.0.0.0 (8:0:27:c5:1:8e) > 255.255.255.255 (ff:ff:ff:ff:ff:ff)
OP: 1 (BOOTPREQUEST)
HTYPE: 1 (Ethernet)
HLEN: 6
HOPS: 0
XID: 31a4f25e
SECS: 0
FLAGS: 0
CIADDR: 0.0.0.0
YIADDR: 0.0.0.0
SIADDR: 0.0.0.0
GIADDR: 0.0.0.0
CHADDR: 08:00:27:c5:01:8e:00:00:00:00:00:00:00:00:00:00
SNAME: .
FNAME: .
OPTION: 53 ( 1) DHCP message type 1 (DHCPDISCOVER)
OPTION: 50 ( 4) Request IP address 10.0.0.170
OPTION: 12 ( 12) Host name debian-serv1
OPTION: 55 ( 13) Parameter Request List 1 (Subnet mask)
28 (Broadcast address)
2 (Time offset)
3 (Routers)
15 (Domainname)
6 (DNS server)
119 (Domain Search)
12 (Host name)
44 (NetBIOS name server)
47 (NetBIOS scope)
26 (Interface MTU)
121 (Classless Static Route)
42 (NTP servers)OPTION: 61 ( 19) Client-identifier ff:27:c5:01:8e:00:01:00:01:1e:77:25:0e:08:00:27:c5:01:8e
TIME: 2016-03-12 14:05:56.393
IP: 10.0.0.101 (b8:27:eb:5e:5e:e8) > 10.0.0.170 (8:0:27:c5:1:8e)
OP: 2 (BOOTPREPLY)
HTYPE: 1 (Ethernet)
HLEN: 6
HOPS: 0
XID: 31a4f25e
SECS: 0
FLAGS: 0
CIADDR: 0.0.0.0
YIADDR: 10.0.0.170
SIADDR: 0.0.0.0
GIADDR: 0.0.0.0
CHADDR: 08:00:27:c5:01:8e:00:00:00:00:00:00:00:00:00:00
SNAME: .
FNAME: .
OPTION: 53 ( 1) DHCP message type 2 (DHCPOFFER)
OPTION: 54 ( 4) Server identifier 10.0.0.101
OPTION: 51 ( 4) IP address leasetime 604800 (7d)
OPTION: 1 ( 4) Subnet mask 255.255.255.0
OPTION: 3 ( 4) Routers 10.0.0.1
OPTION: 15 ( 13) Domainname lan.gtaxl.net
OPTION: 6 ( 4) DNS server 10.0.0.101TIME: 2016-03-12 14:05:56.393
IP: 0.0.0.0 (8:0:27:c5:1:8e) > 255.255.255.255 (ff:ff:ff:ff:ff:ff)
OP: 1 (BOOTPREQUEST)
HTYPE: 1 (Ethernet)
HLEN: 6
HOPS: 0
XID: 31a4f25e
SECS: 0
FLAGS: 0
CIADDR: 0.0.0.0
YIADDR: 0.0.0.0
SIADDR: 0.0.0.0
GIADDR: 0.0.0.0
CHADDR: 08:00:27:c5:01:8e:00:00:00:00:00:00:00:00:00:00
SNAME: .
FNAME: .
OPTION: 53 ( 1) DHCP message type 3 (DHCPREQUEST)
OPTION: 54 ( 4) Server identifier 10.0.0.101
OPTION: 50 ( 4) Request IP address 10.0.0.170
OPTION: 12 ( 12) Host name debian-serv1
OPTION: 55 ( 13) Parameter Request List 1 (Subnet mask)
28 (Broadcast address)
2 (Time offset)
3 (Routers)
15 (Domainname)
6 (DNS server)
119 (Domain Search)
12 (Host name)
44 (NetBIOS name server)
47 (NetBIOS scope)
26 (Interface MTU)
121 (Classless Static Route)
42 (NTP servers)OPTION: 61 ( 19) Client-identifier ff:27:c5:01:8e:00:01:00:01:1e:77:25:0e:08:00:27:c5:01:8e
TIME: 2016-03-12 14:05:56.394
IP: 10.0.0.101 (b8:27:eb:5e:5e:e8) > 10.0.0.170 (8:0:27:c5:1:8e)
OP: 2 (BOOTPREPLY)
HTYPE: 1 (Ethernet)
HLEN: 6
HOPS: 0
XID: 31a4f25e
SECS: 0
FLAGS: 0
CIADDR: 0.0.0.0
YIADDR: 10.0.0.170
SIADDR: 0.0.0.0
GIADDR: 0.0.0.0
CHADDR: 08:00:27:c5:01:8e:00:00:00:00:00:00:00:00:00:00
SNAME: .
FNAME: .
OPTION: 53 ( 1) DHCP message type 5 (DHCPACK)
OPTION: 54 ( 4) Server identifier 10.0.0.101
OPTION: 51 ( 4) IP address leasetime 604800 (7d)
OPTION: 1 ( 4) Subnet mask 255.255.255.0
OPTION: 3 ( 4) Routers 10.0.0.1
OPTION: 15 ( 13) Domainname lan.gtaxl.net
OPTION: 6 ( 4) DNS server 10.0.0.101 -
That's the way the client has always worked, 'release' really just kills the dhclient instance for the interface.
https://github.com/pfsense/pfsense/blob/master/src/etc/inc/interfaces.inc#L1317
The suggested change can't be made directly because dhclient on FreeBSD does not support the -r flag. And using a third-party dhclient like the one from ISC may introduce other undesirable side effects (especially at this point in our release cycle)
-
I know you use ISC for the DHCP server, and thought you used it for the client as well. I mean I even see it as a current package via pkg info under pfSense,
isc-dhcp43-client-4.3.3P1_1 The ISC Dynamic Host Configuration Protocol client.I'm going to look at this: http://www.cyberciti.biz/faq/freebsd-unix-force-dhcp-client-to-get-a-new-lease/
on a fresh freebsd vm and see what sends the proper sequence to kill the lease. I assume that's the dhclient you use? -
Hmm I'm not sure why it's showing installed because that one isn't in use: https://github.com/pfsense/pfsense/blob/master/src/etc/inc/interfaces.inc#L4288
Though if it is there (And it's supposed to be there) then perhaps it could be used to send only the release packet and nothing else. I don't see anything else depending on it, so it may be that was added as a dependency accidentally.
-
Where would the executable binary for it be, since dhclient is a symlink to the freebsd one? And next release (2.4??) will you consider using ISC for the client? Feature wise it appears more superior, at least imo over the freebsd built in one. I mean you use them for the DHCP server, so as a suite it makes since as it all goes together. And I admit I'm an ISC fanboy, idk, I just like how advanced, "over-engineered" their software is.
Basically without the release packet being sent to the DHCP server, the lease won't be expired/revoked keeping the same IP.
Real Scenario: I've been DDoS'd before at home, I do a DHCP release/renew on the router's web interface, it sends the proper release packet, etc. and I end up with a new public IP. DDoS mitigated with a click of a button, just using my dynamic IP for good. Prevents me from 1) not having to spoof MAC's all the time 2) Don't have to unplug the router and wait the lease out. I used to do that when I was dumb..
-
I found where ISC's DHCP client is hanging out on pfSense :P It's in /usr/local/sbin where as the freebsd one is in /sbin/.
[2.3-BETA][root@venom.gtaxl.net]/usr/local/sbin: ./dhclient –version
isc-dhclient-4.3.3-P1
[2.3-BETA][root@venom.gtaxl.net]/usr/local/sbin: ./dhclient -v -i em0 -r
Internet Systems Consortium DHCP Client 4.3.3-P1
Copyright 2004-2016 Internet Systems Consortium.
All rights reserved.
For info, please visit https://www.isc.org/software/dhcp/Listening on BPF/em0/08:00:27:88:45:55
Sending on BPF/em0/08:00:27:88:45:55
Sending on Socket/fallback
Created duid \000\001\000\001\036wMI\010\000'\210EU.
[2.3-BETA][root@venom.gtaxl.net]/usr/local/sbin: ifconfig em0 | grep inet
inet6 fe80::a00:27ff:fe88:4555%em0 prefixlen 64 scopeid 0x1
inet 10.0.0.162 netmask 0xffffff00 broadcast 10.0.0.255Doesn't work though, probably cuz ISC doesn't have a current lease to renew.. Interesting none the less.
-
Apparently I'm not the first to complain about FreeBSD's sub-par dhclient regarding this issue.
https://www.reddit.com/r/PFSENSE/comments/1wvoh7/wan_dhcp_release_issue/
https://forum.pfsense.org/index.php?topic=52608.0
https://forum.pfsense.org/index.php?topic=68396.0
https://twitter.com/search?f=tweets&vertical=default&q=pfsense%20dhcp%20release&src=typd
https://redmine.pfsense.org/issues/4209SIGH! ISC dhclient is long overdue… oops.
Okay, I played around with the copy if ISC's dhclient that seems to be sitting on pfSense 2.3 beta.
It's executable binary and script are in: /usr/local/sbin
It's DHCP lease file is: /var/db/dhclient.leases
It's configuration file is: /usr/local/etc/dhclient.confIt's default config has a bunch of examples that supersede and prepend the lease you get by adding additional domain-name and dns servers, so I just erased the config and wrote my own clean one.
Also the default-lease it asks the DHCP server for is way to low: send dhcp-lease-time 3600; So I changed it to 7 days, 604800.
I killed the FreeBSD dhclient processes that were running by kill -9'ing them.
ISC's dhclient works, but pfSense doesn't appear to pick up the new IP and refresh the rules or whatever the protocol is for that.
I'm able to get an IP and it configures the interface just fine.
/usr/local/sbin/dhclient -v -i em0 - Obtains an IP and sets it to the interface, I use -v verbose to watch what it's doing, might be a good idea to redirect that via > to the correct log spot for DHCP?
And to release I do /usr/local/sbin/dhclient -v -i em0 -r and it sends the correct DHCPRELEASE packet and removes the IP from the interface.
[2.3-BETA][root@venom.gtaxl.net]/usr/local/sbin: ./dhclient -v -i em0 -r
Killed old client process
Internet Systems Consortium DHCP Client 4.3.3-P1
Copyright 2004-2016 Internet Systems Consortium.
All rights reserved.
For info, please visit https://www.isc.org/software/dhcp/Listening on BPF/em0/08:00:27:88:45:55
Sending on BPF/em0/08:00:27:88:45:55
Sending on Socket/fallback
DHCPRELEASE on em0 to 10.0.0.101 port 67It will ask the DHCP server for the same IP if it sees the previous lease from the dhclient.leases file. So if you want the same IP back keep the lease file. If you want a different IP, issue a release, delete the file, then renew. If you delete the lease file before you release'd ISC won't release.
So, in conclusion, please start whatever process to get this on the roadmap. If you do, I request that you give us ability to configure everything via the web gui that would be in the dhclient.conf.
Keep the protocol timing options, but allow us to specify what DHCP lease time we ask the DHCP server, if we don't specify one, exclude the line from the dhclient.conf and we'll respect the DHCP server's default lease time. A lease time of 7 days would be configured like this in dhclient.conf: send dhcp-lease-time 604800;
Also give us the option to choose one of the 3 when the dhclient asks for an IP.
- Ask the DHCP server for our same/old IP that's in the lease file, makes it so our IP stays static. To do this, don't delete the lease file.
- Ask the DHCP server for a new random IP. To do this delete the lease file right after a release, then renew.
- Allow us to explicitly set what IP we want to request from the DHCP server. This would be DHCP option 50, you would set it in dhclient.conf like this: send dhcp-requested-address 192.168.1.240;
I know I know, this could be dangerous, warn the user in the descriptive text. But for people that know what they're doing, like me, will enjoy this. I can basically ask for an IP address from my ISP such as 74.5.69.69 and be bad-ass. Assuming it's available and in the DHCP things will work, if not available the DHCP server just denies the request and we get a random IP.. And yes I know, you have to know what your ISP's DHCP pool is a head of time, like I said this is for people that know what they're doing.
There are a lot of things you can configure in dhclient.conf and I hope the web gui will at least implement what I have said, I see you allow the option for a configuration override and appreciate that a lot. I hope that if and when you switch to ISC you'll have the same options as well as what I asked.