This howto describes setting up a LT2P over IPsec VPN server on your router with TomatoUSB firmware. This should allow you to connect using the built-in client to your Mac, iPhone or Android device. (Not sure about Windows.)
At the end of this tutorial, you should have a L2TP/IPsec VPN server that starts automatically on boot. Mac/iPhone/Android devices can connect with their native client and will be assigned an IP address within your LAN subnet. They should be able to talk to other devices on your LAN and should be able to contact hosts on the Internet NAT'd behind your WAN IP address.
- Router running Shibby's fork of TomatoUSB
- entware installed to a USB stick mounted at /opt (howto)
- Shibby's kernel module extras installed at /opt/extras (howto)
- Dynamic DNS properly configured
- Shibby's fork of TomatoUSB version 1.28 build 121
- ASUS RT-N66U
Place the following in /opt/etc/init.d/S01extras:
#!/bin/sh
# Load the ipsec modules
modprobe /opt/extras/ipsec/af_key # racoon
modprobe /opt/extras/ipsec/esp4 # racoon
modprobe /opt/extras/ipsec/xfrm4_mode_transport # racoon <-> xl2tpd
modprobe /opt/extras/ipsec/xfrm_user # ip xfrm policy
And make the script executable:
chmod 0644 /opt/etc/init.d/S01extras
This script will be executed upon boot by entware.
We need to open up ports for IPsec (udp 4500, 500) and for L2TP (udp 1701). We also need to manually set the policy for clients behind NAT. Apparently racoon generates the wrong policy (reference).
To automatically setup the firewall and policy rules for L2TP/IPsec, place the following in /opt/bin/post_firewall:
#!/bin/sh
# Add the IPsec/L2TP rules if they have not already been added
iptables-save | grep -- "-A INPUT -p udp -m udp --dport 500 -j ACCEPT" > /dev/null
if [ $? = 1 ]; then
# Allow IPSEC connections
iptables -A INPUT -p udp -m udp --dport 500 -j ACCEPT
iptables -A INPUT -p udp -m udp --dport 4500 -j ACCEPT
# Allow L2TP connections
iptables -A INPUT -p udp -m udp --dport 1701 -j ACCEPT
fi
# If the logdrop rule exists, we need to move it to the end
# - This helps if our manual rules were added (above).
# - This also fixes what appears to be a Tomato bug. With some services,
# like the PPTP server, their rules will be placed after the logdrop
# rule. The result is incorrectly dropping packets for valid services.
iptables-save | grep -- "-A INPUT -j logdrop" > /dev/null
if [ $? = 0 ]; then
# Get the number of the logdrop rule in the INPUT chain
LINENUM=`iptables -L INPUT|grep -nr logdrop|cut -f 1 -d :`
RULENUM=`expr $LINENUM - 2`
# Delete the logdrop rule from the INPUT chain
iptables -D INPUT $RULENUM
# Readd the logdrop rule at the end of the INPUT chain
iptables -A INPUT -j logdrop
fi
# Set manual policy (this is needed for clients behind nat, because racoon generates the wrong policy)
#
# Source: http://tomatousb.org/forum/t-625093/ipsec-l2tp-racoon-xl2tpd-tomato-shibby-asus-rt-n16
myServer=`nvram get wan_ipaddr`
ip xfrm policy add src $myServer dst 0.0.0.0/0 proto udp sport 1701 dir out tmpl proto esp mode transport level required
ip xfrm policy add src 0.0.0.0/0 dst $myServer proto udp dport 1701 dir in tmpl proto esp mode transport level required
And then make the script executable:
chmod 0644 /opt/bin/post_firewall
In the web GUI, go to Administration->Scripts. In the "Firewall" tab, paste the following:
/opt/bin/post_firewall
NOTE: The correct rule for L2TP appears to be:
iptables -I INPUT -p udp -m policy --dir in --pol ipsec -m udp --dport 1701 -j ACCEPT
However, there is something missing in the kernel used by Shibby Tomato. When I run the above command, I get the error, "iptables: No chain/target/match by that name". I believe we are missing the xt_policy kernel module. Anyway, as a work around, the post_firewall script just allows all UDP packets on port 1701. This is less slightly secure, but should not be an issue.
By default, dnsmasq responds to DNS queries only on your local LAN interface. Now that we have VPN clients connecting, we need to tell dnsmasq to respond to DNS queries on the pppX interfaces too.
In the web GUI, click on the Advanced->DHCP/DNS section. Add the following to the "Dnsmasq Custom configuration" text input box":
interface=ppp0,ppp1,ppp2,ppp3,ppp4,ppp5,ppp6,ppp7,ppp8,ppp9
no-dhcp-interface=ppp0,ppp1,ppp2,ppp3,ppp4,ppp5,ppp6,ppp7,ppp8,ppp9
Install the ipsec-tools package. This includes the racoon daemon responsible for IPsec.
opkg install ipsec-tools
Replace the contents of /opt/etc/racoon/psk.txt with the following:
# * is a wildcard, means any IP address
* this_is_my_pre_shared_key
Change "this_is_my_pre_shared_key" to something unique. This is the pre-shared key (also known as a shared secret) that you will enter into your client configs.
Make the file readable only by root:
chmod 0600 /opt/etc/racoon/psk.txt
Replace the contents of /opt/etc/racoon.conf with:
path pre_shared_key "/opt/etc/racoon/psk.txt";
remote anonymous
{
exchange_mode main;
nat_traversal on;
generate_policy on;
proposal_check obey; # obey, strict, or claim
proposal {
encryption_algorithm 3des;
hash_algorithm sha1;
authentication_method pre_shared_key;
dh_group 2;
}
}
sainfo anonymous
{
encryption_algorithm aes;
authentication_algorithm hmac_sha1;
compression_algorithm deflate;
}
I had trouble overriding the configuration of Tomato's built-in pppd. So, I installed the entware version. Do this with:
opkg install ppp
However, the entware version apparently does not have the necessary pppol2tp.so plugin. The Shibby built-in pppd does have this plugin, so link to it:
cd /opt/lib/pppd/2.4.5
ln -s /usr/lib/pppd/pppol2tp.so
Create a file called /opt/etc/ppp/chap-secrets with the following contents:
# USERNAME PROVIDER PASSWORD IPADDRESS
user1 * password_for_user1 *
user2 * password_for_user2 *
Set the user names and passwords for all the users that you want to be able to login remotely to the VPN. Add as many users to this file as needed.
Restrict the permissions of this file ot only root:
chmod 0600 /opt/etc/ppp/chap-secrets
Run the following command to install the xl2tpd package:
opkg install xl2tpd
Replace the contents of /opt/etc/xl2tpd/xl2tpd.conf with:
[global]
port = 1701
access control = no
ipsec saref = yes
;debug avp = yes
;debug network = yes
;debug packet = yes
;debug state = yes
;debug tunnel = yes
[lns default]
exclusive = yes
ip range = 192.168.1.91-192.168.1.99
local ip = 192.168.1.1
;hidden bit = no
length bit = yes
name = VPNServer
ppp debug = yes
require authentication = yes
unix authentication = no
require chap = yes
refuse pap = yes
pppoptfile = /opt/etc/ppp/options.xl2tpd
Set "local ip" to the IP address of your Tomato router. Set "ip range" to an unused range of IP's on your subnet. Make sure this range is outside the range of your DHCP server!
Create /opt/etc/ppp/options.xl2tpd with the following:
lock
auth
name "l2tp-server"
# DUMP crashes the daemon - do not uncomment
#dump
# CCP seems to confuse Android clients, better turn it off
noccp
#novj
#novjccomp
nopcomp
noaccomp
require-mschap
require-mschap-v2
ms-dns 192.168.1.1
lcp-echo-interval 120
lcp-echo-failure 10
idle 1800
connect-delay 5000
nodefaultroute
noipdefault
proxyarp
mtu 1400
mru 1400
ip-up-script /opt/etc/ppp/ip-up.sh
ip-down-script /opt/etc/ppp/ip-down.sh
Replace "ms-dns" with the address of your desired DNS server. Usually, this should be the IP address of your router's LAN address.
This was tested on Mac OS X 10.10.0 DP5.
- Open System Preferences and click on Network.
- Click on the + symbol to add a new interface.
- Set the "Interface" to VPN. Set the "VPN Type" to "L2TP over IPSec." Set the "Service Name" to whatever you would like. Click the Create button.
- Set the "Server Address" to your DDNS name. (e.g. myhouse.dyndns.org)
- Set the "Account Name" to your user name--this corresponds to the user names in /opt/etc/ppp/chap-secrets
- Click on "Authenication Settings"
- Under "User Authentication" choose "Password" and fill in the password of your user--again, this corresponds to /opt/etc/ppp/chap-secrets.
- Under "Machine Authentication" choose "Shared Secret" and fill in the pre-shared key from /opt/etc/racoon/psk.txt.
- Leave "Group Name" blank.
- Click OK.
- Click "Advanced" and tick "Send all traffic over VPN connection". Click OK. This will make sure your Internet browsing traffic goes over the VPN instead of just packets destined for your home's LAN.
- Click Apply.
This was tested on iOS 7 and 8 beta 5.
- Launch the Settings app.
- Tap through General->VPN
- Tap "Add VPN Configuration..."
- Choose L2TP and set the "Description" to whatever you want to name the connection.
- Set "Server" to your DDNS name. (e.g. myhouse.dyndns.org)
- Set "Account" to your user name--this corresponds to the user names in /opt/etc/ppp/chap-secrets
- "RSA SecurID" should be off.
- Set "Password" to the password of your user--again, this corresponds to /opt/etc/ppp/chap-secrets.
- Set "Secret" to the pre-shared key from /opt/etc/racoon/psk.txt.
- "Send All Traffic" should be on.
- "Proxy" should be off.
- Click "Save"
This was tested on Android 4.4.4 (CyanogenMod CM11 M9). The instructions for your device or version of Android may vary.
- Launch the Settings app.
- Under "WIRELESS & NETWORKS" tap "More..."
- Tap "VPN" and then tap the + button.
- Choose "L2TP/IPSec PSK" as the type.
- Set the Name to whatever you want to name the connection.
- Set "Server address" to your DDNS name. (e.g. myhouse.dyndns.org)
- Leave "L2TP secret" and "IPSec identifier" empty.
- Set "IPSec pre-shared key" to the pre-shared key from /opt/etc/racoon/psk.txt.
- Tap "Save"
- Tap on the newly created VPN profile.
- Fill in "Username" with your user name--this corresponds to the user names in /opt/etc/ppp/chap-secrets
- Fill in "Password" with the password of your user--again, this corresponds to /opt/etc/ppp/chap-secrets.
- Tick "Save account information" (optional)
- Click "Connect"
Make sure you use a patched racoon. Standard racoon does not recognize "*" in psk.txt
Make sure you have the relevant kernel modules loaded
Make sure you have the right policies (ip xfrm…)
Make sure you have "force userspace = yes" in xl2tpd.conf
Make sure you have interface=ppp4,ppp5,ppp6,ppp7,ppp8,ppp9 in /etc/dnsmasq.conf
Make sure the soft link in /opt/lib/pppd/2.4.5 is valid and resolves to /usr/lib/pppd/pppol2tp.so.
Events are logged to /var/log/messages. You can "tail -f /var/log/messages" to watch what happens when a client attempts to connect.
You can enable more verbose debugging in /opt/etc/xl2tpd/xl2tpd.conf. Uncomment one or more of the "debug" lines.
- Figure out how to use the built-in pppd installation. It would be better if we did not have to install pppd from entware--I don't think it is buying us anything.
- Debug possible issues with two VPN clients connecting from the same source address.
dborca wrote up an excellent tutorial on setting up this server here: http://tomatousb.org/forum/t-625093/ipsec-l2tp-racoon-xl2tpd-tomato-shibby-asus-rt-n16. However, since then the tools within entware have matured resulting in a much less complicated install that I outline here. Thanks for the write up dborca!
Hi, i have configured as described but when i try to conect fron ios it give me time out, and dont see nothing it messages, i think that firewall isnt working good, any ideas?
EDIT: Was a problem with NAT & Port Foward beetwen PPPoE Wan interface and Router LAN address, a little bit of iptables and working like a charm. 👍
thanks