OpenVPN provides an excellent alternative to PPTP over SSH Pptp-ssh without the need for giving out free root access to the client nodes, which essentially means we can have standard Linux desktop machines performing this operation.
OpenVPN also has the ability to keep state of which clients are connected and clients will attempt automatic reconnection if the server gets lost. OpenVPN can distribute routes to the clients automatically. All these features have been successfully implemented for IPv4 only at the moment.
For help on generating the keys on the server for the clients see openvpn.net/howto.html for a good guide. This is a pretty basic operation which involves running the scripts which exist in /usr/share/doc/openvpn/examples/easy-rsa/2.0/
Q: How do you generate addition client keys after the initial keygen process has been complete? A: # cd /usr/share/doc/openvpn/examples/easy-rsa/2.0/ # source ./vars # ./pkitool clientX
files in /etc/openvpn:
ca.crt ca.key dh1024.pem server.crt server.key server.conf
port 1194 proto tcp dev tap ca ca.crt cert server.crt key server.key dh dh1024.pem #magical route statement. #This will automatically route traffic to nodes subnets which can start at 10.13.129 or above #Note that openvpn will assign 10.13.129+ to clients if there are more than 254, maybe start at 132 server 10.13.128.0 255.255.240.0 #connect to sown via vpn tunnel push "route 10.13.0.0 255.255.0.0" push "dhcp-option DNS 10.13.0.253" client-to-client #Allow 1 client certificate to be used many times duplicate on keepalive 10 120 #Downgrade level of access once tap/tun is created (which ssh doesn't have...yet) user nobody group nobody persist-key persist-tun status /var/log/openvpn-status.log log /var/log/openvpn.log log-append /var/log/openvpn.log verb 3
The following part of the config could prove useful if you want to perform operations upon client connection since we are only having one tap device (I think).
# Suppose that you want to enable different # firewall access policies for different groups # of clients. There are two methods: # (1) Run multiple OpenVPN daemons, one for each # group, and firewall the TUN/TAP interface # for each group/daemon appropriately. # (2) (Advanced) Create a script to dynamically # modify the firewall in response to access # from different clients. See man # page for more info on learn-address script. ;learn-address ./script
NEW: Download the get_vpn_keys script from http://auth.sown.org.uk/vpn-keys/get_vpn_keys and run this with your node subnet as the first argument to get your keys: e.g. ./get_vpn_keys 131.
files in /etc/openvpn:
ca.crt client1.crt client1.csr client1.key client.conf update-resolv-conf
client dev tap proto tcp remote auth.sown.org.uk resolv-retry infinite nobind user nobody group nobody persist-key persist-tun ca ca.crt cert client1.crt key client1.key status /var/log/openvpn-status.log log /var/log/openvpn.log log-append /var/log/openvpn.log verb 3
On the server
openvpn /etc/openvpn/server.conf &
On the client
openvpn /etc/openvpn/client1.conf &
No additional rip routing is required and all of the routes are nicely aggregated, keeping the routing tables on the sown servers nice and clean. Next IPv6 of which there are some notes in the section below.
To make the routes nice and clean the vpn routes are static which means that every sown server (bar sown-vpn to which the tunnels are connected needs the following added to /etc/init.d/setup_routes
#!/bin/sh -e case "$1" in start) `route add -net 10.13.128.0/17 gw 10.13.0.253` ;; stop) `route del -net 10.13.128.0/17 gw 10.13.0.253` ;; esac exit 0
And then linked on boot up:
ln -s /etc/init.d/setup_routes /etc/rcS.d/S50setup_routes
An alternative to OpenSSH tunnels has been proposed which would use OpenVPN as a point to point authenticated layer 2 tunnel. This would appear to the network as identical to the Pptp-ssh system.
An OpenVPN connection requires a client and a server. The server runs on a central machine and the client on the access point. To establish a connection the client and server must have a public/private key pair which is signed by the same certificate authority.
Each OpenVPN server listens on its own port (5000-5050)
A good guide to setting up OpenVPN can be found on the the openVPN website at openvpn.net/howto.html. For SOWN we need to do the following:
Install OpenVPN in a way aproprite to your system. For Debian
should be sufficiant The install should have created a directory /usr/share/doc/packages/openvpn or prehaps /usr/share/doc/openvpn-2.0. In that directory should be the following scripts vars, clean-all, build-ca and more. Run the vars script to update the default values for certificates. Now run clean-all to clear any previous keys and finaly run build-ca, this will create you a CA.
build-ca should produce the following:
./build-ca Generating a 1024 bit RSA private key ............++++++ ...........++++++ writing new private key to 'ca.key' ----- You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter '.', the field will be left blank. ----- Country Name (2 letter code) [KG]: State or Province Name (full name) [NA]: Locality Name (eg, city) [BISHKEK]: Organization Name (eg, company) [OpenVPN-TEST]: Organizational Unit Name (eg, section) : Common Name (eg, your name or your server's hostname) :OpenVPN-CA Email Address [firstname.lastname@example.org]:
You now have a working CA
Each server will require a public/private key pair which in turn must be signed by the CA. All the servers could (and possibly should) share the same public/private key pair.
To build a server key called 'server' run the following command:
assuming or course that you were in the same directory as the build-key-server script.
Now you can confgure the server startup script here is an example for server number 10
#Server 10 Config File local $ipOfVPNserver #This prevents routers/computers trying to be clever and causing cahos. port 5010 proto udp #should be tcp if connection tracking is needed dev-type tap dev tun10 #linux may need re-configuring to support more than 4 tap devices ca /etc/vpn/vpnca.crt #path to CA certificate used to sign client and server keys cert /etc/vpn/VPN.crt #path to the server certificate signed by the CA key /etc/vpn/VPN.key #path to the servers private key dh /etc/vpn/dh1024.pem #path to the DH thing created earier server-bridge 172.16.13.37 255.255.255.252 172.16.13.38 172.16.13.38 keepalive 10 120 #Stop NAT from timing out due to inactivity user nobody #user to drop privilages to group nobody persist-key #Load key into memory to avoid sharing problems persist-tun #Can't remember, setting it can't hurt surely? status /var/log/openvpn/openvpn-status-10.log #location of the log for this connection
The server should now work by running the following commands
/usr/local/sbin/openvpn --config /etc/vpn/server10.conf --daemon tunnel-10 ifconfig tun10 link0 ifconfig tun10 inet6 2001:2001:630:c2:0901::37 prefixlen 126 alias
The v6 addreses can be pushed by OpenVPN in the same way v4 adresses can.
The client needs a public private key pair like the server. The clients can share the same key but probably should not in case a user's access needs to be revoked.
To create the client key
Copy the generated files to the client (node).
All clients need to connect to the same port now so the config file looks like so:
client #OpenVPN should run as a client dev tap0 #bind to tap0 so Linux knows what it is doing proto udp #TCP may have to be used but udp is better remote $serverIP 1194 resolv-retry infinite #Never give up never surrender nobind #Don't bind to a specific port persist-key #Load the keys into memory persist-tun #Keep the tunnel working ca /etc/vpn/vpnca.crt #path to CA certificate cert /etc/vpn/client.crt #path to client certificate key /etc/vpn/client.key #path to client private key verb 3 #lots of logging!
To start the client try:
#! /bin/sh echo "Starting VPN" /usr/sbin/openvpn --config /etc/vpn/client.conf --daemon sleep 5 ip -6 addr add 2001:2001:630:c2:0901::38/126 dev tap0 ip -6 route add ::/0 via 2001:2001:630:c2:0901::37 echo "Creating bridges" brctl addbr br0 brctl addbr br1 brctl addif br0 eth0 brctl addif br0 ath2 brctl addif br1 ath0 brctl addif br1 ath1 ip -6 addr add 2001:2001:630:c2:0937::1/64 dev br1 ip -6 addr add 2001:2001:630:c2:0938::1/64 dev br0 #Start Quagga /usr/lib/quagga/zebra -d sleep 1 /usr/lib/quagga/ripngd -d
This script needs customising to what SOWN is curently doing. The v6 tunnel addresses should be pushed by the VPN server. The script also thinks that ath0 and ath1 are SOWN virtual APs and ath2 is the WPA encrypted virtual AP for connecting the the users home network. ath1 is the 1x virtual access point. These things are still in development so the script can be simplified.
Here are some Quagga files to compliment the above setup. They need modifying to actualy work.
! ! Zebra configuration ! password **** enable password **** log syslog ! !Interfaces ! !Home network bridge !This bridge comprises of the WPA encrypted access point and eth0 interface br0 no ipv6 nd suppress-ra ipv6 nd prefix 2001:2001:630:c2:0938::/64 ! !SOWN Bridge !This bridge consists of the sown-1x interface and the sown-nodename interface interface br1 no ipv6 nd suppress-ra ipv6 nd prefix 2001:2001:630:c2:0937::/64 ! !Loop back interface interface lo ! !Tunnel interface back to tunnel broker interface tap0 ipv6 nd suppress-ra ! ipv6 forwarding ! line vty !
! ! RIP-NG configuration ! password **** enable password **** log syslog ! router ripng network tap0 route 2001:2001:630:c2:0938::/64 route 2001:2001:630:c2:0937::/64 ! line vty !