# xl2tpd: the L2TP daemon that most VPNs are built on top of

> xl2tpd is Xelerance's fork of the L2TP daemon that implements RFC 2661, and it is the component that actually carries the PPP session for an L2TP/IPsec VPN, with the IPsec half supplied by something like Openswan. The build is a plain make, and the man page for the configuration is the real documentation.

**xelerance/xl2tpd** — Official Xelerance fork of L2TPd

- Repository: https://github.com/xelerance/xl2tpd
- Stars: 571 · Forks: 208
- Language: C
- License: GPL-2.0
- Published: 2026-10-22 · Updated: 2026-10-22 · Language: en
- Canonical page: https://hysenlabs.com/projects/xelerance-xl2tpd

## What L2TP is, and the piece this daemon actually is

xl2tpd is an implementation of the Layer 2 Tunneling Protocol as defined by RFC 2661, and L2TP allows you to tunnel PPP over UDP.

The README gives two situations where that matters. Some ISPs use L2TP to tunnel user sessions from dial-in servers, which it calls modem banks and ADSL DSLAMs, to back-end PPP servers. And another important application is Virtual Private Networks where the IPsec protocol is used to secure the L2TP connection, which is L2TP/IPsec as defined by RFC 3193. xl2tpd can be used in combination with IPsec implementations such as Openswan, and example configuration files for such a setup are included in the examples directory.

That second case is the one that matters for most readers today, and the division of labour is the thing to understand. IPsec provides the encryption and the authentication of the packets. L2TP provides the session management and the tunnel. And PPP, the point-to-point protocol, is what carries the actual user session, with the IP addresses, the routes and the authentication. xl2tpd sits in the middle of that, and it does not do the encryption itself.

So if you are reading this because you want to offer a VPN to clients that only support L2TP, you need xl2tpd plus an IPsec implementation, and the configuration has to make the two agree about which addresses are protected and which are not.

The implementation detail that explains the design is that xl2tpd uses a pseudo-tty to communicate with pppd. It runs in userspace but supports kernel mode L2TP, which is what lets an administrator choose between the two depending on whether they want the kernel's L2TP handling or the daemon's.

The provenance is older than you would expect. xl2tpd is based on the L2TP code base of Jeff McAdams, and it was de-facto maintained by Jacco de Leeuw in 2002 and 2003. The current version numbers and the GPL-2.0 licence date from that origin.

## NAT and the two features that make overlapping addresses work

There is one feature in the README that deserves more attention than it usually gets, because it is the reason a particular class of deployment works at all.

xl2tpd supports IPsec SA Reference tracking to enable overlapping internal NAT'ed IP addresses by different clients, for example all clients connecting from their linksys internal IP 192.168.1.101, as well as multiple clients behind the same NAT router.

The situation is this. A client on a home network has a private address, say 192.168.1.101, and the NAT router rewrites it to the public address when the packet leaves. Two different clients behind two different NAT routers can both have 192.168.1.101, and both arrive at the VPN gateway appearing to come from the same private address. Without help, the gateway cannot tell the two tunnels apart, and the IPsec security associations end up associated with the wrong client.

The SA Reference tracking solves it by letting the IPsec layer pass a reference identifying the client through to the L2TP layer, so the daemon can distinguish two sessions that share an apparent source address. The practical effect is that the common case of a home router with a private address, and a corporate VPN gateway that has to serve many of them, works without a per-client address plan.

The second half of that sentence matters just as much. Multiple clients behind the same NAT router is a different problem, because one public address is shared by several private ones, and the NAT has to be able to tell the replies apart. The two together mean the deployment does not require every client to have a unique address, which is what most L2TP gateways are actually asked to do.

A note on versions, which is easy to miss. In Linux kernel 4.15 and later there is a kernel bug with ancillary IP_PKTINFO, and as such the recommendation is to use xl2tpd 1.3.12 or newer on those kernels. The bug is in the kernel rather than in the daemon, but the workaround has to live somewhere and this is where it landed.

## Building it, and where the configuration actually lives

The build is two commands, which is what you would expect from a C daemon of this vintage:

```
    make
    sudo make install
```

There is no configure step and no dependency manager. The Makefile includes a separate Makefile.ver for the version, and the header of the file carries the original copyright from 1998 Adtran and Mark Spencer, with the note that the software may be distributed under the terms of the GNU General Public License version 2 or at your option any later version.

The configuration is in the xl2tpd.conf(5) man page, and the README says so directly: that man page has details on how to configure xl2tpd. This is worth flagging because it means the readme is a pointer rather than a guide, and a reader who expects to configure the daemon from the readme will come away empty handed.

The example configurations in the examples/ directory show the shapes you actually need. There is a basic xl2tpd.conf, and then the L2TP/IPsec combinations, with an xl2tpd-L2TP-CERT.conf and an xl2tpd-L2TP-PSK.conf, plus Windows XP oriented variants of each with the orgWIN2KXP suffix, since that was the dominant client of the era. There is also chapsecrets.sample for the CHAP credentials and ppp-options.xl2tpd for the options handed to pppd, and a README in that directory.

The two credential models are the ones you will pick between. The PSK files use a pre-shared key, which is simple and which is also the weaker of the two because the key is symmetric and shared. The CERT files use certificates, which is what you want if you are running a real service, and the presence of a separate chapsecrets.sample is for the inner PPP authentication, which is a different thing from the outer IPsec authentication and is a common source of confusion in L2TP/IPsec setups.

The Windows XP naming is a reminder of the vintage. The examples are still oriented at the clients of that generation, because the configuration differences for a Windows client are about the registry and the connection type rather than about the protocol, and they are still in the file because people still use them.

## The C source layout, and the debugging flags that make it tractable

The source files sit at the top level of the repository with a fairly conventional C layout, and the file names map onto the protocol.

There is xl2tpd.c for the daemon itself and xl2tpd-control.c for the control socket, with aaa.c and aaa.h for the authentication, accounting and access control layer, avp.c and avpsend.c for the attribute value pairs that carry the protocol's parameters, control.c for the control protocol messages, call.c for the call and session state, file.c for the configuration file parsing, misc.c for the odds and ends, network.c for the socket handling, pty.c for the pseudo-tty side, and scheduler.c for the timing. The shared headers are common.h, l2tp.h, ipsecmast.h and osport.h, where osport is the portability layer that isolates the operating system differences.

What is unusual, and useful, is that the protocol is split across separate compilation units rather than being one large file. A daemon that has been maintained for two decades by successive volunteers is exactly the kind of code where a change to the control message handling is feasible without touching the socket layer.

The Makefile documents the debugging flags, and that list is a good map of the protocol's moving parts. DEBUG_ZLB shows all ZLB exchange traffic, which is the keepalive and control exchange. DEBUG_HELLO debugs when hello messages are sent. DEBUG_CLOSE debugs call and tunnel closing. DEBUG_FLOW debugs the flow control system. DEBUG_FILE debugs the file format, which is how you work out why a configuration is not being read as you expect. DEBUG_AAA covers authentication, accounting and access control. DEBUG_PAYLOAD shows information on every payload packet. DEBUG_CONTROL covers every control packet and the l2tp-control pipe. DEBUG_PPPD shows the command line of pppd and how the daemon signals it. DEBUG_HIDDEN debugs the hidden AVPs. DEBUG_ENTROPY debugs entropy generation. There are also DEBUG_CONTROL_XMIT, DEBUG_MAGIC, DEBUG_FLOW_MORE and DEBUG_AUTH, and a test flag called -DTEST_HIDDEN that makes the Assigned Call ID be sent as a hidden AVP.

The last flag in that list is the one that matters most for a real deployment, and it is not a debug flag at all. -DTRUST_PPPD_TO_DIE disables a workaround for broken pppd versions. The workaround exists because some pppd versions ignore SIGTERM, which causes the daemon to hang as well, and the cost of not trusting pppd to die is that the ip-down scripts do not get a chance to run. The Makefile names the confirmed bad version, ppp-2.4.2-6.4.RHEL4, and the confirmed good ones, the recent Ubuntu and Debian pppd builds, and notes that ppp 2.4.3 sends a SIGTERM after five seconds so it should be safe to trust.

## Conclusion

xl2tpd suits an administrator setting up L2TP/IPsec for clients that cannot speak IPsec natively, since it is the component that terminates the L2TP session and hands the PPP connection to pppd, and the example configurations cover the certificate and pre-shared key cases. It does not suit you if you want a complete VPN in one package, because the encryption half is someone else's job. Before you deploy it, read the xl2tpd.conf man page rather than the readme, since the configuration details live there, and note the known kernel bug around ancillary IP_PKTINFO on Linux 4.15 and later, for which the recommendation is 1.3.12 or newer.

## FAQ

### What is xl2tpd and what does it do?

It is an implementation of the Layer 2 Tunneling Protocol as defined by RFC 2661, which tunnels PPP over UDP. It runs in userspace but supports kernel mode L2TP, and it uses a pseudo-tty to communicate with pppd.

### Do I need xl2tpd for an L2TP/IPsec VPN?

You need it for the L2TP half. IPsec provides the encryption and authentication and is supplied by an implementation such as Openswan, and the README notes that example configuration files for such a setup are included in the examples directory.

### How do I configure xl2tpd?

Through the xl2tpd.conf(5) man page, which the README says has details on how to configure it. Example configurations for L2TP/IPsec with certificates or with a pre-shared key, plus Windows XP variants, are in the examples directory along with a CHAP secrets sample and the pppd options file.

### How do I build and install xl2tpd?

Run make and then sudo make install. There is no configure step, and the version lives in a separate Makefile.ver that the Makefile includes.

## Sources

- [Issues](https://github.com/xelerance/xl2tpd/issues)
- [License: GPL-2.0](https://github.com/xelerance/xl2tpd/blob/master/LICENSE)
- [README](https://github.com/xelerance/xl2tpd/blob/master/README.md)
- [Releases](https://github.com/xelerance/xl2tpd/releases)
- [xelerance/xl2tpd on GitHub](https://github.com/xelerance/xl2tpd)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/xelerance-xl2tpd
