I posted some time ago a guide for setting up a PPP over SSH vpn but it was a bit clunky and I was never fully happy with it.
So, I have spent some time adding all of the hard work to a fully interactive script that has the following features;
* Automatically configure your client details in a "vpn.conf" file.
* Bi-directional routing between the server and all remote nodes is automatically configured.
* Interactive functions to
* Function to check the VPN status, attempts restart if down
* Send email to a specified administrator when the state of the VPN changes.
* Automatic setup of keys for passwordless connections.
* Zero scripting skills required
Network admins who want to connect two or more offices using an encrypted, secure VPN over the public Internet. Clients at remote sites will access the Internet directly through their local gateway while all internal traffic is automatically routed via encrypted VPN links back to the central site.
Two debian or ubuntu servers configured as routers, designated as SERVER and CLIENT. Both must be connected to the internet and the SERVER should have a FQDN of some sort (see www.dyndns.com if you don't have your own domain). Assuming you are running a firewall on the server you must poke a hole in it to allow SSH connections from the internet.Authors Note:
This script started out as a simple clean up of the old one but of course that quickly blew out to a full on rewrite until I ended up with an all singing, all dancing mega-vpn management utility that I reckon is the easiest way to setup a VPN ever. Not one line of the original script remains intact!
Anyway, enough of the chest beating, let's get on with the show!
Step 1: Setting up the Server
Clients connecting to the server will do so using a local account on the server that is specifically used for this purpose.
Create a user called "vpn"
sudo adduser --system --group vpn
--systemparameter has set the vpn users shell to be /bin/false. However, because the vpn user needs to be able to log in via ssh, we must change this to /bin/bash in the /etc/passwd file.
sudo vi /etc/passwd
Modify the line for the vpn user so that it ends with /bin/bash;
We also need to set a password for the "vpn" account;
sudo passwd vpn
The vpn account password will only be used while doing the initial configuration of your VPN clients. You should choose a reasonably complex (secure) password and not be concerned about making it easy to type or remember.
The vpn user needs to be able to bring the ppp connection up and down as well as modify the system routing table. We will configure sudo to allow access to those commands.
Edit your sudoers file;
Append these lines to the end of the file;
vpn ALL=NOPASSWD: /usr/sbin/pppd
vpn ALL=NOPASSWD: /sbin/route
Finally, we need to log in as the vpn and set up a few bits in its home folder.
Change to the vpn user;
sudo su vpn
Create an ssh directory;
We need to seed an "active_networks" file with the subnet(s) that the VPN clients should be able to route to (usually the local LAN subnet that your VPN server is on but if you have a more elaborate network there may be multiple subnets. Simply add all the ones that you need remote hosts to route to). The "active_networks" file should be located in the vpn user's home folder (and owned by the vpn user)
Create an active_networks file;
Add a line for the servers local subnet followed by a hash and the server name.
10.1.1.0/24 # vpn-server
If you have more than one subnet then you can add them too (on separate lines)
The active_routes file holds a record of all the remote subnets (VPN network nodes) that the server is connected to. As each client gateway connects to the server it adds it's own LAN subnet to the file. If new routes are added later you can do a "vpn check" on the client gateway which will automatically update the local routing table with any new routes for any other nodes that may have been recently added to your network.
And that's all there is for the server part of this howto!
Step 2: Configuring a Client
Configuring the client is even easier than the server, we just need to download and run my new VPN script.
On the client host, download my vpn client script
Put the vpn script file somewhere in your system path or make a link to wherever you decide to put it.
sudo ln -s /store/scripts/vpn /usr/sbin/vpn
sudo apt-get install ipcalc ppp
And finally, execute the script with the "setup" directive;
sudo ./vpn setup
This will create a default config for your VPN. If this will be the first or only client node to be connected to your VPN server then the only required value is the SERVER_HOSTNAME for the VPN server. This should be a FQDN that is pingable from the Internet. For 99% of scenarios the rest of the default settings will work perfectly fine.
Once you have finished the setup, you can start the vpn;
sudo ./vpn start Starting vpn to vpn.tuxnetworks.net on port 22 - Using interface ppp0 Connect: ppp0 <--> /dev/pts/1 Deflate (15) compression enabled local IP address 192.168.2.2 remote IP address 192.168.2.1 Setting static routes Added route to 10.1.1.0/24 Added route to 10.48.17.0/24
Check the status of your VPN connection;
sudo ./vpn status --------------------------------------------------------- Local network : 10.1.3.1/255.255.255.0 [eth0] Connected to : vpn.tuxnetworks.net Remote IP : 192.168.2.1 Local IP : 192.168.2.2 PID : 25493
To have your client check whether the VPN is up (and automatically restart it if it's not) add an entry to your system crontab;
sudo vi /etc/crontab
Add a line like so;
* * * * * root vpn check >> /dev/null 2>&1
This will run every minute, check the vpn status as well as update any new routes to new nodes that have been added since the last time it was run.
Of course the
vpnscript file will need to be in your system path for this cronjob to execute. (See above)
If you also configure an administrator email address (and your system is able to send emails of course) then it will email the administrator every time the VPN link goes down, and again when it comes back up.
I've tried to make the script as simple as possible to use and I hope I have covered all the possible failure scenarios gracefully.
Give it a go and let me know in the comments or send me an email to the address contained in the script header and tell me what you think.
Any and all feedback is welcome.