l2tp support in Ubuntu 16

Here’s the best step-by-step:

L2TP / IPSEC VPN on Ubuntu 16.04

Here’s another step-by-step that had some mismatched text strings that kind of wrecked stuff: https://gist.github.com/psanford/42c550a1a6ad3cb70b13e4aaa94ddb1c

Meraki doesn’t have much in the way of documentation on setting up the client VPN on Linux servers. They have something for a Linux distro running a GUI: https://documentation.meraki.com/MX-Z/Client_VPN/Configuring_Client_VPN_in_Linux

Here is something about gettig the l2tp vpn client to work in a clean way on a Linux GUI. Again, not applicable for pure Linux servers though: http://blog.z-proj.com/enabling-l2tp-over-ipsec-on-ubuntu-16-04/

Here’s my step-by-step that works on a fresh Ubuntu 16 install and pointed at a Cisco Meraki MX64. It includes a means of keeping the connection alive by using the monit utility:

Install the packages we will need
You’ll have to sudo up to root to install all this stuff

apt-get update
apt-get install -y strongswan xl2tpd

Configure strongswan
Note: this “cat >…..” method replaces the file with the contents that follow. You can kind of script the whole config part that way

cat > /etc/ipsec.conf <

Configure the preshared key
Note: you could just edit the file, so we don’t have the shared key sitting in a Google doc history
In that case, just add a line in/etc/ipsec.secrets that says:
nano /etc/ipsec.secrets
: PSK “pskgoeshere”
You may have to redo the double-quotes… google docs tries to be helpful
And, yes, that colon at the beginning of the line is necessary

cat > /etc/ipsec.secrets < /etc/xl2tpd/xl2tpd.conf <
ppp debug = yes
pppoptfile = /etc/ppp/options.l2tpd.client
length bit = yes

cat > /etc/ppp/options.l2tpd.client < ” > /var/run/xl2tpd/l2tp-control
Redo the double-quotes. Google docs screws these up bad

How to [un]format the Google Docs "Smart Quotes" italicized quotes

When this works you should see a new interface when you look at the local routing table
route -n
The first one resolves DNS; the second doesn’t
You should see something like this:

Notice the middle one, and on the right-most column is has “ppp0″…. That’s what you want.
If you don’t see it, wait 5-10 seconds and check again, then rerun that above “echo…..” command again.

When this works, you should see another connection in ifconfig
You should see something like this:

Notice the “ppp0” connection. It’s not there until after you run that above “echo…..” command. This is the actual VPN connection

Set up a route so we actually use the VPN interface
A few steps here, and I’ll show things with what I actually saw
The goal is to set a route that sends all traffic destined for addresses through the VPN connection.

Get the IP address of the local VPN interface
You need to get the IP address listed right after “P-t-P” in the “ppp0” interface

Add the route
route add -net gw
This makes the OS send all network traffic destined for any IP that starts with “10.x.x.x” through the interface, which means it goes through the VPN tunnel and to the Meraki VPN server, which then routes it as needed.

Disconnect the VPN
echo “d meraki-vpn” > /var/run/xl2tpd/l2tp-control
ipsec down meraki-vpn

Connect the VPN
ipsec up meraki-vpn
echo “c meraki-vpn ” > /var/run/xl2tpd/l2tp-control

Making sure the VPN connection stays active
Latest: monit seems to be a viable means of making sure the vpn connection is stable.

Install monit
apt install monit

Create a config file aimed at monitoring our VPN connection
nano /etc/monit/conf.d/monitor_vpn
In there use the following:
check network ppp0 with interface ppp0
start program = “/bin/bash -c ‘/p4proxy_bh/start_vpn.sh'”
stop program = “/bin/bash -c ‘/p4proxy_bh/stop_vpn.sh'”
if failed link then restart

Create the referenced scripts
nano /p4proxy_bh/start_vpn.sh
ipsec up meraki-vpn
sleep 5
echo “c meraki-vpn ” > /var/run/xl2tpd/l2tp-control
sleep 5
route add -net gw

nano /p4proxy_bh/stop_vpn.sh
echo “d meraki-vpn” > /var/run/xl2tpd/l2tp-control
sleep 5
ipsec down meraki-vpn
sleep 5
route delete -net gw

What this does:
The first “ppp0” in that monit config file is actually the name of the monitor…you could name it anything (used with “monit start ppp0” to manually run the monitor)
It’s saying if there is no interface by the name of “ppp0”, as would be the case when the VPN connection is down, then “restart”… in monit terms, “restart” = run the “stop program” and then the “start program” specs. It then also sets the route, just in case.

Monit wakes up and runs all the configured monitors every 2 minutes

monit status
Shows the last result of each monitor
This worked to successfully and easily detect that the VPN tunnel interface was down and automatically restart it.

Biggest Fail
All the “meraki-vpn” strings refer to each other. Some guides had inconsistent string names. The “conn” name and the “[Lac]” had to use the same string, in this case “meraki-vpn”.
Google Docs changes double quotes to fancy italicized ones, and when copied and pasted into a Linux terminal, they are technically *not* double-quotes, so your commands fail in all kinds of fun and interesting ways. Disable it: https://workwith.natfinn.com/google-docs-smart-quotes-suck-ass/
There is a package you can now install that makes l2tp stuff much easier on Ubuntu desktop-with-a-GUI, but that won’t really work on command-line-only servers.

Here’s a message seen in “journalctl -xe” when nothing happens when you try to start the l2tp part (the “echo c….” command):
Aug 23 09:42:09 vpntest charon[1296]: 02[NET] sending packet: from[4500] to xxxxxxxxxx[4500] (60 bytes)
Aug 23 09:42:14 vpntest xl2tpd[1702]: Maximum retries exceeded for tunnel 3074. Closing.
Aug 23 09:42:14 vpntest xl2tpd[1702]: Connection 0 closed to xxxxxxxxx, port 1701 (Timeout)
Aug 23 09:42:19 vpntest xl2tpd[1702]: Unable to deliver closing message for tunnel 3074. Destroying anyway.
Aug 23 09:42:38 vpntest charon[1296]: 15[IKE] sending keep alive to xxxxxxxxxxx[4500]

A reboot of the VPN server on the MX64 resolved this.

Helpful debugging commands to use on the client
journalctl -xe
“Charon” messages are from ipsec (strongswan)
“Xl2tpd” messages are from xl2tp

/usr/sbin/xl2tpd -D
Can show xl2tpd-specific things