特别提醒:升级ssh是高风险操作,升级失败会导致远程无法连接上,提前做好各种预防措施。
升级思路:
1.先打开telnet相关服务,做好防范
2.先升级ssl,再升级ssh
3.关闭telnet相关服务
为防止出现无法连接服务器,可以通过打开telnet增加进入服务器的方式。
查看是否打开telnet:
sudo netstat -tlnp | grep :23
#无输出,说明telnet服务没打开
--------打开telnet相关服务-----------
Telnet 是一种极不安全的协议,所有数据(包括用户名和密码)都以明文传输,极易被窃取。
绝对禁止在公网或任何生产环境中使用 Telnet。
在 Ubuntu 16.04 中,xinetd 是管理 Telnet 服务的"超级服务器"
步骤一:安装 Telnet 服务
sudo apt-get update
sudo apt-get install xinetd telnetd
步骤二:配置 Telnet 服务
sudo vim /etc/xinetd.d/telnet
增加如下配置:
service telnet
{
disable = no
flags = REUSE
socket_type = stream
wait = no
user = root
server = /usr/sbin/in.telnetd
log_on_failure += USERID
}
保存。
步骤三:启动服务并设置开机自启
重启 xinetd 服务以使配置生效:
sudo /etc/init.d/xinetd restart
sudo systemctl enable xinetd
步骤四:配置防火墙
如果使用 ufw(Ubuntu 默认)
sudo ufw allow 23/tcp
如果使用 iptables
sudo iptables -A INPUT -p tcp --dport 23 -j ACCEPT
步骤五:验证服务是否开启
sudo netstat -a | grep telnet
如果看到输出,表示 Telnet 服务已在运行并监听
问题:telnet打开后,用原有ssh的root用户名 密码无法登录
用 SSH 的 root 密码无法登录 Telnet,通常是出于安全考虑,系统默认禁止了 root 用户通过 Telnet 直接登录
/etc/pam.d/login:这个文件控制着登录行为。其中有一行 auth required pam_securetty.so,它会调用 pam_securetty 模块来检查 root 登录的终端是否被允许。
/etc/securetty:这个文件定义了允许 root 用户登录的"安全"终端列表。出于安全考虑,pts/*(即 Telnet 和 SSH 等远程登录使用的伪终端)默认不在这个列表中,因此 root 登录会被拒绝。
解决办法:修改 /etc/securetty 文件(推荐)
sudo vim /etc/securetty
末尾增加:
pts/0
pts/1
pts/2
pts/3
pts/4
pts/5
pts/6
pts/7
pts/8
pts/9
pts/10
pts/11
pts/12
至少加到pts/12 ,因为排查日志sudo tail -f /var/log/auth.log 发现有验证pts/9或者pts/11,根据情况增加即可。
root@user-UniServer-R4900-G3:~# sudo tail -f /var/log/auth.log
Aug 13 16:30:01 user-UniServer-R4900-G3 CRON[32682]: pam_unix(cron:session): session opened for user root by (uid=0)
Aug 13 16:30:07 user-UniServer-R4900-G3 CRON[32682]: pam_unix(cron:session): session closed for user root
Aug 13 16:35:01 user-UniServer-R4900-G3 CRON[35461]: pam_unix(cron:session): session opened for user root by (uid=0)
Aug 13 16:35:07 user-UniServer-R4900-G3 CRON[35461]: pam_unix(cron:session): session closed for user root
Aug 13 16:40:01 user-UniServer-R4900-G3 CRON[38224]: pam_unix(cron:session): session opened for user root by (uid=0)
Aug 13 16:40:07 user-UniServer-R4900-G3 CRON[38224]: pam_unix(cron:session): session closed for user root
Aug 13 16:45:01 user-UniServer-R4900-G3 CRON[320]: pam_unix(cron:session): session opened for user root by (uid=0)
Aug 13 16:45:07 user-UniServer-R4900-G3 CRON[320]: pam_unix(cron:session): session closed for user root
Aug 13 16:49:05 user-UniServer-R4900-G3 sudo: root : TTY=pts/9 ; PWD=/root ; USER=root ; COMMAND=/usr/bin/tail -f /var/log/auth.log
Aug 13 16:49:05 user-UniServer-R4900-G3 sudo: pam_unix(sudo:session): session opened for user root by root(uid=0)
接下来测试用root的账号密码登录,协议选择telnet 端口23 ,是否能登录服务器
正常是可以测试成功。
--------------升级ssl到3.5.7-------------------
备份关键数据
备份 SSH 配置目录
sudo cp -r /etc/ssh /etc/ssh-bak-$(date +%F)
备份 PAM 配置
sudo cp /etc/pam.d/sshd /etc/pam.d/sshd.bak
记录当前版本信息
ssh -V > ~/ssh_old_version.txt
安装编译依赖:升级需要编译源码,因此必须安装必要的开发工具和库
sudo apt-get update
sudo apt-get install -y build-essential zlib1g-dev libssl-dev
第一步:升级 OpenSSL 到 3.5.7
OpenSSH 9.8p1 需要 OpenSSL 1.1.1 或更高版本,因此需要先升级 OpenSSL。
1.下载并解压源码
cd /opt
# 从官网下载 OpenSSL 3.5.7 源码包
wget https://www.openssl.org/source/openssl-3.5.7.tar.gz
tar -xzvf openssl-3.5.7.tar.gz
cd openssl-3.5.7
2.编译与安装
# 配置。--prefix 指定安装路径
./config --prefix=/usr/local/ssl -d shared
# 开始编译(可使用 -j 参数加快速度,如 make -j 4)
make
# 安装
sudo make install
3.配置动态链接库:让系统能找到新安装的 OpenSSL 库文件
将库路径加入配置文件
echo '/usr/local/ssl/lib' | sudo tee -a /etc/ld.so.conf
更新动态链接库缓存
sudo ldconfig -v
4.验证版本
/usr/local/ssl/bin/openssl version
如果输出 OpenSSL 3.5.7 ...,则说明升级成功。
会发现并没有升级成功,报错信息如下:
root@user-UniServer-R4900-G3:/opt/openssl-3.5.7# /usr/local/ssl/bin/openssl version
/usr/local/ssl/bin/openssl: error while loading shared libraries: libssl.so.3: cannot open shared object file: No such file or directory
echo '/usr/local/ssl/lib' | sudo tee -a /etc/ld.so.conf
echo "/usr/local/ssl/lib" > /etc/ld.so.conf.d/openssl-3.5.7.conf
问题原因:库文件 libssl.so.3 和 libcrypto.so.3 根本没有被安装到 /usr/local/ssl/lib 目录,所以无论怎么配置 ldconfig 都没用。我们需要先确认编译是否真的成功生成了动态库,以及 make install 是否正常复制了文件。
第一步:确认库文件是否在源码目录中生成
ls -l /opt/openssl-3.5.7/*.so
ls -l /opt/openssl-3.5.7/lib*.so
第二步:检查 /usr/local/ssl 目录下有哪些内容
ls -lR /usr/local/ssl | head -30
看看是否有 bin、include 等目录,但缺少 lib 下的库文件。
第三步:重新执行安装(或手动复制)
如果编译生成的库在源码目录中,可以手动复制到 /usr/local/ssl/lib:
sudo mkdir -p /usr/local/ssl/lib
sudo cp -d /opt/openssl-3.5.7/libssl.so* /usr/local/ssl/lib/
sudo cp -d /opt/openssl-3.5.7/libcrypto.so* /usr/local/ssl/lib/
然后重新运行 ldconfig
第四步:如果编译没生成动态库,重新配置编译
cd /opt/openssl-3.5.7
make clean # 清理之前的编译产物
./config --prefix=/usr/local/ssl --openssldir=/usr/local/ssl shared -d
make -j $(nproc)
sudo make install
第五步:安装成功后更新动态库缓存
echo '/usr/local/ssl/lib' | sudo tee /etc/ld.so.conf.d/openssl-3.5.7.conf
sudo ldconfig
ldconfig -p | grep libssl # 应该能看到 libssl.so.3
第六步:验证
/usr/local/ssl/bin/openssl version
-------------------升级OpenSSH到 9.8p1-------------------------
编译并安装 OpenSSH 9.8p1
1.下载并解压源码
cd /opt
wget https://cdn.openbsd.org/pub/OpenBSD/OpenSSH/portable/openssh-9.8p1.tar.gz
tar -zxvf openssh-9.8p1.tar.gz
cd openssh-9.8p1
2.配置编译选项:这一步很关键,需要指定新安装的 OpenSSL 路径
./configure --prefix=/usr/local/ssh \
--sysconfdir=/etc/ssh \
--with-ssl-dir=/usr/local/ssl \
--with-zlib \
--with-pam
会提示:PAM is enabled. You may need to install a PAM control file
for sshd, otherwise password authentication may fail.
Example PAM control files can be found in the contrib/
subdirectory。
说明本步骤安装完成,可以继续。
- 编译与安装
make
sudo make install
会发现执行sudo make install后会报错:
Unable to load host key "/etc/ssh/ssh_host_dsa_key": invalid format
Unable to load host key: /etc/ssh/ssh_host_dsa_key
OpenSSH 9.8p1 默认在编译时禁用了 DSA 密钥(因为 DSA 算法脆弱且已被弃用)。而你的旧系统配置文件 /etc/ssh/sshd_config 中仍然包含加载 DSA 主机密钥的配置行:
新版的 sshd 不认识(或不支持)这种密钥格式,因此配置测试失败。
解决方案:
手动编辑(vim /etc/ssh/sshd_config),找到包含 ssh_host_dsa_key 的那一行,在前面加 # 注释掉。
备份并移除旧的 DSA 密钥文件(避免干扰)
sudo mv /etc/ssh/ssh_host_dsa_key /etc/ssh/ssh_host_dsa_key.bak
sudo mv /etc/ssh/ssh_host_dsa_key.pub /etc/ssh/ssh_host_dsa_key.pub.bak
手动测试新配置是否通过
sudo /usr/sbin/sshd -t
如果没有任何输出,说明配置正确,可以继续。
重启 SSH 服务
sudo systemctl restart sshd
验证服务状态和版本
sudo systemctl status sshd
ssh -V
更新完后,ssh -V 发现ssh和ssl还是没显示更新
问题原因:make install 已经把新文件安装到了 /usr/local/ssh/sbin/sshd 和 /usr/local/ssh/bin/ssh,但尚未复制到系统默认路径,所以系统命令仍指向旧文件
解决办法:
1.备份并替换系统二进制文件
备份旧文件(如果之前未备份)
sudo mv /usr/sbin/sshd /usr/sbin/sshd.bak
sudo mv /usr/bin/ssh /usr/bin/ssh.bak
sudo mv /usr/bin/ssh-keygen /usr/bin/ssh-keygen.bak # 可选
复制新编译的文件到系统路径
sudo cp /usr/local/ssh/sbin/sshd /usr/sbin/sshd
sudo cp /usr/local/ssh/bin/ssh /usr/bin/ssh
sudo cp /usr/local/ssh/bin/ssh-keygen /usr/bin/ssh-keygen # 可选
2.重启 SSH 服务,使新的 sshd 生效
sudo systemctl restart sshd
- 验证版本(分别在当前会话和新会话中)
查看服务端版本(新版支持 -V)
sudo /usr/sbin/sshd -V
查看客户端版本
ssh -V
root@user-UniServer-R4900-G3:/opt/openssh-9.8p1# ssh -V
OpenSSH_9.8p1, OpenSSL 3.5.7 9 Jun 2026
root@user-UniServer-R4900-G3:/opt/openssh-9.8p1#
root@user-UniServer-R4900-G3:/opt/openssh-9.8p1# sudo /usr/sbin/sshd -V
OpenSSH_9.8p1, OpenSSL 3.5.7 9 Jun 2026
root@user-UniServer-R4900-G3:/opt/openssh-9.8p1#
------------关闭telnet相关服务 ---------------
1.停止 Telnet 服务
如果使用 xinetd(最常见)、inetd
sudo systemctl stop xinetd
sudo systemctl stop inetd
2.禁用开机自启
sudo systemctl disable xinetd
sudo systemctl disable inetd
- 关闭防火墙端口(23 端口)
sudo ufw delete allow 23/tcp
sudo iptables -D INPUT -p tcp --dport 23 -j ACCEPT
4.验证 Telnet 已关闭
sudo netstat -tlnp | grep :23