# NetworkManager-l2tp turns a VPN profile into kl2tpd, xl2tpd and an IPsec daemon

> NetworkManager-l2tp is a NetworkManager plugin that drives L2TP and L2TP over IPsec connections by generating runtime configuration for kl2tpd or xl2tpd and by handing secrets to Libreswan or strongSwan. It suits a desktop Linux user who wants a VPN in the system menu, and it depends on three separate daemons underneath.

**nm-l2tp/NetworkManager-l2tp** — L2TP and L2TP/IPsec support for NetworkManager

- Repository: https://github.com/nm-l2tp/NetworkManager-l2tp
- Stars: 518 · Forks: 87
- Language: C
- License: GPL-2.0
- Published: 2026-10-22 · Updated: 2026-10-22 · Language: en
- Canonical page: https://hysenlabs.com/projects/nm-l2tp-networkmanager-l2tp

## The plugin is a front end for three daemons you also have to install

The dependency picture is the first thing to understand, and the documentation is explicit that this is a VPN plugin for NetworkManager 1.52.2, 1.54.3 or 1.56.0 and later, providing support for L2TP and L2TP/IPsec, meaning L2TP over IPsec, connections. Underneath, L2TP support uses either kl2tpd from Katalix's go-l2tp project or xl2tpd from xelerance, and IPsec support uses either Libreswan or strongSwan. That is a choice of four combinations across two layers, and the plugin is the layer that translates a NetworkManager connection profile into configuration for whichever daemons are present. The authentication matrix is similar. User authentication supports username and password credentials or TLS certificates, and machine authentication supports a pre-shared key or TLS certificates. The consequence for a reader is that the plugin is small and the surrounding stack is not, and an installation that fails to connect is far more likely to be a problem with the L2TP daemon, the IPsec daemon or the profile than with the plugin itself.

## Building is autotools, and the default configure settings are called unreasonable

The build is the classic GNU autotools sequence, and the documentation warns you about the defaults in unusually blunt terms. The default `./configure` settings aren't reasonable and should be explicitly overridden with `./configure` arguments. The three commands are:

```bash
    ./autogen.sh
    ./configure  # (see below)
    make
```

Two of the configure arguments exist because of version differences in the dependencies. If you have pppd < 2.5.0 you may need to use `--with-pppd-plugin-dir` and set it to an appropriate directory that exists, and similarly `--with-nm-ipsec-nss-dir` may need to be set to the Libreswan NSS database location if it is not located in `/var/lib/ipsec/nss`. The `--enable-libreswan-dh2` switch can be used with libreswan < 3.30 or with libreswan packages built with `USE_DH2=true`, which means having modp1024 support. The presence of these three switches is a good summary of the project, since each one exists to accommodate a specific old dependency rather than a new feature.

## Three distribution recipes differ only in paths and one extra switch

The documentation gives a configure recipe per distribution family, and the differences are worth reading because they are not cosmetic. For Debian sid and Ubuntu 26.04 on AMD64:

```bash
    ./configure \
      --disable-static --prefix=/usr \
      --sysconfdir=/etc --libdir=/usr/lib/x86_64-linux-gnu \
      --runstatedir=/run \
      --with-gtk4
```

For Fedora 43 and later and Red Hat Enterprise Linux 9 and later on x86-64:

```bash
    ./configure \
      --disable-static --prefix=/usr \
      --sysconfdir=/etc --libdir=/usr/lib64 \
      --runstatedir=/run \
      --with-gtk4
```

And for openSUSE Tumbleweed on x86-64:

```bash
    ./configure \
      --disable-static --prefix=/usr \
      --sysconfdir=/etc --libdir=/usr/lib64 \
      --libexecdir=/usr/lib \
      --localstatedir=/var \
      --enable-libreswan-dh2 \
      --with-gtk4
```

The library directory differs between Debian and the RPM distributions, the openSUSE recipe adds the libexec and local state directories and the libreswan dh2 switch, and every recipe passes `--with-gtk4`, which is the user interface library the plugin needs for its authentication dialog. The `auth-dialog/` directory in the repository root is where that dialog lives.

## Profiles are nmconnection files, and everything at run time lands under /var/run

Where the configuration comes from is a decision with a version dimension. VPN connection profile files will be one of the following, with the latter used when Netplan integration is enabled in NetworkManager: `/etc/NetworkManager/system-connections/*.nmconnection` or `/etc/netplan/90-NM-*.yaml`. So the plugin honours the same profile location NetworkManager itself uses, and a deployment that has moved to declarative Netplan configuration gets YAML profiles instead of the keyfile format. The repository root confirms the shape of the project, with `properties/` holding the connection property definitions, `src/` the plugin itself, `shared/` the shared code, `auth-dialog/` the GTK dialog, `po/` the translations, `appdata/` the desktop metadata and `m4/` the autotools macros. The properties directory is the interesting one for an administrator, because a connection type is defined by what properties it accepts, and those definitions are what the desktop UI and the settings file for a profile are generated from. The runtime behaviour is visible in the list of generated files, and it explains the design. The following files located under `/var/run` assume `--localstatedir=/var` or `--runstatedir=/var/run` were supplied to the configure script at build time. They are `/var/run/nm-l2tp-_UUID_/xl2tpd.conf`, `xl2tpd-control`, `xl2tpd.pid`, `ppp-options` and `ipsec.conf`, plus `/etc/ipsec.d/ipsec.nm-l2tp.secrets`, where _UUID_ is the NetworkManager UUID for the VPN connection. Each connection gets its own directory keyed by the connection UUID, which is how two simultaneous L2TP connections do not overwrite each other's daemon configuration. The per-connection `ipsec.conf` and the shared secrets file are how the IPsec side is kept in step with the NetworkManager profile, and the documentation notes that if strongSwan is being used, NetworkManager-l2tp will append the line `include ipsec.d/ipsec.nm-l2tp.secrets` to `/etc/ipsec.secrets` at run-time if the line is missing. The debugging section also notes that running the service with the debug flag prevents the run-time generated config files from being deleted after the VPN connection is disconnected, which is how you keep the generated configuration around to read it.

## Libreswan's NSS database password is an administrator decision, not the plugin's

One configuration detail can stop a machine-certificate connection from working, and the documentation handles it in its own section. The NSS database is used by NetworkManager-l2tp for machine certificate VPN connections using libreswan. The default libreswan database location for libreswan >= 4.0 is `/var/lib/ipsec/nss/`, and that is also the location for all versions of libreswan on Debian and Ubuntu, while older libreswan versions often use `/etc/ipsec.d/`, such as on older versions of RHEL, Fedora and CentOS. The default libreswan package install for most Linux distributions uses an empty password, and it is up to the administrator to decide whether to use a password. However, a non-empty database password must be provided when running in FIPS mode. The documentation links the libreswan page on how to set the password and the syntax for the `/var/lib/ipsec/nss/nsspassword` file where the password is stored. In other words, the plugin inherits the security posture of the IPsec daemon underneath it, including the parts an administrator has to decide.

## Debugging means the journal first, then a debug service run by hand

The troubleshooting path is documented in enough detail to be useful, and it splits by init system. For systemd based Linux distributions logging goes to the systemd journal, which can be viewed by issuing:

```bash
    journalctl --no-hostname _COMM=nm-l2tp-service _COMM=ipsec _COMM=pluto _COMM=charon _COMM=kl2tpd _COMM=xl2tpd _COMM=pppd
```

The unit names in that filter are a compact map of the stack, since `pluto` is the Libreswan daemon and `charon` is the strongSwan one. For non-systemd based distributions, the appropriate system log file should be viewed, which is most likely located under `/var/log/`. To increase debugging output you issue the following on the command line, which also prevents the run-time generated config files from being deleted after the VPN connection is disconnected. On Debian, Ubuntu, Fedora and Red Hat Enterprise Linux that is:

```bash
    sudo killall -TERM nm-l2tp-service
    sudo /usr/libexec/nm-l2tp-service --debug
```

The openSUSE path differs only in the binary location:

```bash
    sudo killall -TERM nm-l2tp-service
    sudo /usr/lib/nm-l2tp-service --debug
```

Then you start your VPN connection and reproduce the problem. On systemd systems you may additionally need `journalctl -b` to see more log output when running the service with the debug flag.

## Each IPsec implementation has its own debug environment variable

Both supported IPsec daemons can be told to say more, and each uses a different variable that maps onto its own configuration option. Libreswan debugging is customised by setting the `PLUTODEBUG` environment variable, which corresponds to the `plutodebug` ipsec.conf config section option, with a syntax that is a white-space separated list of the form `PLUTODEBUG="TYPE TYPE ... TYPE"`, where the type is a debug option from the list output by `ipsec whack --debug list`. strongSwan debugging uses `CHARONDEBUG`, which corresponds to the `charondebug` ipsec.conf config section option, and its syntax is a comma separated list of the form `CHARONDEBUG="TYPE LEVEL, TYPE LEVEL, ..., TYPE LEVEL"`, where the type is one of any, dmn, mgr, ike, chd, job, cfg, knl, net, asn, enc, tnc, imc, imv, pts, tls, esp and lib, and the level is one of -1, 0, 1, 2, 3 or 4. The two formats differ in a way that trips people up, since Libreswan takes space separated keywords with no levels and strongSwan takes comma separated pairs, and a value valid in one is a parse error in the other. The examples in the documentation show both applied to the service binary per distribution.

## The IKEv1 note at the end is the compatibility warning

The last heading in the documentation is a compatibility statement rather than a feature, and it is the one an administrator should read before deploying. Libreswan 5.0 and later, along with earlier versions of Libreswan on some Linux distros, no longer support IKEv1 packets. That is a change in the IPsec implementation underneath the plugin rather than in the plugin itself, but the effect lands on the user, because a corporate L2TP/IPsec gateway that only negotiates IKEv1 will now fail to connect from a machine running a current libreswan. The same mechanism explains the `--enable-libreswan-dh2` switch, since modp1024 is a group that also sits on the legacy side of the IKEv1 world. The IPv6 restriction has the same shape. IPv6 functionality requires kl2tpd or an IPv6-capable fork of xl2tpd, so an installation with stock xl2tpd and an IPv6 address on the tunnel will not work. Both restrictions are properties of the components the plugin drives, which is the honest way to think about this project. It is an integration layer, and it inherits the compatibility envelope of kl2tpd, xl2tpd, libreswan and strongSwan rather than defining one of its own.

## Conclusion

NetworkManager-l2tp is worth deploying if you want L2TP or L2TP over IPsec configured through the desktop network manager rather than by hand, because the plugin writes the daemon configuration at connection time and keeps the profile in one place, and because it supports both user and machine authentication with either credentials or TLS certificates. It is a poor fit if you need IPv6 on an L2TP connection unless you run kl2tpd or an IPv6-capable fork of xl2tpd, and a poor fit if your IKE peer still speaks IKEv1, since Libreswan 5.0 and later no longer support IKEv1 packets by default. Before you deploy it, confirm which of kl2tpd or xl2tpd is installed and that your IPsec implementation is Libreswan or strongSwan, and note that the last push to the repository was on 2026-09-14.

## FAQ

### What does NetworkManager-l2tp provide and which daemons does it need?

It is a VPN plugin for NetworkManager 1.52.2, 1.54.3 or 1.56.0 and later that provides support for L2TP and L2TP over IPsec connections. L2TP support uses either kl2tpd or xl2tpd, and IPsec support uses either Libreswan or strongSwan, so those daemons have to be present on the machine.

### How do I build NetworkManager-l2tp from source?

Run ./autogen.sh, then ./configure and make. The documentation warns that the default configure settings are not reasonable and should be explicitly overridden, giving per-distribution recipes for Debian and Ubuntu, Fedora and RHEL, and openSUSE, all of which pass --with-gtk4 and differ in library and state directories.

### Where are the VPN connection profiles stored for NetworkManager-l2tp?

Profile files are either /etc/NetworkManager/system-connections/*.nmconnection or, with the latter used when Netplan integration is enabled in NetworkManager, /etc/netplan/90-NM-*.yaml. At run time the plugin writes per-connection files under /var/run/nm-l2tp-_UUID_/ including xl2tpd.conf, xl2tpd-control, xl2tpd.pid, ppp-options and ipsec.conf.

### Does the current Libreswan still work with NetworkManager-l2tp?

Yes, but with a compatibility caveat. Libreswan 5.0 and later, along with earlier versions of Libreswan on some Linux distros, no longer support IKEv1 packets, so a gateway that only negotiates IKEv1 will fail to connect. IPv6 functionality also requires kl2tpd or an IPv6-capable fork of xl2tpd.

## Sources

- [Issues](https://github.com/nm-l2tp/NetworkManager-l2tp/issues)
- [License: GPL-2.0](https://github.com/nm-l2tp/NetworkManager-l2tp/blob/main/LICENSE)
- [nm-l2tp/NetworkManager-l2tp on GitHub](https://github.com/nm-l2tp/NetworkManager-l2tp)
- [README](https://github.com/nm-l2tp/NetworkManager-l2tp/blob/main/README.md)
- [Releases](https://github.com/nm-l2tp/NetworkManager-l2tp/releases)

---

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