1
0312birdzhang 2018-05-29 08:32:17 +08:00 via iPhone
长链接没释放,或许就是这个设定。万一你改错了然后断开了那岂不是永远连不上了?
坐等楼下专业的说明😂 |
2
princeofwales 2018-05-29 08:56:04 +08:00 4
监听的端口就是提供个入口
连接已经建立了 ,还要监听何用 |
3
snnn 2018-05-29 09:00:22 +08:00
嗯,是这样的。
你可以强行把所有 ssh 的进程杀掉,以及它们的子进程。 不过如果是我,我选 reboot。 |
4
ThirdFlame 2018-05-29 09:14:58 +08:00
kill -9 -1
已经建立的连接保持不动,这时候可以试试 1234 能不能连上了。 要是连不上,而且你还断开了,那欢迎你用远程控制台 或者 跑现场吧。 |
5
hilow 2018-05-29 12:26:14 +08:00 via Android 2
ssh 使用 tcp 协议,可以了解一下 tcp 连接简历的过程就容易理解了。
server 调用 listen 监听 22 端口的请求 client 调用 connect 连接到 22 端口,此时 client 自动分配一个 port1 server 调用 accept 接受 client 的连接请求,此时 server 自动分配一个新的 port2 所以更改 ssh 的 listen port 是,对上面已经建立的连接 clientIP:port1<------>serverIP:port2 是没有影响的 |
6
nikoo OP @hilow 谢谢回复,但问题是 server 屏蔽了除了 22 之外的所有端口连接,那么理论上 serverIP:port2 是不可能与 client 通信的,这个怎么理解呢?
|
7
nikoo OP @0312birdzhang @princeofwales 这个“长连接”是如何,通过什么方式( or 端口)与服务器建立的连接?(在服务器端屏蔽除了 22 之外的所有端口的前提条件下)
|
8
hilow 2018-05-29 12:41:09 +08:00 via Android
你的问题是 server 端的 port2 是被禁止访问的,为什么 clientIP:port1<------>serverIP:port2 之间能通信?
这个我也得查资料确认下,猜测是因为防火墙禁止的只是发送到 非 22 端口的 syn 数据包吧。 我这就确认下去 |
9
hilow 2018-05-29 12:53:23 +08:00 via Android
我说的有些地方不准确。晚上有空我再补充下。
抱歉 |
10
mario85 2018-05-29 12:58:19 +08:00 via Android
|
11
nikoo OP @hilow 谢谢,实际上条件中:"服务器端屏蔽除了 22 之外的所有端口" 如果更换为
通过端口映射连接的内网机器,也同样有这个问题, 比如在有公网 IP 路由器的路由器上,映射路由上一个端口(例如 888 )至内网的一台机器 22 端口, 那么 SSH 公网 IP:888 连接这台内网机器,此时我在 SSH 中把该机器 SSH 端口改为 1234 并重启 SSH,在 22 端口失去监听的时候,仍然可以进行 SSH 操作,只要不 exit。 这就很奇怪,好奇此时客户端是如何与这台内网机器通信的。 |
12
zst 2018-05-29 13:08:21 +08:00 via Android
是不是防火墙放行了 established 状态的包
|
13
msg7086 2018-05-29 15:20:18 +08:00 5
监听影响的是新连接。已经建立的连接是不受监听影响的。
我们举个栗子好了。 比如你有 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) 这个进程还活着。 |
14
Tink 2018-05-29 15:25:57 +08:00
你已经建立的连接没有影响
|
15
linyinma 2018-05-29 16:50:48 +08:00 2
看了半天都没有一个回答对 涉及两个知识点:
刚开始 SSHD 进程 22 端口处于 LISTENING 状态, 你 ssh 连接中完成 accept 后内核生产新的 socket fd 完成 5 元组绑定{ 协议, 目的地址、目的端口, 本地地址,本地端口},此过程本地地址端口被复用( SO_REUSEADDR ),并且 SSHD fork 产生协同进程( bash,由 /etc/passwd 配置),协同进程继承 SSHD accept 返回的 socket fd ; 在此后的过程中都是和协同进程交换 和 SSHD 办毛子关系都没有 |
16
nikoo OP @linyinma 谢谢回复!这个协同进程是如何与服务器进行通信的?
或者换个说法,在 SSH 客户端与服务器成功连接以后,客户端(或服务器)的防火墙如何屏蔽能立刻断开此时的 SSH 客户端与服务器的连接? 再次感谢答疑解惑 |
17
xmh51 2018-05-29 17:42:45 +08:00
修改 ssh 端口,和防火墙,还有内网端口映射,没半毛钱关系。单纯修改 ssh 端口生效后,已经建立的连接还是可以用的,新的连接必须连接新的 ssh 端口。你的之所以不能连接是因为虽然 ssh 端口监听了,但是被外部条件阻止了(没配置端口映射,防火墙没放开端口)
|
18
nikoo OP @linyinma 在实际测试里,SSH 登录并将端口 22 改为 1234 后,再在 22 端口开一个 nginx,并确定 22 端口已经是 nginx 的监听了,但此时 SSH 仍然与服务器连接的好好的
|
19
xmh51 2018-05-29 17:45:11 +08:00
你这个是把两个事混在一起看了,应该分开看。
|
21
nikoo OP 也就是一台屏蔽了所有端口仅开放 22 端口的服务器,
SSH 登录上去把 22 端口改到 1234 并且在原 22 端口开一个 nginx, 那么目前这台服务器理论上已和外接彻底隔绝了,用浏览器访问 22 端口也是 nginx 的页面了, 那么为什么没有断开的 ssh 客户端仍然可以操作这台服务器, 这个没有断开的客户端是通过什么方式与服务器进行通信的? |
23
wly19960911 2018-05-29 18:37:45 +08:00
[root@xxxxxxxxxxxx]~# netstat -ano|grep ':22'
tcp 0 0 172.19.113.74:22 00.000.00.00:44947 ESTABLISHED keepalive (6983.97/0/0) 刚刚检查了下,连接没有建立在 localhost 上,建立在内网的 ip 可以解释为什么 ssh-server 没有绑定在 22 端口上但是仍然可以工作。但是至于防火墙的问题我也不懂,抛砖引玉下 |
24
hyq 2018-05-29 19:07:30 +08:00
我猜是建立连接以后 客户端的 ip,端口,服务器 ip,端口这四个属性就被关联起来,操作系统根据这个把包发给对应的进程 /文件描述符
|
25
qbqbqbqb 2018-05-30 00:30:43 +08:00
关闭监听是不会影响已经建立的连接的。sshd 监听对应的地址端口四元组是(ServerIP:22,0.0.0.0:0),协同进程建立的连接对应(ServerIP:22,ClientIP:port),两者是可以区分的,sshd 退出但协同进程仍然存活,监听“(ServerIP:22,0.0.0.0:0)”失效,连接“(ServerIP:22,ClientIP:port)”仍然有效。
你可能是在想象“关闭在 22 端口上的监听”是“把 22 端口堵上”,但实际上 socket 的工作原理不是这样的。 |
26
qbqbqbqb 2018-05-30 00:40:45 +08:00
ssh 不涉及防火墙屏蔽除 22 以外端口的问题,因为连接也是建立在 22 端口上的。
但是即使要在其它端口上通信而不被防火墙屏蔽也是可能的(比如 FTP 协议就要建立额外的连接),因为 Linux 的 iptables 防火墙可以跟踪连接状态,可以(并且经常会)配置为直接放行已经建立的连接( ESTABLISHED )或和某个已经建立的连接相关的连接( RELATED,Linux 内核里有针对已知协议专门编写的模块判断数据包是否属于这个状态)。 |
27
hilow 2018-05-30 00:42:21 +08:00 via Android 2
server 调用 listen 监听 22 端口的请求
client 调用 connect 连接到 22 端口,此时 client 自动分配一个 port1,并向 server 发送一个 syn 包,表示请求建立新的连接 server 收到 syn 后,调用 accept 接受 client 的连接请求,并向 client 回复一个 syn+ack 包 client 回复 ack 包后,连接正式建立完毕。后续双方发送 psh/ack 包交换数据。直到出现 fin 或 rst 包时,或者连接之间长时间无数据传递,即超时,连接才会关闭。 题目所说防火墙禁用非 22 端口的数据,我猜很大可能,仅仅是允许 22 端口收到 syn 包,建立连接,非 22 端口收到 syn 会被防火墙丢弃。 这个需要你来确认,具体使用的什么防火墙,配置的什么策略。 所以能导致当前 ssh 连接失效断开的情况,有以下几种, 1.sshd 进程关闭,导致 client 收到 fin 或者 rst 包 2.防火墙丢弃 22 端口收到的 psh 或 ack 数据 mario85 所贴链接说明,不会出现第 1 种情况,因为每个已建立的连接是新的进程。ssh 代码应该做了特殊处理,以保证不在重启配置时关闭之前启动的进程。 第二种情况也没有出现,因为防火墙的配置中允许所有端口的 push/ack 包,禁止非 22 端口的 syn 包。 tcp 连接建立过程 https://en.m.wikiversity.org/wiki/Wireshark/TCP ssh 重启过程,链接由 mario85 提供 https://unix.stackexchange.com/questions/27636/how-does-ssh-connection-survive-a-network-restart iptables 防火墙使用 https://www.digitalocean.com/community/tutorials/iptables-essentials-common-firewall-rules-and-commands Allow All Incoming SSH To allow all incoming SSH connections run these commands: sudo iptables -A INPUT -p tcp --dport 22 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT sudo iptables -A OUTPUT -p tcp --sport 22 -m conntrack --ctstate ESTABLISHED -j ACCEPT The second command, which allows the outgoing traffic of established SSH connections, is only necessary if the OUTPUT policy is not set to ACCEPT. |
28
GuuJiang 2018-05-30 06:52:01 +08:00 via iPhone
有一家大宝剑开在表♂世界 22 号
楼主想要放♂松一下的时候就进入 22 号 大宝剑为楼主分配了一个伺♂服♂器并且进入里♂世界 22 号 一分钟以后由于外面风声紧,大宝剑只能搬到了表♂世界 1234 号 后面的人想要放♂松只能到 1234 号,而楼主依然留在里♂世界 22 号不受影响 三分钟以后楼主离开了里♂世界 22 号,下次还想再来就只能到 1234 号了 |
29
linyinma 2018-05-30 09:40:55 +08:00
@nikoo Q1:也就是一台屏蔽了所有端口仅开放 22 端口的服务器,
SSH 登录上去把 22 端口改到 1234 并且在原 22 端口开一个 nginx, 那么目前这台服务器理论上已和外接彻底隔绝了,用浏览器访问 22 端口也是 nginx 的页面了, 那么为什么没有断开的 ssh 客户端仍然可以操作这台服务器, 这个没有断开的客户端是通过什么方式与服务器进行通信的? A1: 我不是回答的嘛,socket 通讯 sfd 绑定的一个 5 元组,为什么能绑定成功后因为 地址和端口被复用, 你还在纠结“ SSH 登录上去把 22 端口改到 1234 并且在原 22 端口开一个 nginx ” , 这会 nginx server 那个 socket fd 在内核中只是一个三元组,不影响原先通信; Q2: 你希望修改 sshd 监听端口后,能关闭已连接的客户端, 说白了就要在内核层面修改状态, 从用户层面么 kill 该链接对应的进程,发生中断 |
30
Tyanboot 2018-05-30 12:52:18 +08:00
#5 已经明确的跟你说了建立的连接服务端用的都是新端口了, 你为啥还纠结通过什么方式通信的?
就算你把 22 改成 nginx, 和 nginx 也没半毛钱关系. 至于为什么"防火墙关闭除 22 之外的端口之外还能访问", 这应该是你防火墙还有放行 established 状态的规则. 因为我很久以前就试过 iptables -F 之后 只加一个 22 端口 accept 的规则. 再用-P DROP 设置默认规则之后. 当前的 ssh 链接立马就被中断了. |