vendredi 25 septembre 2015

Router les flux torrent dans une connexion VPN sur Raspberry Pi

Pour la bonne réalisation de ce tutoriel, nous avons au préalable besoin d'un raspberry équipé d'une distribution de type raspbian. Je vous renvoie vers cet article pour la préparation de votre raspberry.
A la fin de ce tutoriel, le raspberry se connectera tout seul sur le réseau VPN, et lancera automatiquement le client BitTorrent Transmission. Une notification PushBullet sera envoyée lorsque le tunnel sera monté. Les flux torrent transiteront uniquement dans le VPN.



L'adresse du VPN étant variable, nous allons créer une interface dédié sur la loopback et nous routerons les flux sur cette interface.

En connexion ssh, commençons par installer openvpn et transmission-daemon :
sudo apt-get install openvpn transmission-daemon

Ajoutons une nouvelle table de routage :
echo 1 VPN >> /etc/iproute2/rt_tables

Création de l'interface local dédié :
vi /etc/network/interfaces

En rajoutant la configuration suivante ( à adapter en fonction votre LAN) :
## The secondary loopback network interface - VPN and torrent
auto lo:1
iface lo:1 inet static
address 192.168.10.1
netmask 255.255.255.255

Munissez-vous des confs openvpn de votre provider et des certificats afin de les rajouter au sein de openvpn :
vi /etc/openvpn/client/airvpn/AirVPN_Europe_UDP-443.conf

# --------------------------------------------------------
# Air VPN | https://airvpn.org
# OpenVPN Client Configuration
# AirVPN
# --------------------------------------------------------
client
dev tun
proto udp
remote europe.vpn.airdns.org 443
resolv-retry infinite
nobind
persist-key
persist-tun
remote-cert-tls server
cipher AES-256-CBC
comp-lzo no
route-delay 5
verb 4
explicit-exit-notify 5
ca "/etc/openvpn/client/airvpn/cert/ca.crt"
cert "/etc/openvpn/client/airvpn/cert/user.crt"
key "/etc/openvpn/client/airvpn/cert/user.key"
tls-auth "/etc/openvpn/client/airvpn/cert/ta.key" 1
#Pas de modification depuis le serveur de la table de routage
route-nopull
#Scripts locaux gérant les routes et le client torrent
script-security 2
up /etc/openvpn/client/airvpn/scripts/up.sh
down /etc/openvpn/client/airvpn/scripts/down.sh
log-append /var/log/openvpn.log
keepalive 10 60
  • La balise route-nopull nous permet de refuser les directives de routage de serveur.
When used on the client, this option effectively bars the server from adding routes to the client's routing table, however note that this option still allows the server to set the TCP/IP properties of the client's TUN/TAP interface.
  • script-security 2 permet d'appeler des scripts externes dans les fichiers up.sh et down.sh
--script-security level [method]This directive offers policy-level control over OpenVPN's usage of external programs and scripts. Lower level values are more restrictive, higher values are more permissive. Settings for level:0 -- Strictly no calling of external programs.
1 -- (Default) Only call built-in executables such as ifconfig, ip, route, or netsh.
2 -- Allow calling of built-in executables and user-defined scripts.
3 -- Allow passwords to be passed to scripts via environmental variables (potentially unsafe).
The method parameter indicates how OpenVPN should call external commands and scripts. Settings for method:
execve -- (default) Use execve() function on Unix family OSes and CreateProcess() on Windows.
system -- Use system() function (deprecated and less safe since the external program command line is subject to shell expansion).
The --script-security option was introduced in OpenVPN 2.1_rc9. For configuration file compatibility with previous OpenVPN versions, use: --script-security 3 system
  • keepalive 10 60 envoie un ping toutes les 10 secondes vers le serveur. Si aucune réponse dans les 60 secondes, openvpn se redémarrera.
Pour la prise en compte de openvpn, faisons un lien symbolique :
ln -s /etc/openvpn/client/airvpn/AirVPN_Europe_UDP-443.conf /etc/openvpn/client.conf

Création du script up.sh :
vi /etc/openvpn/client/airvpn/scripts/up.sh

#! /bin/bash
PORT_TORRENT=28195
# Route par défaut via tun0 dans la table de routage VPN
ip route add default dev $1 table VPN
# On envoie le traffic depuis lo:1 (192.168.10.1) dans la table de routage VPN
ip rule add from 192.168.10.1/32 table VPN
# On envoie le trafic depuis tun0 l'adresse IP dans la table de routage VPN
ip rule add from $4/32 table VPN
#On ajoute les règles iptables pour faire le NAT
# Regles de source NAT et destination NAT pour s'assurer que cela passe dans $
iptables -A PREROUTING -t nat -i $1 -p tcp --dport 443 -j DNAT --to 192.168.10.1
iptables -A PREROUTING -t nat -i $1 -p udp --dport 443 -j DNAT --to 192.168.10.1
iptables -A POSTROUTING -t nat -o $1 -j MASQUERADE
# On autorise le traffic des connexions établies
iptables -A INPUT -i $1 -m state --state RELATED,ESTABLISHED -j ACCEPT
# Trafic Bittorrent via tun0
iptables -N SERVICES
iptables -A SERVICES -p tcp --dport $PORT_TORRENT -j ACCEPT # rTorrent random range
iptables -A SERVICES -p udp --dport $PORT_TORRENT -j ACCEPT # DHT
# On refuse le trafic bittorent dans eth0 - pour vraiment être sur !
iptables -A FORWARD -s 192.168.10.1/32 -o eth0 -j DROP
# Démarrage de transmission
/etc/init.d/transmission-daemon restart
## Notification Pushbullet
/bin/bash /home/pi/scripts/pushbullet.sh &
  • La variable $1 dans le script up.sh contient le nom de l'interface et la variable $4 l'ip du tunnel. C'est openvpn qui les fournis aux scripts up.sh et down.sh.
  • Le port 443 est le port du provider openvpn.
  • La variable PORT_TORRENT est le port ouvert au sein de transmission, le client torrent. A configurer la valeur dans le fichier

Création du script down.sh :
#! /bin/sh
PORT_TORRENT=28195
/etc/init.d/transmission-daemon stop
#On efface les règles iptables ajoutées
iptables -D FORWARD -s 192.168.10.1/32 -o eth0 -j DROP
iptables -D SERVICES -p udp --dport $PORT_TORRENT -j ACCEPT # DHT
iptables -D SERVICES -p tcp --dport $PORT_TORRENT -j ACCEPT # rTorrent random range
iptables -D INPUT -i $1 -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -D POSTROUTING -t nat -o $1 -j MASQUERADE
iptables -D PREROUTING -t nat -i $1 -p udp --dport 443 -j DNAT --to 192.168.10.1
iptables -D PREROUTING -t nat -i $1 -p tcp --dport 443 -j DNAT --to 192.168.10.1
# on enlève lo:1 (192.168.10.1) de la table de routage VPN
ip rule del from 192.168.10.1/32 table VPN
# on enlève l'ip VPN de la table de routage VPN
ip rule del from $4/32 table VPN

Configuration de transmission-daemon (faire attention à bien arrêter le daemon afin la modification de settings.json) :
sudo /etc/init.d/transmission-daemon stop
sudo vi /etc/transmission-daemon/settings.json
{
"alt-speed-down": 60,
"alt-speed-enabled": true,
"alt-speed-time-begin": 1020,
"alt-speed-time-day": 127,
"alt-speed-time-enabled": true,
"alt-speed-time-end": 30,
"alt-speed-up": 30,
"bind-address-ipv4": "192.168.10.1",
"bind-address-ipv6": "::",
"blocklist-enabled": true,
"blocklist-url": "http://list.iblocklist.com/?list=bt_level1&fileformat=p2p&archiveformat=gz",
"cache-size-mb": 1,
"dht-enabled": true,
"download-dir": "/home/pi/downloads",
"download-limit": 100,
"download-limit-enabled": 0,
"download-queue-enabled": true,
"download-queue-size": 5,
"encryption": 1,
"idle-seeding-limit": 30,
"idle-seeding-limit-enabled": false,
"incomplete-dir": "/home/pi/downloads/incomplete",
"incomplete-dir-enabled": true,
"lpd-enabled": false,
"max-peers-global": 200,
"message-level": 2,
"peer-congestion-algorithm": "",
"peer-limit-global": 240,
"peer-limit-per-torrent": 100,
"peer-port": VALEUR de PORT_TORRENT,
"peer-port-random-high": 65535,
"peer-port-random-low": 49152,
"peer-port-random-on-start": false,
"peer-socket-tos": "default",
"pex-enabled": true,
"port-forwarding-enabled": true,
"preallocation": 1,
"prefetch-enabled": 1,
"queue-stalled-enabled": true,
"queue-stalled-minutes": 30,
"ratio-limit": 1,
"ratio-limit-enabled": true,
"rename-partial-files": true,
"rpc-authentication-required": true,
"rpc-bind-address": "0.0.0.0",
"rpc-enabled": true,
"rpc-password": "PASSWORD",
"rpc-port": PORT_DISTANT,
"rpc-url": "/transmission/",
"rpc-username": "USERNAME",
"rpc-whitelist": "",
"rpc-whitelist-enabled": false,
"scrape-paused-torrents-enabled": true,
"script-torrent-done-enabled": true,
"script-torrent-done-filename": "",
"seed-queue-enabled": false,
"seed-queue-size": 10,
"speed-limit-down": 100,
"speed-limit-down-enabled": false,
"speed-limit-up": 250,
"speed-limit-up-enabled": false,
"start-added-torrents": true,
"trash-original-torrent-files": false,
"umask": 18,
"upload-limit": 100,
"upload-limit-enabled": 0,
"upload-slots-per-torrent": 14,
"utp-enabled": true
}
Modifiez les valeurs USERNAME et PASSWORD et PORT_DISTANT en fonction de vos besoins. Ces valeurs concernent l'accès à distance via l'interface web. Modifiez la valeur de peer-port en fonction de celle des scripts up.sh et down.sh et modifiez la valeur de bind-address-ipv4 en fonction de l'ip de lo:1

Création du script de notification Pushbullet :
vi /home/pi/scripts/pushbullet.sh

puis :
/bin/sleep 5
CURL_CMD="$(which curl)"
DATE="$(date +"%d-%m-%y à %T")"
API_TOKEN="API_PUSHBULLET"
IPWAN_VPN=$(curl --silent --interface tun0 ifconfig.co)
IPWAN_VPN_COUNTRY="$(echo $(geoiplookup $IPWAN_VPN) | awk {'print $5'})"
$CURL_CMD --silent --header 'Authorization: Bearer '"$API_TOKEN"'' -X POST https://api.pushbullet.com/v2/pushes --header 'Content-Type: application/json' --data-binary '{"type": "note", "title": "[VPN] Connected on '"$IPWAN_VPN_COUNTRY"'", "body": "Connected on '"$IPWAN_VPN"' at '"$DATE"'"}'

Pour le bon fonctionnement du script, installons les programmes et dépendances :
sudo apt-get install curl geoip-bin

Pour mettre à jour la géolocalisation des ip, nous pouvons rajouter dans une crontab :
crontab -e

puis :
0 3 1 * * /home/pi/scripts/geopip_update.sh > /dev/null 2>&1

puis :
vi /home/pi/scripts/geopip_update.sh

#!/bin/bash
# geoip-update.sh -- update geoip lite database(s).
prg="wget --quiet"
#prg="wget"
download_path="/usr/share/GeoIP/download"
geolite_path="/usr/share/GeoIP"
#set -e
[ -d $download_path ] || mkdir $download_path
if [ ! -e $geolite_path ]; then
echo "Unable to find GeoIP directory: $geolite_path"
exit 1
fi
cd $download_path
$prg http://geolite.maxmind.com/download/geoip/database/GeoLiteCountry/GeoIP.dat.gz
if [ ! -e $download_path/GeoIP.dat.gz ]; then
echo "Unable to find GeoIP.dat.gz!"
exit 1
fi
gunzip -c $download_path/GeoIP.dat.gz > $geolite_path/GeoIP.dat
rm -f $download_path/GeoIP.dat.gz
$prg http://geolite.maxmind.com/download/geoip/database/GeoLiteCity.dat.gz
if [ ! -e $download_path/GeoLiteCity.dat.gz ]; then
echo "Unable to find GeoLiteCity.dat.gz!"
exit 1
fi
gunzip -c $download_path/GeoLiteCity.dat.gz > $geolite_path/GeoLiteCity.dat
rm -f $download_path/GeoLiteCity.dat.gz



Aucun commentaire:

Publier un commentaire