How to get IPSEC/L2TP VPN working on Ubuntu with network manager GUI:
This is already documented, you can follow the following post:
http://blog.z-proj.com/enabling-l2tp-over-ipsec-on-ubuntu-16-04/
Just a note on the above post, I did not install custom xl2tpd version like mentioned in the above post on my Lubuntu 16.04 box and I went with the stock xl2tpd provided in the repos and it worked fine. In fact I did not compile anything, apart from using the PPA and installing whatever it pulled in.
In this post I will detail how I used Debian 9 to connect to corporate VPN based on IPSEC/L2TP from the CLI.
The other VPNs which can be connected using OpenVPN and Cisco Openconnect are fairly straight forward to work with and I never had any trouble with them before. But some organizations that we work with use this type of VPN. I wanted to achieve this without any GUI and using only CLI as I have stopped using Network-Manager.
Further, I wanted to make this work on both FreeBSD and Debian as these are my OSs of choice. Network Manager does not support FreeBSD yet.
Note that FreeBSD 11 and onward has kernel support built in for this VPN stack/protocol, in older releases you will need to use a custom kernel with patches applied to get this working. I will focus on Debian 9 in this post and perhaps the next post will be on FreeBSD 11, if I get it working.
I have tried real hard to make it work using CLI tools, but it did not work causing much frustration, so I used Lubuntu 16.04 VM to connect using the GUI and get the content of the config files which worked and mirror the config setup on the other VMs, along with the help from different posts shared below in references.
How to get IPSEC/L2TP VPN working on Debain 9:
The IT guy provided me with:
A username and password, my LDAP and account details.
The URL of the VPN to connect to.
A secret/PSK(pre shared key).
What I need in addition to above was the hash, encryption scheme used, etc which we will collect below, other than these I used the default values provided by the respective software.
As root install:
root shell> apt-get install -y strongswan xl2tp ppp ike-scan
ike-scan is for determining the remote VPN server settings related to authentication.
Run it on the target server, where you need to connect:
root shell> ike-scan YOUR_VPN_URL_OR_IP_HERE.COM
Starting ike-scan 1.9.4 with 1 hosts (http://www.nta-monitor.com/tools/ike-scan/)
3x.xxx.xxx.xxx Main Mode Handshake returned HDR=(CKY-R=e7f46fcf375e22e3) SA=(Enc=3DES Hash=SHA1 Auth=PSK
Group=2:modp1024 LifeType=Seconds LifeDuration(4)=0x00007080)
Ending ike-scan 1.9.4: 1 hosts scanned in 0.635 seconds (1.58 hosts/sec). 1 returned handshake; 0 returned notify
You will need the above details to configure strongswan/openswan/libreswan:
Edit /etc/ipsec.conf, add following, I am pasting the snippet from my configuration:
config setup
# strictcrlpolicy=yes
# uniqueids = no
# Add connections here.
conn myvpn
auto=add
type=transport
authby=psk
keyingtries=0
left=%defaultroute
leftprotoport=udp/l2tp
right=3x.xxx.xxx.xxx
rightid=%any
rightprotoport=udp/l2tp
keyexchange=ikev1
ike=3des-sha1-modp1024
esp=3des-sha1
Values for ike and esp vary according to the setup, use ike-scan to determine these and/or consult the IT person to get these, if all fails, connect from GUI and check the values after successful connection.
Next edit and add the pre-shared key(PSK/secret) /etc/ipsec.secrets:
Important! Ensure you echo the line instead of manually adding it, I have spent few days debugging around when I manually edited the file!
root shell> echo ': PSK "YOUR_PSK_OR_SECRET_HERE"' >> /etc/ipsec.secrets
You can now test whether this work by restarting strongswan service:
root shell> systemctl -u strongswan.service
In another terminal check the logs using
root shell> journalctl -u strongswan.service
Jan 13 15:06:14 debian charon[6503]: 00[LIB] dropped capabilities, running as uid 0, gid 0
Jan 13 15:06:14 debian charon[6503]: 00[JOB] spawning 16 worker threads
Jan 13 15:06:14 debian ipsec[6489]: charon (6503) started after 20 ms
Jan 13 15:06:14 debian ipsec_starter[6489]: charon (6503) started after 20 ms
Jan 13 15:06:14 debian charon[6503]: 05[CFG] received stroke: add connection 'myvpn'
Jan 13 15:06:14 debian charon[6503]: 05[CFG] added configuration 'myvpn'
Now run
root shell> ipsec status
Security Associations (0 up, 0 connecting):
none
root shell> ipsec up myvpn
.
.
.
sending packet: from 10.0.2.15[4500] to 3x.xxx.xxx.xxx[4500] (220 bytes)
received packet: from 3x.xxx.xxx.xxx[4500] to 10.0.2.15[4500] (172 bytes)
parsed QUICK_MODE response 150100366 [ HASH SA No ID ID NAT-OA NAT-OA ]
connection 'myvpn' established successfully
In the other terminal where journalctl -u strongswan.service, you should see something like:
Jan 13 15:08:26 debian charon[6503]: 06[NET] received packet: from 3x.xxx.xxx.xxx[4500] to 10.0.2.15[4500] (92 bytes)
Jan 13 15:08:26 debian charon[6503]: 06[ENC] parsed ID_PROT response 0 [ ID HASH V ]
Jan 13 15:08:26 debian charon[6503]: 06[IKE] received DPD vendor ID
Jan 13 15:08:26 debian charon[6503]: 06[IKE] IKE_SA myvpn[1] established between 10.0.2.15[10.0.2.15]...3x.xxx.xxx.xxx[3x.xxx.xxx.xxx]
Jan 13 15:08:26 debian charon[6503]: 06[IKE] IKE_SA myvpn[1] established between 10.0.2.15[10.0.2.15]...3x.xxx.xxx.xxx[3x.xxx.xxx.xxx]
Check the status with ipsec status/statusall:
root shell> ipsec status
Security Associations (1 up, 0 connecting):
myvpn[1]: ESTABLISHED 3 minutes ago, 10.0.2.15[10.0.2.15]...3x.xxx.xxx.xxx[3x.xxx.xxx.xxx]
myvpn{1}: INSTALLED, TRANSPORT, reqid 1, ESP in UDP SPIs: c641102f_i 03118698_o
myvpn{1}: 10.0.2.15/32[udp/l2f] === 3x.xxx.xxx.xxx/32[udp/l2f]
Now, stop the service and move on with configuring other components.
Configure xl2tpd:
Edit file /etc/xl2tpd/xl2tpd.conf:
[global]
access control = yes
port = 1701
[lac l2tp]
lns = 3x.xxx.xxx.xxx
pppoptfile = /etc/ppp/ppp-options.opts
autodial = yes
tunnel rws = 8
Now edit file /etc/ppp/ppp-options.opts, you can change the location to something else.
nodetach
usepeerdns
noipdefault
nodefaultroute
noauth
noccp
refuse-eap
refuse-chap
refuse-mschap
refuse-mschap-v2
lcp-echo-failure 0
lcp-echo-interval 0
mru 1400
mtu 1400
user YOUR_LDAP_USERNAME_OR_ACCOUNTANME_GIVEN_BY_IT
password YOUR_ACCOUNT_OR_LDAP_PASSWORD_PROVIDED
Once done start strongswan first then run ipsec up command like above and start xl2tpd service, so as in one line:
systemctl start strongswan.service ; sleep 3; ipsec up myvpn; systemctl start xl2tpd.service
Check whether the connection got established using ipsec statusall.
To stop, run:
systemctl stop xl2tpd.service ; ipsec down myvpn; systemctl stop strongswan.service;
The VPN got setup by we need to add the routing tables inorder for the traffic to flow in and out of VPN:
As root user:
route add 3x.xxx.xxx.xxx gw 10.0.2.2
route add default dev ppp0
So in general:
route add VPN-PUBLIC-IP gw LOCAL-NIC-IP
route add default dev pppX
Here 10.0.2.2 is the local IP my VM received from NAT of Virtalbox service, in your case change this accordingly.
Check using a fetch/curl/wget command and you should see the the public IP address of the remote network, like:
wget -qO- https://canihazip.com/s
or,
curl https://canihazip.com/s
To change back to non-VPN setup:
1. Change routing table to what it was before,
2. Stop xl2tpd and strongswan services.
To delete the added routes:
route del default dev ppp0
route del 3x.xxx.xxx.xxx gw 10.0.2.2
To understand what happens, before you configure, check the routing tables and current network setup on your local machine, this is just to get an understanding, or for troubleshooting the setup, not necessary for the actual setup.
Pre-connection routing table:
$ netstat -nr4
Kernel IP routing table
Destination Gateway Genmask Flags MSS Window irtt Iface
0.0.0.0 10.0.2.2 0.0.0.0 UG 0 0 0 enp0s3
10.0.2.0 0.0.0.0 255.255.255.0 U 0 0 0 enp0s3
192.168.56.0 0.0.0.0 255.255.255.0 U 0 0 0 enp0s8
$ ip route
default via 10.0.2.2 dev enp0s3 proto static metric 100
10.0.2.0/24 dev enp0s3 proto kernel scope link src 10.0.2.15 metric 100
192.168.56.0/24 dev enp0s8 proto kernel scope link src 192.168.56.8 metric 100
Network address/link/device configuration:
$ ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: enp0s3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 08:00:27:85:30:8b brd ff:ff:ff:ff:ff:ff
inet 10.0.2.15/24 brd 10.0.2.255 scope global dynamic enp0s3
valid_lft 78860sec preferred_lft 78860sec
inet6 fe80::a00:27ff:fe85:308b/64 scope link
valid_lft forever preferred_lft forever
3: enp0s8: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 08:00:27:67:7e:ad brd ff:ff:ff:ff:ff:ff
inet 192.168.56.8/24 brd 192.168.56.255 scope global enp0s8
valid_lft forever preferred_lft forever
inet6 fe80::a00:27ff:fe67:7ead/64 scope link
valid_lft forever preferred_lft forever
Compare the above output to routing/networking information after connection.
Post connection routing table:
$ ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: enp0s3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 08:00:27:85:30:8b brd ff:ff:ff:ff:ff:ff
inet 10.0.2.15/24 brd 10.0.2.255 scope global dynamic enp0s3
valid_lft 78910sec preferred_lft 78910sec
inet6 fe80::a00:27ff:fe85:308b/64 scope link
valid_lft forever preferred_lft forever
3: enp0s8: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 08:00:27:67:7e:ad brd ff:ff:ff:ff:ff:ff
inet 192.168.56.8/24 brd 192.168.56.255 scope global enp0s8
valid_lft forever preferred_lft forever
inet6 fe80::a00:27ff:fe67:7ead/64 scope link
valid_lft forever preferred_lft forever
4: ppp0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1400 qdisc pfifo_fast state UNKNOWN group default qlen 3
link/ppp
inet 10.12.14.147 peer 192.0.2.1/32 scope global ppp0
valid_lft forever preferred_lft forever
$ netstat -nr4
Kernel IP routing table
Destination Gateway Genmask Flags MSS Window irtt Iface
0.0.0.0 0.0.0.0 0.0.0.0 U 0 0 0 ppp0
0.0.0.0 10.0.2.2 0.0.0.0 UG 0 0 0 enp0s3
10.0.2.0 0.0.0.0 255.255.255.0 U 0 0 0 enp0s3
3x.xxx.xxx.xxx 10.0.2.2 255.255.255.255 UGH 0 0 0 enp0s3
192.0.2.1 0.0.0.0 255.255.255.255 UH 0 0 0 ppp0
192.168.56.0 0.0.0.0 255.255.255.0 U 0 0 0 enp0s8
$ ip route
default dev ppp0 proto static scope link metric 50
default via 10.0.2.2 dev enp0s3 proto static metric 100
10.0.2.0/24 dev enp0s3 proto kernel scope link src 10.0.2.15 metric 100
3x.xxx.xxx.xxx via 10.0.2.2 dev enp0s3 proto static metric 100
192.0.2.1 dev ppp0 proto kernel scope link src 10.12.14.147 metric 50
192.168.56.0/24 dev enp0s8 proto kernel scope link src 192.168.56.8 metric 100
Edit (on 13 August 2018):
I created a crude shell script to make it simple to connect and disconnect, it has some issues, the connection sometimes is not established due to missing records. I have to run it again to get it connect.
#!/bin/sh
start_oh() {
echo "Starting VPN services.."
systemctl start strongswan.service && sleep 1 && ipsec up oh && systemctl start xl2tpd.service;
echo "Adding required routing records.."
sleep 1
route add 38.88.227.130 gw 10.0.2.2
sleep 1
route add default dev ppp0
echo "OH VPN started.."
return 0
}
stop_oh() {
echo "removing the VPN routing records.."
route del default dev ppp0
sleep 1
route del 38.88.227.130 gw 10.0.2.2
systemctl stop xl2tpd.service && ipsec down oh && sleep 1 && systemctl stop strongswan.service
echo "OH VPN stopped.."
return 0
}
case $1 in
start) start_oh ;;
stop) stop_oh ;;
restart) stop_oh && start_oh;;
*) echo "Invalid command" ;;
esac
References:
https://wiki.archlinux.org/index.php/Openswan_L2TP/IPsec_VPN_client_setup
http://www.jasonernst.com/2016/06/21/l2tp-ipsec-vpn-on-ubuntu-16-04/
https://libreswan.org/wiki/VPN_server_for_remote_clients_using_IKEv1_with_L2TP