Projet

Général

Profil

VPN Client OpenWrt

Introduction

Le routeur doit être assez puissant pour supporter les opérations de chiffrement de Wireguard (eg. TP-Link Archer C7).

Il doit avoir été préalablement flashé en OpenWrt.

Doc testée avec OpenWrt 19.07.3.

Exemple de configuration

On suppose que votre service Wireguard a été configuré comme suit côté Tetaneutral :

  • Réseau IPv6:
    2001:db8:dead:be00::/56
  • Adresse IPv4:
    203.0.113.42/32
  • Clé privée Wireguard:
    XF4wYSh/Ox9CoPl/YvFECu1DH6FQy7fLNUnur4sv9nM=

Variables et commandes à copier-coller

Se connecter en SSH au routeur pour obtenir un terminal sur OpenWrt.

Variables à personnaliser puis copier-coller dans le terminal du OpenWrt :

WG_ADH_NET6="2001:db8:dead:be00::" 
WG_ADH_ADDR4="203.0.113.42" 
WG_ADH_PRIV_KEY="XF4wYSh/Ox9CoPl/YvFECu1DH6FQy7fLNUnur4sv9nM=" 

Variables et commandes à copier-coller ensuite telles quelles dans le terminal du OpenWrt (sauf expert·e) :

# Install wireguard
opkg update
opkg install wireguard luci-proto-wireguard

# Global TTNN parameters
WG_SRV_ADDR="h10.tetaneutral.net" 
WG_SRV_PORT="51820" 
WG_SRV_PUB_KEY="DsIeOCRs/5uYdi8rLiBzRNmN4zUzKCQRqY3Sbl8NS0A=" 
WG_ADH_ADDR6_LAN="${WG_ADH_NET6}1/64" 
WG_ADH_ADDR4_WAN="${WG_ADH_ADDR4}/32" 
WG_LOCAL_IF="wg0" 

# Configure firewall
uci rename firewall.@zone[0]="lan" 
uci rename firewall.@zone[1]="wan" 
uci rename firewall.@forwarding[0]="lan_wan" 
uci del_list firewall.wan.network="${WG_LOCAL_IF}" 
uci add_list firewall.wan.network="${WG_LOCAL_IF}" 
uci commit firewall
/etc/init.d/firewall restart

# Configure network
uci -q delete network.${WG_LOCAL_IF}
uci set network.${WG_LOCAL_IF}="interface" 
uci set network.${WG_LOCAL_IF}.proto="wireguard" 
uci set network.${WG_LOCAL_IF}.private_key="${WG_ADH_PRIV_KEY}" 
uci del network.lan.ip6assign
uci add_list network.lan.ip6addr="${WG_ADH_ADDR6_LAN}" 
uci add_list network.${WG_LOCAL_IF}.addresses="${WG_ADH_ADDR4_WAN}" 

# Add TTNN VPN peer
uci -q delete network.wgserver
uci set network.wgserver="wireguard_${WG_LOCAL_IF}" 
uci set network.wgserver.public_key="${WG_SRV_PUB_KEY}" 
uci set network.wgserver.endpoint_host="${WG_SRV_ADDR}" 
uci set network.wgserver.endpoint_port="${WG_SRV_PORT}" 
uci set network.wgserver.route_allowed_ips="1" 
uci set network.wgserver.persistent_keepalive="25" 
uci add_list network.wgserver.allowed_ips="::/0" 
uci add_list network.wgserver.allowed_ips="0.0.0.0/0" 

# Preserve default route
uci set network.${WG_LOCAL_IF}.metric="10" 
uci set network.wan6.metric="100" 
uci set network.wan.metric="100" 
uci commit network

# Add a hook to fix the clock before starting the VPN
cat <<EOF> /etc/hotplug.d/iface/30-ntpclient-before-vpn
#!/bin/sh

[ "\${INTERFACE}" = ${WG_LOCAL_IF} -a "\${ACTION}" = ifup ] || exit 0

default_gw6=\$(ip -6 route | grep 'default via' | awk '{ print \$3 }')
default_gw4=\$(ip -4 route | grep 'default via' | awk '{ print \$3 }')

if [ ! -z "\${default_gw6}" ]; then
  ip -6 route del default via "\${default_gw6}" 
  ip -6 route add default via "\${default_gw6}" metric 0
fi

if [ ! -z "\${default_gw4}" ]; then
  ip -4 route del default via "\${default_gw4}" 
  ip -4 route add default via "\${default_gw4}" metric 0
fi

ntpd -nq -p 0.openwrt.pool.ntp.org -p 1.openwrt.pool.ntp.org -p 2.openwrt.pool.ntp.org -p 3.openwrt.pool.ntp.org

if [ ! -z "\${default_gw6}" ]; then
  ip -6 route del default via "\${default_gw6}" 
  ip -6 route add default via "\${default_gw6}" metric 100
fi

if [ ! -z "\${default_gw4}" ]; then
  ip -4 route del default via "\${default_gw4}" 
  ip -4 route add default via "\${default_gw4}" metric 100
fi

exit 0
EOF

# Restart the network and so mount the VPN
/etc/init.d/network restart

Tests

Se connecter en DHCP avec un Linux sur l'un des ports LAN du routeur.

Sur l'interface filaire du PC on devrait obtenir quelque chose qui ressemble à :

# ip address
inet6 2001:db8:dead:be02:3e47:edd:f3cb:2e04/64 scope global dynamic mngtmpaddr
inet 192.168.1.201/24 brd 192.168.1.255 scope global dynamic enp0s25

# ip -6 route
default via fe80::4afe:7cde:fa1e:310b dev enp0s25 proto ra metric 1024 expires 1724sec hoplimit 64 pref medium

# ip -4 route
default via 192.168.1.1 dev enp0s25

Les IP retournées par curl devraient ressembler à :

# curl ip6.yunohost.org
2001:db8:dead:be02:3e47:edd:f3cb:2e04

# curl ip.yunohost.org
203.0.113.42

Notes sur IPv6

Avec cette configuration, le range IPv6 /56 fournit par Tetaneutral est réduit à un /64 pour satisfaire les pré-requis de l'autoconfiguration stateless (attribution des IP en fonction des adresses MAC).

Si vous souhaitez utiliser le range IPv6 pour faire des sous-réseaux, libre à vous d'ajouter des routes, par exemple avec les /64 restants :

* 2001:db8:dead:be00::/56 -- range complet
  * 2001:db8:dead:be00::/64 -- sous-réseau utilisé pour l'interco du WAN (pourrait être réduit)
  * 2001:db8:dead:be01::/64 -- sous-réseau libre
    [...]
  * 2001:db8:dead:beff::/64 -- sous-réseau libre

Débits

Les tests de débit (genre avec speedtest.net) sont toujours un peu aléatoires, mais il n'est pas étonnant que le VPN écrase un peu les débits. Cependant, le CPU ne semble pas particulièrement sollicité durant le test...

Tests de débit avec un TP-Link Archer C7 :

  • [Sans VPN] Down: 60 Mbps / Up: 40 Mbps
  • [Avec VPN] Down: 25 Mbps / Up: 16 Mbps