[原創]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、IPv6、PIPE、EXEC、System、Open、Proxy、Openssl、Socket等。更多功能待驗證和熟悉。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM