Inicio de un servidor VPN detrás de la NAT de un proveedor

Un artículo sobre cómo logré ejecutar un servidor VPN detrás de la NAT de un proveedor doméstico (sin una dirección IP blanca). Déjame decirte de inmediato: el rendimiento de esta implementación depende directamente del tipo de NAT que utilice su proveedor, así como del enrutador.
Entonces, necesitaba conectarme desde mi teléfono inteligente Android a la computadora de mi casa, ambos dispositivos están conectados a Internet a través de NAT del proveedor, además la computadora está conectada a través de un enrutador doméstico, que también tiene conexiones NAT.
El esquema clásico que utiliza un VPS/VDS arrendado con una dirección IP blanca, así como el alquiler de una dirección IP blanca del proveedor, no se consideró por varias razones.
En vista de experiencia de artículos anteriores, habiendo pasado varios experimentos con STUNs y NATs de proveedores. Me decidí por un pequeño experimento ejecutando el comando en un enrutador doméstico que ejecuta el firmware OpenWRT:

$ stun stun.sipnet.ru

obtuve el resultado:

Cliente STUN versión 0.97
Primario: mapeo independiente, filtro independiente, puerto aleatorio, horquilla
el valor devuelto es 0x000002

Traducción literal
Mapeo independiente - visualización independiente
Filtro independiente - filtro independiente
puerto aleatorio - puerto aleatorio
habrá horquilla - habrá una horquilla
Después de ejecutar un comando similar en mi PC, obtuve:

Cliente STUN versión 0.97
Primario: mapeo independiente, filtro dependiente del puerto, puerto aleatorio, horquilla
el valor devuelto es 0x000006

Filtro dependiente del puerto - filtro dependiente del puerto
La diferencia en los resultados de la salida de los comandos indicó que el enrutador doméstico hizo "su contribución" al proceso de transmisión de paquetes desde Internet, esto se manifestó en el hecho de que cuando se ejecutó el comando en la computadora:

stun stun.sipnet.ru -p 11111 -v

obtuve el resultado:

...
Dirección asignada = XX.1XX.1X4.2XX:4398
...

en ese momento, se abrió una sesión UDP por un tiempo, si en ese momento se envió una solicitud UDP (por ejemplo: netcat XX.1XX.1X4.2XX 4398 -u), entonces la solicitud llegó al enrutador doméstico, que fue confirmado por TCPDump ejecutándose en él, pero la solicitud no llegó a la computadora: IPtables como un traductor NAT en el enrutador lo dejó caer.
Inicio de un servidor VPN detrás de la NAT de un proveedor
Pero el solo hecho de pasar una solicitud UDP a través del NAT del proveedor dio esperanzas de éxito. Como el router está en mi jurisdicción, resolví el problema redirigiendo el puerto UDP/11111 a la computadora:

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

Por lo tanto, tuve la oportunidad de iniciar una sesión UDP y recibir solicitudes de Internet desde cualquier dirección IP. En este momento, inicié el servidor OpenVPN (después de configurarlo) escuchando el puerto UDP/11111, indiqué la dirección IP externa y el puerto (XX.1XX.1X4.2XX:4398) en el teléfono inteligente y conecté con éxito desde el teléfono inteligente al computadora. Pero en esta implementación surgió un problema, era necesario mantener de alguna manera la sesión UDP hasta que el cliente OpenVPN se conectara al servidor, no me gustaba la opción de lanzar periódicamente el cliente STUN - No quería cargar servidores STUN en vano.
También llamó la atención la entrada "habrá horquilla - habrá una horquilla", este modo

Hairpinning permite que una máquina en una red local detrás de NAT acceda a otra máquina en la misma red en la dirección externa del enrutador.

Inicio de un servidor VPN detrás de la NAT de un proveedor
Como resultado, resolví el problema de mantener una sesión UDP simplemente: inicié el cliente en la misma computadora con el servidor.
Funcionó así:

  • lanzó el cliente STUN con el puerto local 11111
  • respuesta recibida con dirección IP externa y puerto XX.1XX.1X4.2XX:4398
  • datos enviados con una dirección IP externa y puerto al correo (cualquier otro servicio es posible) configurado en el teléfono inteligente
  • lanzó un servidor OpenVPN en una computadora que escucha en el puerto UDP/11111
  • lanzó un cliente OpenVPN en una computadora especificando XX.1XX.1X4.2XX:4398 para conectarse
  • en cualquier momento lanzó el cliente OpenVPN en el teléfono inteligente, especificando la dirección IP y el puerto (en mi caso, la dirección IP no cambió) para conectarse

Inicio de un servidor VPN detrás de la NAT de un proveedor
Por lo tanto, tuve la oportunidad de conectarme a mi computadora desde un teléfono inteligente. Esta implementación le permite conectarse a cualquier cliente OpenVPN.

Práctica

Usted necesitará:

# apt install openvpn stun-client sendemail

Después de escribir un par de scripts, un par de archivos de configuración, generar los certificados necesarios (dado que el cliente en el teléfono inteligente solo funciona con certificados), obtuvimos la implementación habitual del servidor OpenVPN.

Guión principal en la computadora

# 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

Script de envío de correo electrónico:

# 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"

Archivo de configuración del servidor:

# 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

Archivo de configuración del cliente:

# 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

Los certificados se generaron de acuerdo con este artículo.
Ejecutando el script:

# ./vpn11.sh

Hacerlo ejecutable primero

# chmod +x vpn11.sh

En el lado del teléfono inteligente

Al instalar la aplicación Abrir VPN para Android, copiando el archivo de configuración, certificados y configurándolo, quedó así:
Revisar el correo electrónico en mi teléfono inteligenteInicio de un servidor VPN detrás de la NAT de un proveedor
Edito el número de puerto en la configuraciónInicio de un servidor VPN detrás de la NAT de un proveedor
Arranco el cliente y me conectoInicio de un servidor VPN detrás de la NAT de un proveedor

En el proceso de escribir el artículo, transfirí la configuración de la computadora a la Raspberry Pi 3 e intenté ejecutar todo en un módem LTE, ¡pero no funcionó! resultado del comando

# stun stun.ekiga.net -p 11111

Cliente STUN versión 0.97
Primario: mapeo independiente, filtro dependiente del puerto, puerto aleatorio, horquilla
el valor devuelto es 0x000006

значение Filtro dependiente del puerto impidió que el sistema se iniciara.
Pero el proveedor local permitió que el sistema se ejecutara en Raspberry Pi 3 sin ningún problema.
Junto con una cámara web, con VLC para
crear una transmisión RTSP desde una cámara web

$ 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

y VLC en un teléfono inteligente para ver (stream rtsp://10.2.0.1:8554/), resultó que no es un mal sistema de videovigilancia a distancia, también puede configurar Samba, enrutar el tráfico a través de VPN, controlar una computadora de forma remota y mucho más ...

conclusión

Como ha demostrado la práctica, para organizar un servidor VPN, puede prescindir de una dirección IP externa por la que debe pagar, así como de un VPS / VDS alquilado. Pero todo depende del proveedor. Por supuesto, quería obtener más información sobre los distintos proveedores y tipos de NAT utilizados, pero esto es solo el comienzo...
Gracias por su atención!

Fuente: habr.com

Añadir un comentario