Outils pour utilisateurs

Outils du site


reseau:wireguard

Wireguard

Pourquoi wg ?

  • ovpn c’est chiant à gérer
  • dès que quelqu’un tire un peu sur ovpn, la machine est à plat
  • wg a de bien meilleures perfs
  • on est en 2024

Technique

Pour le moment le PoC se passe sur ovpn02.grif histoire d’éviter de spawn une VM juste pour les tests

La mise en place se fait avec deux fichiers et trois commandes. Chaque utilisateur a son port que l’on extrapole du dernier bloc de l’adresse IPv6 : 2a00:5884:8316::/48 donne printf '%d\n' '0x8316' soit 33558.

Ensuite, on écrit la conf dans /etc/wireguard/wg$port.conf, par exemple :

/etc/wireguard/wg33558.conf
[Interface]
ListenPort = 33558
PrivateKey = blah=

[Peer]
PublicKey = YtTa180Wgh3HiV4iVxoFL8vb3E+NueGpv4BLGuN3Zgs=
AllowedIPs = 89.234.186.78/32, 2a00:5884:8316::/48

Par défaut gentoo ignore toute la magie de wg-quick et ça nous va assez bien. On a pas envie d’avoir des rules et du marquage de firewall sur la machine de routage wg. On utilise les tools de base de gentoo pour mettre la route dans le kernel :

/etc/conf.d/net.wg33558
wireguard_wg33558="/etc/wireguard/wg33558.conf"
config_wg33558="null"
routes_wg33558="
89.234.186.78/32
2a00:5884:8316::/48
"

postup () {
	ip link set wg33558 alias "Cust: yvonnick"
}

Ensuite, on fait démarrer l’interface par défaut :

ln -s /etc/init.d/net.lo /etc/init.d/net.wg33558
rc-update add net.wg33558
rc-service net.wg33558 start

Gestion de la MTU

wg a une interface avec une MTU de 1420, et il ne fait pas de clamping par défaut, donc on le fait avec netfilter :

iptables -t mangle -A FORWARD -i wg+ -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
iptables -t mangle -A POSTROUTING -o wg+ -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
rc-service iptables save
ip6tables -t mangle -A FORWARD -i wg+ -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
ip6tables -t mangle -A POSTROUTING -o wg+ -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
rc-service ip6tables save

Debug

Wireguard étant un module kernel, il faut jouer avec le debug du kernel :

echo module wireguard +p > /sys/kernel/debug/dynamic_debug/control # activation
echo module wireguard -p > /sys/kernel/debug/dynamic_debug/control # desactivation

Ensuite ça se consulte avec dmesg -Tw. À noter que le temps dans dmesg n’est pas hyper fiable, et que ça nécessite l’option kernel DYNAMIC_DEBUG.

Configuration côté client

J’ai aussi fait le test avec une gentoo, et j’ai du routage par rules sur ce routeur, donc ça donne ça :

/etc/conf.d/net.wg33558
[Interface]
PrivateKey = blahblah=

[Peer]
Endpoint = wg.grifon.fr:33558
PublicKey = 0LFVijcJWjjgdSjnBQXSrPXkCy3fqA/DcYbO7ERW6mM=
AllowedIPs = 0.0.0.0/0, ::/0
/etc/conf.d/net.wg33558
wireguard_wg33558="/etc/wireguard/wg33558.conf"
config_wg33558="89.234.186.78/32 2a00:5884:8316::1/128"
routes_wg33558="
0.0.0.0/0 dev wg33558 table 204092
::/0 dev wg33558 table 204092
"

Un petit sed pour le firewall et zou !

De toutes façons on fournira un fichier de conf client d’exemple comme on le faisait pour OpenVPN.

Script de génération

Voici la v1 du script de génération de VPN wg. C’est une adaptation bête de celui d’OpenVPN.

/usr/local/sbin/add-wg
#!/bin/sh
 
usage() {
    printf "Usage:\n"
    printf "\t-h, --help    Affiche ce message d’aide\n"
    printf "\t-u, --user    Identifiant de connexion au VPN\n"
    printf "\t-i, --id  Numéro servant à la génération des IPs\n"
    printf "\t-m, --email   Adresse mail à qui envoyer les informations de
connexion\n"
}
 
OPTS=$(getopt -o u:,m:,h -l user:,email:,help -- "$@")
 
if [ $? != 0 ]; then
    exit 1
fi
 
if [ $1 ]; then
    if [ $1 = '-h' ] || [ $1 = '--help' ]; then
        usage
        exit 0
    elif [ $# -lt 4 ]; then
        echo "Paramètre manquant"
        usage
        exit 1
    fi
else
    echo "Paramètre manquant"
    usage
    exit 1
fi
 
eval set -- "$OPTS"
 
while :; do
    case "$1" in
        -h | --help)    usage;
                exit 0;;
        -u | --user)    user="$2";
                shift 2;;
        -m | --email)   EMAIL="$2";
                shift 2;;
        --)     shift; break;;
    esac
done
 
mailregex=$(echo $EMAIL | egrep '[^.]+@[^.]+\.[^.]+')
if [ ${#mailregex} != ${#EMAIL} ]; then
    echo "Adresse mail invalide"
    exit 1
fi
 
echo "1 - Récupération last IPv4"
LAST_VPN_V4=$(add-ovpn.netbox.py -a ipv4 -u "${user}")
V4_RETURN=$?
echo ${LAST_VPN_V4}
if [ ${V4_RETURN} = 1 ]; then
	exit 1
fi
 
echo "2 - Récupération last IPv6"
LAST_VPN_V6=$(add-ovpn.netbox.py -a ipv6 -u "${user}")
echo ${LAST_VPN_V6}
 
WG_PORT=$(printf '%d' "0x$(echo ${LAST_VPN_V6} | cut -d ':' -f 3)")
 
echo "3 - Génération de la clé wg" >&2
wg genkey | tee "/etc/wireguard/wg${WG_PORT}-srv.key" | wg pubkey > "/etc/wireguard/wg${WG_PORT}-srv.pub"
wg genkey | tee "/etc/wireguard/wg${WG_PORT}-clt.key" | wg pubkey > "/etc/wireguard/wg${WG_PORT}-clt.pub"
 
echo "4.1 - Génération de la configuration wg" >&2
echo "[Interface]
ListenPort = ${WG_PORT}
PrivateKey = $(cat /etc/wireguard/wg${WG_PORT}-srv.key)
 
[Peer]
PublicKey = $(cat /etc/wireguard/wg${WG_PORT}-clt.pub)
AllowedIPs = ${LAST_VPN_V4}/32, ${LAST_VPN_V6}" > "/etc/wireguard/wg${WG_PORT}.conf"
 
echo "4.2 - Génération de la configuration ip" >&2
echo "wireguard_wg${WG_PORT}=\"/etc/wireguard/wg${WG_PORT}.conf\"
config_wg${WG_PORT}=\"null\"
routes_wg${WG_PORT}=\"
${LAST_VPN_V4}/32
${LAST_VPN_V6}
\"
 
postup () {
	ip link set wg${WG_PORT} alias \"Cust: ${user}\"
}" > "/etc/conf.d/net.wg${WG_PORT}"
 
echo "4.3 - Activation du VPN" >&2
ln -s /etc/init.d/net.lo /etc/init.d/net.wg${WG_PORT}
rc-update add net.wg${WG_PORT}
rc-service net.wg${WG_PORT} start
 
echo "5 - Envoi du mail" >&2
SUBJECT=$(perl -wse "use utf8; use Encode qw(encode); print encode(\"MIME-Q\",\
\"Votre VPN wireguard vient d’être créé\");")
 
echo "Date: $(date --rfc-2822)
Content-Type: text/plain; charset=UTF-8
MIME-Version: 1.0
Content-Transfer-Encoding: 8bit
From: Adminsys grifon <adminsys@grifon.fr>
To: <$EMAIL>
Subject: $SUBJECT
Organization: Grifon
Message-ID: <$(date | md5sum | cut -d ' ' -f 1)@wg.grifon.fr>
 
Bonjour,
Votre VPN vient d’être créé.
 
Vous avez l’IPv4 $LAST_VPN_V4 et le subnet IPv6 $LAST_VPN_V6.
Votre configuration se trouve à la fin de ce mail.
Si vous souhaitez regénérer votre clé, n’hésitez pas à nous envoyer votre
nouvelle clé publique.
 
Si vous voulez un reverse DNS sur votre VPN, merci d’envoyer un mail à
adminsys@grifon.fr contenant votre choix, ou les serveurs à qui déléguer les
zones.
 
##### DÉBUT DU FICHIER DE CONFIGURATION #####
 
[Interface]
PrivateKey = $(cat /etc/wireguard/wg${WG_PORT}-clt.key)
DNS = 89.234.186.4, 89.234.186.5, 2a00:5884::7, 2a00:5884::9
 
[Peer]
Endpoint = wg.grifon.fr:${WG_PORT}
PublicKey = $(cat /etc/wireguard/wg${WG_PORT}-srv.pub)
AllowedIPs = 0.0.0.0/0, ::/0
 
##### FIN DU FICHIER DE CONFIGURATION #####
 
Cordialement,
--
Les adminsys de grifon" | /usr/sbin/sendmail -f adminsys@grifon.fr -t
 
 
SUBJECT=$(perl -wse "use utf8; use Encode qw(encode); print encode(\"MIME-Q\",\
\"Création du VPN wg de $user\");")
 
echo "From: Adminsys grifon <adminsys@grifon.fr>
To: adminsys@grifon.fr
Content-Type: text/plain; charset=UTF-8
Subject: ${SUBJECT}
 
IPv4 : ${LAST_VPN_V4}
IPv6 : ${LAST_VPN_V6}
 
" | /usr/sbin/sendmail -f adminsys@grifon.fr -t
reseau/wireguard.txt · Dernière modification : 2024/08/17 13:58 de alarig