WireGuard – VPN mellem mine datacentre

Jeg har nu i næsten 10 år haft mine egne datacentre spredt ud over flere kontinenter.

Det startede med at jeg ikke kunne få fast IP addresse til vores hus i New York, og dermed kunne jeg ikke køre min WEB-server som jeg har haft siden forrige årtusind.

Jeg fik fat i en fast IP til vores sommerhus i Danmark og installerede WEB-serveren der og det har virket fint siden.  Deværre har det indtil denne uge været baseret på en ADSL forbindelse, så der har ikke været båndbredde ud af sommerhuset til f.ex. video trafik. Så vi har været lykkelig forhindret i at følge  “Vild Med Dans”.

Jeg har haft forskellige tunneller åbne mellem mine to datacentre så jeg har kunnet forgøgle f.ex Amazon at jeg sad i USA mens jeg i virkeligheden var i sommerhuset, eller snyde DR til at at tro at jeg var en rigtig dansk-dansker-i-danmark når jeg i virkligheden sad og nød vinteren i USA.

Der er mange forskellige netværks tunneller, min favorit er blot at bruge -L option i ssh og lave en simpel port-forwarding af f.ex. port 80, 443 eller 5900, det kan gøres ad hoc, er simpelt, og rimeligt sikkert.  Skal det være mere permanent så er det langt fra simpelt (eller sikkert), og slet ikke trivielt at fejlfinde, og hvis der skal en fornuftig kryptering af traffiken, begynder de små billige low-power OpenWRT baserede routere jeg bruger, at få åndenød, sådan var det indtil WireGuard. WireGuard er lidt ligesom at bruge ssh uden password dvs med private/public key login. Jeg har i rsh som i gamle dage beskrevet hvordan man effektivt kan sætte sådan noget op.

Wireguard – layer 3 netværks tunnel

WireGuard. er temmelig nyt og stadig i Alpha-state, men det er simpelt og elegant og effektivt, “it is the new kid on the block”.  har du 38 minutter så check denne FOSDEM-17  video hvis du har en eftermiddag kan du skanne hele kildeteksten igennem, der er mindre end 4000 linier, og består af et kernel-module og wg kommandoen.

Nedenstående er fra min laptop der har en VPN forbindelse til vores hus i USA og vores sommerhus i Danmark.

peter@envy:peter> wg --help
Usage: wg <cmd> [<args>]

Available subcommands:
  show: Shows the current configuration and device information
  showconf: Shows the current configuration of a given WireGuard interface, for use with `setconf'
  set: Change the current configuration, add peers, remove peers, or change peers
  setconf: Applies a configuration file to a WireGuard interface
  addconf: Appends a configuration file to a WireGuard interface
  genkey: Generates a new private key and writes it to stdout
  genpsk: Generates a new preshared key and writes it to stdout
  pubkey: Reads a private key from stdin and writes a public key to stdout
You may pass `--help' to any of these subcommands to view usage.

peter@envy:peter> sudo wg show
interface: wg0
  public key: wXL8WE2FR..............
  private key: (hidden)
  listening port: 55889

peer: jj/FY2flvBf7wmPcGm............
  endpoint: 24.61.79.90:12345
  allowed ips: 192.168.2.0/24
  latest handshake: 1 minute, 4 seconds ago
  transfer: 20.99 MiB received, 1.45 MiB sent

peer: KXHamYkYAcfqS1VUVV............
  endpoint: 46.32.52.113:12345
  allowed ips: 192.168.3.0/24
  latest handshake: 1 hour, 50 minutes, 56 seconds ago
  transfer: 22.58 KiB received, 24.21 KiB sent
peter@envy:peter> 

 

Ubuntu

Jeg kører ubuntu-16.04 som er fra før WireGuard blev opfundet, så der skal installeres et nyt kernel-module og programmer, heldigvis er der debian pakker der tager hånd om det, vi skal blot tilføje repository og installere det., som beskrevet i wireguard.com/install

$ sudo add-apt-repository ppa:wireguard/wireguard
$ sudo apt-get update
$ sudo apt-get install wireguard

Skal du blot lave en VPN mellem to Debian systemer er der en god tutorial her

Wireguard VPN: typical setup

Under en normal Linux-distribution som Ubuntu kan man bruge wg-quick kommandoen til at initiere en VPN forbindelse, configurations filerne ligger under /etc/wireguard, jeg har 3 forskellige VPN setups jeg bruger:

  • wg0.conf – vpn tunnels to all my server networks, other traffic is not via WireGuard
  • us0.conf – all trafic is WireGuard routed via our network in the US
  • dk0.conf – all trafic is WireGuard routed via our network in Denmark
wg-quick up wg0 starter en VPN forbindelse
wg-quick down wg0 stopper VPN forbindelsen

OpenWRT

Jeg har kørt OpenWRT på mine routere siden White Russian (2006), jeg har nok mindst 10 forskellige hardware platforme, med helt forskellige CPU-er (mips,arm…) som kører det samme system, og jeg bruger det ikke kun til netværk, musik distribution i vores hus kører også under OpenWRT.

Så snart jeg får en ny netwærks enhed ind i huset der kan kører OpenWRT bliver det installeret, og derefter kan enhedderne konfigureres og opgraderes via ssh.

OpenWRT kører normalt i årevis uden at det er nødvendigt at pille i dem, og når det er nødvendigt at pille opgraderer jeg altid til nyeste version, her er hvad der skulle til for at opgradere en af mine boxe en Asus wl500gp fra 2007

$ ssh root@192.168.1.1

cd /tmp
wget http://downloads.openwrt.org/releases/18.06.0/targets/brcm47xx/legacy/openwrt-18.06.0-brcm47xx-legacy-asus-wl-500gp-v1-squashfs.trx
sysupgrade ./openwrt-18.06.0-brcm47xx-legacy-asus-wl-500gp-v1-squashfs.tr

Så er en funklende ny version installeret.

Under OpenWRT ligger alle konfigurations filer under /etc/config/ og sysupgrade ovenfor har reetableret dem fra forrige version, men alt andet også ekstra installerede pakker er tabt, så de skal installeres påny

opkg update
opkg install wireguard luci-app-wireguard

Nu er WireGuard kernel modulet, selve wg kommandoen og WEB-konfigator installeret og man kunne konfigurere systemet alene via WEB-en eller ved at rette i et par filer under /etc/config. Hvis du er mest til click setup via WEB-en, så er der hjælp at hente her

How to configure WireGuard on OpenWrt/LEDE using LuCi

Foruden selve WireGuard konfigurationen skal Firewall også tilpasses, her er hvad jeg har tilføjet til /etc/config/firewall

config rule
	option target 'ACCEPT'
	option src 'wan'
	option proto 'udp'
	option dest_port '12345'
	option name 'wireguard'

config zone
	option name 'vpn'
	option output 'ACCEPT'
	option forward 'REJECT'
	option network 'wg0'
	option input 'REJECT'

config forwarding
	option dest 'lan'
	option src 'vpn'

config forwarding
	option dest 'wan'
	option src 'vpn'

config forwarding
	option dest 'vpn'
	option src 'lan'

config rule
	option target 'ACCEPT'
	option src 'vpn'
	option proto 'tcp'
	option dest_port '22'
	option name 'ssh-from-VPN'

config rule
	option target 'ACCEPT'
	option src 'vpn'
	option proto 'tcp'
	option dest_port '80'
	option name 'web-from-VPN'

Konfguration af WireGuard

Jeg har 2 netværk der skal forbindes

  • 192.168.2.0/24 som ligger bagved en NAT på 24.61.79.90 i USA
  • 192.168.3.0/24 som ligger bagved en NAT på 46.32.52.113 i Danmark

Og vores familie har et antal laptops jeg gerne vil give VPN access til ovenstående netværk fra hvor-som-helst de måtte befinde sig, dem giver jeg disse

  • 10.10.1.0/24 laptop 1
  • 10.10.2.0/24 laptop 2
  • 10.10.3.0/24 laptop 3
  • 10.10.4.0/24 laptop 4

Der skal genereres private/public keys for hvert netværk, og  der skal laves et antal konfigurations filer til disse routere og laptops.

Konfigurations filerne til OpenWRT og Ubuntu har forskellig syntax, men indholder essentielt det samme, nemlig enhedens private-key og ip-address/port og public-key ip-address/port for de netværk man skal forbindes til

Distribuering af nøgler er ikke en del af selv WireGuard, og da jeg skal genere/distribure private/public key ud over mange config filer har jeg lavet et lille script til at genere config filerne, distributionen sker per håndkraft via ssh/rsync

#!/bin/bash
# create WireGuard config files for Servers and Laptops
# WireGuard on laptops are used when the Laptops are not "home"
# servers knows about servers and laptops
# laptop only know about servers
# servers are on subnet 192.168.x.y and are running OpenWRT
# laptops are on subnet 10.10.x.y and are runing ubuntu, there are 3 ways to run WireGuard
#  wg0 - vpn tunnels to all my server networks, other traffic is not via WireGuard
#  us0 - all trafic is WireGuard routed via our network in the US
#  dk0 - all trafic is WireGuard routed via our network in Denmark

umask 077

port=12345
gw[1]=77.215.174.179
gw[2]=24.61.79.90
conf[2]=us0
gw[3]=46.32.52.113
conf[3]=dk0
servers="${!gw[@]}"
laptops="$(seq 1 10)"

priv_key()
{
	if [ ! -f $1/priv_key ]; then
		mkdir -p $1
		wg genkey > $1/priv_key
	fi
	cat $1/priv_key
}
pub_key()
{
	priv_key $1 | wg pubkey
}
interface()	 # our-net
{
	echo "[Interface]"
	echo "PrivateKey = $(priv_key $1)"
#	echo "# PublicKey $(pub_key $1)"
	echo "Address = $1/24"
	echo
}
wrt_interface() # our-net
{
	echo "config interface 'wg0'"
	echo "	option proto 'wireguard'"
	echo "	option private_key '$(priv_key $1)'"
#	echo "#        public  key  $(pub_key $1)"
	echo "	option listen_port '${port}'"
	echo
}
peer()		# peer-net gateway 0=default-route
{
	echo "[Peer]"
	echo "PublicKey = $(pub_key $1)"
	if [ x$2 != x ]; then
		echo "EndPoint = $2:${port}"
	fi
	if [ x$3 == x0 ]; then
		echo "AllowedIPS = 0.0.0.0/0"
	else
		echo "AllowedIPS = $1/24"
	fi
	echo 
}
wrt_peer()	# peer-net gateway
{
	echo "config wireguard_wg0"
	echo "	option public_key '$(pub_key $1)'"
#	echo "#	option persistent_keepalive '25'"
	echo "	option route_allowed_ips '1'"
	echo "	list allowed_ips '$1/24'"
	if [ x$2 != x ]; then
		echo "	option endpoint_host '$2'"
		echo "	option endpoint_port '${port}'"
	fi
	echo
}

echo "# pub_keys for Servers"
for i in $servers; do
	echo -n "192.168.$i.0 "
	pub_key 192.168.$i.0
done

echo "# pub_keys for laptops"
for i in $laptops; do
	echo -n "10.10.$i.0   "
	pub_key 10.10.$i.0
done

for s in $servers; do
	n=192.168.$s.0
	echo "# config file for Server $n"
	echo "# append to /etc/config/network" > $n/openwrt_network
	wrt_interface $n i>> $n/openwrt_network
	for c in $servers; do
		if [ $s != $c ]; then
			if [ x${conf[$c]} != x ]; then
				echo "# ${conf[$c]} " >>$n/openwrt_network
			fi
			wrt_peer 192.168.$c.0 ${gw[$c]} >>$n/openwrt_network
		fi
	done
	for c in $laptops; do
		wrt_peer 10.10.$c.0 >>$n/openwrt_network
	done
done

for c in $laptops; do
	n=10.10.$c.0
	echo "# config files for laptop $n"
	interface $n > $n/wg0.conf
	for i in "${!conf[@]}"; do
		peer 192.168.$i.0 ${gw[$i]} >> $n/wg0.conf
		(interface $n; peer 192.168.$i.0 ${gw[$i]} 0) > $n/${conf[$i]}.conf
	done
done

Hvor hurtigt er det så ?

Jeg har lavet hastighedstest op mod bredbånd.dk og stofa.dk som leverer min internet forbindelse i Danmark, og xfinity.com som leverer internet forbindelsen i USA, testene er udført fra en ubuntu laptop forbindet via Wifi, VPN er fra laptop til router, hvor:

  • dk0 er en WR1043ND-v1(400Mhz CPU) i sommerhuset i Danmark
  • us0 er en WNDR3700-v2. (680Mhz CPU) i huset i Massachusetts

Alle testene nedenfor er udført 3 gange, hvor min/max er værdierne smidt væk.

Den første test er via vores gamle ADSL forbindelse som er købt som en 8/1 Mbit forbindelse dvs. man kan forvente en download hastighed på 8 Mbit/sec og upload hastighed på 1Mbit/sec.  Denne test svarer til at bruge det fra en tredieparts adresse i det der er 7-9 routere mellem min stofa-router og telenor-router og går lige tur omkring København.

bredbånd.dk hastighedstest stofa hastighedstest xfinity speedtest
direkte 10.2/1.1 8.3/2.2 7.7/3.3
dk0.conf 8.9/1.1 8.2/1.9 8.2/3.2
us0.conf 5.6/0.9 7.8/1.0 8.1/2.0

 

Den anden test er udført direkte fra Stofa routeren som er en 15/15 Mbit forbindelse,

bredbånd.dk hastighedstest stofa hastighedstest xfinity speedtest
direkte 17.4/11.0 18.3//11.6 17.9/12.3
dk0.conf 17.4/10.9 19.8/14.7 17.4/15.0
us0.conf 9.8/11.1 8.4/11.5 10.7/13.8

 

Og hvad kan der så konkluderes ud af disse tal

  • sammenligner man direkte med dk0.conf så ser det ud til at det ikke koster  båndbredde at gå via en Wireguard VPN. Hvorfor det er værre når VPN går hele vejen til USA kan jeg ikke umiddelbart forklare.

Der er ingen problemer med at se 1080 video-er fra Amazon.com via us0.conf forbindelsen, ligesom dr.dk via dk0.conf forbindelsen virker upåklageligt, jeg har lige set en film og dermed routed 2.5Gbit via Wireguard med laptop forbundet via ADSL routed ud i Danmark og tilbage ti Stofa fiber-forbindelsen hvorfra forbindelsen til dr.dk sker på Vanlig vis. Dvs fra dr.dk ser det ud til filmen bliver set fra Stofa.

This entry was posted in internet, Linux. Bookmark the permalink.