恒美微站
首页
关于我们
建站服务
主题模板
案例展示
资讯中心
联系我们
Ubuntu 20.04离线安装sshd:依赖收集、dpkg部署与避坑指南
首页
资讯中心
/
Ubuntu 20.04离线安装sshd:依赖收集、dpkg部署与避坑指南
Ubuntu 20.04离线安装sshd:依赖收集、dpkg部署与避坑指南
发布时间:2026/10/8 3:36:10
简介面向需要在无网络环境下为 Ubuntu 20.04 桌面版部署 SSH 服务的系统管理员与运维人员这份离线安装包提供了完整解决方案。包内共 4 个文件包含 openssh 客户端、服务端及 sftp 组件共 3 个 deb 安装包并附带一个自动化安装脚本总大小约 1.05MB可在离线环境中直接完成 sshd 的安装与依赖修复。目前已获得 1251 人次学习下载适用于内网服务器初始化、远程管理环境搭建等场景该方案省去联网下载与依赖解析环节显著提升部署效率。压缩包内部文件组织简洁脚本封装了从解压、安装到启动服务的完整流程即使不熟悉命令行也能按提示操作deb 包版本与 Ubuntu 20.04 自带版本匹配降低兼容性风险。借助该资源读者可以避免在线仓库不可用的限制快速搭建安全的远程访问通道并在此基础上进行端口修改、密钥认证等安全加固实践。1. 没有外网的 ubuntu20.04sshd 离线安装包到底在解决什么一台没有外网的 ubuntu20.04 服务器安全基线检查要求开启 SSH 服务你敲下 apt-get install openssh-server看到的却是 Unable to locate package另一台运维平台里则直接提示 The ssh or sshd service is unavailable。这时候你需要的就是一份 sshd 离线安装包——把 Ubuntu 20.04 上 openssh-server 以及它依赖的 deb 包在联网机器上一次性收集齐拷进内网在离线机上完成安装和启动。这篇文章按工程落地流程来写先在联网机把依赖拉全再讲离线安装与五条高频踩坑最后给出把离线包转成内网源的复用方案。适合需要在内网离线环境交付 SSH 服务、又不想反复试错的运维和交付工程师。2. 离线装 sshd 为什么绕不开依赖解析从 apt 的包结构看最小可行路径2.1 openssh-server 在 focal 上不是孤立二进制Ubuntu 20.04 的 openssh-server 属于 OpenSSH 8.2p1 系列这个包解压后会覆盖 /usr/sbin/sshd、/etc/ssh/sshd_config、/lib/systemd/system/ssh.service、/etc/pam.d/sshd 等路径。问题在于这些路径里的内容并不全由 openssh-server 一个包提供ssh 和 scp 客户端在 openssh-client 里sftp-server 在 openssh-sftp-server 里动态链接层还需要 libc6、libssl1.1、libpam0g、libselinux1 等基础库。最小化安装的系统往往缺掉其中好几个包联网条件下 apt 会自己补齐离线时这些依赖就成了黑匣子。依赖不是只有直接一层。openssh-server 装完要能起来还需要 ucf 处理配置文件变更提示procps 提供 sshd 运行时的进程工具这些又各自带着 libc6 级别的底层依赖。手工在网上一张纸列下来的依赖清单换个安全更新版本就会失效。所以我在做离线包时从不用“网上别人整理好的列表”只用 apt 自己解析出来的结果后面第三章的命令就是这么设计的。2.2 直接拷 sshd 二进制为什么总翻车不少人在离线机上尝试最粗暴的方案从同版本机器上把 /usr/sbin/sshd 和几个 .so 文件用 scp 拷过去结果启动时要么报 error while loading shared libraries要么 sshd 起来了但登录后直接 Permission denied。这类问题在论坛里常被当成玄学讨论其实是踩中了 Linux 动态链接的底层规则ldd /usr/sbin/sshd 会列出 libcrypto.so.1.1、libpam.so.0、libselinux.so.1、libc.so.6 这些路径单纯复制二进制文件时库路径、符号版本GLIBC_2.x、SSH 配置目录、主机密钥、systemd unit 文件都会被漏掉。就算你把依赖库全部找齐并放进 /usr/lib还会遇到另一个坑OpenSSH 启动时需要 /etc/ssh/ssh_host_*_key 主机密钥这个密钥通常由 deb 包的 postinst 脚本调用 ssh-keygen 生成裸拷二进制不会触发任何安装脚本于是报 Failed to start OpenBSD Secure Shell server。这还没算 AppArmor 策略和 PAM 配置。结论很直接ssh 服务不是一个文件能代表的必须以 deb 包为单位离线交付让 dpkg 把文件、脚本和目录结构一次还原。2.3 三条路线的选型内网源、download-only、本地 deb 目录我在交付现场见过三种“离线装 sshd”的做法它们的适用条件差别很大。第一种是机房内本来就有 Ubuntu 软件源镜像这种直接“apt 换源”到内网地址openssh-server 只要一条命令就能装严格说已经不是离线安装。第二种是这台离线机没有源但有一个能临时连外网的窗口期那我一般会在这个窗口里用后面的 download-only 方案把包拉下来。第三种是机器彻底离线只能靠 U 盘或者内部文件服务器传文件这就是本文真正要讲的方案。路线适用条件优点明显缺点内网 apt 镜像源机房有同步好的源一劳永逸所有包可装需要维护几百 GB 同步download-only 离线包有联网窗口能访问目标源轻量集齐当前依赖只覆盖 openssh 相关包本地 deb 目录完全离线交付物可校验、可复用换机器架构需重新收集我的选择标准很简单只装七八台以内的机器就做离线 deb 包机器数量超过一个机柜直接把 deb 目录升级成 file 源或内网 HTTP 源也就是第六章的做法。离线 deb 包是其中最灵活的一条路它不依赖机房基础设施拿一个 U 盘就能完成交付。3. 在联网机攒齐 sshd 离线包download-only 命令与依赖清单核对3.1 apt-get clean 与 download-only一次拿到完整依赖集合制作离线包的联网机必须和离线机同样架构、同样系统版本。我一般先在联网机上执行这一组命令# 联网机Ubuntu 20.04 x86_64 sudo apt-get update sudo apt-get clean # 如果这台机上已经装过 openssh-server用 --reinstall 强制重新拉取所有相关包 sudo apt-get install --reinstall --download-only openssh-server # 如果还没装过去掉 --reinstall 直接用下面这条 # sudo apt-get install --download-only openssh-server先解释 apt-get clean它会清空 /var/cache/apt/archives 里残留的旧 deb。这一步很关键因为 download-only 只是把包放进这个缓存目录如果不清理可能把半年前下载的旧版本包混进交付物。接着用 --reinstall 的语义是“即使 openssh-server 已安装也重新获取安装包”配合 --download-only 后系统不会执行安装只会把 openssh-server 及全部依赖写入缓存。apt 在解析依赖时会递归处理所以这一条命令拿到的就是当前源里完整可用的依赖集合。执行完可以看一眼缓存目录确认结果ls -lh /var/cache/apt/archives/*.deb。你会发现除了 openssh-server还有 openssh-client、openssh-sftp-server、libssl1.1、libpam0g 这些包数量通常在十几个到二十个之间具体以你机器当前 apt 源解析结果为准。不要拿别人截图的清单来对照源路径不同、安全更新进度不同都会影响这个列表。3.2 交付物清单与校验SHA256SUMS 不是可选项把缓存里的 deb 复制到工作目录同时生成校验文件。我的习惯是建一个名为 sshd-offline 的目录把它当作最终交付物mkdir -p ~/sshd-offline cp /var/cache/apt/archives/*.deb ~/sshd-offline/ cd ~/sshd-offline # 记录 openssh-server 的实际版本确认是 Ubuntu 20.04 对应版本 dpkg-query -W -f${binary:Package} ${Version} ${Architecture}\n openssh-server # 给目录内所有 deb 生成校验值传输后用于完整性核对 sha256sum *.deb SHA256SUMScp 命令把缓存目录里所有 deb 复制走这里的前提就是前面做过 apt-get clean否则会把无关包一并带走。dpkg-query 这行是核实当前源里解析到的版本输出内容类似openssh-server 1:8.2p1-4ubuntu0.x amd64看到版本号前缀“1:8.2p1”就能确认这确实是 Ubuntu 20.04 focal 的包。sha256sum 生成的 SHA256SUMS 文件要跟着 U 盘一起走离线安装前先校验。这个目录里的核心文件可以整理成一张表方便交付时核对文件角色关键内容openssh-server_*_amd64.deb服务端主体sshd、ssh.service、sshd_config、PAM 配置openssh-client_*_amd64.deb客户端与依赖ssh、scp、sftp、ssh-keygenopenssh-sftp-server_*_amd64.debsftp 子系统sftp-server 二进制libssl1.1_*_amd64.deb核心 TLS 库libcrypto.so.1.1、libssl.so.1.1SHA256SUMS完整性校验所有 deb 的 sha256 摘要表里没有列出的包不要自行脑补比如 libc6、libpam0g 等基础库如果 download-only 把它们拉下来了就给它们一席之地如果离线机 base 系统里已经有了它们也在缓存里出现。反正整个目录一起拷贝多带无害缺了才致命。3.3 版本与架构前提为什么必须“同发行版、同架构”Ubuntu 20.04 的包管理严格区分架构x86_64 机器下载的 deb 文件名里都带 amd64放上 arm64 机器dpkg 会直接拒绝安装。更隐蔽的是跨版本问题Ubuntu 20.04 和 22.04 的 openssh-server 依赖的 OpenSSL 库不一样20.04 依赖 libssl1.122.04 用的是 libssl3。如果拿 20.04 的包去装 22.04安装时可能不报错但 sshd 一起动就报找不到 libcrypto.so.1.1。所以我在下载前会先在联网机执行# 确认系统代号与架构各输出一次 lsb_release -cs dpkg --print-architecture第一行输出 focal第二行输出 amd64说明这台联网机适配的是 Ubuntu 20.04 x86_64。离线机上同样跑这两条命令四个输出全部对齐再开始拷贝。内核版本 uname -r 不一致不影响只要发行版线和架构一致即可。这里还有一个经常被忽视的细节联网机 apt 源里的包版本会比离线机 base 镜像里的版本高这是因为安全更新仓库一直在滚动。把较高版本装到旧内核的离线机上通常没问题因为依赖的库都包含在离线包集合里但反过来就不行——用旧版本覆盖新版本会引发 dpkg 版本冲突。因此离线包只要做一次就沿用同一份目录发布不要在内网里混用新旧两批包。4. 离线机的最小安装操作集传包校验、dpkg 与服务启动验证4.1 传包与 sha256sum -c 校验把 sshd-offline 目录放进 U 盘或通过内部文件服务传到离线机落到用户目录下。装之前先在离线机上做一次完整性校验这一步能拦截绝大多数传输损坏问题# 离线机进入交付目录并校验 cd ~/sshd-offline sha256sum -c SHA256SUMS不要把 SHA256SUMS 这个文件漏在 U 盘根目录要让它和 deb 在同一层命令才能用相对路径找到它。校验输出会逐个文件打印 OK只要出现一个 FAILED就说明对应 deb 在 U 盘格式转换、网络传输或拷贝过程中被截断或篡改。我见过 FAT32 格式 U 盘在大量写入后出现文件大小对但内容不一致的情况表现就是校验失败但 ls 看起来正常。这时不要做任何 dpkg 操作回联网机重新复制。4.2 dpkg -i 全量安装与依赖排序校验通过后直接对目录内的全部 deb 执行安装sudo dpkg -i ~/sshd-offline/*.deb这里的关键认知是dpkg 在安装一组包时会先对全部包做依赖拓扑排序再按序配置各个包所以参数里 *.deb 的先后顺序并不像网上老教程说的那么敏感。真正决定成败的是这个 deb 集合是否完整。如果集合完整dpkg 会先解包再配置看到“正在设定 openssh-server”时离成功只差一步如果集合缺包输出会卡在 dependency problems并列出缺的具体包名。遇到 dependency problems 时别急着执行 apt-get install -f。离线机的 apt 源里没有这些 deb这条命令不会自动从你的 U 盘补包只会把 dpkg 的安装状态搞得更乱。正确的补救方式是回到第三章看缺的是哪些依赖在联网机上把它们补进 sshd-offline 目录重新校验后拷贝过来。所以交付时保留整个目录结构而不是只拷 openssh-server 一个包就是为了给这类返工留余地。4.3 ssh-keygen -A、systemctl enable --now ssh 与监听确认安装完成后不要直接以为服务已经跑起来。我建议按这个顺序做三件事生成主机密钥、启动服务、确认监听# 生成缺失的 SSH 主机密钥RSA、ECDSA、ED25519 一并补齐 sudo ssh-keygen -A # 启用开机自启并立即启动 ssh 服务 sudo systemctl enable --now ssh # 查看服务状态确认 Active 不是 failed sudo systemctl status ssh --no-pager # 确认 22 端口已监听 ss -tlnp | grep :22ssh-keygen -A 这行一定要放在启动之前它的作用是扫描 /etc/ssh/ 目录把缺失的主机密钥补全。有些 base 镜像在打包时把 /etc/ssh/ssh_host_*_key 清理掉了deb 安装脚本又因为批量 dpkg 的时机问题没有生成于是 sshd 一启动就报错。systemctl enable --now ssh 是一次完成“设置开机自启”和“立即启动”两件事Ubuntu 20.04 的服务名是 sshsshd 是它的别名所以写成 systemctl start sshd 也兼容但统一用 ssh 更符合 Ubuntu 习惯。最后一项 ss -tlnp 如果输出里没有 127.0.0.1:22 或 0.0.0.0:22说明服务根本没起来直接看 systemctl status 的日志输出定位原因。服务起来了还要做一次登录验证才算交付完成# 本机回环验证 ssh localhost # 局域网验证换目标机实际 IP ssh sysadmin10.0.0.20第一次连接会提示确认主机指纹输入 yes 后正常获得 shell 就说明 sshd 工作正常。如果前面有运维平台报 The ssh or sshd service is unavailable现在再回去看一眼通常已经恢复。5. sshd 离线安装避坑五条高频翻车记录与处理路径5.1 dependency problems 卡在“正在设定 openssh-server”现象是 dpkg -i 执行到一半终端出现红色的 dependency problems具体报错指向某个库缺失而离线机上 apt-get install -f 只是转了一圈又回到原样。原因大多不是“离线方案不可行”而是你没清理 /var/cache/apt/archives 就顺手把旧包一起拷走了或者 download-only 拉取时机器上原本残留的包互相冲突。解决方法是回到联网机严格按第三章顺序执行apt-get clean 之后重新 download-only再核对一遍 SHA256SUMS。如果离线机安装时又报缺包把报错里出现的依赖名带回联网机用 apt-get download 下载后补进目录再重新拷贝安装。5.2 Failed to start OpenBSD Secure Shell server 与主机密钥现象是安装与 enable 都成功但 systemctl status ssh 显示 Active: failedjournalctl -u ssh 里能看到 no hostkeys available 或 Permission denied while loading host key。原因是在某些最小化交付的磁盘镜像里主机密钥被清理过而批量 dpkg 安装时 postinst 脚本的执行环境不完整没有触发 ssh-keygen。解决方法是执行一次sudo ssh-keygen -A如果目录里有残留的密钥文件但权限不对顺手sudo chmod 600 /etc/ssh/ssh_host_*_key然后 systemctl restart ssh。我一般会把这个命令固定写进离线安装的步骤清单里不带任何条件判断。5.3 amd64 的包拷到 arm64 上架构报错现象是 dpkg -i 直接跳过并提示 package architecture (amd64) does not match system (arm64)。原因是制作离线包的联网机和目标机架构不一致。解决方法是不要只看操作系统版本安装前在两台机器上分别执行 dpkg --print-architecture。常见场景是现场拿了台 ARM 开发板做接收端却用 x86 云服务器做的离线包两边都是 Ubuntu 20.04 但架构不同。ARM 机器的离线包必须重新在 ARM 联网机上生成不存在“通用离线包”这种东西。5.4 Permission denied (publickey,password)登录策略与 auth.log现象是 sshd 起来了、端口也监听了但用密码登录始终 Permission denied客户端 ssh -vvv 能看到 server accepts password最终仍被拒绝。原因大多是 sshd_config 里的 PasswordAuthentication 被设成 no或 PermitRootLogin 是 prohibit-passwordroot 用户不配密钥就进不来。解决方法是查看配置实际生效值sudo grep -E ^(PasswordAuthentication|PermitRootLogin|PubkeyAuthentication) /etc/ssh/sshd_config如果输出是 no用 sed 改成 yes 再 reloadsudo sed -i s/^PasswordAuthentication no/PasswordAuthentication yes/ /etc/ssh/sshd_config sudo systemctl reload ssh改完再看 /var/log/auth.log日志里会明确记录 Failed password 还是 Accepted password这是判断登录问题的第一现场。很多人在这类问题上一头雾水往往是因为只看了客户端输出没看服务端日志。5.5 跨发行版混用 libssl1.1focal 的包不要喂给 jammy现象是安装过程顺利但 sshd 首次启动就崩报 error while loading shared libraries: libcrypto.so.1.1而离线机系统明明是 Ubuntu 20.04。原因可能是你做离线包用的联网机已经换过源比如源指向了 22.04 的 jammy 仓库下载到的是 focal 不存在匹配关系的包集合。另一个常见混用是把 20.04 的 deb 装到 22.04 的机器上20.04 依赖 libssl1.122.04 只有 libssl3于是动态链接直接失败。解决方法是检查联网机刚才那两条 lsb_release -cs 与 dpkg --print-architecture 的输出确保机器是干净没有改过源的 Ubuntu 20.04 x86_64。不要相信“换一套招就能兼容”的说法发行版之间的共享库 ABI 不兼容属于硬边界。6. 把离线包目录转成本地源后续机器装 sshd 的复用工作流6.1 用 dpkg-scanpackages 生成索引如果同一内网里还有第二台、第三台机器要装 sshd重复做 dpkg -i 也可以但更省事的是把 sshd-offline 这个目录转成本地 apt 源。先确认生成索引的工具在联网机已安装sudo apt-get install -y dpkg-dev cd ~/sshd-offline # 扫描当前目录生成 Packages 压缩索引 dpkg-scanpackages . /dev/null | gzip -9c Packages.gz # 写一个最小 Release 文件否则 apt 会拒绝识别该源 printf Origin: local\nLabel: local\nSuite: focal\nCodename: focal\nArchitectures: amd64\nComponents: main\n Releasedpkg-scanpackages 会把当前目录所有 deb 的元信息汇总成索引。Release 文件是 apt 的硬性要求缺了它执行 apt-get update 会报 Repository does not have a Release file这是很多人转本地源时最容易忽略的一步。Architectures 字段按实际包架构写ARM 机器就是 arm64。6.2 离线机挂 file 源与 apt-cache policy 验证把整个 sshd-offline 目录原样拷到目标机器然后追加一个本地源# 离线机把本地目录挂为信任源 echo deb [trustedyes] file:/home/sysadmin/sshd-offline ./ | sudo tee /etc/apt/sources.list.d/sshd-offline.list sudo apt-get update apt-cache policy openssh-servertrustedyes 表示跳过 GPG 签名校验仅适合这种内部手工源。apt-cache policy 输出里 Candidate 一行如果能显示版本号说明源生效。此后这台机就只需要一条sudo apt-get install -y openssh-server和在线环境一样走 apt 的正常依赖流程。如果离线机在内网也可以把目录放到 HTTP 服务器上source 行改成deb [trustedyes] http://内网IP/sshd-offline ./其他机器就都能直接安装。6.3 让后续安装走上 apt 正道这个方案的收益在于dpkg -i 是“一次性手术”而本地 apt 源是“长期能力”。后续机器安装 xxd、rsync 或其他依赖包时只要这个目录里的包够用apt 都能处理依赖关系不用再手工管顺序。如果内网本来就有基于 Ubuntu 20.04 的镜像源直接换源是更省心的选择但机器数量不多、又不想为几个包维护一个大源时一个 sshd-offline 目录加三条命令就能走完复用流程。我现在做这类离线交付的习惯是目录做好后固化成基线把 SHA256SUMS、Packages.gz、Release 一起纳入交付物清单后续机器一律走 file 源安装不再手工逐台 dpkg。这个改动让离线安装从碰运气变成可复现的流程希望帮到你。本文还有配套的精品资源点击获取