LinuxSelfhelp.com

3. Software Installation

3.1. Terminology

Because setting up the VPN very much resembles a client-server transaction, I'll borrow from that terminology to give a name to the computer at each end of the tunnel:

Server

This is the computer that passively waits for incoming VPN connection requests. It runs completely unattended.

Client

This is the computer that initiates the connection request, asking the Server to bring up the VPN.

3.2. Requirements

  • Your kernel must have support for TCP/IP and PPP compiled in. Almost all distributions ship with PPP support straight out of the box. If yours didn't, or if you're using a custom kernel, I'll include a little more detail about this in Section 3.4.

  • You must install the pppd daemon. This most likely comes with your distribution. I'm using ppp-2.3.11. Later versions should work just fine, and earlier versions should also work as well as long as they support the "pty" option. You don't need to install chat or any of the other tools designed to work with PPP -- you just need pppd.

  • The client machine needs to have the the ssh client installed. There are many different versions of ssh floating around, but they should all work. I'm using OpenBSD's OpenSSH package version 2.2.0p1.

  • The server machine needs the sshd daemon to field ssh requests from the client. OpenSSH includes a very good ssh daemon.

  • Finally, you want to install the sudo tool on the server. You can find out more about sudo in the Linux Administrator's Security Guide, in the Administration Tools section, and the Linux Security HOWTO, in the Root Security section. You might also want to look at sudo's home page.

3.3. Planning

To set up a PPP-SSH link, you need to specify the the following parameters:

Server Hostname

What is the hostname or IP address for your VPN server?

Server VPN Username

On your server, what username will the VPN software run under? This HOWTO includes instructions on how to create a user named "vpn" specifically for this. This should not be root! For security and logging, this should be a dedicated account.

Server Interface IP Address

The PPP-SSH VPN sets up dedicated network interfaces on both the client and the server. The interface will be pppN, where N is the number of the first unused ppp interface (i.e. it will be ppp1 if you're already using ppp0 to dial out over your modem).

You will need to specify the IP address for the interface on the server. This address is only visible to the client and server (and to any machines on subnets that the client and server may be forwarding unmasqueraded packets for).

If you don't know what IP address to pick, read chapter 2.2 in the Linux Network Administrators Guide and especially look at Table 2-1. For example, 192.168.0.1 is a good choice.

Client Interface IP Address

You need to select the IP address for the interface on the client. It must, of course, be on the same network as the server's IP address. It must not conflict with any other networks on the client, nor can it be the same as the server's network interface IP address. If you selected 192.168.0.1 for the previous answer, you would probably use 192.168.0.2 here.

My setup looks like this:

SERVER_HOSTNAME = eldivino.domain.com
SERVER_USERNAME = vpn
SERVER_IFIPADDR = 192.168.3.1
CLIENT_IFIPADDR = 192.168.3.2

3.4. Set Up PPP

The kernel's PPP code can either be compiled into the kernel itself or it can be put in loadable kernel modules. If you compiled it into the kernel, you can skip on to the next step -- you're done here. However, if you're loading PPP as modules, you need to make sure the modules get properly loaded.

You can check to see if ppp is listed, along with all other currently loaded modules, when you run lsmod. Remember to check that the PPP module is loaded on both the client and the server.

server$ /sbin/lsmod
Module                  Size  Used by
ppp                    20780   0 (unused)
slhc                    4376   0 [ppp]
3c59x                  21636   1

client$ lsmod
Module                  Size  Used by
ppp_deflate            40308   0  (autoclean)
bsd_comp                4076   0  (autoclean)
ppp                    20844   2  [ppp_deflate bsd_comp]
slhc                    4376   1  [ppp]

If you're sure ppp was compiled as a module, but it's not loaded into the kernel, try loading it with modprobe:

# modprobe ppp

If modprobe didn't return any errors, check lsmod again -- it should be listed this time. If so, then your ppp module is not being loaded at boot time. This is OK if you're running the kernel daemon as the PPP modules will be loaded on demand. If you're not, however, you'll need to manually load the modules at boot time by putting a single line consisting entirely of the word "ppp" in your /etc/modules file.

See the Linux Kernel HOWTO for more on this subject.

3.5. Allow SSH Through the Firewall

The only network traffic between the two machines (as a result of the tunnel, of course) will be over the SSH protocol.

SSH uses only TCP streams -- no UDP or ICMP. The ssh server (sshd) listens on port 22. Our client (because we use the -P flag) only uses the unpriveleged ports from 1024 through 65535. This description should have given you enough information to set up your firewall.

For example, here are the ipchains commands needed to allow ssh connections to the server. We allow incoming SSH connection between port 22 on the local machine and any port on the remote. Replace eth0 with the interface that will be carrying the ssh traffic and $IPADDR with the IP address of that interface.

ipchains -A input  -i eth0 -p tcp -d $IPADDR 22 -j ACCEPT
ipchains -A output -i eth0 -p tcp ! -y -s $IPADDR 22 -j ACCEPT

And, here are the commands needed to set up the firewall on the client. We don't allow incoming ssh connections, and we only allow the protocol to pass between port 22 on the remote machine and unprivileged ports on this machine. Again, replace eth0 with the interface that will be carrying the ssh traffic, and $IPADDR with the IP address of that interface..

ipchains -A input  -i eth0 -p tcp ! -y --source-port 22 -d $IPADDR 1024:65535 -j ACCEPT
ipchains -A output -i eth0 -p tcp -s $IPADDR 1024:65535 --destination-port 22 -j ACCEPT