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等。更多功能待验证和熟悉。

[原创]SSH Tunnel for UDP的更多相关文章

  1. 通过ssh tunnel连接内网ECS和RDS

    通过ssh tunnel连接内网ECS和RDS 这里讲了ssh tunnel的原理.很清晰. 此后又给外网访问内网增加了一种思路.感觉特别棒. 拓宽了思路:

  2. 2016-12-14 - SSH Tunnel

    2016-12-14 - SSH Tunnel ssh Network Topo Network Topo A: Internet sshd B: NAT sshd C: NAT B Create S ...

  3. windows SSH Tunnel实施日记

    1.准备条件:SSH跳板服务器一个.软件:Putty,CCProxy 2.putty建立SSH Tunnel:先在session那儿把服务器地址填好,到Tunnel界面上,选Dynamics和Auto ...

  4. Navicat 或者Java的JDBC通过SSH Tunnel连接MySQL数据库

    JDBC通过SSH Tunnel连接MySQL数据库 - 明明 - CSDN博客https://blog.csdn.net/a351945755/article/details/21782693 Na ...

  5. 使用ssh tunnel 来做代理或跳板

    接前文 http://www.cnblogs.com/piperck/p/6188984.html  使用ssh config配置文件来管理ssh连接 前文说了如何配置自己的ssh config 来方 ...

  6. navicat链接阿里云mysql报80070007: SSH Tunnel: Server does not support diffie-hellman-group1-sha1 for keyexchange

      http://www.jianshu.com/p/200572ed066c navicat 链接数据库 使用navicat 的ssh通道连接数据库回遇到权限问题 错误代码如下: 80070007: ...

  7. Navicat---使用SSH远程连接到MySql,报错80070007: SSH Tunnel: Server does not support diffie-hellman-group1-sha1 for keyexchange

    尝试使用Navicat远程连接到我在阿里云服务器上的MySql,通过SSH. 但是报错: 80070007: SSH Tunnel: Server does not support diffie-he ...

  8. [svc]通过ssh tunnel连接内网ECS和RDS

    问题背景: 一些ECS没有访问公网的需求,或是RDS出于安全考虑只允许内网访问.但是希望远程连接这些ECS或RDS进行管理时就会比较麻烦,一般可以通过选一台有公网的ECS搭建VPN的方法来解决这个问题 ...

  9. 使用putty进行ssh tunnel远程内网机器

    通常我们通过登录具有外网ip的远程机器来连接内网的机器:本文介绍,通过putty进行ssh tunnel,进而达到使用本机直接连接远程内网机器: 1,在putty中创建一个session,输入具有外网 ...

随机推荐

  1. WPF使用NAudio录音

    代码: using NAudio.Wave; using System.Windows; namespace NAudioDemo { /// <summary> /// MainWind ...

  2. 【JDK源码分析】String的存储区与不可变 专题

    <Think in Java>中说:“关系操作符生成的是一个boolean结果,它们计算的是操作数的值之间的关系”. "=="判断的是两个对象的内存地址是否一样,适用于 ...

  3. 危险的DDD聚合根

    原文:危险的DDD聚合根 DDD的核心是聚合.这没有问题,大家都认同.但关于DDD中的聚合方式,其实我还是有些担心,下面说说我的想法,希望大家参与讨论.其实当初第一次看到DDD中关于聚合根部分论述的时 ...

  4. iostat命令浅析

    报告中央处理器(CPU)统计信息.整个系统.适配器.TTY 设备.磁盘 CD-ROM.磁带和文件系统的异步输入/输出(AIO)与输入/输出统计信息,iostat也有一个弱点,就是它不能对某个进程进行深 ...

  5. Win10的UWP之标题栏的返回键(一)

    原文:Win10的UWP之标题栏的返回键(一) 关于返回键,放在标题栏是目前较为完美的一种方案.继前一篇的Hello World,博主进行一些修改实现该方法. - - - - - - - - - - ...

  6. 在Delphi中创建线程,请一定使用BeginThread()代替CreateThread()创建线程!(更好的管理异常)

    在Delphi中创建线程,请一定使用BeginThread()代替CreateThread()创建线程! 如果直接使用Win32的API函数CreateThread()创建多个线程,也是可以创建的.但 ...

  7. 星星的模块封装类 IDSStarsScoreView

    1 IDSStarsScoreView 的实现效果     2 类的封装方法:   <声明文件>   // //  IDSStarsScoreView.h //  Near // //  ...

  8. vue+TS(CLI3)

    1.用CLI3创建项目 查看当前CLI的版本,如果没有安装CLI3的  使用npm install --global vue-cli来安装CLI 安装好CLI 可以创建项目了 使用vue create ...

  9. Tido c++树状数组知识讲解(转载)

    树状数组可以用来动态计算前缀和,可以随时进行更新 而普通的前缀和只是静态的         

  10. java基础知识总结(一)

    满满的干货=-= (一)环境变量的作用: 每个人刚开始学习java的时候,肯定都是安装JDK,配置环境变量,怎么配置网上教程很多很多,但是为什么这么配置呢? 我配置的环境变量: JAVA_HOME:C ...