为什么修改端口号后仍可保持连接?

2018-05-29 07:59:14 +08:00
 nikoo
一台服务器仅开放 22 端口,屏蔽其他所有端口的访问权限
通过 ssh ip:22 登录该服务器,修改 /etc/ssh/sshd_config 将 ssh 端口号改为例如 1234
保存后重启 ssh 执行 /etc/init.d/ssh restart

此时通过 netstat 查看 22 端口已经没有了监听,ssh 端口成功改为了 1234

但神奇的是此时与服务器仍然保持着连接,只要不 exit,那么这个 ssh 客户端是一直可用的

但是一旦 exit 后,无法再次通过 1234 或者 22 端口连接服务器

好奇的是为什么在修改端口号并且 22 端口已经没有了监听的情况下,没有退出的那个客户端仍然可以与服务器通信
因为 22 端口已没有了监听,其他端口都由防火墙屏蔽了,那这个通信是如何进行的?
3578 次点击
所在节点    问与答
31 条回复
0312birdzhang
2018-05-29 08:32:17 +08:00
长链接没释放,或许就是这个设定。万一你改错了然后断开了那岂不是永远连不上了?
坐等楼下专业的说明😂
princeofwales
2018-05-29 08:56:04 +08:00
监听的端口就是提供个入口
连接已经建立了 ,还要监听何用
snnn
2018-05-29 09:00:22 +08:00
嗯,是这样的。
你可以强行把所有 ssh 的进程杀掉,以及它们的子进程。
不过如果是我,我选 reboot。
ThirdFlame
2018-05-29 09:14:58 +08:00
kill -9 -1
已经建立的连接保持不动,这时候可以试试 1234 能不能连上了。 要是连不上,而且你还断开了,那欢迎你用远程控制台 或者 跑现场吧。
hilow
2018-05-29 12:26:14 +08:00
ssh 使用 tcp 协议,可以了解一下 tcp 连接简历的过程就容易理解了。

server 调用 listen 监听 22 端口的请求
client 调用 connect 连接到 22 端口,此时 client 自动分配一个 port1
server 调用 accept 接受 client 的连接请求,此时 server 自动分配一个新的 port2

所以更改 ssh 的 listen port 是,对上面已经建立的连接 clientIP:port1<------>serverIP:port2
是没有影响的
nikoo
2018-05-29 12:31:43 +08:00
@hilow 谢谢回复,但问题是 server 屏蔽了除了 22 之外的所有端口连接,那么理论上 serverIP:port2 是不可能与 client 通信的,这个怎么理解呢?
nikoo
2018-05-29 12:34:25 +08:00
@0312birdzhang @princeofwales 这个“长连接”是如何,通过什么方式( or 端口)与服务器建立的连接?(在服务器端屏蔽除了 22 之外的所有端口的前提条件下)
hilow
2018-05-29 12:41:09 +08:00
你的问题是 server 端的 port2 是被禁止访问的,为什么 clientIP:port1<------>serverIP:port2 之间能通信?

这个我也得查资料确认下,猜测是因为防火墙禁止的只是发送到 非 22 端口的 syn 数据包吧。
我这就确认下去
hilow
2018-05-29 12:53:23 +08:00
我说的有些地方不准确。晚上有空我再补充下。
抱歉
mario85
2018-05-29 12:58:19 +08:00
nikoo
2018-05-29 13:03:02 +08:00
@hilow 谢谢,实际上条件中:"服务器端屏蔽除了 22 之外的所有端口" 如果更换为
通过端口映射连接的内网机器,也同样有这个问题,

比如在有公网 IP 路由器的路由器上,映射路由上一个端口(例如 888 )至内网的一台机器 22 端口,
那么 SSH 公网 IP:888 连接这台内网机器,此时我在 SSH 中把该机器 SSH 端口改为 1234 并重启 SSH,在 22 端口失去监听的时候,仍然可以进行 SSH 操作,只要不 exit。

这就很奇怪,好奇此时客户端是如何与这台内网机器通信的。
zst
2018-05-29 13:08:21 +08:00
是不是防火墙放行了 established 状态的包
msg7086
2018-05-29 15:20:18 +08:00
监听影响的是新连接。已经建立的连接是不受监听影响的。

我们举个栗子好了。
比如你有 SSH-Server (PID=1000),监听 IP1 端口 22。
现在你用 SSH 客户端从 IP2 连上去 22 端口,这会发生什么事呢。
1. SSH-Server 接受了你的连接 (IP2 49123 IP1 22);
2. SSH-Server 叉出一个新进程 SSH-Conn (PID=1096);
3. SSH-Conn 接管 (IP2 49123 IP1 22) 连接,开始产生 SSH 通信;
4. SSH-Server 继续摸鱼,等待下一个连接。

现在你更改端口为 1234 并重启 SSH 以后,会发生什么事呢。
1. SSH-Server 被谋杀;
2. SSH-Conn 苟且偷生,继续 SSH 通信;
3. SSH-Server 被复活 (PID=1140),监听 IP1 端口 1234。

至于为什么还能进行 SSH 操作,当然是因为
1. (IP2 49123 IP1 22) 这个连接还活着;
2. SSH-Conn (PID=1096) 这个进程还活着。
Tink
2018-05-29 15:25:57 +08:00
你已经建立的连接没有影响
linyinma
2018-05-29 16:50:48 +08:00
看了半天都没有一个回答对 涉及两个知识点:

刚开始 SSHD 进程 22 端口处于 LISTENING 状态, 你 ssh 连接中完成 accept 后内核生产新的 socket fd 完成 5 元组绑定{ 协议, 目的地址、目的端口, 本地地址,本地端口},此过程本地地址端口被复用( SO_REUSEADDR ),并且 SSHD fork 产生协同进程( bash,由 /etc/passwd 配置),协同进程继承 SSHD accept 返回的 socket fd ;


在此后的过程中都是和协同进程交换 和 SSHD 办毛子关系都没有
nikoo
2018-05-29 17:40:08 +08:00
@linyinma 谢谢回复!这个协同进程是如何与服务器进行通信的?

或者换个说法,在 SSH 客户端与服务器成功连接以后,客户端(或服务器)的防火墙如何屏蔽能立刻断开此时的 SSH 客户端与服务器的连接?
再次感谢答疑解惑
xmh51
2018-05-29 17:42:45 +08:00
修改 ssh 端口,和防火墙,还有内网端口映射,没半毛钱关系。单纯修改 ssh 端口生效后,已经建立的连接还是可以用的,新的连接必须连接新的 ssh 端口。你的之所以不能连接是因为虽然 ssh 端口监听了,但是被外部条件阻止了(没配置端口映射,防火墙没放开端口)
nikoo
2018-05-29 17:43:55 +08:00
@linyinma 在实际测试里,SSH 登录并将端口 22 改为 1234 后,再在 22 端口开一个 nginx,并确定 22 端口已经是 nginx 的监听了,但此时 SSH 仍然与服务器连接的好好的
xmh51
2018-05-29 17:45:11 +08:00
你这个是把两个事混在一起看了,应该分开看。
nikoo
2018-05-29 17:45:55 +08:00
@xmh51 谢谢回复,问题是已经建立的 SSH 连接客户端与服务器之间是如何通信的?(通过什么方式通信的)

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/458531

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX