[原創]SSH Tunnel for UDP

SSH Tunnel for UDP
UDP port forwarding is a bit more complicated. We will need to convert the packets from UDP to TCP on the SSH client side, tunnel it over the SSH connection and convert it back from TCP to UDP on the SSH server side.
 
因爲業務須要,要實現內網一個服務器的udp服務對外暴露,而且外網須要訪問該服務,可是該機器沒有公網IP,也不能作NAT。因此實現基於ssh隧道的端口轉發,拓撲圖和原理以下:
 

根據以上原理,配置以下:
server01:xxx.xxx.xxx.xxx
server02:10.21.xxx.xxx
server03:172.18.153.13
 
1.配置ssh隧道和socat的udp/tcp端口轉發:
在server02(10.21.17.15)上執行
# autossh -p 22 -M 6777 -NfR '*:8899:127.0.0.1:8899' root@94.191.109.129 或者 # ssh -R 8899:127.0.0.1:8899 xxx.xxx.xxx.xxx "vmstat 30"
# socat tcp4-listen:8899,reuseaddr,fork udp:172.18.153.13:9999 或者使用管道來實現 # mkfifo /tmp/fifo && nc -l -p 8899 < /tmp/fifo | nc -u 172.18.153.13 9999 > /tmp/fifo
在server01(94.191.109.129)上執行
# socat udp4-listen:9999,reuseaddr,fork tcp:localhost:8899 或者使用管道來實現 # mkfifo /tmp/fifo && nc -l -u -p 9999 < /tmp/fifo | nc localhost 8899 > /tmp/fifo
*其中udp4-listen:改爲udp4-recvfrom也是能夠的。
 
2.在server03上啓動python進程:
# -*- coding: utf-8 -*-
import socket
 
'''
使用UDP協議時,不須要創建鏈接,只須要知道對方的IP地址和端口號,就能夠直接發數據包。可是,能不能到達就不知道了。
雖然用UDP傳輸數據不可靠,但它的優勢是和TCP比,速度快,對於不要求可靠到達的數據,就可使用UDP協議。
咱們來看看如何經過UDP協議傳輸數據。和TCP相似,使用UDP的通訊雙方也分爲客戶端和服務器。服務器首先須要綁定端口
綁定端口和TCP同樣,可是不須要調用listen()方法,而是直接接收來自任何客戶端的數據
'''
# ipv4 SOCK_DGRAM指定了這個Socket的類型是UDP
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# 綁定 客戶端口和地址:
s.bind(('172.18.153.13', 9999))
print 'Bind UDP on 9999...'
while True:
# 接收數據 自動阻塞 等待客戶端請求:
data, addr = s.recvfrom(1024)
print 'Received from %s:%s.' % addr
s.sendto('Hello, %s!' % data, addr)

  

 
3.在測試機器上作以下測試:
測試一:只有一個進程鏈接傳輸數據
1)持續寫數據到臨時文件中:
# while true;do echo test >> /tmp/socat.tmp;sleep 0.05;done
2)從臨時文件中讀取數據並使用socat發送udp數據:
# tail -f /tmp/socat.tmp | socat - udp-connect:xxx.xxx.xxx.xxx:9999
測試二:不斷使用新端口鏈接傳輸數據
# while true;do echo test | socat - udp-connect:xxx.xxx.xxx.xxx:9999;sleep 0.05;done
 
4.socat進程在會話完成以後會自動斷開,須要寫腳本自動拉起:
#!/bin/bash

while :
do
    pid=`ps -ef|grep socat|grep listen|awk '{print $2}' | wc -l`
    sleep 10
    {
        if [ "$pid" -le 8 ]
        then
            		socat tcp4-listen:9010,reuseaddr,fork udp:172.18.171.15:43010 >> 9010.log 2>&1 &
			socat tcp4-listen:9011,reuseaddr,fork udp:172.18.171.15:43011 >> 9011.log 2>&1 &
			socat tcp4-listen:9012,reuseaddr,fork udp:172.18.171.15:43012 >> 9012.log 2>&1 &
			socat tcp4-listen:9013,reuseaddr,fork udp:172.18.171.15:43013 >> 9013.log 2>&1 &
			socat tcp4-listen:9014,reuseaddr,fork udp:172.18.171.15:43014 >> 9014.log 2>&1 &
			socat tcp4-listen:9015,reuseaddr,fork udp:172.18.171.15:43015 >> 9015.log 2>&1 &
			socat tcp4-listen:9016,reuseaddr,fork udp:172.18.171.15:43016 >> 9016.log 2>&1 &
			socat tcp4-listen:9017,reuseaddr,fork udp:172.18.171.15:43017 >> 9017.log 2>&1 &
        fi
    }||{
        if [ "$pid" -le 8 ]
        then
            ps -ef|grep socat|grep listen|awk '{print $2}'|xargs kill -9
            sleep 5
            		socat tcp4-listen:9010,reuseaddr,fork udp:172.18.171.15:43010 >> 9010.log 2>&1 &
			socat tcp4-listen:9011,reuseaddr,fork udp:172.18.171.15:43011 >> 9011.log 2>&1 &
			socat tcp4-listen:9012,reuseaddr,fork udp:172.18.171.15:43012 >> 9012.log 2>&1 &
			socat tcp4-listen:9013,reuseaddr,fork udp:172.18.171.15:43013 >> 9013.log 2>&1 &
			socat tcp4-listen:9014,reuseaddr,fork udp:172.18.171.15:43014 >> 9014.log 2>&1 &
			socat tcp4-listen:9015,reuseaddr,fork udp:172.18.171.15:43015 >> 9015.log 2>&1 &
			socat tcp4-listen:9016,reuseaddr,fork udp:172.18.171.15:43016 >> 9016.log 2>&1 &
			socat tcp4-listen:9017,reuseaddr,fork udp:172.18.171.15:43017 >> 9017.log 2>&1 &
        fi
    }
done

  

 
總結:
1.配置完成以後,隧道,socat端口轉發和數據的傳輸正常,穩定,測試過程當中沒有出現斷線,丟包的問題。
2.socat工具強大,主要特色就是在兩個數據流之間創建通道,且支持衆多協議和連接方式。如 IP、TCP、 UDP、IPv六、PIPE、EXEC、System、Open、Proxy、Openssl、Socket等。更多功能待驗證和熟悉。

原文出處:https://www.cnblogs.com/wsjhk/p/11064992.htmlhtml

相關文章
相關標籤/搜索