CentOS离线安装sshpass全攻略:从rpm包准备到验证
做运维的朋友应该都遇到过这种场面手里一台 CentOS 服务器安全策略限定不能开通外网出口但自动化运维脚本里又需要远程登录偏偏 SSH 在脚本里执行时总是卡在密码提示符上不动。你想装一个 sshpass 来给 SSH 自动喂密码结果 yum 源里根本没有这个包离线安装又不知道去哪找包、装完怎么验证。这篇博文就把 CentOS 离线安装 sshpass 的完整流程讲清楚从包准备、依赖检查到安装验证再到我实际环境中踩过的坑照着做基本不会再卡壳。1. 为什么要在离线环境里折腾 sshpass1.1 sshpass 是什么、能解决什么问题sshpass 是一个为 ssh 提供密码输入的辅助小工具。它的核心原理其实不复杂ssh 命令在标准终端里连接远程主机时如果没有配置密钥认证就会在本地终端提示输入密码。这个输入动作必须是终端交互完成的你试着用管道echo password | ssh ...是没用的SSH 会直接检测到标准输入不是终端拒绝读取密码。sshpass 的解决办法是通过伪终端pty模拟一个终端环境把密码像真人敲键盘一样“喂”给 ssh 进程。这样一来原本需要人工参与的密码输入环节就被自动化了。它本身是一个非常轻量的工具源码量不大依赖也很少这也是为什么它经常被拿来当作离线安装示例的经典对象。实际工作中我用到 sshpass 的场景大致有这么几类批量运维巡检需要对几十台服务器逐台执行命令、收集信息又不想逐台手动输入密码。跳板机场景先登录堡垒机再通过脚本自动跳到目标主机减少重复劳动。远程备份脚本通过 rsync 或者远程执行 mysqldump 拉取数据目标机器临时不支持密钥认证。自动化测试环境需要临时用 ssh 执行命令但测试环境的账号策略不允许永久配置免密。如果你们环境里已经把 SSH 密钥体系建得很完善那 sshpass 确实有点多余。但现实情况是很多内网环境出于安全和合规要求不允许随便配置免密登录或者密码要周期性轮换。这时候运维手里留一个 sshpass就能解决很多临时性的自动化需求。1.2 为什么“离线安装”会成为刚需稍微有点规模的机房生产网和办公网之间往往有严格的网络隔离。服务器能访问的只有内部资源外网是根本不通的。很多公司的内网 yum 源搭建得也不完整默认的 Base 仓库里又没有 sshpass 这个包于是yum install sshpass直接提示找不到包。有的朋友可能会说yum 不行就编译源码呗。但编译源码需要 gcc、make 以及一堆开发依赖库精简安装的 CentOS 上这些东西很可能都不全而且源码编译在目标机器上还可能遇到兼容性问题。相比之下找一个对应系统版本和架构的 rpm 包拷进去安装是最省事的路径。前提是包找对、依赖理清。离线安装的核心思路总结起来就是三步在一台能上网的机器上把 rpm 包和依赖准备好把文件传到目标机器然后用 rpm 或 yum 的本地安装模式完成安装。看起来简单但真正容易翻车的地方恰好集中在“版本不匹配”和“依赖缺失”这两个问题上。下面我按从准备到部署再到验证的完整流程走一遍这些问题都会逐一讲到。2. 准备安装包在有网络的机器上做好功课2.1 先确认目标系统的版本和架构不管在哪个环节开始准备包第一步永远是确认目标机器的系统版本和 CPU 架构。这一步看着基础但我真的见过有人在这上面栽跟头。常用命令就两条cat /etc/redhat-release uname -m输出示例典型的 CentOS 7 服务器CentOS Linux release 7.9.2009 (Core) x86_64这里有个细节值得多说一句CentOS 7 和 CentOS 8 的包管理思路差异不小。CentOS 7 对应的是 el7 的 rpm 包CentOS 8 对应 el8CentOS 9 Stream 则对应 el9。不同大版本的系统glibc 版本和依赖库都不一样。虽然偶尔能看到 el6 的包硬装在 el7 上也能跑但依赖检查时极容易报 glibc 或 libc.so 版本不满足的问题所以尽量不要跨大版本使用 rpm 包。架构方面绝大多数服务器是 x86_64但也有少量老机器是 i686 或者 ARM 架构。rpm 包的架构必须和系统一致否则安装时会直接报“架构不匹配”或者让你去装一堆 32 位兼容库非常折腾。2.2 sshpass 从哪几条渠道弄到手先去了解一件事sshpass 并不在 CentOS 默认的 Base 仓库里它主要在 EPELExtra Packages for Enterprise Linux扩展仓库中维护。这决定了我们找包的搜索方向。最常用的几个渠道阿里云镜像站mirrors.aliyun.com/epel/目录按系统大版本、架构和包名首字母组织。网易镜像站mirrors.163.com/epel/结构和阿里云类似。Fedora EPEL 官方镜像dl.fedoraproject.org/pub/epel/最权威但国内访问速度时快时慢。rpmfind.net 等第三方 rpm 搜索站点可以快速搜到包但下载后要注意校验来源和签名。以 CentOS 7 x86_64 为例典型的下载命令是这样的wget https://mirrors.aliyun.com/epel/7/x86_64/Packages/s/sshpass-1.06-1.el7.x86_64.rpmCentOS 8 的话路径会稍有不同wget https://mirrors.aliyun.com/epel/8/Everything/x86_64/Packages/s/sshpass-1.09-1.el8.x86_64.rpm这里有个查找小技巧rpm 包在主目录下是按包名字母排序存放到子目录的sshpass 以 s 开头所以直接看Packages/s/就行了。如果目录列表太长可以在浏览器里按 CtrlF 搜索“sshpass”快速定位文件。如果你的工作环境里已经有一台机器能访问内网 yum 镜像更省事的办法是用 yumdownloader 下载yum install -y yum-utils yumdownloader sshpassyumdownloader 会自动解析仓库里最新的 sshpass 版本并下载到当前目录。这个方案的前提是那台机器已经正确配置了仓库源适合公司内部已经自建 yum 镜像的情况。2.3 依赖检查与包完整性校验sshpass 的依赖很少主要就是一个 glibcCentOS 系统本身就自带。但作为离线安装流程查依赖是个好习惯尤其是你后面还要离线装其他软件的时候。在能上网的机器上执行rpm -qpR sshpass-1.06-1.el7.x86_64.rpm参数说明-q表示查询-p表示针对未安装的 rpm 包文件操作-R表示列出依赖关系。输出通常类似/bin/sh libc.so.6()(64bit) libc.so.6(GLIBC_2.2.5)(64bit) rtld(GNU_HASH)去目标机器上确认这些依赖是否存在rpm -q glibc rpm -q /bin/sh如果输出能看到 glibc 版本号基本就说明依赖没问题。另外下载完 rpm 包后建议顺手算一下 SHA256 校验值确认文件完整防止下载过程中出现损坏sha256sum sshpass-1.06-1.el7.x86_64.rpm如果是从官方 EPEL 仓库下载的还可以用 GPG 签名验证包的来源但这一步对大多数内网部署场景来说不是必须的。我自己在下载完成后通常会看一眼文件大小是否合理一般 sshpass 的 rpm 就是几十 KB 的样子如果下载出来只有几百字节那八成是下载不完整。3. 离线部署把包传到内网机器并完成安装3.1 传输方式怎么选安装包准备好之后下一步是把文件弄到目标机器上。根据内网的隔离程度和现场条件我试过几种方式scp / sftp如果目标机器能直接从你的办公网访问这是最直接的。比如scp sshpass-1.06-1.el7.x86_64.rpm root192.168.1.101:/tmp/。堡垒机运维平台的网页上传入口很多公司有一层可视化运维系统可以在页面上传文件到指定服务器。U盘 / 移动硬盘物理接触服务器时把 rpm 包拷进 U 盘插入服务器后挂载并复制到本地目录。带外管理系统挂载 ISO 镜像通过服务器的带外管理接口挂载一个封装好的 ISO把 rpm 放进去适合批量交付的场景一次能处理多台机器。不论用哪种方式我都习惯先把包放到 /tmp 或 /opt 目录下。不要直接放在 /root 下因为 home 分区在某些环境中可能设置了较小的配额碰到过因为配额满导致复制失败的情况。3.2 安装命令的三种姿势到了目标机器后根据依赖情况的复杂度可以选择不同的安装方式。方式一直接 rpm 安装。这是最干净的方法依赖满足时速度最快。cd /tmp rpm -ivh sshpass-1.06-1.el7.x86_64.rpm命令参数含义-i安装-v显示详细信息-h打印 hash 进度条。正常执行后输出大概长这样Preparing... ################################# [100%] Updating / installing... 1:sshpass-1.06-1.el7.x86_64 ################################# [100%]方式二yum localinstall。如果系统提示缺少依赖而内网又有可用的 yum 仓库哪怕是部分仓库可以用这个命令。yum localinstall 会扫描本机已安装的包并尝试从已配置的仓库中补齐缺失的依赖。yum localinstall sshpass-1.06-1.el7.x86_64.rpm如果你的环境连内网仓库都没有那就只能把缺失的依赖 rpm 也下载好放到同一个目录下再执行rpm -ivh sshpass*.rpm一次装完。方式三建本地 repo 目录。当离线依赖包特别多的时候或者后续还打算在内网机器上继续离线装其他软件时建议直接做一个临时本地仓库。步骤不复杂# 在准备好 rpm 包的目录下执行 createrepo /data/rpms然后把整个 /data/rpms 目录同步到内网机器新增一个 repo 文件vi /etc/yum.repos.d/local.repo文件内容如下[local] nameLocal RPM Repository baseurlfile:///data/rpms enabled1 gpgcheck0保存后执行yum clean all yum makecache接下来就能用yum install sshpass正常安装了。这个方法我特别推荐给需要批量维护多台内网服务器的运维等于在最简条件下搭了一个内部 yum 源。3.3 安装后的功能验证与实际用法示例安装完成后先确认程序安装到了预期位置which sshpass sshpass -V如果能打印出版本号说明二进制没问题。但装了不代表能用我习惯立刻做一次真实的 SSH 连接测试。为了避免影响远程生产机器可以用本机先测sshpass -p 你的测试密码 ssh -o StrictHostKeyCheckingno root127.0.0.1 hostname这里的-o StrictHostKeyCheckingno是让 SSH 首次连接时不交互确认主机指纹这在脚本环境里很常用。执行成功后会直接返回主机名说明 sshpass 已经能正常替 ssh 转发密码。sshpass 的参数还有一些实用选项-p password直接在命令行指定密码。适合临时测试不适合生产脚本因为密码会留在 shell 历史里。-f filename从文件读取第一行作为密码。适合把密码放在权限受限的文件里。-e从环境变量 SSHPASS 中读取密码。使用前需要先export SSHPASS密码。-P prompt指定等待的密码提示符默认监听“password”字符串。某些定制 SSH 服务或网络设备上会用到。一个典型的批量执行脚本大概是这样的#!/bin/bash export SSHPASS服务器密码 sshpass -e ssh -o StrictHostKeyCheckingno \ -o ConnectTimeout5 root192.168.1.101 uptime; df -h这个例子里我特意用了-e而不是-p就是为了避免密码直接出现在命令行参数中降低被 ps 命令查到的风险。虽然环境变量也有一定暴露可能但比直接写在参数里要稳妥一些。4. 常见问题与排查技巧实录4.1 安装期常见的报错全解把我在各种环境里碰到过的安装报错整理成了一张速查表建议截图保存。报错现象常见原因处理办法No package sshpass available当前 yum 源中没有 sshpass默认 Base 仓库不带该包启用 EPEL 仓库或者改用离线 rpm 安装Failed dependencies: libc.so.6 needed包版本与系统不匹配或包架构不匹配先检查 el6/el7/el8 标识和 x86_64/i686 架构Package is for a different architecture下载了 i686 或 arm 架构的包与系统不一致换成对应架构的 rpm 包package sshpass-... is already installed已经装了旧版本用rpm -Uvh升级而不是-ivhNo space left on device/usr 分区满了清理磁盘后重新安装rpmdb open failed可能之前强制中断过 rpm 操作尝试rpm --rebuilddb重建数据库最容易被误判的是第二类看到“依赖缺失”就以为系统少库。其实在 sshpass 身上这种报错的根源十有八九是下载的包版本不对。同样叫 libc 依赖el6 的包在 el7 上会报 GLIBC 版本过低i686 的包在 x86_64 上会报缺少 32 位库。所以排查顺序永远是先核对版本和架构再考虑真缺依赖的情况。4.2 使用阶段的典型坑装完并不代表万事大吉实际使用 sshpass 时我也踩过不少坑。第一个坑sshpass 与新版 OpenSSH 的兼容性。老版本的 sshpass比如 1.05配合 OpenSSH 8.x 以上版本时偶尔会卡在提示符识别上表现为脚本长时间没有响应然后超时。后续版本修复了部分问题。如果你用旧版 sshpass 遇到不明原因的挂起优先升级到 1.09 或更高版本。第二个坑没有处理主机指纹确认。脚本第一次连接一台新主机时SSH 会提示是否信任主机密钥。sshpass 虽然能自动输密码但这种交互提示不会被自动跳过。最直接的办法是加-o StrictHostKeyCheckingno。如果环境允许更严谨的做法是先执行ssh-keyscan 目标IP ~/.ssh/known_hosts把主机指纹预置进去。第三个坑密码里包含特殊字符。如果密码里有!、、#等符号直接放在双引号里可能被 shell 解释尤其是感叹号在 bash 里会触发历史展开。建议把密码写进一个权限为 600 的文件用-f参数读取能避开大部分麻烦。第四个坑连续失败导致登录被锁。fail2ban 这类工具会统计 SSH 认证失败次数超过阈值会临时封禁来源 IP。写批量脚本时必须先在单台机器上小范围测试不要在几十台上同时跑一个没经过验证的密码脚本否则容易触发连锁封禁。第五个坑远程命令执行后会话不退出。当远程命令产生大量输出或者本身不返回时脚本可能一直卡住。建议给 ssh 加上-o ConnectTimeout5并在远程命令末尾加echo $?或者用exit保证会话能正常终结。其实使用期的很多问题责任并不在 sshpass 本身而是 SSH 的常规行为。只要记住 sshpass 只解决了“密码自动输入”这一步其他 SSH 参数、已知主机管理、超时控制都还是要按常规方式去配置排查起来思路会清晰很多。5. 几点实践经验分享最后聊几点我个人在实际操作中的体会不一定写在官方文档里但确实能帮你少走弯路。第一离线安装包最好一次性备齐。在能上网的机器上把 sshpass 的 rpm、对应的依赖以及说明文件全部放到一个目录里算好 SHA256再统一传到内网。如果有多个系统版本文件名里写上版本号区分避免混用。第二尽量把本地 repo 建起来。如果内网机器后续还要装别的软件一次性建好本地仓库以后所有离线安装都能走 yum依赖也能让 yum 自动解析比自己手动逐个安装 rpm 要安全得多。createrepo 建索引和写 local.repo 的操作前面已经写清楚了照着做就行。第三对 sshpass 的定位要清楚。它是应急和特殊场景下的工具能用 SSH 密钥认证的地方尽量用密钥。大规模服务器管理密钥体系才是王道。sshpass 的价值在于解决那些临时性的、密钥方案暂时覆盖不到的需求。第四装完后要留一个自测命令。我的习惯是在脚本里内置一条最小化连接测试比如每天巡检前先连一次巡检机器确认 sshpass 工作正常再往下走。这个动作虽然简单但能及早发现版本兼容变化或者系统升级后的问题。以上就是 CentOS 离线安装 sshpass 从准备到落地的完整流程。整个过程并不神秘关键就是包选对、依赖查清、参数用对。如果你也正在做内网运维自动化希望这些经验能帮你省下一些排查时间。
上一篇/下一篇内容由系统自动关联
返回资讯列表 →