Lancer un serveur VPN derrière un NAT de fournisseur

Un article sur la façon dont j'ai réussi à me connecter serveur VPN derrière le NAT de mon fournisseur d'accès domestique (sans adresse IP publique). Je précise tout de suite que le fonctionnement de cette solution dépend directement du type de NAT utilisé par votre fournisseur, ainsi que du routeur.
Donc, j'avais besoin de me connecter de mon smartphone Android à mon ordinateur à domicile, les deux appareils étant connectés à Internet via les NAT de mon fournisseur, et de plus, l'ordinateur étant connecté via un routeur domestique qui NAT également les connexions.
Le schéma classique utilisant un VPS/VDS loué avec une adresse IP publique, ainsi que la location d'une adresse IP publique auprès du fournisseur, n'a pas été envisagé pour plusieurs raisons.
En tenant compte de l'expérience des articles précédents, après avoir réalisé plusieurs expériences avec des STUN et les NAT des fournisseurs. J'ai décidé de faire une petite expérience, en exécutant la commande sur mon routeur domestique fonctionnant sur le firmware OpenWRT :

$ stun stun.sipnet.ru

j'ai obtenu le résultat :

Port 21234 ouvert avec fd 3
Principal : Mapping Indépendant, Filtre Indépendant, port aléatoire, va faire une pince
La valeur de retour est 0x000002

Traduction littérale :
Mapping Indépendant — mapping indépendant
Filtre Indépendant — filtre indépendant
port aléatoire — port aléatoire
va faire une pince — va être un hairpin
En exécutant une commande similaire sur mon PC, j'ai obtenu :

Port 21234 ouvert avec fd 3
La valeur de retour est 0x000006
La valeur de retour est 0x000006

Filtre Dépendant du Port — filtre dépendant du port
La différence dans les résultats des commandes indiquait que le routeur domestique avait « sa part » dans le processus de translation des paquets depuis Internet ; cela se manifestait par le fait qu'en exécutant la commande sur l'ordinateur :

stun stun.sipnet.ru -p 11111 -v

j'obtenais le résultat :

…
MappedAddress = XX.1XX.1X4.2XX:4398
…

à ce moment-là, une session UDP s'ouvrirait temporairement, si à ce moment-là j'envoyais une demande UDP (par exemple : netcat XX.1XX.1X4.2XX 4398 -u), la demande atteignait le routeur domestique, ce que confirmait TCPDump lancé sur celui-ci, mais la demande n'atteignait pas l'ordinateur — IPtables en tant que traducteur NAT sur le routeur la supprimait.
Lancement d'un serveur VPN derrière un NAT de fournisseur
Mais le simple fait que la demande UDP traverse le NAT de mon fournisseur offrait de l'espoir pour le succès. Comme le routeur est sous ma juridiction, j'ai résolu le problème en redirigeant le port UDP/11111 vers l'ordinateur :

iptables -t nat -A PREROUTING -i eth1 -p udp -d 10.1XX.2XX.XXX --dport 11111 -j DNAT --to-destination 192.168.X.XXX

Ainsi, j'ai pu initier une session UDP et recevoir des requêtes Internet depuis n'importe quelle adresse IP. À ce moment-là, j'ai lancé le serveur OpenVPN (après l'avoir configuré) en écoutant le port UDP/11111, j'ai indiqué sur le smartphone l'adresse IP externe et le port (XX.1XX.1X4.2XX:4398) et je me suis connecté avec succès depuis le smartphone à l'ordinateur. Cependant, dans cette réalisation, un problème est survenu : il fallait maintenir la session UDP jusqu'à ce que le client OpenVPN se connecte au serveur, l'option de lancer périodiquement un client STUN ne m'a pas plu — je ne voulais pas surcharger inutilement les serveurs STUN.
J'ai également remarqué l'enregistrement «va faire une pince — va être un hairpin«, ce mode

Le Hairpinning permet à une machine sur un réseau local derrière un NAT d'accéder à une autre machine sur le même réseau via l'adresse externe du routeur.

Lancement d'un serveur VPN derrière un NAT de fournisseur
Finalement, j'ai résolu le problème de maintien de la session UDP simplement en lançant le client sur le même ordinateur que le serveur.
Cela fonctionnait comme suit :

  • je lançais le client STUN avec le port local 11111
  • je recevais une réponse avec l'adresse IP externe et le port XX.1XX.1X4.2XX:4398
  • j'envoyais des données avec l'adresse IP externe et le port par e-mail (tout autre service est possible), configuré sur le smartphone
  • je lançais le serveur OpenVPN sur l'ordinateur en écoutant le port UDP/11111
  • je lançais le client OpenVPN sur l'ordinateur en indiquant XX.1XX.1X4.2XX:4398 pour se connecter
  • à tout moment, je lançais le client OpenVPN sur le smartphone en indiquant l'adresse IP et le port (dans mon cas, l'adresse IP ne changeait pas) pour me connecter

Lancement d'un serveur VPN derrière un NAT de fournisseur
Ainsi, j'ai pu me connecter à mon ordinateur depuis mon smartphone. Cette réalisation permet de connecter n'importe quel client OpenVPN.

Pratique

Il faudra :

# apt install openvpn stun-client sendemail

En écrivant quelques scripts, quelques fichiers de configuration, en générant les certificats nécessaires (car le client sur le smartphone fonctionne uniquement avec des certificats), j'ai obtenu une réalisation classique d'un serveur OpenVPN.

Le script principal sur l'ordinateur

# cat vpn11.sh
#!/bin/bash
until [[ -n "$iftosrv" ]]; do echo "$(date) Определяю сетевой интерфейс"; iftosrv=`ip route get 8.8.8.8 | head -n 1 | sed 's|.*dev ||' | awk '{print $1}'`; sleep 5; done
ABSOLUTE_FILENAME=`readlink -f "$0"`
DIR=`dirname "$ABSOLUTE_FILENAME"`
localport=11111
until [[ $a ]]; do
	address=`stun stun.sipnet.ru -v -p $localport 2>&1 | grep "MappedAddress" | sort | uniq | head -n 1 | sed 's/:/ /g' | awk '{print $3" "$4}'`
        ip=`echo "$address" | awk {'print $1'}`
        port=`echo "$address" | awk {'print $2'}`
	srv="openvpn --config $DIR/server.conf --port $localport --daemon"
	$srv
	echo "$(date) Сервер запущен с внешним адресом $ip:$port"
	$DIR/sendemail.sh "OpenVPN-Server" "$ip:$port"
	sleep 1
	openvpn --config $DIR/client.conf --remote $ip --port $port
	echo "$(date) Cоединение клиента с сервером разорвано"
	for i in `ps xa | grep "$srv" | grep -v grep | awk '{print $1}'`; do
		kill $i && echo "$(date) Завершен процесс сервера $i ($srv)"
		done
	echo "Жду 15 сек"
	sleep 15
	done

Le script d'envoi de données par e-mail :

# cat sendemail.sh 
#!/bin/bash
from="От кого"
pass="Пароль"
to="Кому"
theme="$1"
message="$2"
server="smtp.yandex.ru:587"
sendEmail -o tls=yes -f "$from" -t "$to" -s "$server" -xu "$from" -xp "$pass" -u "$theme" -m "$message"

Fichier de configuration du serveur :

# cat server.conf
proto udp
dev tun
ca      /home/vpn11-srv/ca.crt
cert    /home/vpn11-srv/server.crt
key     /home/vpn11-srv/server.key
dh      /home/vpn11-srv/dh2048.pem
server 10.2.0.0 255.255.255.0
ifconfig-pool-persist ipp.txt
tls-server
tls-auth /home/vpn11-srv/ta.key 0
tls-timeout 60
auth    SHA256
cipher  AES-256-CBC
client-to-client
keepalive 10 30
comp-lzo
max-clients 10
user nobody
group nogroup
persist-key
persist-tun
log /var/log/vpn11-server.log
verb 3
mute 20

Fichier de configuration du client :

# cat client.conf
client
dev tun
proto udp
ca      "/home/vpn11-srv/ca.crt"
cert    "/home/vpn11-srv/client1.crt"
key     "/home/vpn11-srv/client1.key"
tls-client
tls-auth "/home/vpn11-srv/ta.key" 1
auth SHA256
cipher AES-256-CBC
auth-nocache
comp-lzo
user nobody
group nogroup
persist-key
persist-tun
log /var/log/vpn11-clent.log
verb 3
mute 20
ping 10
ping-exit 30

La génération des certificats a été réalisée par cet article.
Lancement du script :

# ./vpn11.sh

Après l'avoir rendu exécutable

# chmod +x vpn11.sh

Du côté du smartphone

En installant l'application OpenVPN pour Android, en copiant le fichier de configuration, les certificats et en le configurant, cela a donné :
Sur le smartphone, je vérifie mes mailsLancement d'un serveur VPN derrière un NAT de fournisseur
Je modifie le numéro de port dans les paramètresLancement d'un serveur VPN derrière un NAT de fournisseur
Je lance le client et me connecteLancement d'un serveur VPN derrière un NAT de fournisseur

Pendant l'écriture de cet article, j'ai transféré la configuration de l'ordinateur vers un Raspberry Pi 3 et j'ai essayé de tout faire fonctionner avec un modem LTE, mais cela n'a pas fonctionné ! Le résultat de la commande

# stun stun.ekiga.net -p 11111

Port 21234 ouvert avec fd 3
La valeur de retour est 0x000006
La valeur de retour est 0x000006

la valeur Filtre Dépendant du Port a empêché le système de démarrer.
Mais le fournisseur d'accès à domicile a permis au système de démarrer sans problème sur le Raspberry Pi 3.
En association avec une webcam, avec VLC pour
créer un flux RTSP à partir de la webcam

$ cvlc v4l2:///dev/video0:chroma=h264 :input-slave=alsa://hw:1,0 --sout '#transcode{vcodec=x264,venc=x264{preset=ultrafast,profile=baseline,level=31},vb=2048,fps=12,scale=1,acodec=mpga,ab=128,channels=2,samplerate=44100,scodec=none}:rtp{sdp=rtsp://10.2.0.1:8554/}' --no-sout-all --sout-keep

et VLC sur le smartphone pour visionner (flux rtsp://10.2.0.1:8554/), j'ai obtenu un bon système de vidéosurveillance à distance, il est également possible de mettre en place Samba, de router le trafic via VPN, de gérer l'ordinateur à distance et bien plus encore...

Sortie

Comme l'a montré l'expérience, pour organiser un serveur VPN, il est possible de se passer d'une adresse IP publique pour laquelle il faut payer, tout comme pour celle qui est louée VPS/VDS. Mais tout dépend du fournisseur. Bien sûr, j'aurais voulu obtenir plus d'informations sur les différents fournisseurs et les types de NAT utilisés, mais ceci n'est que le début...
Merci de votre attention !

Source : habr.com

Acheter un hébergement fiable pour les sites avec protection DDoS, serveurs VPS VDS 🔥 Acheter un hébergement fiable pour les sites avec protection DDoS, serveurs VPS VDS | ProHoster