Patch: Fix renewals, releases sent from wrong source address on multihomed/VPN hosts

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

Patch: Fix renewals, releases sent from wrong source address on multihomed/VPN hosts

Thor Simon

I have a population of systems which use dhclient on their physical interfaces for DHCP, but otherwise perform essentially no local network traffic.  The interface coming up triggers (via NetworkManager, not the dhclient scripts) creation of an IPsec tunnel, which uses a ‘vti’ interface which itself receives a separate address via IKE.  The machines run Debian Stretch.

 

This effectively creates a multihomed host configuration where dhclient is operating on a different interface than the one used by the default route.  If you search the lists you’ll find a scattering of reports going back over a decade that dhclient intermittently sends messages from the wrong interface’s source address on such hosts.  This got to be enough of a nuisance (I ran into a non-ISC DHCP server which not only NAKed such requests, it blacklisted the client!) that I finally root-caused the issue.

 

The problem is caused by inappropriate use of the “fallback” send mechanism when the message in question need not be routed.  According to the block comment in osdep.h which appears to be the only documentation:

 

/* Porting::

 

   If you add support for sending packets directly out an interface,

   and your support does not do ARP or routing, you must use a fallback

   mechanism to deal with packets that need to be sent to routers.

   Currently, all low-level packet interfaces use BSD sockets as a

   fallback. */

 

However, what dhclient.c actually does is this, in both the REQUEST and RELEASE cases:

 

        if (destination.sin_addr.s_addr != INADDR_BROADCAST &&

            fallback_interface) {

                result = send_packet(fallback_interface, […]

 

In other words, don’t bother actually checking if the destination is on a local network, send all unicast traffic via the fallback interface.  The fallback interface doesn’t have a bound address so we are effectively sending from 0.0.0.0 and the system routing machinery may do with us what it will.  Such as select an inappropriate source address which does not match the client-ip in the lease and freak out the DHCP server.

 

The attached diff, which is against Debian’s patched 4.3.5, seems to fix the issue.

 

Thor

 


_______________________________________________
dhcp-users mailing list
[hidden email]
https://lists.isc.org/mailman/listinfo/dhcp-users

sane-fallback.patch (6K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Patch: Fix renewals, releases sent from wrong source address on multihomed/VPN hosts

John Ioannidis-2
Thor!!! It's been ages!

Couple of things on this patch:

1. does the faulty behavior you are trying to fix happen if you have explicitly set a more-specific route with a default src address for the traffic in question, thus using the kernel's proper mechanism for setting the source address rather than replicating in the dhclient code?
2. Fix your formatting, it's inconsistent with the surrounding code, and Vixie will probably be annoyed :)
Cheers,

/ji

On Mon, Apr 27, 2020 at 8:19 PM Thor Simon <[hidden email]> wrote:

I have a population of systems which use dhclient on their physical interfaces for DHCP, but otherwise perform essentially no local network traffic.  The interface coming up triggers (via NetworkManager, not the dhclient scripts) creation of an IPsec tunnel, which uses a ‘vti’ interface which itself receives a separate address via IKE.  The machines run Debian Stretch.

 

This effectively creates a multihomed host configuration where dhclient is operating on a different interface than the one used by the default route.  If you search the lists you’ll find a scattering of reports going back over a decade that dhclient intermittently sends messages from the wrong interface’s source address on such hosts.  This got to be enough of a nuisance (I ran into a non-ISC DHCP server which not only NAKed such requests, it blacklisted the client!) that I finally root-caused the issue.

 

The problem is caused by inappropriate use of the “fallback” send mechanism when the message in question need not be routed.  According to the block comment in osdep.h which appears to be the only documentation:

 

/* Porting::

 

   If you add support for sending packets directly out an interface,

   and your support does not do ARP or routing, you must use a fallback

   mechanism to deal with packets that need to be sent to routers.

   Currently, all low-level packet interfaces use BSD sockets as a

   fallback. */

 

However, what dhclient.c actually does is this, in both the REQUEST and RELEASE cases:

 

        if (destination.sin_addr.s_addr != INADDR_BROADCAST &&

            fallback_interface) {

                result = send_packet(fallback_interface, […]

 

In other words, don’t bother actually checking if the destination is on a local network, send all unicast traffic via the fallback interface.  The fallback interface doesn’t have a bound address so we are effectively sending from 0.0.0.0 and the system routing machinery may do with us what it will.  Such as select an inappropriate source address which does not match the client-ip in the lease and freak out the DHCP server.

 

The attached diff, which is against Debian’s patched 4.3.5, seems to fix the issue.

 

Thor

 

_______________________________________________
dhcp-users mailing list
[hidden email]
https://lists.isc.org/mailman/listinfo/dhcp-users

_______________________________________________
dhcp-users mailing list
[hidden email]
https://lists.isc.org/mailman/listinfo/dhcp-users