Introduction
This tutorial shows how to setup a PPTP/GRE VPN server within your Tomato router, which allows external devices to connect to your network through a secured encrypted connection. PPTP is the oldest type of VPN and is probably the most supported across different operating systems (both desktop and mobile). This is a list of operating systems which ship with a PPTP VPN client:
- Any version of Windows (since 95)
- Linux: at least Ubuntu & Fedora, and probably most others (it’s supported by NetworkManager).
- Mac OSX: any version since 10.2
- iOS: any version since 2.0
- Android: any version since 1.5
Why a VPN with your home router can be useful
- If you’re browsing with your laptop or phone from a public Wifi hotspot, your accounts are probably unsecure (see for instance Firesheep), unless the websites are fully HTTPS (no, just using HTTPS for passwords is not enough). Instead, if you connect home through VPN, you can send all your traffic through the tunnel, it will be encrypted and your accounts will stay secure.
- You can access your shared disks/resources remotely without having to open the risky Samba ports on the Internet.
- You can listen to your music or watch your videos exposed through TomatoUSB MiniDLNA even if you are not home. The same applies for any other multimedia server (eg: mt-daapd to simulate an iTunes Home Server and stream your music to your iPod Touch/iPhone even if you are not home).
Choosing the VPN network
While configuring the PPTP VPN, you have choose between two alternatives (and both valid) structures for your network:
- Single-Net: Bring the VPN clients directly inside your LAN. In this setup, any VPN client that connects to your network will be given an IP address in your LAN range (eg: 192.168.1.x). In this case, you will have to make sure there is no conflicts between the range of IP addresses assigned by DHCP, the static leases, and the range assigned by the VPN server. Pros: Easier to configure for the clients. Cons: Slightly harder to configure on the server; harder to decide what a VPN client can or cannot do within your LAN (they get the same privileges of real LAN devices).
- Multi-Net: Create a separate subnet for VPN clients. In this setup, you will create a totally different subnet for the VPN (eg: 192.168.10.x, separated from LAN which is 192.168.1.x). Pros: Easier to configure on the server; very easy to decide what a VPN client can or cannot do with respect to LAN resources. Cons: Harder to configure on the clients.
Single-Net should be chosen if it’s OK that a VPN client can access your whole network. Multi-Net should be chosen if you want to be totally in control of what VPN clients should or should not do.
If you have not understood anything of the above, just go with Single-Net setup.
Requirements
Any version of TomatoUSB is fine. You don’t need the VPN version: that version just ships with a GUI to setup a OpenVPN connection (which is a more powerful but less broadly supported VPN type).
You need to have configured optware in your router. Please follow the tutorial if you have not already.
VPN clients will start the VPN connection by contacting your Tomato router on TCP port 1723. This means that your router needs to have a public IP address; if it’s behind a NAT, you will need a way to open the port TCP/1723, otherwise VPN clients will not be able to initiate the connection.
Server Configuration
Installation
Login into your Tomato box through telnet/ssh. Install the package poptop from optware:
ipkg install poptop
That’s all. poptop actually depends on the pppd server that is already shipped with all TomatoUSB versions.
Configuring the server
Edit the file /opt/etc/pptpd.conf.
First thing, comment the line logwtmp. This disables the usage of wtmp which is not included in Tomato and would results in an error, and switches to using the standard syslog (so that you will find VPN logs in/var/log/message).
The only other thing you must configure is the IP addresses to be used by the VPN, which vary depending on your configuration type:
Single-Net: choose a range of IPs that you will reserve to VPN. For instance:
localip 192.168.1.1
remoteip 192.168.1.250-253
In this example, we declare that our local VPN IP is the standard TomatoUSB IP (usually 192.168.1.1), and then we reserve a range of IPs (from .250 to .253) for up to 4 VPN clients. You will then have to make sure that this range does not overlap with the DHCP range (from the web interface, Basic » Network » LAN » DHCP Server » IP address range). Check also the static DHCP leases (Basic » Static DHCP). Avoid any conflicts!
Multi-Net: choose a new subnet for the VPN. For instance:
localip 192.168.10.1
remoteip 192.168.10.10-19
In this example, your tomato box will get an additional IP address on the VPN subnet (192.168.10.1) and then we reserve IPs for up to 10 VPN clients.
Now, edit the file /opt/etc/ppp/options.pptpd. What follows is a correct complete configuration of everything you need (you can comment/remove all other options):
name pptpd
refuse-pap
refuse-chap
refuse-mschap
require-mschap-v2
require-mppe-128
nomppe-stateful
ms-dns 192.168.1.1
proxyarp
lock
nobsdcomp
The nomppe-stateful option means that the encryption is stateless (that is, every packet can be decrypted on its own). This is more solid in case of VPN clients on flaky connections (eg: 3g), and it is also required for iOS clients (iPhone/iPad) since otherwise they will refuse to connect. It is only slightly less secure than the default stateful encryption protocol.
The ms-dns setting is the DNS to be used by VPN clients to resolve names. Since Tomato runs a DNS server, just specify its IP in this line (in both the Single-Net and Multi-Net configuration). Note: iOS has a bug (as of 4.3.1) in its VPN client and requires this address to be a public global IP address. If you plan to use iOS devices as clients of your VPN, use your ISP DNS here or OpenDNS or Google DNS (8.8.8.8). The only side effect is that VPN clients will not know any more the names of devices in your LAN (eg: you will not be able to do «telnet tomato» from a VPN client, and you will need «telnet 192.168.1.1» instead).
Creating access credentials
Create and edit the file /opt/etc/ppp/chap-secrets to setup your VPN client credentials. This is an example:
# Username Server Password Allowed IPs
username1 * FooBar01! *
username2 * !98BarFoo foobar.example.com 4.12.128.7/24
The first line is a comment. Then, each line is a different access credential, with four fields separated by spaces. You need to specify username and password (in plaintext). You can specify * for the server (it means any server, and it’s only useful for very advanced setup where you want to share this password file between different VPN servers). If you want to allow the VPN client to only connect from a static IP or IP range, specify it in the fourth field (can be either a hostname or a IP address, optionally with a subnet indication to allow multiple IPs); otherwise specify * to allow the client to connect from any IP address.
NOTE: It looks like there is a bug because the allowed IP field does not work (it prevents all connections). For now, always use * until the bug is found and solved.
Make sure the file is readable only by root: chmod 600 /opt/etc/ppp/chap-secrets. This will avoid warnings in the log files.
Security suggestion: Use very complex passwords. Specify IP ranges if possible. Also, make sure to create one different VPN credential per-device and not per-user. This makes it easier to revoke a credential if a specific device is compromised.
Configuring the firewall
We now need to configure the firewall to both allow the incoming VPN connections and let VPN clients access your LAN and go out on the Internet. Create and edit the file /opt/etc/config/vpn.fire (if the configdirectory does not exist, create it). Put the following script in there:
#!/bin/sh
iptables -A INPUT -p gre -j ACCEPT
iptables -A INPUT -p tcp --dport 1723 -j ACCEPT
iptables -A INPUT -i ppp+ -j ACCEPT
iptables -A FORWARD -i ppp+ -j ACCEPT
iptables -A FORWARD -o ppp+ -j ACCEPT
iptables -t nat -I PREROUTING -p tcp —dport 1723 -j ACCEPT
iptables -I INPUT -p tcp —dport 1723 -j ACCEPT
iptables -I INPUT -i ppp+ -j ACCEPT
iptables -I FORWARD -i ppp+ -j ACCEPT
Make the script executable: chmod +x /opt/etc/config/vpn.fire. Then restart your firewall: service firewall restart.
This script will be automatically executed by TomatoUSB every time the firewall needs to be reconfigured. The script opens the TCP port 1723 on your Tomato router (standard PPTP port), and allow the GRE protocol to be used. It then allows up to 10 VPN devices (interfaces ppp0-ppp9) to browse your local LAN, access Tomato itself and go out on the Internet.
Starting the server
Run these commands once to make sure that the /opt/var/run directory exists and is accessible: mkdir -p /opt/var/run; chmod 755 /opt/var/run.
Then, create and edit the file /opt/etc/config/vpn.wanup, with the following contents:
#!/bin/sh
if [ ! -f /tmp/ppp/chap-secrets ]; then
mkdir -p /tmp/ppp
ln -s /opt/etc/ppp/chap-secrets /tmp/ppp
fi
/opt/etc/init.d/S20poptop restart
Make this script executable: chmod +x /opt/etc/config/vpn.wanup. This script will be automatically executed every time your Internet connection is (re-)estabilished. Run it manually once to start the server.
The first part of the script adds a symlink of the chap-secrets script into /tmp/ppp. This is required because we will be using Tomato’s standard pppd server (/usr/sbin/pppd), which does not know about optware, so it looks for the password file in /tmp/ppp.
Debugging
To debug any problem with your clients, have a look at /var/log/messages, where the VPN server will log. You can add a line with the option debug to /opt/etc/ppp/options.pptpd to see more verbose output from the server.
Client configuration
Please notice that you cannot connect a VPN client if it is already connected to your Tomato router (eg: through a cable or wifi). So, if for instance you want to configure a mobile device, make sure you first turn off the wifi so that the device will not be within your LAN already.
Set up a iOS device as VPN client
- Open the Settings app. Go to General, Network, VPN.
- Tap to add a new VPN configuration.
- Select the PPTP tab at the top.
- Fill the form:
- Description: can be anything («My Home» or whatever).
- Server: set your router public IP address. If your IP address is dynamic, you should setup a dynamic DNS service (TomatoUSB has builtin support for DDNS updating).
- Account: the username you want to use for logging in
- RSA SecurID: off
- Password: the password you want to use for logging in. If you keep this empty, iOS will ask for the password every time you want to estabilish the VPN connection.
- Encryption level: Automatic is fine (will be the Maximum level anyway)
- Send all the traffic: If you turn this on, when the VPN connection will be active, the device will use the VPN for accessing the Internet, so all browsing, mailing, twitting, etc. will go through the VPN. If you turn this off, the device will use the VPN only if you explicitly connect to a device in your router’s LAN (eg: if you browse to http://192.168.0.1 to access your router, or if you access the Samba shares, etc.).
- Proxy: if you don’t have any proxy configured within Tomato, No is correct.
- Save the new configuration.
It’s done! You can now activate the VPN by clicking on the VPN button in the main screen of the Settings App (it should appear there now that you have one VPN configured).
Remember that iOS always disconnects from the VPN whenever the devices goes to sleep/standby mode.
Set up an Android device as VPN client
- Open the Settings app. Go to Wireless and Network, VPN Settings
- Tap on Add VPN
- Tap on Add PPTP VPN
- Insert the following settings
- VPN Name: can be anything («My Home» or whatever)
- VPN Server: set your router public IP address. If your IP address is dynamic, you should setup a dynamic DNS service (TomatoUSB has builtin support for DDNS updating).
- Cryptography: leave it as checked (default).
- Save the VPN
- Now tap on the VPN network to connect for the first time
- Enter the username and password. Tap the checkmark to save the username
Done! Your Android device should now connect to your VPN. Anytime you want to turn it on/off, you need to go back to the main VPN screen in the Settings app.
The main problem with Android is that it currently does not allow to save your password (tested up to Gingerbread 2.3). This means that you will be forced to reenter your password any time you want to reconnect. This is a nuisance but please remember not to make your password easier because of this! An easier password will be easier to bruteforce for an attacker.