Bug 868391 - xl2tpd sends response packets from wrong IP address
Summary: xl2tpd sends response packets from wrong IP address
Alias: None
Product: Fedora EPEL
Classification: Fedora
Component: xl2tpd
Version: el5
Hardware: i686
OS: Linux
Target Milestone: ---
Assignee: Paul Wouters
QA Contact: Fedora Extras Quality Assurance
Depends On:
TreeView+ depends on / blocked
Reported: 2012-10-19 17:29 UTC by James Moore
Modified: 2014-05-31 18:35 UTC (History)
3 users (show)

Fixed In Version: xl2tpd-1.3.6-1.el6
Doc Type: Bug Fix
Doc Text:
Clone Of:
Last Closed: 2014-05-21 23:27:23 UTC
Type: Bug

Attachments (Terms of Use)

Description James Moore 2012-10-19 17:29:10 UTC
When xl2tpd Version 1.3.1 Release 1.el5 is installed on a system with multiple network interfaces, XL2TPD always sends response packets with the source IP address set to the address of the interface that the packet leaves from unless xl2tpd is bound to a single IP address with the listen-addr directive in xl2tpd.conf. This is not the correct behavior and makes it impossible to configure xl2tpd to listen on multiple ip addresses when asymmetric routing may occur. See the diagram below:

     ISP-A                                    ISP-B
       |                                       |
       |                                       |
    (eth3)                                   (eth3)
 Linux Router A-(eth2)-----------(eth2)-Linux Router B
    (eth1)                                   (eth1)
       |                                         |
       |                                         |
                       DMZ Network

Linux Router A and Linux Router B run BGP with the connected ISP and each other. Depending on current networking conditions and BGP configurations, response packets may be sent out a different interface and ISP than the incoming packets are received on. Unless xl2tpd is bound to a single IP address with the listen-addr directive in xl2tpd.conf, xl2tpd incorrectly sends response packets from the IP address of the interface the packet leaves from which in some cases may be different than the IP address that the L2TP/IPsec client tries to connects to. When this occurs, two problems occur: 1) The response packet is not encapsulated in IPsec and 2) even it it were possible to encrypt the packet, the client would not recognize the packet as belonging to the connection it was trying to establish.  For example, if an internet client tries to establish a L2TP/IPSec connection using the hostname or IP address assigned to the eth1 interface of either Linux router, the response packets from xl2tpd will use the IP address of either eth2 or eth3 unless xl2tpd is bound to the IP address assigned to eth1.

Under many circumstances binding XL2TPD to the IP address of the eth1 interface on each router would resolve the issue. However in my case, Linux Router A and Linux Router B also use VRRP to provide a highly available virtual gateway for the servers in the DMZ network. The MAC and IP addresses of the VRRP interface are only available on one of the routers at any given time. If the router currently holding the VRRP interface dies the other router seizes the MAC an IP addresses of the interface. Under ideal circumstances, I would want to allow XL2TPD to listen on all interfaces so that L2TP/IPsec clients could be configured to connect to hostname assigned to the VRRP interface to provide high availability. Unfortunately, I this can't be done if XL2TPD has to be bound to a single IP since the desired IP address to bind to will not be available on the backup VRRP router for binding until after a failure of the primary VRRP router occurs. 

On system running Linux kernels that lack IPsec Mast support (RedHat, Fedora, etc.), its also not possible to DNAT IPsec packets sent to the VRRP IP address to the eth1 IP address where XL2TPD is bound since the "unnatting" process occurs after the decision is made for whether or not to encapsulate the packet in IPSec so the response packets will not be encrypted when a DNAT is used.

I have attempted to contact the upstream development team using the email address listed in xl2tpd man pages (xl2tpd-dev@xelerance.com) but the message bounced saying that the mailbox did not exist.

Comment 1 Paul Wouters 2012-10-19 22:22:05 UTC
I'll look into this.

I think it would be good enough for you if xl2tpd answers using the ip it was contacted at. Is that correct?


Comment 2 James Moore 2012-10-20 06:14:18 UTC
Yes, you are correct. I just need the response to always come from the same ip that was contacted without having to specify the listen-addr in the config. Thanks for for looking into it.

Comment 3 David Herselman 2012-11-22 22:15:29 UTC
This problem is common to most stateless connections utilising UDP. It would be great if Paul could submit a patch to get xl2tpd to simply originate responses using the same IPs that requests arrived on.

I am currently over coming this problem by logging connection requests and running a simple script every 2 minutes to add routing rules, which then results in the kernel sending UDP response packets using that device's IP address. The original purpose was to handle multiple concurrent SIP (VoIP) registrations on a multihomed system but it also works on L2TP tunnels.

NB: This can not handle multiple concurrent connections on a multi homed systems where the originating IP is the same.

Firewall rule:
iptables -A INPUT -m state --state NEW -p udp --dport 1701 -j LOG --log-prefix "routeme:"
iptables -A INPUT -m state --state NEW -p udp --dport 1701 -j ACCEPT

set_route () {
  [ "$dev" == "" ] && return;
  [ `echo $ip | grep -Pc '^\d{1,3}(\.\d{1,3}){3}$'` -lt 1 ] && return;
  [ `route -n | grep "^$ip" | grep -cv "$dev$"` -gt 0 ] && route del -host $ip;
  route add -host $ip dev $dev 2> /dev/null;

# Find firewall log entries that match 'routeme:' and add a route via the last interface:
ips=`tail -n 10000 /var/log/messages | grep 'routeme:' | perl -pe 's/.*SRC=(\d{1,3}(\.\d{1,3}){3}).*/\1/' | sort | uniq`;
for ip in $ips; do
  dev=(`tail -n 10000 /var/log/messages | grep "routeme:.*SRC=$ip" | perl -pe 's/.*IN=(\S+).*/\1/' | tail -n 1`;

Comment 4 James Moore 2012-11-26 13:59:32 UTC
David, that's an interesting approach. I'm surprised it works though. How do the firewall and application on the other side of the connection recognize the response from a different ip address?

Comment 5 James Moore 2012-11-26 14:03:57 UTC
David, I get it now, it forces the packet out the interface with the ip that the connection arrived on. This probably wouldn't work with IPSec in netkey mode though since the kernel wouldn't know that the packet belonged to an IPSec connection.

Comment 6 Paul Wouters 2012-11-28 04:35:12 UTC
I've started work on portinf his to recvfrom() recvfromto()

Comment 7 Timur Bakeyev 2014-05-12 15:00:02 UTC
I hit the same problem with xl2tpd 1.3.1 on Debian and was wondering - was there any progress on this bug?

It seems, that development of xl2tpd now moved to https://github.com/xelerance/xl2tpd

Comment 8 Fedora Update System 2014-05-13 15:36:51 UTC
xl2tpd-1.3.6-1.fc20 has been submitted as an update for Fedora 20.

Comment 9 Fedora Update System 2014-05-13 15:38:49 UTC
xl2tpd-1.3.6-1.fc19 has been submitted as an update for Fedora 19.

Comment 10 Fedora Update System 2014-05-13 15:39:57 UTC
xl2tpd-1.3.6-1.el6 has been submitted as an update for Fedora EPEL 6.

Comment 11 Fedora Update System 2014-05-14 23:55:23 UTC
Package xl2tpd-1.3.6-1.fc19:
* should fix your issue,
* was pushed to the Fedora 19 testing repository,
* should be available at your local mirror within two days.
Update it with:
# su -c 'yum update --enablerepo=updates-testing xl2tpd-1.3.6-1.fc19'
as soon as you are able to.
Please go to the following url:
then log in and leave karma (feedback).

Comment 12 Fedora Update System 2014-05-21 23:27:23 UTC
xl2tpd-1.3.6-1.fc20 has been pushed to the Fedora 20 stable repository.  If problems still persist, please make note of it in this bug report.

Comment 13 Fedora Update System 2014-05-24 23:24:29 UTC
xl2tpd-1.3.6-1.fc19 has been pushed to the Fedora 19 stable repository.  If problems still persist, please make note of it in this bug report.

Comment 14 Fedora Update System 2014-05-31 18:35:50 UTC
xl2tpd-1.3.6-1.el6 has been pushed to the Fedora EPEL 6 stable repository.  If problems still persist, please make note of it in this bug report.

Note You need to log in before you can comment on or make changes to this bug.