Ubuntu 20.04离线安装sshd完整指南:依赖解析与避坑实践

📅 发布时间:2026/9/2 18:36:52
Ubuntu 20.04离线安装sshd完整指南:依赖解析与避坑实践 简介面向Ubuntu 20.04桌面版有远程运维需求的用户当目标主机处于无外网或内网隔离状态时这份离线SSH安装包提供了快速部署sshd服务的方案。系统默认未预装SSH常规在线安装需要额外下载依赖而该资源将所需组件集中打包免去手动逐一配置的麻烦。压缩包约1.05MB内含4个文件其中3个为deb安装包覆盖openssh-client、openssh-server与SFTP服务组件另附sh安装脚本可一键执行安装、自动补齐依赖并完成服务配置。已有1243人学习/下载适合运维人员、开发者在受限网络环境中使用也适用于学校机房、企业内网等离线场景。借助脚本可自动完成安装、启动及开机自启配置并附有远程管理安全建议如修改默认端口、启用公钥认证、定期更新等帮助用户从基础部署到安全提升一步到位。 搞过内网服务器的人基本都会遇到这么个场景机器放在机房或者办公网里系统装好了Ubuntu 20.04但是上不了外网。这时候想通过SSH远程登进去维护结果发现连sshd都没装。你敲下apt install openssh-server等来的不是进度条而是“域名解析失败”或者一串源连接超时。这个尴尬我经历过好几次后来干脆养成了习惯不管机器有没有网络先想办法把sshd离线包备好。这篇文章就把Ubuntu 20.04下离线安装sshd的完整过程记录下来重点解决三个问题怎么在有网的机器上下载到正确的离线安装包、怎么把依赖捡干净、到了目标机器上怎么装不踩坑。适合所有要维护离线Linux服务器、或者在虚拟化环境里批量初始化系统的朋友参考照着操作基本十分钟内能搞定。1. 离线安装的整体思路与准备1.1 先搞清楚sshd在Ubuntu里到底对应哪个包很多人一上来就搜“sshd下载”其实Ubuntu里头没有叫sshd的独立软件包sshd是OpenSSH的服务端进程对应的包名是openssh-server。安装之后系统里会多出一个sshd服务通过systemd管理。同时它还依赖一个叫openssh-client的包虽然客户端工具一般系统里自带但如果目标机器镜像特别精简客户端也可能缺最好一并带上。另外还有几个子包容易被忽略openssh-sftp-serverSFTP子系统、openssh-tests测试工具不需要的话可以不带。实际安装时只要把openssh-server的依赖链补全就行不需要全量下载所有OpenSSH相关包。1.2 离线安装的三条路线怎么选我在不同场景下试过三种方案各有优劣你可以根据手头条件挑方案操作方式优点缺点方案Adeb包直接下载在联网机器上用apt download抓取deb包复制到目标机用dpkg -i安装对目标机无特殊要求最通用需要手动解析依赖容易漏包方案B离线apt源在联网机器上下载所有deb到目录用dpkg-scanpackages生成Packages索引目标机配置本地file源接近在线apt体验可反复安装准备步骤繁琐适合企业批量部署方案C打包整个系统文件从运行正常的同版本机器上把/usr/sbin/sshd和相关配置、so库打tar包拷过去不依赖deb机制适合极度精简系统二进制与系统库版本不匹配时容易翻车不推荐新手用我最常用的是方案A对于就装一个sshd的场景来说它最直接。后面讲的所有步骤也都基于方案A。2. 在有网络的机器上准备离线安装包2.1 下载deb包的三种方式准备离线安装包的第一步是先找一台能正常联网、同样跑着Ubuntu 20.04的机器。版本一定要一致哪怕对方是20.10或者22.04都可能导致依赖版本对不上。方式是直接用apt download。先更新一下本机索引sudo apt update然后下载openssh-server以及它的依赖包。我习惯写个小脚本循环获取sudo apt download openssh-server openssh-client openssh-sftp-server如果运气好这几个包的依赖都已经在本机安装过那么这一条命令就够了。但绝大多数情况下目标机器和下载机装的软件种类不一样dpkg依赖解析时会报缺失。这时候需要把依赖一并下载。方式二用apt-get install --reinstall --print-uris来打印下载地址apt-get install --reinstall --print-uris --yes openssh-server这个命令会输出一串.deb包的URL然后你在联网机器上用wget挨个抓下来。这个方式的好处是输出即所需缺点是输出的URL有时候是镜像站路径拿下来之后还得确认文件名。方式三用apt-rdepends递归列出依赖关系sudo apt install apt-rdepends apt-rdepends openssh-server输出结果会列出多层次的依赖树非常直观。但前提是联网机器上先装好apt-rdepends这个工具没网的话就又陷入先有鸡还是先有蛋的循环。2.2 依赖分析到底要捡哪些文件这里重点说一下为什么很多人按教程下载完到了目标机上还是会报错因为漏了依赖。以Ubuntu 20.04focal为例openssh-server的典型依赖链包括openssh-clientlibc6libgssapi-krb5-2libkrb5-3libk5crypto3libcom-err2libkeyutils1libpam0glibselinux1libsystemd0libwrap0zlib1glibcrypt1liblzma5libaudit1libcap-ng0openssh-sftp-serverucfdebconf这个列表看着长其实不用自己背下来直接用下面这个命令自动解析并下载最靠谱sudo apt download $(apt-cache depends --recurse --no-recommends --no-suggests --no-conflicts --no-breaks --no-replaces --no-enhances openssh-server | grep -v i386 | grep ^\w | sort -u)解释一下这里做了什么事apt-cache depends --recurse会递归找出所有依赖--no-*参数是过滤掉推荐包、建议包和冲突项grep -v i386是剔除32位架构的包避免下载到一套用不上的i386包最后通过sort去重后进入apt download。实测下来这个命令打出来的包数量大概在30个左右其中有一部分是系统核心库比如libc6、libpam0g目标机上如果已经存在同版本旧包dpkg安装时会跳过或报“already installed”。不过为了保险建议全量带过去。2.3 下载时的三个坑这里记录几个我在准备离线包时踩过的坑希望你能避开。第一个坑是sources.list源的问题。如果联网机器配置的是内网镜像源下载的包版本可能和Ubuntu官方的focal版本号有细微差异。比如官方源里openssh-server是1:8.2p1-4ubuntu0.5内网源可能是1:8.2p1-4。版本号不一致在dpkg安装时一般不冲突但如果目标机上已经装了旧版本可能因为版本回退导致依赖校验失败。解决办法是下载前固定源为archive.ubuntu.com保证和官方源同步。第二个坑是架构。Ubuntu 20.04有amd64、arm64、i386等架构目标机是arm64的话你在x86机器上下载的deb包完全装不上。可以用uname -m确认目标机架构然后下载时加上架构参数apt download openssh-server:arm64或者在下载机上加dpkg --add-architecture arm64。这个细节最容易被忽略尤其现在很多ARM服务器、树莓派、飞腾平台都在跑Ubuntu。第三个坑是不要把整个/var/cache/apt/archives目录无脑拷过去。这个目录里的包可能来自不同的Ubuntu版本、不同软件源直接dpkg安装时很可能提示某个依赖版本不满。规范做法是新建一个干净目录把这次下载的deb包全部放进去mkdir ~/sshd-offline cd ~/sshd-offline # 执行上面的apt download命令这样目录里只有本次下载所需的包传到目标机上用通配符安装也方便。3. 在目标机上安装与启动sshd3.1 文件传输与dpkg安装离线包准备好之后把它传到目标机器上。如果目标机器现在连局域网都进不去那就用U盘拷贝。如果已经能通过串口或者控制台登录最省事的方式是在目标机上起一个临时的http服务接收文件或者用scp从联网机器直接推过来scp -r ~/sshd-offline user目标机IP:/tmp/sshd-offline这里有个悖论目标机器还没装sshd怎么用scp所以实操中更多是用U盘、光驱或者带外的管理口上传文件。如果目标机已经能通过串口登录直接插入U盘挂载复制就行。文件到位后进入目录执行安装cd /tmp/sshd-offline sudo dpkg -i *.deb第一次执行大概率会报依赖错误因为dpkg本身不解析依赖它只会机械地检查当前系统里有没有所需的包。不过别慌这很常见只要把下载好的deb包都放在同一个目录再执行一次就能解决sudo apt --fix-broken install如果目标机没有网络apt --fix-broken install可能报错找不到源这时候可以加--no-download参数让它只做本地的依赖修复sudo apt --fix-broken install --no-download实测如果deb包齐全这串命令能自动把依赖关系理顺安装成功后sshd二进制就会出现在系统中。3.2 systemd服务配置与启动安装完成后需要用systemd管理sshd服务。Ubuntu 20.04下OpenSSH-server装好后会自动注册一个ssh.service服务。启动前先检查一下配置文件语法这是很多教程忽略的一步sudo sshd -tsshd -t是测试模式它会读取/etc/ssh/sshd_config并检查语法没有任何输出就是没问题有输出就按提示修改配置。这一步能避免后面启动失败时手忙脚乱。配置检查没问题就可以启动服务了sudo systemctl enable ssh sudo systemctl start ssh注意服务名是ssh而不是sshd这个命名坑了我不少新手朋友。在Ubuntu上执行systemctl start sshd会提示找不到服务因为包安装注册的服务名称就是ssh.service和CentOS/RHEL上叫sshd.service不一样。启动后查看状态systemctl status ssh看到active (running)就说明服务起来了。再顺手检查一下端口监听sudo ss -lntp | grep 22输出里会看到0.0.0.0:22的监听记录表示sshd已经在22端口上等待连接。3.3 防火墙与登录验证服务启动后还有两道关卡一个是防火墙一个是SELinux/AppArmor。Ubuntu 20.04默认没有启用ufw但如果之前启用过就要放行22端口sudo ufw allow 22/tcp sudo ufw statusAppArmor一般不会拦sshd可以不用管。放行防火墙后从另一台机器上试连ssh user目标机IP如果连接被拒绝优先检查sshd是否在运行、端口是否监听。如果连接卡住不动检查网络和防火墙策略。有几个配置项建议顺手调整。默认情况下Ubuntu 20.04的sshd配置允许密码登录、禁止root直接登录。如果你的内网环境需要以root身份运维可以修改/etc/ssh/sshd_configPermitRootLogin yes PasswordAuthentication yes改完之后必须重启sshd才能生效sudo systemctl restart ssh不过这里要给个提醒允许root密码登录在内网环境中风险可控但如果机器暴露在公网强烈建议只保留密钥登录PermitRootLogin设为prohibit-password。4. 常见问题与排查技巧实录4.1 安装时报“Unmet dependencies”错误这是离线安装最经典的问题dpkg -i *.deb之后提示类似dpkg: dependency problems prevent configuration of openssh-server: openssh-server depends on libwrap0; however: Package libwrap0 is not installed.解决办法就是继续下载缺失的依赖包放到同一个目录后再次执行dpkg -i。如果嫌麻烦可以在联网机器上把整条依赖链都下载齐全这也是为什么我前面专门用了一段讲依赖解析。还有一种情况是deb包都齐了但执行dpkg -i *.deb时因为包的安装顺序问题某个包先装、依赖还没装导致报错。这时直接执行sudo apt --fix-broken install --no-downloadapt会把所有未配置的包重新按正确顺序配置一遍。4.2 启动时报“/var/empty/sshd”相关错误这个报错在热搜关键词里也出现了原话类似Privilege separation user sshd does not exist或者Missing privilege separation directory: /var/empty/sshd这个问题通常是因为系统里没有sshd这个系统用户或者/var/empty/sshd目录不存在。OpenSSH从6.x版本开始强制使用特权分离机制sshd主进程会派生一个子进程来处理网络数据这个子进程必须以低权限用户运行。如果目录缺失服务就起不来。解决方式sudo mkdir -p /var/empty/sshd sudo chown root:root /var/empty/sshd sudo chmod 755 /var/empty/sshd同时要确保系统里有sshd用户sudo useradd -r -s /usr/sbin/nologin -d /run/sshd -M sshd有的教程是创建到/var/empty/sshd我倾向于/run/sshd因为/run是tmpfs重启后自动生成不存在权限残留问题。如果用的是/var/empty/sshd重启后目录还在一般也不会有问题。另外还有一种变体报错是invalid user for 74:privilege-separated ssh:/var/empty/sshd:/sbin/nologin这个大概率是系统的/etc/passwd里没有正确创建sshd用户或者是用户的主目录设置成了不存在的路径。用上面的useradd命令重建用户再检查一下/etc/passwd中sshd用户的字段是否正常即可。4.3 Host key缺失导致无法启动或无法连接第一次启动sshd时如果系统里没有任何主机密钥sshd会拒绝启动。日志里会看到sshd: no hostkeys available解决办法是手工生成sudo ssh-keygen -A这个命令会生成RSA、ECDSA和ED25519三种秘钥文件存放在/etc/ssh/目录下。生成后再执行systemctl restart ssh。如果你的离线环境里还打算装别的机器建议把这些host key也一并备份做成模板免得每台机器都重复生成步骤。不过更好的做法是每台机器独立生成避免企业环境里因为共享密钥引发安全问题。4.4 连接被拒绝/连接超时排查我把这类问题整理成一张速查表方便你对照定位现象可能原因解决思路Connection refusedsshd没有运行systemctl start sshConnection refused端口不是22查看sshd_config中的Port设置Connection refusedsshd崩溃journalctl -u ssh -n 50看日志Connection timed out防火墙拦截sudo ufw allow 22/tcpConnection timed out网络不通ping目标IP检查IP配置Permission denied密码错误或Root登录被禁改sshd_config并重启Host key verification failed目标机器重装过客户端保存了旧key执行ssh-keygen -R 目标IP其中journalctl -u ssh -n 50是最常用的排障命令能在sshd启动失败时直接输出真实原因比瞎猜快得多。5. 离线组装完之后的收尾体验按照上面这套流程前前后后我在内网环境里配了不下十次离线sshd最容易被绊倒的就两个地方一个是apt-cache depends递归不全导致漏掉libcrypt1这种基础库另一个是目标机器镜像被裁剪过缺少安全用户和目录文件。所以现在每次准备离线包我都会多带一份openssh-client和openssh-sftp-server反正体积不大关键时刻能省很多事。另外如果你需要批量给十几台机器装sshd我的经验是先在一台机器上把deb包目录做成一个公用的本地源脚本装完一台后直接拿U盘插下一台执行比每台机器都去解析依赖高效得多。步骤也不复杂只要把所有deb包放到/opt/sshd-deb然后写一个安装脚本循环执行dpkg -i和apt --fix-broken install --no-download就行。这样整套流程下来单台机器的安装时间能压缩到两分钟以内。本文还有配套的精品资源点击获取