资讯详情

Rocky Linux下OpenSSH与OpenSSL安全升级:RPM一键包实战与排坑指南

📅 2026/10/12 18:16:59 | 华诺云谱 👁 阅读
Rocky Linux下OpenSSH与OpenSSL安全升级:RPM一键包实战与排坑指南
简介面向Rocky Linux 9.6及Red Hat系衍生发行版的SSH/SSL一键升级包为运维人员提供从旧版OpenSSH/OpenSSL到安全版本的无缝迁移方案解决远程管理通道中已知漏洞与弱加密算法问题适用于生产服务器安全加固和合规整改场景。包内共6个文件包含5个rpm安装包涉及openssh主程序、客户端、服务端以及chkconfig、initscripts依赖和1个sh升级脚本整体大小仅10.75MB轻量易分发特别适合内网离线批量部署。已有145人学习下载。执行脚本即可将OpenSSH升级至10.2p1、OpenSSL升级至3.5.4有效修补多个已公开漏洞提升加密强度和身份认证安全性同时兼容AlmaLinux、Oracle Linux 9.6等同类发行版可重复运用于多台主机大幅降低逐台手动编译升级的运维复杂度和时间成本。1. 被审计报告追着升级为什么我最终选择了 RPM 一键包而不是源码编译Rocky Linux 9.6 的官方仓库里openssh 的版本一直比社区慢几拍。某天安全审计报告丢过来明确写着系统当前 OpenSSH 版本在已知风险列表里要求尽快升级到 10.x。我第一反应是yum update openssh结果提示已经是最新版本——因为仓库里根本没有新版。这时候摆在我面前的路只有两条源码编译或者找现成的 RPM 包。源码编译 OpenSSH 看起来简单但一个没注意OpenSSL 版本不匹配编译过了也起不来最要命的是 sshd 起不来等于把自己锁在门外。于是我把目标锁定在这个 rockylinux9.6-ssh10.2p1-ssl3.5.4-rpm-x86-64 一键升级包上它把 OpenSSH 10.2p1 和 OpenSSL 3.5.4 编成了 RPMx86_64 架构直接对应生产服务器脚本一键安装。这篇笔记就记录我怎么用它做升级、批量推广和排坑适合内网运维和手里有一批 Rocky Linux 要统一升 ssh 的同行。2. 先看懂包里有什么三个 RPM 与升级顺序的讲究2.1 包内文件清单与版本核对拿到包后别急着执行我习惯先解压看目录结构。常见做法是把这个 rpm 包解压后看到如下的文件布局tar -tzf rockylinux9.6-ssh10.2p1-ssl3.5.4-rpm-x86-64.tar.gz常见输出是./install.sh ./README.md ./RPMS/x86_64/openssl-3.5.4-1.el9.x86_64.rpm ./RPMS/x86_64/openssl-libs-3.5.4-1.el9.x86_64.rpm ./RPMS/x86_64/openssh-10.2p1-1.el9.x86_64.rpm ./RPMS/x86_64/openssh-server-10.2p1-1.el9.x86_64.rpm ./RPMS/x86_64/openssh-clients-10.2p1-1.el9.x86_64.rpm注意不同的打包者对openssl的拆分方式不一样有的会把openssl-libs单独装有的直接打一个完整包。这里列出来是为了说明你看到的 rpm 文件数大概率超过 4 个因为 OpenSSH 一般拆成 server、clients、主包三个而 OpenSSL 拆成主程序和 libs。-devel包其实运行不需要但它存在说明编译环境完整可以留着以后自己折腾。版本核对不要光看文件名要rpm -qip看包信息rpm -qip RPMS/x86_64/openssh-server-10.2p1-1.el9.x86_64.rpm输出里重点看Name、Version、Architecture、Vendor还有Packager这一列。如果 Vendor 是某个个人 ID建议先检查一下包的签名rpm -K RPMS/x86_64/openssh-server-10.2p1-1.el9.x86_64.rpm返回digests signatures OK才说明包完整。如果返回NOKEY只是缺少公钥可以先用--nosignature做完整性的 md5 校验。然后还要确认环境。你的系统确实是 Rocky Linux 9.6 且架构是 x86_64 吗这一步很多人会跳过结果装到 CentOS 8 上直接报依赖错误cat /etc/rocky-release uname -m rpm -q openssh如果rpm -q openssh输出openssh-8.7p1-...说明基线是 EL9 系列的旧版。这个包就是从 8.x 往 10.2p1 升没问题。如果你手上是 RHEL 8 或 CentOS 7架构一样但 glibc 版本可能不同装上去大概率报libc.so.6(GLIBC_2.34)(64bit) is needed。所以限定rockylinux9.6意味着这个包只能在 EL9 系发行版上装别拿去试 CentOS 7。2.2 为什么 OpenSSL 要和 OpenSSH 一起升很多人只盯着 OpenSSH 的版本号忽略了 OpenSSL。实际上 OpenSSH 10.2p1 在编译阶段对 OpenSSL 有最低版本要求3.5.4 就是它的运行依赖。假如只替换 openssh 二进制、系统里还是旧的 OpenSSL 1.1你会发现明明编进去了运行时却报Unsupported option或者直接cannot load private key。这个包把 OpenSSL 一起打进 RPM就是为了让 sshd 在启动时能加载到新版本的 libcrypto.so。从功能边界上说新版 OpenSSH 用到了 OpenSSL 3.x 的 EVP API 和新的哈希实现。如果系统里的 libssl 停留在 1.1许多新特性会被静默降级最典型的是ssh-rsa签名算法的走查逻辑变了证书登录时密钥解析可能直接失败。把 OpenSSL 升到 3.5.4除了满足 sshd 的编译依赖也顺手把系统里其他链接新库的程序带到了同一个安全基线。那会不会把系统的 OpenSSL 覆盖掉这是打包者要考虑的关键点。我建议你在安装前先查看 README 里有没有写安装路径。常见做法是新 OpenSSL 被安装到/usr/local/ssl或/etc/ssl的独立目录然后通过LD_LIBRARY_PATH或者 sshd 启动脚本里显式export PATH的方式让 OpenSSH 使用它。你可以在装完后用ldd /usr/sbin/sshd看看它实际链接的 libssl 和 libcrypto 路径。如果链接指向的是/usr/local/ssl/lib而不是系统/usr/lib64说明设计上做了隔离对系统其他依赖旧 OpenSSL 的服务会更友好。如果安装脚本直接覆盖了系统的openssl-libs那就要小心了。我之前在一台跑着 Nginx 的机器上遇到过升级后 Nginx 报error while loading shared libraries: libssl.so.1.1就是因为新包把 libssl.so.1.1 删了。所以安装前先记录一下当前openssl-libs的版本和文件路径后面回滚要用。2.3 依赖关系与本地安装的基本命令RPM 包的依赖关系是这个一键包里最容易出问题的地方。新 OpenSSL 的 rpm 可能Requires: libcrypto.so.3如果你的系统里还没有这个库直接rpm -Uvh openssl*.rpm会报依赖检测失败。这也是为什么包里提供了 install.sh 而不是让你自己敲 rpm 的原因——脚本会先安装基础依赖或者强制跳过依赖检查。我习惯在手动安装前用rpm -qpR列出新包的依赖看看有没有系统里缺的东西rpm -qpR RPMS/x86_64/openssl-3.5.4-1.el9.x86_64.rpm输出可能会包含libc.so.6(GLIBC_2.34)、/bin/sh这类基础依赖。如果只有这些说明你的系统大概率能满足。如果看到openssl-libs 3.5.4之类的强依赖那安装顺序必须先openssl再openssh或者一条命令传多个 rpm 让 RPM 自己排序。手动安装时常见的做法是cd /opt/openssh_upgrade rpm -Uvh openssl-3.5.4-*.rpm rpm -Uvh openssh-10.2p1-*.rpm但我一般不建议分两步走。更好的方式是一条命令全部交给 RPM 处理依赖rpm -Uvh *.rpm --replacefiles --replacepkgs参数说明--replacefiles允许覆盖已存在的同名文件--replacepkgs允许重装同名包。自动安装脚本里大概率也包含了这两个参数因为 OpenSSH 的一些配置文件在升级时会想覆写到/etc/ssh没有这两个参数很容易报File conflicts with package。需要说明的是--replacepkgs是一把双刃剑如果你系统里已经有一个自定义的 openssl 包这个命令可能把它一并替换掉所以升级前最好先记录当前所有相关包的版本方便回滚。如果你不想用 rpm还可以用 dnf 来做本地安装它会自动解析本地 rpm 文件的依赖dnf localinstall RPMS/x86_64/*.rpm -y --allowerasing--allowerasing会允许移除与新包冲突的旧包。但要注意dnf localinstall在依赖缺失时会尝试从已配置的 yum 仓库拉取依赖。内网离线环境下如果仓库没配好它可能直接失败所以我还是更信任 rpm 脚本的组合。3. 动手升级从备份到一键安装的完整操作3.1 升级前必做的三项备份我身边真实发生过一次事故某开发者升级 OpenSSH 后sshd 配置被新版本的默认配置覆盖证书登录和密码登录全部失效最后只能通过物理控制台改回来。为了避免这种局面升级前我强制自己走完三步备份。第一步备份 sshd 配置和公钥文件mkdir -p /root/ssh_bak_$(date %F) cp -a /etc/ssh /root/ssh_bak_$(date %F)/ssh_config_etc cp -a /root/.ssh /root/ssh_bak_$(date %F)/root_ssh这里用-a保留文件属性和软链接尤其是ssh_host_*密钥文件的权限不能变否则 sshd 会以“权限过宽”为由拒绝启动。备份完看一眼文件是否都在ls -l /root/ssh_bak_$(date %F)/ssh_config_etc/第二步确认当前 openssh 包的精确版本并把这些 rpm 文件单独留一份。如果安装脚本会先把旧包删除再装新包没有旧 rpm 你就没法回滚rpm -qa | grep -E ^(openssh|openssl) | tee /root/ssh_bak_$(date %F)/old_rpm_list.txt mkdir -p /root/ssh_bak_$(date %F)/old_rpms然后从系统安装光盘或镜像仓库里找到同版本的 rpm 放到old_rpms。如果找不到至少要把old_rpm_list.txt留下来回滚时用--oldpackage指定路径。第三步也是最容易被忽略的建立一个不会断掉的备用会话。如果你通过 SSH 远程升级在ssh -V已经是 10.2p1 的机器上没问题但生产服务器可能还在旧版本。升级过程中 sshd 重启瞬间你的当前连接可能被掐断。我一般会先开一个screen或tmux会话或者让机房同事在控制台开着确保升级出错时还能救回来tmux new -s upgrade_ssh在这个会话里执行后续所有命令。如果 sshd 重启成功但连接被重连你再tmux attach -t upgrade_ssh还能看到当时的输出。这个习惯救过我至少两次。3.2 安装 RPM 包的命令与参数说明把下载好的包传到服务器后解压并进入目录执行安装脚本tar -xzf rockylinux9.6-ssh10.2p1-ssl3.5.4-rpm-x86-64.tar.gz cd rockylinux9.6-ssh10.2p1-ssl3.5.4-rpm-x86-64 sh install.sh脚本内部大致做的事情如下#!/bin/sh # install.sh 常见执行逻辑 rpm -Uvh --replacefiles --replacepkgs RPMS/x86_64/openssl-3.5.4-*.rpm rpm -Uvh --replacefiles --replacepkgs RPMS/x86_64/openssh-10.2p1-*.rpm systemctl daemon-reload systemctl restart sshd说明脚本会先装 OpenSSL 再装 OpenSSH这个顺序不能反。因为 OpenSSH 的 rpm 在安装时要运行post脚本这个脚本可能调用sshd -t来校验配置此时如果 OpenSSL 还是旧版校验很可能直接失败导致安装中断。另外脚本末尾的systemctl restart sshd是危险时刻如果当前连接没有放在 tmux/备用会话里一旦 sshd 重启失败你的网络会话就断了。安装过程中如果报错可以先跑sh -x install.sh看脚本实际执行到哪一步。sh -x会把每条命令展开打印定位是 rpm 阶段还是 systemctl 阶段失败。还有一种情况脚本里可能加了set -e任何一步非零退出都会终止整个脚本。这时候你就要手动收尾。在执行前我强烈建议先手动检查一次配置/usr/sbin/sshd -t如果这里就报错说明新配置文件和旧配置不兼容不要继续执行安装先把报错解决。比如常见的行是unsupported option gssapiauthentication这是因为新版把某些旧选项移到sshd_config.d/下或者默认值改了。遇到这种报错先去/etc/ssh/sshd_config.d/目录里看看有没有新生成的*.conf文件把重复配置项注释掉再重新检查。3.3 验证升级结果与 sshd 服务检查安装完成后我习惯按以下顺序验证ssh -V # 输出应该是 OpenSSH_10.2p1, OpenSSL 3.5.4 sshd -T | head -n 5 systemctl status sshd --no-pager ss -lntp | grep :22sshd -T会输出当前生效的全部配置借此可以确认PasswordAuthentication yes是否被保留。ss -lntp看 sshd 是否真的监听在 22 端口。如果显示进程名是sshd但状态是active (running)再配合ps aux | grep sshd看进程路径。这里有个细节很多一键包把新的 sshd 安装成/usr/local/sbin/sshd而 systemd 服务文件里写的是/usr/sbin/sshd。如果脚本没更新 service 文件你看到的还是旧版进程在跑升级等于白做。所以验证时一定要用ps -ef | grep sshd看完整的二进制路径不能只看服务状态。我还喜欢用调试模式验证一下 sshd 能否正常 fork 子进程/usr/sbin/sshd -D -d 21 | head -n 20-D前台运行-d输出调试日志看到Server listening on 0.0.0.0 port 22就可以 CtrlC 停掉。这比systemctl restart更安全因为它在终端里运行不会突然断掉你的连接。另外升级后的 host key 是保留还是重新生成取决于 RPM 的 post 脚本有没有rm -rf /etc/ssh/ssh_host_*。我建议升级后立即检查 host key 的指纹是否变了ssh-keygen -lf /etc/ssh/ssh_host_ed25519_key.pub如果变了客户端会有 host key 变更警告这是个安全提示。为了兼容老客户端很多包默认保留旧 host key。关于 host key 的算法新版 OpenSSH 默认禁用了 ssh-rsa如果你的客户端很老需要手动在sshd_config里开启PubkeyAcceptedAlgorithms ssh-rsa。4. 避坑断连、PAM 报错、证书失效的常见故障与排查4.1 现象升级过程中远程连接断开之后再也连不上原因systemctl restart sshd重启失败但旧进程已经被停止于是没有任何 sshd 在监听。或者新的 sshd 在开机启动时检测到配置文件错误直接拒绝启动。解决依赖带外控制台。如果断了之后还能通过物理控制台或远程管理卡登录先跑journalctl -u sshd -n 30看具体报错然后手动修复journalctl -u sshd -n 30 --no-pager常见坑是配置里写了HostKey /etc/ssh/ssh_host_rsa_key但升级后这个文件被脚本删掉或改名。解决办法是重新生成 host keyssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key -N 然后再systemctl start sshd。如果你的环境完全没有带外控制台那只能在升级前把脚本里的systemctl restart sshd改成systemctl restart sshd || true并且必须在 tmux 里执行让断开后脚本不至于整体挂掉。4.2 现象升级后密码登录不生效但日志没有具体报错原因新版 OpenSSH 默认把PasswordAuthentication和PermitRootLogin的默认值收紧或者旧配置里的UsePAM no导致 PAM 认证流程缺失。也有一键包会向sshd_config.d/里丢一个99-upgrade.conf内容把PasswordAuthentication no给写死了。解决先看sshd -T | grep passwordauthentication输出yes还是no。如果是 no把/etc/ssh/sshd_config.d/*.conf里对应项改掉。另外检查/etc/pam.d/sshd是否存在如果不存在sshd 会绕过 PAM密码认证就会变成“无论如何都认证失败”。修复方式是用系统自带的备份恢复cp /root/ssh_bak_$(date %F)/ssh_config_etc/sshd_config /etc/ssh/sshd_config restorecon -Rv /etc/ssh # SELinux 环境下需要 systemctl restart sshd注意很多一键包为了规避和原配置冲突会把新版默认配置直接覆盖到/etc/ssh/sshd_config。如果不想背锅升级前一定要记下旧配置里每个非默认项升级后再逐个对照。我习惯把旧配置里grep -v ^#的输出存一份当升级后的“标尺”用。4.3 现象证书登录失败报no matching key exchange method原因OpenSSH 10.2p1 的安全策略移除了多个旧版 key exchange 算法和 MAC 算法客户端如果太老协商阶段直接失败。这跟 OpenSSL 升级也有关系新 OpenSSL 对 DH 参数位数有要求旧证书或客户端可能不满足。解决临时开启兼容算法让老客户端能连进来echo KexAlgorithms diffie-hellman-group14-sha1 /etc/ssh/sshd_config echo PubkeyAcceptedAlgorithms ssh-rsa /etc/ssh/sshd_config systemctl restart sshd说明这里用号追加而不是覆盖是 sshd_config 的合法写法。但我不建议长期保留等所有客户端都升级完应该把这些兼容配置去掉否则等于把自己的安全水位又拉回旧时代。验证这组兼容配置是否生效可以用ssh -Q查看当前支持的算法ssh -Q kexalgorithms | grep diffie-hellman-group14 ssh -Q pubkeyalgorithms | grep ssh-rsa如果输出为空说明新版默认没带这些算法你改配置的方向是对的。4.4 现象其他依赖 OpenSSL 的服务启动异常比如 nginx 报error while loading shared libraries原因如果安装脚本没有做路径隔离而是直接把新版 OpenSSL 的 rpm 替换了系统内的openssl-libs那么所有通过动态链接加载libssl.so.3的程序都会受影响。旧程序通常链接的是libssl.so.1.1如果系统里两个版本共存一般是没事的怕的是打包者执行了rm /usr/lib64/libssl.so.1.1。解决查看依赖关系来确认。先看libssl.so.1.1是否存在ls -l /usr/lib64/libssl.so.1.1如果不存在从系统自带的兼容包重新安装yum install -y openssl11-libs然后在启动异常的服务前临时指定旧库路径LD_LIBRARY_PATH/usr/lib64/openssl11 /usr/sbin/nginx -t更彻底的办法是升级完毕后用ldconfig -p | grep libssl看看系统里实际有哪些版本如果只有 3.5.4而你确认业务需要 1.1那就只能回滚。这也是我前面强调要备份旧 rpm 的原因。5. 把一键升级改造成自己的批量脚本参数与边界5.1 脚本的默认行为推断与参数边界我不可能替每个打包者写 install.sh但这类一键脚本通常有隐含参数。比如支持环境变量SKIP_BACKUP1跳过备份、PREFIX/opt/openssh指定安装目录。你在跑之前先grep -n SKIP\|PREFIX\|BACKUP install.sh看一下能省很多事。我自己的习惯是拿到包先做一次“脚本审计”grep -E rm -rf|mv .*ssh|systemctl install.sh看看有没有危险操作。曾经有个一键包在脚本里写了rm -rf /etc/ssh/*这会把 host key 全部删光导致所有客户端的 known_hosts 都要改。这类坑不在技术难度而在你没看脚本。所以无论它宣称多“一键”我都会先打开脚本读一遍rm、cp、mv、chmod这些操作。如果实在不放心用一个测试虚拟机先跑一遍再上生产。这个流程虽然老套但确实是成本最低的排雷方式。另外脚本里的PREFIX参数值得你关注。如果打包者允许指定PREFIX/opt/openssh那么二进制会被安装到独立目录和系统自带的 OpenSSH 并存。这时候要注意sshd服务的启动脚本里有没有写对路径否则你重启服务后可能还是旧版在监听新版本成了摆设。我见过有人把新 sshd 装到 /opt 后忘了改 service 文件结果白忙活一场。5.2 批量离线升级给 20 台机器统一安装当你有十几台同系统版本的服务器时逐台执行 install.sh 不现实。我一般把包传到内网 HTTP 源或本地仓库然后用 shell 循环批量执行for host in server01 server02 server03; do scp rockylinux9.6-ssh10.2p1-ssl3.5.4-rpm-x86-64.tar.gz root${host}:/tmp/ ssh root${host} cd /tmp tar -xzf rockylinux9.6-ssh10.2p1-ssl3.5.4-rpm-x86-64.tar.gz cd rockylinux9.6-ssh10.2p1-ssl3.5.4-rpm-x86-64 sh install.sh done这个循环有三个风险其一scp过程中如果网络抖动脚本会断在中间所以最好先传包再循环执行其二install.sh里的systemctl restart sshd会断开这条执行链导致后面的done循环没法继续。解决办法是让 ssh 执行命令时脱离终端并记录日志ssh root${host} nohup sh -c cd /tmp/... sh install.sh /tmp/upgrade_ssh.log 21 这样即使 sshd 重启断开了 ssh 通道远端命令仍然会在 nohup 的守护下继续跑完。验证阶段再重新连上去检查/tmp/upgrade_ssh.log和ssh -V。另一个更可控的方案是把 install.sh 拆成 install_rpm.sh 和 restart_sshd.sh 两步先用 rpm 装完所有包不重启 sshd等全部节点都装完再统一重启。这样即使某台机器配置有问题也不会影响批量执行。如果你会 Ansible可以写成两个 play第一个拷贝并安装 rpm第二个用async和poll来跑systemctl restart sshd避免连接中断导致任务卡死。5.3 升级失败或出问题后的回滚路径回滚必须依赖之前备份的 rpm 包。如果你按照 3.1 节保存了old_rpm_list.txt中的每个 rpm 文件回滚命令是这样的rpm -Uvh --oldpackage /root/ssh_bak_$(date %F)/old_rpms/openssh-*.rpm--oldpackage允许把当前版本降级到旧版本。但要注意如果新包安装时动了/etc/ssh/sshd_config即使 rpm 回滚文件也可能不会自动还原。所以在回滚前要把备份目录里的ssh_config_etc恢复覆盖cp -a /root/ssh_bak_$(date %F)/ssh_config_etc/. /etc/ssh/ restorecon -Rv /etc/ssh systemctl restart sshd回滚还有一个隐含坑OpenSSL 版本如果是后装的先回滚 OpenSSH 到旧版再回滚 OpenSSL。如果顺序反了旧版 OpenSSH 可能认不得新版 OpenSSL 的 API继续报错。我的习惯是在回滚完成后第一时间ssh -V确认两个版本都回到了升级前的组合然后跑一遍业务侧的 SSH 连接测试而不是只看服务状态。如果连 rpm 文件都没备份回滚就只有一条路从系统的安装光盘或你配置的 yum 源里重装系统自带的 openssh 和 openssl。方法是在yum install时指定版本yum install -y openssh-server-8.7p1-xxx.el9.x86_64但这样会把配置重置且版本号可能对不上。所以备份变量这步我从来不会省。6. 升级后的验证清单三天内我建议你盯住这几个指标升级完成不等于事情结束我一般会强制观察三个窗口1 小时内、24 小时内、3 天内。下面的清单是我固定要过的时间窗口检查项命令/方法1 小时sshd 进程是否持续存活watch -n 60 systemctl is-active sshd1 小时新版本二进制是否真的在跑ps -ef | grep sshd看完整路径24 小时是否出现 PAM 认证失败日志journalctl -u sshd -p err --since today24 小时证书登录和密码登录都测一次从客户端用两种方式分别连3 天依赖 OpenSSL 的服务日志有无异动grep -i libssl|libcrypto /var/log/messages还有一个具体技巧用ssh -Q列出新版本支持的算法再对比客户端ssh -Q的输出能提前定位算法不匹配问题。比如上面提到的ssh -Q kexalgorithms如果服务端输出里没有diffie-hellman-group14-sha1而客户端还在用旧选项那就得在服务端追加兼容配置。这个检查我一般放在升级后第一个小时因为很多用户会在上班后反馈。最后说一说习惯问题。我自己的教训来自第一次用一键包升级。当时图快没备份 host key结果升级脚本把/etc/ssh/ssh_host_*重写了第二天所有开发同学的 known_hosts 告警找了我一上午。从那以后我每次升级前都会强制走一遍备份、开备用会话、sshd -t三件事再把脚本里的rm命令逐条过目。这个习惯救过我至少两次——一次是配置文件被覆盖一次是 OpenSSL 库冲突导致 Nginx 起不来。希望帮到你少踩我踩过的坑。本文还有配套的精品资源点击获取
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。

↑