ssh端口转发
根据网上搜罗到的资料,ssh端口转发有两种类型——本地转发和远程转发。
先假设一下场景,我手头上有机器A在办公室(内网),而有一台国内的服务器(外网,IP: 157.75.35.251),下简称机器B。而我要在不同的地方用机器C来访问机器A。
- 本地转发
就一个简单的应用场景来说就是我拿着机器C想要访问机器B的443端口的服务,而机器C与机器A如今身处一个内网里,那么就可以通过机器A的某个端口来监听机器B的443端口,将外网机器B443端口的数据转发到内网的机器A的某个端口上,这样身处同个内网里的机器C就可以直接访问机器A的那个监听端口即可实现机器C间接访问到机器B的443端口。
简单来说,本地转发就是本地机器监听远程机器,当然了,也可以通过自己转发自己来实现端口数据的分流,这也是可以的。
1 | ssh -f -N -L 机器A的监听端口:157.75.35.251:443 user@localhost |
以上命令在机器A进行输入,记住的要点就一个,我们只能拿到公网的IP,要清楚自己身在何处。
解释一下上边的代码的意思
-f //后台运行
-N //不显示运行代码,常与-f一块连用
-L //本地转发,后边接的就是
[可选写localhost:]localhost监听端口:要监听的服务器IP:要监听的服务器的端口 user@localhost
注意: 如果localhost的ssh端口不是默认的22,那么需要加入-p参数来指定localhost的ssh端口,否则报错,之后会讲到如何修改ssh的默认端口。
- 远程转发
与本地转发的例子相反,远程转发用途主要是将内网的某个端口转发到外网机器上的某个端口实现远程转发,即内网穿透。这个过程更多的是由内向外的过程。本次用的技术就是ssh远程转发实现在任何能连上机器B的地方都能访问到我办公室的机器A,而且也能实现我直接上校园网的功能,还是不错的,不过数据接收能力还得看机器A。
不多说直接上代码,在机器A终端运行
1 | ssh -f -N -R 机器B监听的端口:localhost:机器A要转发的端口 [email protected] |
-R //远程转发,后边接的是[localhost:]本地要转发的端口:外网的机器IP:外网的机器监听的端口 user@外网机器的IP
因为是要访问外网的ssh,如果外网的机器Bssh默认端口不是22,那么也要加上参数-p来指定特定的ssh登录端口。
- 最后,记住本地转发和远程转发就一点,看你登录的ssh是在localhost还是外网机器的IP,前者是本地转发,后者是远程转发。
ssh保活
在刚刚建立的ssh隧道,可能过不了多久就会自己断掉,原因是因为在内网的路由器或者防火墙会自动关闭空闲的外部连接来保证内网的安全。那么如何实现ssh隧道长久的保活呢?我在一篇博客上找到了想要的答案,这里列出我在服务器段sshd_config
的配置——针对远程转发。
本地转发如何配置我也不太清楚,但是可以肯定的是服务端一定要在一定的时间内主动发送信息询问客户端,看看连接是否存在,若不存在还要进行重新连接,存在就保活,保持通信,保持联系~
1 | AllowTcpForwarding yes |
解释一下参数
AllowTcpForwarding yes //允许Tcp数据转发
这里本来是想着直接通过机器C一步访问机器A的,但是没做到,想着用机器B来进行本地转发,但是ssh登录毕竟有指向性,如果我将登录机器B的ssh端口进过本地转发到监听机器Assh登录的端口的话,那么我也不懂会发生什么,可能我就登录不上我的机器B了,所以尝试了以后就放弃了链式登录,不够对于其他应用服务端口的链式转发还是有很多教程的,不过ssh链式登录,貌似不太合理的样子~
TCPKeepAlive yes //表示Tcp保持连接不断开
ClientAliveInterval 60 //表示指定服务端向客户端请求消息的时间间隔,单位是秒,默认是0,即不发送Tcp连接信息。这里是服务端主动发送信息给客户端,等待客户端响应,若完成3次握手,成功,则保持连接。
ClientAliveCountMax 86400 //表示服务端发出请求厚无响应并重新发送请求的最大次数,这里我修改到了86400次,这样$86400 \times 60s = 60$天,这期间只要机器A连接上网络并且能访问外网,这个ssh隧道即可恢复,关于这里我之后还要写一个自动登录校园网的脚本程序,避免假期人不在机器A断网的情形。
注意: 博客中还说到TCPKeepAlive一定得是yes,不然会影响到后边参数的设置。并且ClientAliveInterval设置的值要小于各层防火墙的最小值,不然也没有用,可能第一个保活信息的发不出去,隧道就塌陷了。
当然,修改完服务的配置文件后一定得重启服务
1 | systemctl restart sshd.service |
ssh修改默认端口
这里先说一下为什么要修改ssh的默认端口,因为有些闲人无聊,特别喜欢用端口扫描工具来扫别人的服务器,像常见的21、22、80、11、443、3306
等等都是重灾区,我每次登我国内那台服务器就是,每次我登录都有上千上万次的登录失败信息发送给我,我很是费解这些闲人的举动。
正好这次要做内网穿透,那么我顺带学习一下如何修改ssh的默认端口,来保证我的服务器安全一些,不然总有些心慌慌
根据网上博客所述,修改ssh默认端口稍微复杂一些,但是无伤大雅,但是要动SELinux,这个东西保护机制过于严格,所以一般都是关闭的,不然有些服务很难跑起来。
首先编辑sshd_config
文件
1 | vim /etc/ssh/sshd_config |
随后找到并修改端口,这里省事我直接用的root用户做登录,平常的话尽量用新的用户,不然别人真的登上你的root账户,你的机器还是很危险的。
1 | #Port 22 //这一行的注释给删掉,然后将默认的22改为你喜欢的数字,尽量大一点不和22沾边,这样别人扫到的几率会大大减小 |
其次修改firewall配置
1 | firewall-cmd --permanent --zone=public --add-port=新的ssh登录端口/tcp && firewall-cmd --reload |
修改完firewall
的配置后,再检查一下端口是否添加成功
1 | firewall-cmd --zone=public --query-port=新的添加的端口/tcp |
若返回值为yes则添加成功,否则为no
随后修改SELinux
使用以下命令查看当前SElinux 允许的ssh端口
1 | semanage port -l | grep ssh |
随后添加新的端口到SELinux
1 | semanage port -a -t ssh_port_t -p tcp 新的ssh登录端口 |
最后检查一下是否成功添加
1 | semanage port -l | grep ssh |
如果成功添加则会返回
1 | ssh_port_t tcp 新的端口, 22 |
最后重启sshd并测试新端口的ssh连接
重启sshd服务
1 | systemctl restart sshd.service |
随后用另外一台连上外网的计算机测试一下新的端口连接即可
参考链接
- ssh端口转发
https://cloud.tencent.com/developer/article/1407594
https://www.zsythink.net/archives/2450
- 修改ssh端口
https://www.jianshu.com/p/4e92e91469d8
- ssh保活