Secure IPsec/L2TP VPN for on the road android devices
Today people are using more frequently public hotspots, many Cafe, Restaurants and Pubs offer wifi connection for free. Who doesn’t check their Facebook or send a tweet while having an espresso macchiato or enjoying a fresh beer? I guess everyone. The downside of using a public hotspot is that you put your personal data and information at serious risk. Connecting to a public hotspot can expose your data and the system to various attacks, like man in the middle, password sniffing and credential stealing. If we really want protect our data wen we are on the road, we need to use a VPN connection, a VPN is a particular service that encapsulates our network traffic keeping it private. Fortunately android has a standout built-in VPN connection tool that allows to use various VPN technologies, such 2TP/IPSec PSK, PPTP VPNS and many other. In this post i’m going to show how to set up a VPN gateway and connect with your android device safely while using a public hotspot.
First of all you need to have a linux server, in this case I’m using Ubuntu Linux 10.04. A public ip address is required.
You need to install the xl2tpd openswan ppp from the apt repository and then download the newest version from the Ubuntu 11.04 repository, otherwise the VPN won’t work.
apt-get install xl2tpd openswan ppp wget http://se.archive.ubuntu.com/ubuntu/pool/universe/o/openswan/openswan_2.6.28+dfsg-5_i386.deb wget http://ubuntu.linux-bg.org/ubuntu//pool/universe/x/xl2tpd/xl2tpd_1.2.7+dfsg-1_i386.deb dpkg -i openswan_2.6.28+dfsg-5_i386.deb dpkg -i xl2tpd_1.2.7+dfsg-1_i386.deb
In the /etc/ipsec.conf file copy:
config setup
nat_traversal=yes
virtual_private=%v4:10.0.0.0/8,%v4:192.168.0.0/16,%v4:172.16.0.0/12,%v4:!10.152.2.0/24
oe=off
protostack=netkey
conn L2TP-PSK-NAT
rightsubnet=vhost:%priv
also=L2TP-PSK-noNAT
conn L2TP-PSK-noNAT
authby=secret
pfs=no
auto=add
keyingtries=3
rekey=no
ikelifetime=8h
keylife=1h
type=transport
left=x.x.x.x
leftprotoport=17/1701
right=%any
rightprotoport=17/%any
In the /etc/ipsec.secrets file copy:
x.x.x.x %any: PSK "somegoodpassword"
Start the IPSEC service with /etc/init.d/ipsec start
Please verify the IPSEC service with : ipsec verify
you must get no errors.
Checking your system to see if IPsec got installed and started correctly: Version check and ipsec on-path [OK] Linux Openswan U2.6.28/K2.6.32-32-generic-pae (netkey) Checking for IPsec support in kernel [OK] NETKEY detected, testing for disabled ICMP send_redirects [OK] NETKEY detected, testing for disabled ICMP accept_redirects [OK] Checking that pluto is running [OK] Pluto listening for IKE on udp 500 [OK] Pluto listening for NAT-T on udp 4500 [OK] Checking for 'ip' command [OK] Checking for 'iptables' command [OK] Opportunistic Encryption Support [DISABLED]
Create a file called ipsec.vpn in /etc/init.d/
case "$1" in
start)
echo "Starting my Ipsec VPN"
iptables -t nat -A POSTROUTING -o eth0 -s 10.152.2.0/24 -j MASQUERADE
echo 1 > /proc/sys/net/ipv4/ip_forward
for each in /proc/sys/net/ipv4/conf/*
do
echo 0 > $each/accept_redirects
echo 0 > $each/send_redirects
done
/etc/init.d/ipsec start
/etc/init.d/xl2tpd start
;;
stop)
echo "Stopping my Ipsec VPN"
iptables --table nat --flush
echo 0 > /proc/sys/net/ipv4/ip_forward
/etc/init.d/ipsec stop
/etc/init.d/xl2tpd stop
;;
restart)
echo "Restarting my Ipsec VPN"
iptables -t nat -A POSTROUTING -o eth0 -s 10.152.2.0/24 -j MASQUERADE
echo 1 > /proc/sys/net/ipv4/ip_forward
for each in /proc/sys/net/ipv4/conf/*
do
echo 0 > $each/accept_redirects
echo 0 > $each/send_redirects
done
/etc/init.d/ipsec restart
/etc/init.d/xl2tpd restart
;;
*)
echo "Usage: /etc/init.d/ipsec.vpn {start|stop|restart}"
exit 1
;;
esac
Disalble the ipsec default init script with
#update-rc.d -f ipsec remove
And enbable the custom one.
#update-rc.d ipsec.vpn defaults
In the file /etc/xl2tpd/xl2tpd.conf
[global] ipsec saref = no [lns default] ip range = 10.152.2.2-10.152.2.254 local ip = 10.152.2.1 require chap = yes refuse pap = yes require authentication = yes ppp debug = yes pppoptfile = /etc/ppp/options.xl2tpd length bit = yes
In the file /etc/xl2tpd/l2tp-secrets copy:
Choose a good challenge-response authentication string,The secret should, ideally, be 16 characters long, and should probably be longer to ensure sufficient security. There is no minimum length requirement, however.
* * exampleforchallengestring
In the file /etc/ppp/options.xl2tpd copy:
refuse-mschap-v2 refuse-mschap ms-dns 8.8.8.8 ms-dns 8.8.4.4 asyncmap 0 auth lock hide-password local #debug name l2tpd proxyarp lcp-echo-interval 30 lcp-echo-failure 4
In the file /etc/ppp/chap-secrets copy:
Note: you can add as many user you like.
user1 * chooseagoodpassword * user2 * chooseagoodpassword *
Starting the VPN.
/etc/init.d/ipsec.vpn restart
Connecting to the VPN
On the Android mobile:
Go to Settings > Wireless & networks > VPN settings > Add VPN > Add L2TP/IPSec PSK VPN >
VPN name > the name you like
Set VPN server > ip address of the VPN server (x.x.x.x)
Set IPSec pre-shared key > somegoodpassword
Enable L2TP secret > enable
Set L2TP secret > was exampleforchallengestring
Press back, then connect using the PPP username/password (user1 chooseagoodpassword)
Wait for the message VPN connected on the mobile.
Debug.
In case of problems this are a few commands that can help out the debugging.
tcpdump -i ppp0
tail -f /var/log/auth.log
tail -f /var/log/daemon.log
Devices:
So far I’ve tested this configuration on only two devices, the ideos u8150 and the HTC Desire HD.
Scridb filter



27/07/2011 at 12:38 pm Permalink
Hey Phillip,
I always wanted to install an IPSec server, but this is the only good tutorial!
I used the tutorial, copied everything as-it-is just to test if it works.
I got this error, when I try to connect:
Jul 27 14:29:24 server pluto[2899]: packet from 79.xx.xx.xx:500: initial Main Mode message received on 78.xx.xx.xx:500 but no connection has been authorized with policy=PSK
when I restart ipsec, I got this error:
Jul 27 14:36:55 server pluto[3130]: ERROR “/etc/ipsec.secrets” line 12: index “x.x.x.x” does not look numeric and name lookup failed
Can you give any advise on this issue? Thx!
27/07/2011 at 1:36 pm Permalink
Hi Alex,
what you have at the line nr 20 of ipsec.conf ? The local ip address ?
try to take a look in the ipsec.secrets file, must be something like this
192.168.1.1 %any: PSK “blablablabla”
where 192.168.1.1 is the local ipsec server and blablablabla is the key.
27/07/2011 at 2:00 pm Permalink
Thx! It was the ipsec.conf I missed. Thank you very much!
27/07/2011 at 2:03 pm Permalink
Glad that my hint was helpful.
Phillip
30/07/2011 at 7:22 am Permalink
I have VPN connection success with a Google Nexus S running Android 2.3.4 with no special enhancements (not rooted, no one else’s ROMs, just a nice pure Google Gingerbread Android setup for Nexus S), and OpenSwan running on an Ubuntu 9.10 machine as:
> Linux Openswan U2.6.28/K2.6.31-22-generic (netkey)
My Ubuntu 9.10 machine is behind a router that is NATed. I’m using a cable modem ISP with dynamic IP (so I use Dynamic DNS). On my router I port forward IKE UDP 500 and NAT-T 4500 to my Ubuntu server. The only difference is that I don’t use L2TP secrets (I have L2TP to defer to PPP with CHAP) … too many secrets and passwords for a person to try and remember (first for pre-shared key with IPSec authentication to establish the tunnel, then another for L2TP, then another with PPP — ugh!). I am very excited about trying this out with by replacing IPSec pre-shared key with certificates (not only is it doable with OpenSwan on the server side but also with Android with its built-in VPN client)!
17/08/2011 at 1:45 am Permalink
Phillip – thanks for the great walkthrough!
I’ve had issues using certs w/ android and openswan, so I thought I’d take a step back and try PSK.
I setup a 10.04 box just to make sure I’m on the exact same page as you.
The only difference I have between what you’ve done above and what I did:
1. This is a 64 bit box so I used the amd64 packages instead of the i386.
2. xl2tpd 1.2.8 was released, so I opted for it instead of .7.
And of course my passwords are all different from yours (to keep it simple, I put testpassword in all three spots).
On my android I keep getting “Challenge Error. Do you want to check your secret setting?”
I’ve re-entered them and double-checked them when I was entering them several times now.
I know it’s getting past the ipsec psk, because if I change that password on the phone I see:
pluto[3993]: “L2TP-PSK-NAT”[1] 192.168.1.151 #7: probable authentication failure (mismatch of preshared secrets?): malformed payload in packet
pluto[3993]: | payload malformed after IV
pluto[3993]: | 48 c2 62 f4 8e 20 3e 5c ad e3 57 5e 12 55 40 dd
pluto[3993]: | 4a d1 c9 3f
and the connection hangs for a bit on the phone before it gives up.
When I purposely trash the L2TP secret the behavior is just the same as when I enter the correct password, so I suspect it’s failing on that secret, but I’m not seeing anything in the logs to indicate the problem.
What are my next steps for debugging this?
Thanks again, you rock!
28/08/2011 at 12:04 am Permalink
Hi Phillip,
My pppd reports “peer refuse to authenticate: terminating link”
Any hints?
17/12/2011 at 11:47 pm Permalink
Hi Phillip,
Thank you for the great tutorial. I have set up a VPN server based on your tutorial and it woks very well on my Android (Huawei Ideos U8150-D) running Android 2.2 (Frodo). Deviating from your how-to I needed to disable the “Enable L2TP secret” on the Android settings (no check, option not active).
What surprises me is that my girlfriends iPhone 4 can’t establish a reliable VPN through L2TP. By the way, my server is based on the latest Debian Squeeze.
Does anybody have any ideas what might be the problem of the iPhone? By the way, it sometimes works – but most times doesn’t.
Thank you
Sven
18/12/2011 at 4:53 pm Permalink
Thank you for the great tutorial. I have established my VPN server based on Debian Squeeze and it works great with Android (I have a Android 2.2/Frodo mobile phone).
What surprises me: It doesn’t work at all with my girlfriends iPhone. Does anybody have any suggestion what I need to change in order to make it work with iOS?
Thank you
Sven
27/12/2011 at 5:27 pm Permalink
Hi Phillip,
I’ve tried your configuration but from strange reason it can’t work for me.
I’m using private network : if wlan0 .. my local adress is 192.168.1.2 (router address 192.168.1.1) .. so i changed your configuration regarding my as :
apt-get install xl2tpd openswan ppp
wget http://se.archive.ubuntu.com/ubuntu/pool/universe/o/openswan/openswan_2.6.28+dfsg-5_amd64.deb
wget http://ubuntu.linux-bg.org/ubuntu//pool/universe/x/xl2tpd/xl2tpd_1.2.7+dfsg-1_amd64.deb
dpkg -i openswan_2.6.28+dfsg-5_amd64.deb
dpkg -i xl2tpd_1.2.7+dfsg-1_amd64.deb
In the /etc/ipsec.conf file copy:
config setup
nat_traversal=yes
virtual_private=%v4:10.0.0.0/8,%v4:192.168.0.0/16,%v4:172.16.0.0/12,%v4:!192.168.1.0/24
oe=off
protostack=netkey
conn L2TP-PSK-NAT
rightsubnet=vhost:%priv
also=L2TP-PSK-noNAT
conn L2TP-PSK-noNAT
authby=secret
pfs=no
auto=add
keyingtries=3
rekey=no
ikelifetime=8h
keylife=1h
type=transport
left=192.168.1.2
leftprotoport=17/1701
right=%any
rightprotoport=17/%any
In the /etc/ipsec.secrets file copy:
192.168.1.2 %any: PSK “somegoodpassword”
Start the IPSEC service with /etc/init.d/ipsec start
i see :
Version check and ipsec on-path [OK]
Linux Openswan U2.6.28/K2.6.38-12-generic (netkey)
Checking for IPsec support in kernel [OK]
NETKEY detected, testing for disabled ICMP send_redirects [OK]
NETKEY detected, testing for disabled ICMP accept_redirects [OK]
Checking that pluto is running [OK]
Pluto listening for IKE on udp 500 [OK]
Pluto listening for NAT-T on udp 4500 [OK]
Two or more interfaces found, checking IP forwarding [OK]
Checking NAT and MASQUERADEing
Checking for ‘ip’ command [OK]
Checking for ‘iptables’ command [OK]
Opportunistic Encryption Support [DISABLED]
Create a file called ipsec.vpn in /etc/init.d/
case “$1″ in
start)
echo “Starting my Ipsec VPN”
iptables -t nat -A POSTROUTING -o wlan0 -s 192.168.1.0/24 -j MASQUERADE
echo 1 > /proc/sys/net/ipv4/ip_forward
for each in /proc/sys/net/ipv4/conf/*
do
echo 0 > $each/accept_redirects
echo 0 > $each/send_redirects
done
/etc/init.d/ipsec start
/etc/init.d/xl2tpd start
;;
stop)
echo “Stopping my Ipsec VPN”
iptables –table nat –flush
echo 0 > /proc/sys/net/ipv4/ip_forward
/etc/init.d/ipsec stop
/etc/init.d/xl2tpd stop
;;
restart)
echo “Restarting my Ipsec VPN”
iptables -t nat -A POSTROUTING -o wlan0 -s 192.168.1.0/24 -j MASQUERADE
echo 1 > /proc/sys/net/ipv4/ip_forward
for each in /proc/sys/net/ipv4/conf/*
do
echo 0 > $each/accept_redirects
echo 0 > $each/send_redirects
done
/etc/init.d/ipsec restart
/etc/init.d/xl2tpd restart
;;
*)
echo “Usage: /etc/init.d/ipsec.vpn {start|stop|restart}”
exit 1
;;
esac
Disalble the ipsec default init script with
#update-rc.d -f ipsec remove
And enbable the custom one.
#update-rc.d ipsec.vpn defaults
In the file /etc/xl2tpd/xl2tpd.conf
[global]
ipsec saref = no
[lns default]
ip range = 192.168.1.3-192.168.1.254
local ip = 192.168.1.2
require chap = yes
refuse pap = yes
require authentication = yes
ppp debug = yes
pppoptfile = /etc/ppp/options.xl2tpd
length bit = yes
In the file /etc/xl2tpd/l2tp-secrets copy:
Choose a good challenge-response authentication string,The secret should, ideally, be 16 characters long, and should probably be longer to ensure sufficient security. There is no minimum length requirement, however.
* * exampleforchallengestring
In the file /etc/ppp/options.xl2tpd copy:
refuse-mschap-v2
refuse-mschap
ms-dns 8.8.8.8
ms-dns 8.8.4.4
asyncmap 0
auth
lock
hide-password
local
#debug
name l2tpd
proxyarp
lcp-echo-interval 30
lcp-echo-failure 4
In the file /etc/ppp/chap-secrets copy:
Note: you can add as many user you like.
user1 * chooseagoodpassword *
user2 * chooseagoodpassword *
Starting the VPN.
/etc/init.d/service ipsec.vpn restart
Everything seems to be ok but i’m unable to connect with my HTC Wildfire S .. Any idea where can be the problem ?
03/01/2012 at 9:36 am Permalink
I would love a walk through for making L2TP IPSec for iOS devices.
http://developer.apple.com/library/ios/#featuredarticles/FA_VPN_Server_Configuration_for_iPhone_OS/Introduction/Introduction.html
Apparently iOS needs MS-CHAPV2
03/02/2012 at 2:43 pm Permalink
Hello,
when starting the Server, I get:
tail -f /var/log/auth.log
Feb 3 15:40:59 VDR pluto[5215]: NAT-Traversal: ESPINUDP(1) setup failed for new style NAT-T family IPv4 (errno=19)
Feb 3 15:40:59 VDR pluto[5215]: NAT-Traversal: Trying old style NAT-T
Feb 3 15:40:59 VDR pluto[5215]: adding interface eth0/eth0 192.168.178.20:500
Feb 3 15:40:59 VDR pluto[5215]: adding interface eth0/eth0 192.168.178.20:4500
Feb 3 15:40:59 VDR pluto[5215]: adding interface lo/lo 127.0.0.1:500
Feb 3 15:40:59 VDR pluto[5215]: adding interface lo/lo 127.0.0.1:4500
Feb 3 15:40:59 VDR pluto[5215]: adding interface lo/lo ::1:500
Feb 3 15:40:59 VDR pluto[5215]: loading secrets from “/etc/ipsec.secrets”
Feb 3 15:40:59 VDR pluto[5215]: ERROR “/etc/ipsec.secrets” line 14: index “x.x.x.x” does not look numeric and name lookup failed
Feb 3 15:40:59 VDR pluto[5215]: “/etc/ipsec.secrets” line 14: unterminated string
Any Ideas?
Greetings,
Hendrik