在提供者的 NAT 後面執行 VPN 伺服器

一篇關於我如何設法在我的家庭提供者的 NAT 後面運行 VPN 伺服器(沒有白色 IP 位址)的文章。 讓我馬上預訂:那個 此實現的效能直接取決於提供者使用的 NAT 類型以及路由器.
因此,我需要從我的 Android 智慧型手機連接到我的家用計算機,這兩個設備都透過提供者 NAT 連接到互聯網,並且計算機透過家庭路由器連接,這也是 NAT 連接。
由於多種原因,未考慮使用具有白色 IP 位址的租賃 VPS/VDS 以及從提供者租用白色 IP 位址的經典方案。
考慮在內 過去文章的經驗,對提供者的 STUN 和 NAT 進行了多次實驗。 我決定做一個小實驗,在運行 OpenWRT 韌體的家庭路由器上執行以下命令:

$ stun stun.sipnet.ru

得到結果:

STUN客戶端版本0.97
主要:獨立映射、獨立過濾、隨機連接埠、髮夾
傳回值為 0x000002

字面翻譯:
Independent Mapping——獨立映射
獨立過濾器-獨立過濾器
隨機端口-隨機端口
會髮夾-會有髮夾
在我的電腦上運行類似的命令,我得到:

STUN客戶端版本0.97
主要:獨立映射、連接埠相關過濾器、隨機連接埠、髮夾
傳回值為 0x000006

Port Dependent Filter - 連接埠相關過濾器
命令輸出結果的差異表明家庭路由器正在為互聯網傳輸資料包的過程做出「貢獻」;這體現在當在電腦上執行命令時:

stun stun.sipnet.ru -p 11111 -v

我得到的結果是:

...
映射位址 = XX.1XX.1X4.2XX:4398
...

此時,一個UDP會話已開啟一段時間,如果此時您發送一個UDP請求(例如:netcat XX.1XX.1X4.2XX 4398 -u),則該請求來到了家庭路由器,即由其上運行的TCPDump確認,但請求未到達計算機- IPtables 作為路由器上的NAT 轉換器將其丟棄。
在提供者的 NAT 後面執行 VPN 伺服器
但 UDP 請求透過提供者的 NAT 這一事實給了成功的希望。 由於路由器位於我的管轄範圍內,因此我透過將UDP/11111連接埠重新導向到電腦來解決問題:

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

因此,我能夠啟動 UDP 會話並從任何 IP 位址接收來自 Internet 的請求。 此時,我啟動了 OpenVPN-server(之前已配置)監聽 UDP/11111 端口,在智慧型手機上指示外部 IP 位址和連接埠(XX.1XX.1X4.2XX:4398),並成功從智慧型手機連接到電腦。 但在這個實作中出現了一個問題:有必要以某種方式維持 UDP 會話,直到 OpenVPN 用戶端連接到伺服器;我不喜歡定期啟動 STUN 用戶端的選項 - 我不想浪費負載STUN 伺服器。
我還注意到條目“會髮夾-會有髮夾”,這個模式

Hairpinning 允許 NAT 後面的本地網路上的一台電腦透過路由器的外部位址存取同一網路上的另一台電腦。

在提供者的 NAT 後面執行 VPN 伺服器
結果,我簡單地解決了維護 UDP 會話的問題 - 我在與伺服器相同的電腦上啟動了客戶端。
它的工作原理是這樣的:

  • 在本機連接埠 11111 上啟動 STUN 用戶端
  • 收到具有外部 IP 位址和連接埠 XX.1XX.1X4.2XX:4398 的回應
  • 使用外部 IP 位址和連接埠將資料傳送到智慧型手機上配置的電子郵件(可以使用任何其他服務)
  • 在偵聽 UDP/11111 連接埠的電腦上啟動 OpenVPN 伺服器
  • 在指定 XX.1XX.1X4.2XX:4398 的電腦上啟動 OpenVPN 用戶端進行連接
  • 隨時在智慧型手機上啟動 OpenVPN 用戶端,指示 IP 位址和連接埠(在我的情況下,IP 位址沒有更改)以進行連接

在提供者的 NAT 後面執行 VPN 伺服器
這樣我就可以從智慧型手機連接到我的電腦。 此實作允許您連接任何 OpenVPN 用戶端。

實踐

你將需要:

# apt install openvpn stun-client sendemail

編寫了幾個腳本、幾個設定檔並產生了必要的憑證(因為智慧型手機上的客戶端只能使用憑證),我們得到了 OpenVPN 伺服器的通常實作。

計算機上的主要腳本

# 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

透過電子郵件發送資料的腳本:

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

伺服器設定檔:

# 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

客戶端設定檔:

# 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

證書是使用生成的 這篇文章.
運行腳本:

# ./vpn11.sh

首先使其可執行

# chmod +x vpn11.sh

在智慧型手機方面

透過安裝應用程式 適用於 Android 的 OpenVPN,複製了設定檔、憑證並進行了配置,結果是這樣的:
我在智慧型手機上查看電子郵件在提供者的 NAT 後面執行 VPN 伺服器
我在設定中編輯連接埠號在提供者的 NAT 後面執行 VPN 伺服器
我啟動客戶端並連接在提供者的 NAT 後面執行 VPN 伺服器

在撰寫本文時,我將設定從電腦轉移到 Raspberry Pi 3,並嘗試在 LTE 數據機上運行整個系統,但沒有成功! 命令結果

# stun stun.ekiga.net -p 11111

STUN客戶端版本0.97
主要:獨立映射、連接埠相關過濾器、隨機連接埠、髮夾
傳回值為 0x000006

連接埠相關過濾器 不允許系統啟動。
但家庭提供者允許系統在 Raspberry Pi 3 上啟動,沒有任何問題。
與網路攝影機結合使用 VLC
從網路攝影機建立 RTSP 串流

$ 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

和VLC在智慧型手機上進行觀看(流rtsp://10.2.0.1:8554/),它被證明是一個很好的遠端視訊監控系統,您還可以安裝Samba,透過VPN路由流量,遠端控制您的計算機等等更多的...

產量

實踐表明,要組織 VPN 伺服器,您無需付費即可使用外部 IP 位址,就像租用 VPS/VDS 一樣。 但這一切都取決於提供者。 當然,我想獲得有關所使用的不同提供者和 NAT 類型的更多信息,但這只是開始...
謝謝你的關注!

來源: www.habr.com

添加評論