OpenVPN Bridge
From ArchWiki
OpenVPN is a full-featured SSL VPN solution which can accommodate a wide range of configurations and is particularly useful for "road warriors" :).
This wiki page will discuss how to configure OpenVPN (1.6) in Bridge mode with a linux server and either a linux or a windows client. http://openvpn.sourceforge.net/howto.html discusses how to setup OpenVPN routing and explains the pros and cons of each. Also, I'm not going into depth on iptables or how to make a hole in your firewall to allow traffic to reach your OpenVPN machine. That's for another wiki, or someone who's willing to add to this one.
This page describes the "quick n dirty" setup using a secret ssh key for authentication, see the openvpn website for more information about SSL setups.
TODO: This document seems out of date. I noticed there is a /etc/conf.d/bridges now, probably the bridging part should be taken out of the vpn configuration.
Contents |
Server Config
First thing you want to do is install OpenVPN
pacman -Sy openvpn bridge-utils
Next install this script as /etc/rc.d/openvpn
TODO: this script doesn't always correctly report "FAILED" or "DONE" so output can't be relied upon and may be confusing. Check /var/log/daemons if things don't seem to work.
#!/bin/bash # /etc/rc.d/openvpn # # An init script to start and stop OpenVPN daemons . /etc/rc.conf . /etc/rc.d/functions openvpn_config_dir=/etc/openvpn make_bridge () { #echo "# mkbr $1" # for example $1 = "br0" and # $br0 = ("br0 192.168.2.1 netmask 255.255.255.0 broadcast 192.168.2.255" eth1) eval brvar="(\"\${${1}[@]}\")" brdev=$1 brctl addbr $brdev add_to_bridge ${brvar[1]} $brdev ifconfig ${brvar[0]} return $? } add_to_bridge () { #echo "# addbr $1 $2" # for example $1=tap0 and $2=br0 ifconfig $1 down >/dev/null 2>&1 brctl addif $2 $1 ifconfig $1 0.0.0.0 promisc up } destroy_bridge () { eval brvar="(\"\${${1}[@]}\")" brdev=$1 ifconfig $brdev down brctl delbr $brdev } make_vpn () { #echo "# mkvpn $1" # for example $1 = vpn0 and # $vpn0 = ("default.conf" tap0 br0) eval vpnvar="(\"\${${1}[@]}\")" openvpn --mktun --dev ${vpnvar[1]} > /dev/null if [ "${vpnvar[2]}" != "" ]; then add_to_bridge ${vpnvar[1]} ${vpnvar[2]} fi openvpn --cd $openvpn_config_dir --daemon --config ${vpnvar[0]} return $? } destroy_vpn () { eval vpnvar="(\"\${${1}[@]}\")" openvpn --rmtun --dev ${vpnvar[1]} > /dev/null return $? } case "$1" in start) stat_busy "Starting OpenVPN daemons" # enable IP forwarding echo 1 > /proc/sys/net/ipv4/ip_forward # create bridge(s) error=0 for brconf in ${BRIDGES[@]}; do if echo $brconf | grep '^[^\!]' >/dev/null 2>&1; then make_bridge $brconf || error=1 fi done # create vpn(s) for vpnconf in ${VPNS[@]}; do if echo $vpnconf | grep '^[^\!]' >/dev/null 2>&1; then make_vpn $vpnconf || error=1 fi done if [ $error -eq 0 ]; then stat_done else stat_fail fi ;; stop) stat_busy "Stopping OpenVPN daemons" killall `which openvpn` 2> /dev/null # destroy bridge(s) error=0 for brconf in ${BRIDGES[@]}; do if echo $brconf | grep '^[^\!]' >/dev/null 2>&1; then destroy_bridge $brconf || error=1 fi done # destroy vpn(s) for vpnconf in ${VPNS[@]}; do if echo $vpnconf | grep '^[^\!]' >/dev/null 2>&1; then destroy_vpn $vpnconf || error=1 fi done if [ $error -eq 0 ]; then stat_done else stat_fail fi ;; restart) $0 stop sleep 1 $0 start ;; *) echo $"Usage: $0 {start|stop|restart}" RETVAL=1 esac
and make the script executable
chmod 755 /etc/rc.d/openvpn
In /etc/rc.conf add the following modules to the MODULES array
tun bridge
add the following configuration
# Bridges and VPN setup br0=("br0 192.168.0.1 netmask 255.255.255.0 broadcast 192.168.0.255" eth0) BRIDGES=(br0) vpn0=("vpn0.conf" tap0 br0) VPNS=(vpn0)
and add the following daemons to the DAEMONS array
bridge_devices openvpn
So what does all of that mean up there? First we create a bridge called br0 which attaches itself to eth0 and has certain ip address etc. Then we create a vpn daemon with config file "vpn0.conf" (see below) which uses device tap0 and attaches to the bridge br0. The "BRIDGES" and "VPNS" arrays should allow you to define more then one of each (but I didn't test this).
Now onto creating the config files
Firstly create the secret key
openvpn --genkey --secret /etc/openvpn/vpn0.key
and then make the vpn0.conf and save it in /etc/openvpn/
#/etc/openvpn/vpn0.conf # # Sample OpenVPN server configuration file # using a pre-shared static key. # # See man openvpn for more configuration options. # (the config file options are the same as the commandline switches) # # '#' or ';' may be used to delimit comments. # Define the virtual ethernet device. dev tap0 # Our pre-shared static key secret /etc/openvpn/vpn0.key # OpenVPN uses UDP port 1194 by default. # Each OpenVPN tunnel must use # a different port number. # lport or rport can be used # to denote different ports # for local and remote. port 1194 # Protocol to use; udp is the default for good reason. # Alternative is 'tcp-server' (with 'tcp-client' on the other side of the line) # which can be useful in certain situations or behind certain firewalls. ; proto udp # Downgrade UID and GID to # "nobody" after initialization # for extra security. user nobody group nobody # If you built OpenVPN with # LZO compression, uncomment # out the following line. comp-lzo # Send a UDP ping to remote once # every 15 seconds to keep # stateful firewall connection # alive. Uncomment this # out if you are using a stateful # firewall. ; ping 15 # Uncomment this section for a more reliable detection when a system # loses its connection. For example, dial-ups or laptops that # travel to other locations. ping 15 ping-restart 45 ping-timer-rem persist-tun persist-key # Verbosity level. # 0 -- quiet except for fatal errors. # 1 -- mostly quiet, but display non-fatal network errors. # 3 -- medium output, good for normal operation. # 9 -- verbose, good for troubleshooting verb 3
If you have more then one vpn daemon you should not reuse devices or port numbers across .conf files.
Now we can start up our daemons scripts.
sudo modprobe tun sudo modprobe bridge sudo /etc/rc.d/openvpn start
Linux client config
Install openvpn on the client machine the same way as on the server. Copy /etc/rc.d/openvpn, /etc/openvpn/vpn0.key and /etc/openvpn/vpn0.conf to the client (preferably using sftp or scp).
Add the following lines to /etc/openvpn/vpn0.conf with the "real" address of the server and the virtual address of the client.
remote real_server_address ifconfig vpn_client_ip vpn_netmask
(And set proto to 'tcp-client' if you used 'tcp-server' on the server)
Now edit /etc/rc.conf to include
# Bridges and VPN setup BRIDGES=() vpn0=("vpn0.conf" tap0) VPNS=(vpn0)
Now start it up
modprobe tun /etc/rc.d/openvpn start
You should now be able to ping across the tunnel to any of the hosts on the other end.
Windows client config
Install OpenVPN from openvpn-1.6.0-install.exe now copy the vpn0.key from the VPN server (preferably using sftp or scp) and the vpn0.conf below to "C:\Program Files\OpenVPN\config\". And delete the sample file in that folder (or at least move it to another folder).
# replace with the public ip address of the vpn server remote remote.public.ip.address port 5000 dev tap ifconfig 192.168.0.200 255.255.255.0 ifconfig-nowarn secret "C:\Program Files\OpenVPN\config\vpn0.key" ping 10 comp-lzo verb 5
Now open a command prompt and enter
net start openvpnservice
You should now be able to ping across the tunnel to any of the hosts on the other end.
Any additions, clarifications, reorganizations, feedback etc. etc. are more than appreciated.