买了一台阿里云的VPS,有了公网IP就想着内网穿透的事情
一台内网服务器A,一台外网服务器B,我希望通过外网连接SSH来连接到A
也就是在家里连公司内网的办公虚拟机
中间踩了几波坑,记录一下
ssh反向代理(不推荐)
最简单的内网穿透就是利用ssh反向代理
在B上设置/etc/sshd_config中修改GatewayPorts no为yes来转发外网的ip请求,随后重启sshserver,systemctl restart sshd
在A上安装autossh
执行命令
1
| autossh -R [服务器IP或省略]:[服务器端口]:[客户端侧能访问的IP]:[客户端侧能访问的IP的端口] [登陆服务器的用户名@服务器IP] -p [服务器ssh服务端口(默认22)]
|
后台运行是需要输入密码的,然而autossh并没有提供帐号密码的选择,因此需要配置免密钥登录,把A的公钥拷贝到B上
1 2 3
| nohup autossh -M port1 -NR port2:localhost:22 root@B.B.B.B >> autosshlog 2>&1 & 此时就可以用 ssh -p port2 访问B了
|
用autossh是看中他的重连功能,结果效果并不好,用了一段时间经常整个进程挂掉,于是换工具
dog tunnel lite 反向代理
国人用golang开发的,能完美替代ssh反向代理
这是官网,上面有lite的下载地址,dog tunnel
lite版使用文档
B.B.B.B就是server的地址
1 2
| server: ./dtunnel_lite -service :1234 client: ./dtunnel_lite -service B.B.B.B:1234 -local :8787 -action :22
|
此时连接server的8787端口即可连接到client的22端口上
dog tunnel p2p 打洞
这个就厉害啦
代理模式受限与代理机器的网速
然而P2P打洞,只是一开始寻址要经过公网机器,后面即使公网机器挂了,短时间内也不会影响到打出来的洞
以下是别人整理的文档(本身的P2P版本的文档好像不全),来自Senraの小窝
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| dtunnel_s的参数说明
-addr:TCP端口地址,用于C/S模式 -addrudp:UDP端口地址,用于P2P辅助打洞 -admin:管理接口,用于提供API方便管理 -https:启用管理接口的HTTPS支持,需要指定-cert和-cert参数,默认关闭 -ssl:启用ssl支持,启用需要指定-cert和-cert参数,默认关闭 -cert:证书路径 -key:证书密钥路径 -dbhost:数据库服务器 -dbpass:数据库密码 -dbuser:数据库用户 -replace:如果客户端注册名冲突,踢掉之前的,默认关闭 -version:显示版本
dtunnel 的参数说明 -addip:出口IP(单个或列表) -buster:打洞服务器,用于P2P模式 -remote:远程服务器,用于C/S模式,默认官方服务器(已挂,必须自己设置) -clientkey:客户端Key,用于远端和近端认证,需一致 -compress:压缩数据,远端和近端需一致 -debug:调试模式 -delay:打洞失败后重试延迟,秒 -dnscache:DNS缓存有效期,如果大于0将定时清空DNS缓存,分钟 -encrypt:P2P模式加密 -f:从文件中加载配置 -kcp:kcp配置,远端和近端需一致 -key:访问Key(服务端数据库中的AuthKey) -reg:注册名,远端使用 -link:连接的注册名,近端使用,用于识别连接远端 -local:本地监听端口,填socks5则为socks5代理服务 -mode:连接模式(0:P2P打洞失败后切换为C/S 1:只使用P2P 2:只使用C/S) -pipen:管道数 -ds:数据纠错??仅在P2P模式有效,远端和近端需一致 -ps:奇偶校验??仅在P2P模式有效,远端和近端需一致 -ssl:启用ssl支持,默认启用,服务端没有启用的话请使用-ssl=false来关闭 -v:输出详细日志 -version:显示版本
|
琢磨了一下这些文档,这里是我的使用方式
port1是机器B对外服务的udp端口,port2是机器B的对外服务tcp端口。
B.B.B.B是B的ip地址
1 2 3 4 5 6
| 公网机器B: nohup ./dtunnel_s -addrudp :port1 -addr 0.0.0.0:port2 2>&1 >> log & 内网机器A: nohup ./dtunnel -reg serviceName -local :22 -buster B.B.B.B:port1 -remote B.B.B.B:port2 -ssl=false -mode 1 >> log 2>&1 & 家里电脑C(windows): dtunnel.exe -link serviceName -local :8888 -buster B.B.B.B:port1 -remote B.B.B.B:port2 -ssl=false
|
这样配置以后会以p2p模式连接port1,如果失败的话会以c/s模式去连接port2,这两个模式必须要配置,否则会默认连接官方已经挂掉的服务器。
然后必须加上-ssl=false这个参数项,来关闭TCP的ssl校验
此时ssh家里电脑C的127.0.0.1:8888就可以和内网机器A进行交互了
总结
在大部分情况下p2p模式都是最好的,因为不受代理服务器的限制,也不需要忍受代理服务器的延迟
但是对于使用4G信号的手机或者ipad来说,并不关心速度,此时使用dog tunnel反向代理的端口即可
(当然更重要的原因是在android上用p2p也挺蛋疼的。。)