OpenSSH 10.2p1一键升级脚本(可 ansible 批量升级)
本文介绍了一个用于在CentOS 7和RedHat 7系统上升级OpenSSH到10.2p1版本的自动化脚本。该脚本包含完整的升级流程和回退机制,支持单机执行和Ansible批量部署。主要功能包括:系统版本检查、Telnet备用连接安装、依赖管理、源码下载、备份机制、编译安装、服务管理等。脚本会自动记录详细日志到/var/log/openssh-upgrade.log,并在升级失败时自动回退到默认
脚本简介
本脚本用于在 CentOS 7 和 Redhat 7 系统上升级 OpenSSH 服务到 10.2p1 版本,包含完整的升级流程和回退机制。
注意:需要优先升级OpenSSL 3.5.4 如果自己提前升级了 注意修改脚本编译环境那块的。
- 脚本编写参考此教程:CentOS 7 OpenSSH 10.2p1 升级全攻略
- OpenSSL脚本批量升级脚本:OpenSSL3.5.4升级方案:自动化脚本+错误回滚
主要功能
- 系统版本检查:自动检测系统类型和版本,仅支持 CentOS 7 和 Redhat 7
- Telnet 备用连接:安装并启用 Telnet 服务作为备用连接方式
- 依赖管理:自动安装编译所需的依赖包
- 源码下载:从本地 HTTP 服务下载 OpenSSH 源码包
- 备份机制:自动备份原有配置文件
- 编译安装:配置编译选项并安装新版本
- 服务管理:启动并验证 SSH 服务
- 回退机制:升级失败时自动回退到默认版本
- 日志记录:详细的操作日志,便于排查问题
- Ansible 兼容:支持通过 Ansible 批量执行
准备工作
1. 准备 OpenSSH 源码包
将 openssh-10.2p1.tar.gz 文件放置在本地 HTTP 服务的根目录(192.168.1.11)。需要安装httpd服务,然后通过这个服务分发ssh升级包,有公网的话可以直接用 githup 那个链接。
2. 配置 Ansible 主机清单
如果需要批量执行,创建一个 hosts 文件:
# hosts 文件内容
[servers]
192.168.1.101
192.168.1.102
使用方法
单台服务器执行
-
将脚本上传到目标服务器:
scp upgrade_openssh.sh root@服务器IP:/tmp/ -
执行脚本:
chmod +x /tmp/upgrade_openssh.sh cd /tmp ./upgrade_openssh.sh
批量执行(使用 Ansible)
如果服务器特别多的话建议指定并发数量 ’-f 50‘ ansible 默认是5个并发。
ansible -i hosts servers -m script -a "/tmp/upgrade_openssh.sh"
执行流程
- 系统检查:验证系统版本是否符合要求
- Telnet 安装:安装并启动 Telnet 服务作为备用连接
- 依赖安装:安装编译所需的依赖包
- 源码下载:从本地 HTTP 服务下载 OpenSSH 源码
- 备份配置:备份现有的 SSH 配置文件
- 卸载旧版:卸载系统默认的 OpenSSH
- 编译安装:配置编译选项并安装新版本
- 服务启动:启动新的 SSH 服务
- 验证升级:检查 SSH 版本和服务状态
- 关闭 Telnet:升级成功后关闭 Telnet 服务
回退机制
如果升级过程中出现错误,脚本会自动执行回退操作:
- 停止当前 SSH 服务
- 从默认仓库安装 OpenSSH
- 恢复备份的配置文件
- 启动 SSH 服务
如果回退失败,脚本会保留 Telnet 服务,确保您仍然可以远程连接到主机进行排查。
日志管理
脚本会将所有操作记录到目标主机的 /var/log/openssh-upgrade.log 文件中,包括:
- 执行时间
- 操作步骤
- 错误信息
- 回退操作
您可以通过查看此日志文件来了解执行情况和排查问题。
注意事项
- 网络连接:确保目标服务器可以访问 192.168.1.11 上的 HTTP 服务
- 权限要求:执行脚本需要 root 权限
- OpenSSL 依赖:脚本默认使用
/usr/local/openssl-3.5.4作为 OpenSSL 目录 - 安全提示:Telnet 服务仅在升级过程中临时使用,升级完成后会自动关闭
- 重复执行:脚本支持重复执行,会跳过已经完成的步骤
- 备份保留:每次执行都会创建新的备份文件,避免覆盖之前的备份
- 错误处理:升级失败时会自动回退,回退失败时会保留 Telnet 服务
脚本参数说明
脚本中的主要配置参数:
| 参数 | 说明 | 默认值 |
|---|---|---|
| OPENSSH_VERSION | OpenSSH 版本 | 10.2p1 |
| OPENSSH_DOWNLOAD_URL | 下载地址 | http://192.168.1.11/openssh-10.2p1.tar.gz |
| OPENSSH_INSTALL_DIR | 安装目录 | /usr/local/openssh-10.2p1 |
| OPENSSL_DIR | OpenSSL 目录 | /usr/local/openssl-3.5.4 |
| LOG_FILE | 日志文件 | /var/log/openssh-upgrade.log |
完整代码
#!/bin/bash
# OpenSSH 升级脚本 for CentOS 7/Redhat 7
set -e
# 配置参数
OPENSSH_VERSION="10.2p1"
OPENSSH_TARBALL="openssh-${OPENSSH_VERSION}.tar.gz"
OPENSSH_DOWNLOAD_URL="http://192.168.1.11/${OPENSSH_TARBALL}"
OPENSSH_INSTALL_DIR="/usr/local/openssh-${OPENSSH_VERSION}"
OPENSSL_DIR="/usr/local/openssl-3.5.4"
BACKUP_DATE=$(date +%Y%m%d_%H%M%S)
TMP_DIR="/tmp"
LOG_FILE="/var/log/openssh-upgrade.log"
# 日志输出
log_info() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] INFO: $1"
echo "[$(date '+%Y-%m-%d %H:%M:%S')] INFO: $1" >> ${LOG_FILE}
}
log_warning() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] WARNING: $1"
echo "[$(date '+%Y-%m-%d %H:%M:%S')] WARNING: $1" >> ${LOG_FILE}
}
log_error() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] ERROR: $1"
echo "[$(date '+%Y-%m-%d %H:%M:%S')] ERROR: $1" >> ${LOG_FILE}
}
# 检查root权限
check_root() {
if [ "$(id -u)" -ne 0 ]; then
log_error "需要root权限执行此脚本"
exit 1
fi
}
# 检查系统版本
test_system() {
log_info "检查系统版本"
os_name=$(cat /etc/os-release | grep '^NAME=' | cut -d'=' -f2 | tr -d '"')
os_version=$(cat /etc/os-release | grep '^VERSION_ID=' | cut -d'=' -f2 | tr -d '"')
log_info "当前系统: ${os_name} ${os_version}"
# 仅支持CentOS 7和Redhat 7
if [[ "${os_name}" == "CentOS Linux" && "${os_version}" == "7" ]] || \
[[ "${os_name}" == "Red Hat Enterprise Linux Server" && "${os_version}" == "7" ]]; then
log_info "系统版本验证通过"
else
log_error "仅支持CentOS 7和Redhat 7系统"
exit 1
fi
}
# 安装并启用Telnet服务
install_telnet() {
log_info "安装Telnet服务作为备用连接"
yum install -y telnet-server telnet xinetd >/dev/null 2>&1
# 配置Telnet
cat > /etc/xinetd.d/telnet << 'EOF'
service telnet
{
flags = REUSE
socket_type = stream
wait = no
user = root
server = /usr/sbin/in.telnetd
log_on_failure += USERID
disable = no
}
EOF
# 启动xinetd服务
systemctl enable xinetd >/dev/null 2>&1
systemctl start xinetd
log_info "Telnet服务已安装并启动"
log_warning "Telnet明文传输密码,仅在内网使用"
}
# 准备工作
prepare() {
log_info "开始准备工作..."
# 确认系统版本
log_info "系统版本:"
cat /etc/centos-release
# 查看当前OpenSSH版本
log_info "当前OpenSSH版本:"
ssh -V
# 安装编译依赖
log_info "安装编译依赖..."
yum groupinstall -y "Development Tools" >/dev/null 2>&1
yum install -y wget curl gcc make zlib-devel pam-devel \
libselinux-devel openssl-devel bzip2 gcc-c++ libstdc++* libcap* >/dev/null 2>&1
log_info "准备工作完成"
}
# 下载OpenSSH源码
download_openssh() {
log_info "下载OpenSSH ${OPENSSH_VERSION}源码到${TMP_DIR}目录..."
cd ${TMP_DIR}
log_info "从${OPENSSH_DOWNLOAD_URL}下载安装包..."
wget ${OPENSSH_DOWNLOAD_URL}
log_info "解压安装包..."
tar -zxvf ${OPENSSH_TARBALL} >/dev/null 2>&1
cd openssh-${OPENSSH_VERSION}
log_info "OpenSSH源码下载完成,已放置在${TMP_DIR}目录"
}
# 备份并卸载默认SSH
backup_and_remove() {
log_info "备份并卸载默认SSH..."
# 备份配置
cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak-${BACKUP_DATE}
cp /etc/pam.d/sshd /etc/pam.d/sshd.bak-${BACKUP_DATE}
# 卸载旧版SSH
yum -y remove openssh >/dev/null 2>&1
log_info "默认SSH已备份并卸载"
}
# 配置编译选项
configure_openssh() {
log_info "配置编译选项..."
./configure \
--prefix=${OPENSSH_INSTALL_DIR} \
--sysconfdir=/etc/ssh \
--with-ssl-dir=${OPENSSL_DIR} \
--with-zlib \
--with-pam \
--with-privsep-path=/var/lib/sshd \
--with-md5-passwords >/dev/null 2>&1
log_info "编译选项配置完成"
}
# 编译与安装
compile_and_install() {
log_info "开始编译与安装..."
# 编译
make -j$(nproc) >/dev/null 2>&1
# 配置权限
chmod 600 /etc/ssh/ssh_host_*
chown root.root /etc/ssh/ssh_host_*
# 安装
make install >/dev/null 2>&1
cp -p contrib/redhat/sshd.init /etc/init.d/sshd
chmod +x /etc/init.d/sshd
# 配置允许root登录(根据需要)
echo 'PermitRootLogin yes' >> /etc/ssh/sshd_config
echo 'UsePAM yes' >> /etc/ssh/sshd_config
# 恢复PAM配置
cp /etc/pam.d/sshd.bak-${BACKUP_DATE} /etc/pam.d/sshd 2>/dev/null || true
# 创建软连接
ln -sf ${OPENSSH_INSTALL_DIR}/sbin/sshd /usr/sbin/sshd
ln -sf ${OPENSSH_INSTALL_DIR}/bin/ssh /usr/bin/ssh
ln -sf ${OPENSSH_INSTALL_DIR}/bin/ssh-keygen /usr/bin/ssh-keygen
ln -sf ${OPENSSH_INSTALL_DIR}/bin/ssh-keyscan /usr/bin/ssh-keyscan
ln -sf ${OPENSSH_INSTALL_DIR}/bin/ssh-agent /usr/bin/ssh-agent
ln -sf ${OPENSSH_INSTALL_DIR}/bin/scp /usr/bin/scp
ln -sf ${OPENSSH_INSTALL_DIR}/bin/sftp /usr/bin/sftp
ln -sf ${OPENSSH_INSTALL_DIR}/bin/ssh-add /usr/bin/ssh-add
cp ${TMP_DIR}/openssh-${OPENSSH_VERSION}/contrib/ssh-copy-id /usr/bin/
chmod +x /usr/bin/ssh-copy-id
log_info "OpenSSH编译与安装完成"
}
# 启动SSH服务
start_ssh() {
log_info "启动SSH服务..."
systemctl daemon-reload
systemctl enable sshd
systemctl restart sshd
log_info "SSH服务已启动"
}
# 验证升级
verify_upgrade() {
log_info "验证升级结果..."
log_info "新的OpenSSH版本:"
ssh -V
log_info "SSH服务状态:"
ss -tnlp | grep sshd
log_info "升级验证完成"
}
# 回退操作
rollback() {
log_info "执行回退操作..."
# 停止当前SSH服务
systemctl stop sshd || true
# 从默认仓库安装OpenSSH
log_info "从默认仓库安装OpenSSH..."
if ! yum install -y openssh openssh-server openssh-clients; then
log_error "回退失败:无法安装OpenSSH"
return 1
fi
# 恢复配置
if [ -f "/etc/ssh/sshd_config.bak-${BACKUP_DATE}" ]; then
cp /etc/ssh/sshd_config.bak-${BACKUP_DATE} /etc/ssh/sshd_config
fi
if [ -f "/etc/pam.d/sshd.bak-${BACKUP_DATE}" ]; then
cp /etc/pam.d/sshd.bak-${BACKUP_DATE} /etc/pam.d/sshd
fi
# 重启SSH服务
systemctl daemon-reload
systemctl enable sshd >/dev/null 2>&1
if ! systemctl restart sshd; then
log_error "回退失败:无法启动SSH服务"
return 1
fi
systemctl status sshd >/dev/null 2>&1
log_info "回退操作完成"
return 0
}
# 关闭Telnet服务
close_telnet() {
log_info "关闭Telnet服务..."
# 停止xinetd服务
systemctl stop xinetd
# 禁止开机自启
systemctl disable xinetd >/dev/null 2>&1
# 禁用Telnet配置文件
mv /etc/xinetd.d/telnet /etc/xinetd.d/telnet.disabled 2>/dev/null || true
# 验证Telnet是否关闭
log_info "验证Telnet是否关闭:"
telnet 127.0.0.1 2>&1 | grep -E "Connection refused|无法连接"
log_info "Telnet服务已关闭"
}
# 主函数
main() {
check_root
# 创建日志文件
touch ${LOG_FILE}
chmod 644 ${LOG_FILE}
log_info "===================================="
log_info "OpenSSH 升级脚本 for CentOS 7/Redhat 7"
log_info "===================================="
log_info "开始升级流程,日志将保存到 ${LOG_FILE}"
# 检查系统版本
test_system
# 安装Telnet
install_telnet
# 准备工作
prepare
# 下载OpenSSH源码
download_openssh
# 备份并卸载默认SSH
backup_and_remove
# 配置编译选项
configure_openssh
# 编译与安装
compile_and_install
# 启动SSH服务
start_ssh
# 验证升级
verify_upgrade
# 自动关闭Telnet服务(ansible批量执行模式)
log_info "===================================="
log_info "升级完成!自动关闭Telnet服务"
log_info "===================================="
# 关闭Telnet服务
close_telnet
log_info "===================================="
log_info "OpenSSH 升级流程已完成"
log_info "详细日志请查看: ${LOG_FILE}"
log_info "===================================="
}
# 处理错误
trap 'log_error "升级过程中出现错误,执行回退操作..."; if rollback; then close_telnet; else log_warning "回退失败,保留Telnet服务以便排查问题"; fi; exit 1' ERR
# 执行主函数
main
总结
提示:在执行升级操作前,建议先在测试环境中验证脚本的可行性,确保升级过程不会影响生产环境的正常运行。同时,保持网络连接稳定,避免在升级过程中出现网络中断的情况。
希望本文对您有所帮助,如果您有任何问题或建议,欢迎在评论区留言讨论。
关注微信公众号 Linux容器运维 并回复关键字 “视频资料”,即可获取我们整理的 Kubernetes、Docker 容器、Python 编程、Linux 运维等教学视频合集(总计 548GB)。本资源仅面向学习交流使用,请遵守版权和使用规范,严禁商用、转售或违规传播。
更多推荐
所有评论(0)