Howto for "el cheapo" VPN with FREESCO

What is it?

This 'recipe' will build a Virtual Private Network between two FREESCO boxes. It is based on the Virtual Private Network Daemon by Andreas Steinmetz. The credits for this howto go to Ubiquity who figured it all out. My input was merely the compiled tarball vpnd, some beta testing of his howto and making this page. I also like to thank scooterboy for testing this howto.

Why “el cheapo”? Because this VPN solution is not compatible with any “standard”. It's f.i. not compatible with Micro$oft's VPN. It also runs on two 386 PC's if needed…

VPN tunnel

Both networks in the picture above will be joined via the VPN tunnel over a “potential hostile” link. Because the link is compressed and encrypted (blowfish) it's fairly safe. Read the official site for details how safe.

When you rely only on vpnd to secure your communications - just better don't use vpnd at all. 
If one of the two systems involved in the vpnd communication gets compromised the whole bridged LAN may
be compromised and at least all traffic painfully transfered encrypted can be easily sniffed in the plain version.

Requirements

  • two FREESCO boxes at both ends (it's possible to use other linux distro too, but that's outside the scope of this howto). Both boxes do not neccesarily need to be the same FREESCO version, but to keep it simple this howto is based on two 027 boxes. The only changes for 03x are path names.
  • Both private LAN's must have a different IP addressing scheme, otherwise it will not be possible to make a valid route between them. This howto uses a 10.0.0.x and 192.168.0.x network.
  • full OpenSSH package (both server and client) must be installed on both FREESCO boxes and they must be able to setup an SSH connection to each other. This is only required during the setup and to x-fer the key in a secure way. SSH is not required when things are setup properly (although it seems like a sane thing to me to be able to login to the remote box when the VPN link goes down for some reason and you need to fix it at the other side).
  • devices /dev/random and /dev/urandom must exist, which is automatically the case if you have OpenSSH package installed.
  • external IP addresses of each box or their (dynamic) domain names.
  • My tarball VPN tarball. This version has been compiled for use on Pentium class machines. A 386 version of the binary is also in the tarball, but you'll need to rename it to vpnd if you want to follow this howto.
  • A (preferable) human at the keyboard.

Introduction

Let's say you have two private networks attached to the Internet using FREESCO. How do you connect the two nets securely?
VPND (http://sunsite.dk/vpnd/) may be a solution for you. Here is an example of how I set it up between my home network and my church's network (which I set up). IP addresses have been changed to protect the innocent :-)

Network 1:
Church
192.168.0.1/24 internal network address/mask
ch.ur.c.h external IP address
Network 2:
Home
10.0.0.1/24 internal network address/mask
h.o.m.e external IP address

Step 1

Unpack the tarball on both routers, like so:

[Linux] cd /mnt/router/packages
[Linux] snarf -n http://dingetje.homeip.net/tarballs/vpnd-1.1.0.tar.gz
vpnd-1.1.0.tar.gz [########################] 185K | 679.89K/s
190003 bytes transferred in 0.28 sec (672.65k/sec)
[Linux] zcat < vpnd-1.1.0.tar.gz | star
[Linux] rm vpnd-1.1.0.tar.gz
[Linux] cp vpnd/sbin/vpnd /bin

After this procedure you should be able to type vpnd -h and get the help message. If not, check your steps. For FREESCO 03x I suggest you change /mnt/router/packages to /usr/local.

[Linux] vpnd -h
vpnd version 1.1.0
usage: vpnd -h
       vpnd -m [<master-key-file>]
       vpnd -x <extended-master-key-directory>
       vpnd -c <extended-master-key-file>
       vpnd [-p] [-l] [-n|-t] [-f configfile] 

    -h prints this info
    -m creates master key file (default is /etc/vpnd.key),
       note that the file must not yet exist
    -x creates extended master key files named vpnd.lcl.key
       and vpnd.rmt.key in the given directory,
       note that the files must not yet exist
    -c set/change/remove user password of extended master
       key file, note that a newly created extended master
       key file has no user password, to set a password
       enter no password for the old password, to change
       the password enter old and new password, to remove
       the password enter no password for the new password
       NOTE: no password verification is done, it is solely
       your responsibility to enter and remember the
       correct values, if you enter wrong values here
       recovery is NOT possible, you must then create and
       use a new set of extended master key files
    -p request user password for extended master key file,
       if standard input is a pipe the user password is
       read from the pipe, otherwise the user is prompted
       to enter the password
    -l allow dns lookups so host names can be used
    -n do not become daemon
    -t do modem init chat test
    -f use configfile instead of /etc/vpnd.conf

Compression is available.

The vpnd binary should now be in /bin. This will not survive a reboot (because /bin lives in ramdisk), but we'll get to that later on.

Step 2

Next I create a master key on my home router. It creates a 576 bit blowfish key. I do this on only one of the routers since each router would create (supposedly) a unique key. We don't want that. Both machines must use the same key.

[Linux] vpnd -m /etc/vpnd.key
New key file /etc/vpnd.key created.

If you get

'Failed to gather random data'

at this point, then your box doesn't have the /dev/random device, which is kinda strange because the opensshd package creates that device if it's missing.1) Are you sure you're box meets the requirements? A quick fix is to type:

mknod /dev/random c 1 8

But it's better to install OpenSSH since you're going to need it later on, believe me!

Step 3

I then have to transfer the key to the church machine. I use SCP. You may use whatever means you want, but if you want security, you have to transfer it by secure means.

[Linux] scp /etc/vpnd.key root@ch.ur.c.h:/etc/vpnd.key

If you get

'scp: No such file or directory'

at this point, then you really must install the full OpenSSH package now, before proceeding…

Step 4

Next I create a configuration file named /etc/vpnd.conf. This howto shows with edit because that editor is available on every FREESCO box, but of course you can use your favorite editor here.

[Linux] edit /etc/vpnd.conf

I set up the church's FREESCO box to be the server and my home to be the client. The configuration file must be different on each machine. The IPs I choose for the Virtual SLIP interface are 172.16.0.1 and 172.16.0.2. 1 being for the church's side and 2 being for my home side. I could use just about any IPs but choose these for clarity. The server (church) is going to listen on port 777 (if you leave this out, it will default to 376) and the client (home) is going to have a dynamic address, since my home router gets its IP via DHCP. The vpnd.conf files end up looking like this:

Church's vpnd.conf:

mode server
server ch.ur.c.h 777
client 0.0.0.0
local 172.16.0.1
remote 172.16.0.2
route1 10.0.0.0 255.255.255.0 172.16.0.2
keyfile /etc/vpnd.key
pidfile /var/run/vpnd.pid
randomdev /dev/urandom

Home's vpnd.conf:

mode client
server ch.ur.c.h 777
client 0.0.0.0
local 172.16.0.2
remote 172.16.0.1
route1 192.168.0.0** 255.255.255.0 172.16.0.1
keyfile /etc/vpnd.key
pidfile /var/run/vpnd.pid
randomdev /dev/urandom

Some notes about these config files (by dingetje):

  • If you want to use a domain name rather than IP addresses (ch.ur.c.h and h.o.m.e in the example), that is possible too, but then you'll need to add the -l (lower case L) option to the vpnd startup command.
  • The 172.16.0.1 and 172.16.0.2 IP's are used for the pseudo serial interface (sl0) that is created when vpnd sets up the tunnel. See official homepage for details how VPN does it's magic.
  • Because of the dynamic IP address of the client, 0.0.0.0 is used in the config. For an extra level of security it's better to use the DYNDNS or No-IP domain name of the client and start the vpnd process with name resolution enabled (-l option).
  • If you need to connect a class B network, change the mask settings from 255.255.255.0 (class C) to 255.255.0.0 and in the firewall rules (see below), use /16 instead of /24.
  • if you don't have /dev/urandom or /dev/random than add the next lines to your rc_user or vpnd startup script:
if [ ! -f /dev/random ]; then
  mknod /dev/random c 1 8 2>/dev/null
fi

if [ ! -f /dev/urandom ]; then
  mknod /dev/urandom c 1 9 2>/dev/null
fi

Step 5

Okay, now comes time to test the configuration. On the server (church) I start the vpnd service in non-daemon mode. That way informational messages will appear in the console, rather than in syslog.

[Linux] vpnd -n
vpnd[23194]: version 1.1.0 (compression enabled) starting.
vpnd[23194]: slip link established.
vpnd[23194]: listening with address ch.ur.c.h on port 777

The number between brackets is the process ID of the server. On the client I let it run in daemon mode.

[Linux] vpnd
[Linux]

The server screen should show something like:

vpnd[23194]: connect from h.o.m.e

I then ping the server's SLIP address (172.16.0.1).

[Linux] ping 172.16.0.1
PING 172.16.0.1 (172.16.0.1): 56 data bytes

--- 172.16.0.1 ping statistics ---
8 packets transmitted, 0 packets received, 100% packet loss

Hmm, the server says that the connection was made, but I can't even ping the SLIP address? What's going on here? Repeat after me, “Firewall.” This is where I originally got stuck (note from dingetje: and so did I). Eventually I came up with the answer. I won't ever need to ping the SLIP addresses and I don't care if a traceroute balks on the second hop but passes the third so to simplify my firewall rules, I do this:

Step 6

at church (server):

[Linux] ipfwadm -I -i accept -W sl0 -D 192.168.0.0/24

at home (client):

[Linux] ipfwadm -I -i accept -W sl0 -D 10.0.0.0/24

This allows packet from the SLIP interface sl0 destined for the local network.

Since I wanted to keep the rules simple, I leave it like this and try to ping from another machine on my LAN to another machine on the remote LAN, i.e. ping from 10.0.0.2 to 192.168.0.2.

It's still not working, ugh! Why? “Masquerade!” If you are using a FREESCO box as a NAT router, the default rules say to NAT any packets with a source address of the local network. So what is happening now is packet from 10.0.0.2 is going to the router on 10.0.0.1, it's being accepted but the source IP is changed to the SLIP IP 172.16.0.2. It goes over the tunnel with its destination address intact, 192.168.0.2 and is now allowed by the above rules. It is forwarded to the target machine and that machine responds with its proper ECHO REPLY, but it thinks the packet came from 176.16.0.2 and sends it to that address. The reply packet gets to the router at 192.168.0.1 and is again masqueraded but this time both the source and destination addresses are wrong. The packet has a source address of 172.16.0.1 and a destination of 172.16.0.2.

How to fix this?

Step 7

[Linux] ipfwadm -F -i accept -b -S 192.168.0.0/24 -D 10.0.0.0/24

Since this is a bi-directional rule, the same rule can be put on both machines.

This should make it work, and I've found it does.

Notes

  • Pressing Ctrl-C on the server or client will kill the vpnd process (even if you started it in daemon mode without the ”-n”) so for a permanent solution, use fork.
  • Now I add some more rules to prevent source IP spoofing on my Internet interface. I also copied the needed files to /mnt/router/packages/vpnd so they will survive a reboot and created scripts in rcuser to map symlinks back to /etc, add the appropriate firewall rules, and start the daemon (on at least the server). Since these are beyond the scope of this tutorial, I'll let you figure it out for yourself. (Note by dingetje: see wrap up section below for another solution).

Good luck.

Wrap up

(this part by dingetje)

For FREESCO 027 you can copy the /etc/vpnd.conf and /etc/vpnd.key files to /mnt/router/etc so they will get automatically get copied to /etc (in ramdisk) at every reboot. For FREESCO 03x you'll have to use /boot/etc.

On the server FREESCO box (ch.ur.c.h), add the following lines in the start section of rc_user:

ln -fs /mnt/router/packages/vpnd/sbin/vpnd /bin/vpnd
fork /bin/vpnd
sleep 1
ipfwadm -I -i accept -W sl0 -D 192.168.0.0/24
ipfwadm -F -i accept -b -S 192.168.0.0/24 -D 10.0.0.0/24

If you have used a (dynamic) domain name in the VPND config, then you'll need to add -l (lower case L) option to enable DNS lookup (so: fork /bin/vpnd -l).

On the client FREESCO box (h.o.m.e), add the next lines to rc_user or in a seperate make_tunnel script or something similar:

ln -fs /mnt/router/packages/vpnd/sbin/vpnd /bin/vpnd
fork /bin/vpnd
sleep 1
ipfwadm -I -i accept -W sl0 -D 10.0.0.0/24
ipfwadm -F -i accept -b -S 192.168.0.0/24 -D 10.0.0.0/24

Both vpnd processes are executed in background (fork) and will log messages to system log file (/var/log/log for FREESCO 027 and /var/log/messages for FREESCO 03x). When the server isn't up at boot time of the client, then the connection will fail to setup (doh). That's why it's a good idea to make a seperate script for the client.

Here's the ifconfig list of the server when the link is up:

[Linux] ifconfig
lo Link encap:Local Loopback
inet addr:127.0.0.1 Bcast:127.255.255.255 Mask:255.0.0.0
UP BROADCAST LOOPBACK RUNNING MTU:3584 Metric:1
RX packets:362192 errors:0 dropped:0 overruns:0
TX packets:362192 errors:0 dropped:0 overruns:0

eth0 Link encap:10Mbps Ethernet HWaddr 00:20:AF:DF:FE:CF
inet addr:ch.ur.c.h Bcast:ch.ur.c.255 Mask:255.255.254.0
UP BROADCAST NOTRAILERS RUNNING MTU:1500 Metric:1
RX packets:6048 errors:0 dropped:0 overruns:0
TX packets:1957 errors:0 dropped:0 overruns:0
Interrupt:5 Base address:0x310

eth1 Link encap:10Mbps Ethernet HWaddr 00:60:8C:DF:F0:AE
inet addr:192.168.0.1 Bcast:192.168.0.255 Mask:255.255.255.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:258 errors:0 dropped:0 overruns:0
TX packets:203 errors:0 dropped:0 overruns:0
Interrupt:10 Base address:0x300

sl0 Link encap:VJ Serial Line IP
inet addr:172.16.0.1 P-t-P:172.16.0.2 Mask:255.255.255.255
UP POINTOPOINT RUNNING NOARP MULTICAST MTU:1500 Metric:1
RX packets:28 errors:0 dropped:0 compressed:0
TX packets:28 errors:0 dropped:0 compressed:0

Notice the sl0 interface? It's created by the vpnd process, making a point-to-point connection from 172.16.0.1 to 172.16.0.2. A sample route table looks like this:

[Linux] route -n
Kernel routing table
Destination     Gateway        Genmask         Flags MSS  Window Use Iface
255.255.255.255 *              255.255.255.255 UH    1500 0       14 eth1
172.16.0.2      *              255.255.255.255 UH    1500 0        1 sl0
192.168.0.0     *              255.255.255.0   U     1500 0       44 eth1
ch.ur.r.0       *              255.255.254.0   U     1500 0        5 eth0
127.0.0.0       *              255.0.0.0       U     3584 0      706 lo
10.0.0.0        172.16.0.2     255.0.0.0       UG    1500 0        2 sl0
default         ga.te.wa.y     *               UG    1500 0    15698 eth0

Notice the route to the remote SLIP device (172.16.0.2)? And the route to the remote network 10.0.0.0 as configured in /etc/vpnd.conf (see line with route1). On the client the route table is of course just the other way round, using 172.16.0.1 to network 192.168.0.0.

Browsing

Also see the VPND FAQ (see links below). Browsing over the VPN link is most likely not going to work, but it is possible to map a network share if you know the IP address or NetBIOS name of the remote PC. A “trick” to view the shares is to do the following:

  • On your PC Use Start → Run…
  • In the Run dialog type: \\ip.address.of.remoteworkstation 2)
  • hit ENTER or click OK

After a while the shares of the remote workstation should open in a new window. You can then Map a share to a local disk name.

Credits

  • Andreas Steinmetz for his Virtual Private Network Daemon
  • Ubiquity for his excellent work.
  • scooterboy for testing this howto and providing feedback.

Usefull Links

Original article

This article describes howto build a Virtual Private Network between two FREESCO boxes. Because of the color coding (not possible yet in this Wiki) of both networks, the original article may be better readable.

1) Only in the 027 version of the package, for FREESCO 03x you may need to create the devices as described in this howto
2) f.i. \\10.0.0.100
 
freesco/howtos/el_cheapo_vpn_tunnel.txt (44089 views) · Last modified: 2005/09/14 00:49 (external edit)
 
Recent changes RSS feed Creative Commons License Donate Powered by PHP Valid XHTML 1.0 Valid CSS Driven by DokuWiki