Proxy pour seedbox


Comme j'aime ma vie privée (surtout vis-à-vis de l'ARCOM), j'ai eu besoin de présenter comme IP publique une autre que celle-chez moi pour mon client Torrent (qBittorrent pour le moment). Le principe de seedbox chez un hébergeur me plaît pas trop, je préfère avoir les données à domicile pour la pérénité, décentralisation et des coûts plus faibles.

J'utilise habituellement systemd-networkd, je continue donc à l'utiliser pour ce projet. Et c'est l'occasion pour moi d'utiliser à long-terme Wireguard.

Configuration

Côté serveur distant "proxy"

Interface réseau publique

Le serveur a une adresse publique IPv4 (X.X.X.X/24) et IPv6 (2001:X:X:X::1/64), auxquelles on ajoute une autre (2001:X:X:X::2/64) qui sera routée au travers du tunnel. Pour que le trafic en direction de cette adresse soit routé, et non masqueradé/naté, cette IP ne doit pas être présente sur l'interface réseau publique du serveur. Mais il faut tout de même indiquer aux routeurs proches que le trafic de cette IP doit passer par le serveur. Cela se fait grâce à la directive IPv6ProxyNDPAddress=2001:X:X:X::2/64, qui indique au serveur qu'il doit répondre aux sollicitations des autres machines pour l'IPv6 concernée.

systemd/network/20-wired.network

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
[Match]
Name=eth0

[Network]
Address=X.X.X.X/24
Address=2001:X:X:X::1/64
Gateway=X.X.X.X
DNS=X.X.X.X
IPv6ProxyNDPAddress=2001:X:X:X::2/64

# Spécificité de mon hébergeur OVH, la gateway IPv6 n'est pas sur le même réseau /64
# Il faut donc forcer la route avec GatewayOnLink=yes
[Route]
Gateway=2001:41D0:A:25ff:ff:ff:ff:ff
GatewayOnLink=yes

Interface Wireguard

La configuration de l'interface Wireguard a deux particularités : Le trafic IPv4 est masqueradé (Source NAT) avec IPMasquerade=IPv4, et une route est ajoutée sur ce périphérique pour router le trafic au travers de l'interface, même si elle ne porte pas cette IP.

/etc/systemd/network/50-wg0.network

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
[Match]
Name=wg0

[Network]
Address=10.0.0.1/24
Address=fdc9:281f:04d7:9ee9::1/64
IPMasquerade=IPv4

[Route]
Destination=2001:41d0:a:2511::2/128

/etc/systemd/network/50-wg0.netdev

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
[NetDev]
Name=wg0
Kind=wireguard
Description=WireGuard tunnel wg0

[WireGuard]
ListenPort=51871
PrivateKey=XXX

[WireGuardPeer]
PublicKey=XXX
PresharedKey=XXX
AllowedIPs=10.0.0.2/32
AllowedIPs=fdc9:281f:04d7:9ee9::2/128
AllowedIPs=2001:X:X:X::2/128
Endpoint=client.fqdn:51902

La configuration Wireguard est plutôt classique, et inspirée du wiki Archlinux. À part IPMasquerade=IPv4, qui permet de faire du masquerading: les connexions IPv4 provenant du tunnel (10.0.0.0/24), à direction d'autres réseaux (ici Internet), seront traduites dynamiquement par le serveur, Ce paramètre implique automatiquement IPForward=IPv4, ce qui active le routage sur le serveur.

La configuration netdev est classique :

/etc/systemd/network/50-wg0.netdev

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
[NetDev]
Name=wg0
Kind=wireguard
Description=WireGuard tunnel wg0

[WireGuard]
ListenPort=51871
PrivateKey=<Private key>

[WireGuardPeer]
PublicKey=<Public key>
PresharedKey=<PSK>
AllowedIPs=10.0.0.2/32
AllowedIPs=fdc9:281f:04d7:9ee9::2/128
AllowedIPs=2001:X:X:X::2/128
Endpoint=<Public seedbox IP and port>

Ajouter et sauvegarder une règle DNAT Ipv4 pour rediriger le trafic entrant IPv4 du port 50000 sur l'adresse IP de la seedbox au travers du tunnel IPv4. Penser à activer la restauration des règles IPtables au démarrage si ce n'est pas déjà fait.

1
2
iptables -t nat -A PREROUTING -p tcp --dport 50000 -i eth0 -j DNAT --to 10.0.0.2:50000
iptables-save -f /etc/iptables/iptables.rules

Dernière étape : permettre une redirection de port depuis l'IPv4 publique unique du serveur, vers l'IP du client via le tunnel.

Côté Seedbox locale

La configuration côté client torrent est plus subtile. Pour avoir deux routes par défaut, différentes entre les deux interfaces réseau (celle "classique", et le tunnel wireguard wg0), il y a besoin de marquer avec FirewallMark les paquets afférents à l'interface wireguard, et les envoyer sur une seconde table de routage (1000) avec une RoutingPolicyRule. Il faut aussi ajouter une [Route] pour préciser où se situe la passerelle par défaut via l'adresse Unique-Local. Pour la génération des clés, voir le wiki Archlinux.

/etc/systemd/network/50-wg0.netdev

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
[NetDev]
Name=wg0
Kind=wireguard
Description=WireGuard tunnel wg0

[WireGuard]
ListenPort=51902
PrivateKey=<Private Key>
FirewallMark=0x8888

[WireGuardPeer]
PublicKey=<Public key>
PresharedKey=<PSK>
AllowedIPs=0.0.0.0/0
AllowedIPs=::/0
Endpoint=<Remote server and port>

/etc/systemd/network/50-wg0.network

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
[Match]
Name=wg0

[Network]
Address=10.0.0.2/24
Address=fdc9:281f:04d7:9ee9::2/64
Address=2001:41d0:a:2511::2/128

[Address]
Address=fe80::64:2/10/64
Scope=link

[RoutingPolicyRule]
FirewallMark=0x8888
Table=1000
Priority=10

[Route]
Gateway=fdc9:281f:4d7:9ee9::1
Table=1000

[RoutingPolicyRule]
Table=1000
From=2001:41d0:a:2511::/64

Conclusion

C'était pas évident de trouver comment avoir les deux tables de routage. Il y a sûrement une meilleure manière de faire, qu'il faudra pas hésiter à partager si un jour j'ajoute les commentaires sur ce blog :p Sinon via mes réseaux sociaux, et je citerait les améliorations. Mais globalement j'en suis très satisfait, ça marche de manière transparente pour le client torrent (il faut juste préciser les adresses IP publiques à donner aux traqueurs).