折腾主机时最怕发生什么事?那就是主机的一些设置完全不按自己期望的方式工作,又死活搞不明白,完全可以用灵异事件来解释。
(图源 :pixabay)
话说突然想到以前中央电视台有一档节目《走近科学》,那么我折腾主机时遇到的问题,走近科学是不是能拍上十集连续剧呀?
扯远了,话说大家都知道SSH服务的默认端口号是22,也是脚本小子等黑客最喜欢攻击(比如暴力登陆测试)的目标,所以管它有用没用,每次弄新主机,我都要该一下默认的SSH端口。
灵异事件
在以前,改端口是一件很简单的事情,使用root权限编辑/etc/ssh/sshd_config这个文件,找到这行:
#Port 22
这行的意义是sshd默认监听22端口,前边的#表示这行已经被注释掉,不起作用(所以使用默认的端口)。
我们可以在这一行上进行修改,去掉#,再将端口修改成我们想要的端口。但是我更喜欢新加一行,如果我们要监听更多的端口,就多写几行,比如:
Port 50001Port 50002
注意,我们指定了新端口,又没有显式指定22端口(比如Port 22),就会在修改端口的同时禁用22端口。
修改完成后要重启服务,使相应的设置生效,指令如下:
sudo systemctl restart ssh
这时不要退出当前窗口,可以使用打开新窗口来测试,以免修改错误导致自己被屏蔽在外,又没法重新修改,哈哈哈。
话说,好多好多年前,我犯过类似的错误(不是设置SSH,好像是设置防火墙,把自己挡外边了),最后只能重装系统,惨就一个字!
话说这次我又打开了一个新窗口测试了一下新的端口,结果竟然被提示如下信息:

啥,是可忍熟不可忍!我曾经做了无数次的事情,怎么可能出错?!不过我又死心试了N多次,每次都如此,大概是哪里出错了?
我重新检查了所有环节,发现并无哪里做得不对,又用22端口试了一下,竟然诡异地发现22端口依然可以连接。
也就是说我想启用端口完全没有生效,我想禁用的端口它还活着?这咋解释?这就是灵异事件了吧?!等我打电话联系《走近科学》剧组!
找出问题
哈哈,联系剧组是不可能联系的,况且这个栏目还有没有都不清楚了呢!我还是自己想办法吧!
我突然想到既然sudo systemctl restart ssh,那我试试先关闭在启动呢?
sudo systemctl stop sshsudo systemctl start ssh
貌似问题依旧,不过在我停掉ssh服务的时候,有个这样的提示:

Stopping 'ssh.service', but its triggering units are still active:ssh.socket
字是黄色的,或许这就是解决问题的金钥匙?让我用ssh.socket做关键字,在Google.com中搜索一下看看。👀
感谢强大的Google,第一条结果就给了我完美的答案,且底下还有AI的贴心总结:

简单来讲,在新版本的Ubuntu中( Ubuntu 22.10 或更高版本中), OpenSSH 默认配置为使用 systemd 套接字激活。这意味着 sshd 只有在收到传入连接请求后才会启动。
既然sshd 只有在收到传入连接请求后才会启动,那么监听端口肯定是在systemd 套接字中进行相关设置呀。
可以使用这条指令(或者加sudo查看更详细信息)查看系统当前监听的 TCP 端口:
ss -tlpn
返回如下:

或者使用如下指令ssh.socket 的 systemd 配置文件:
systemctl cat ssh.socket
返回如下(就不逐条解释啦)

或者用如下指令查看ssh.socket 状态:
systemctl status ssh.socket

解决问题
既然明白了问题所在,解决问题就是轻而易举了。大概有两个方向:一是恢复sshd按老旧的机制;二是基于新机制解决监听端口的问题。
回归老机制
老机制就是禁用systemd 管理 socket,让 sshd 自己监听:
sudo systemctl disable --now ssh.socketsudo systemctl enable --now ssh.service
使用新机制
虽然回归老机制也可以让sshd按我期望的样子工作,但是既然有更优秀的新机制,当然选新机制啦。
据说使用ssh.socket的方式有诸多优点,比如说可以省3M内存(额,好大一笔内存开销)。
直接修改ssh.socket 的 systemd 配置文件是不可以的,升级时会被覆盖,正确的做法是使用 override(覆盖)机制。
执行如下指令:
sudo systemctl edit ssh.socket
或者直接使用编辑器编辑相应文件
sudo vi /etc/systemd/system/ssh.socket.d/override.conf
然后对这个文件进行编辑:

加入类似如下内容:
[Socket]ListenStream=ListenStream=0.0.0.0:50001ListenStream=0.0.0.0:50002
需要指出的是ListenStream=并非笔误,而是要用这行先清空旧的默认值(22)。
修改好后重新加载并应用
sudo systemctl daemon-reloadsudo systemctl restart ssh.socket
这次再尝试连接22端口,发现是如下提示了:

而连接我指定的新端口,则一切正常。用sudo ss -tlpn以及systemctl status ssh.socket检查一下,也确如我所希望的样子。
(图源 :pixabay)
《走进科学》剧组也不用来了,搞定收工!