Linux漏洞修复脚本
OpenSSH 9.9p2 升级脚本 适用于 CentOS8 / AnolisOS8 / AlibabaCloudLinux3 / OpenEuler22 系统
#!/bin/bash
# OpenSSH 升级脚本 适用于 CentOS8 / AnolisOS8 / AlibabaCloudLinux3 / OpenEuler22 系统
# 日期: $(date +%Y-%m-%d)
# 特点: 不编译 OpenSSL,不修改 LD_LIBRARY_PATH,最小化系统影响将openssh升级
set -e # 任何命令失败则退出
# 颜色输出函数
red_echo() { echo -e "\033[31m$1\033[0m"; }
green_echo() { echo -e "\033[32m$1\033[0m"; }
yellow_echo() { echo -e "\033[33m$1\033[0m"; }
# 检查是否为 root 用户
if [ "$EUID" -ne 0 ]; then
red_echo "请以 root 用户或使用 sudo 运行此脚本。"
exit 1
fi
# 定义变量
CURRENT_DIR=$(pwd)
OPENSSH_VERSION="9.9p2"
OPENSSH_TAR="openssh-${OPENSSH_VERSION}.tar.gz"
OPENSSH_DIR="openssh-${OPENSSH_VERSION}"
OPENSSH_DOWNLOAD_URL="https://mirrors.aliyun.com/pub/OpenBSD/OpenSSH/portable/openssh-${OPENSSH_VERSION}.tar.gz"
# 检查当前 OpenSSH 版本是否已是要安装的版本
CURRENT_SSH_VERSION=$(/usr/sbin/sshd -V 2>&1 | head -n1)
if echo "$CURRENT_SSH_VERSION" | grep -q "OpenSSH_${OPENSSH_VERSION}"; then
green_echo "✅ 检测到当前 OpenSSH 版本已是 ${OPENSSH_VERSION},无需升级。"
exit 0
fi
green_echo "开始 OpenSSH 升级流程(仅升级 OpenSSH,使用系统 OpenSSL)..."
# 步骤 1: 安装编译依赖(使用系统 OpenSSL)
yellow_echo "步骤 1: 安装编译工具和依赖..."
dnf install -y gcc make wget tar gzip openssl-devel zlib-devel pam-devel systemd-devel
# 步骤 2: 备份现有 SSH 配置
yellow_echo "步骤 2: 备份现有 SSH 配置..."
cp -r /etc/ssh /etc/ssh.bak.$(date +%Y%m%d-%H%M%S)
cp /usr/lib/systemd/system/sshd.service /usr/lib/systemd/system/sshd.service.bak.$(date +%Y%m%d-%H%M%S) || true
green_echo "SSH 配置已备份。"
# 步骤 3: 解压并编译 OpenSSH
yellow_echo "步骤 3: 编译安装 OpenSSH ${OPENSSH_VERSION}..."
if [ ! -f "$CURRENT_DIR/$OPENSSH_TAR" ]; then
yellow_echo "未找到 $OPENSSH_TAR 文件,尝试自动下载..."
if wget -O "$CURRENT_DIR/$OPENSSH_TAR" "$OPENSSH_DOWNLOAD_URL"; then
green_echo "✅ 安装包下载成功"
else
red_echo "❌ 下载失败,请手动下载:"
echo "wget $OPENSSH_DOWNLOAD_URL"
exit 1
fi
fi
tar -zxvf "$OPENSSH_TAR"
cd "$OPENSSH_DIR"
# 提前确保主机密钥存在且权限正确(关键!)
if [ ! -f /etc/ssh/ssh_host_rsa_key ]; then
ssh-keygen -A
fi
chmod 600 /etc/ssh/ssh_host_*_key
chown root:root /etc/ssh/ssh_host_*_key
chmod 644 /etc/ssh/ssh_host_*_key.pub
# 关键:使用系统 OpenSSL(通过 pkg-config 自动发现)
./configure \
--prefix=/usr \
--sysconfdir=/etc/ssh \
--with-zlib \
--with-pam \
--with-privsep-path=/var/lib/sshd \
--with-privsep-user=sshd \
--with-sandbox=yes \
--with-ssl-engine \
--with-md5-passwords=no \
--disable-strip
make
make install
green_echo "OpenSSH ${OPENSSH_VERSION} 安装完成。"
# 步骤 4: 配置系统
yellow_echo "步骤 4: 配置 SSHD 用户和权限..."
# 创建 sshd 用户 (如果不存在)
if ! id -u sshd > /dev/null 2>&1; then
useradd -r -c "sshd privsep" -d /var/lib/sshd -s /sbin/nologin sshd
fi
mkdir -p /var/lib/sshd
chown root:sshd /var/lib/sshd
chmod 755 /var/lib/sshd
# 生成主机密钥(如果缺失)
if [ ! -f /etc/ssh/ssh_host_rsa_key ]; then
ssh-keygen -A
fi
# 修复 SELinux 上下文(如果启用)
if command -v restorecon >/dev/null 2>&1; then
restorecon -R /etc/ssh/
restorecon /usr/sbin/sshd
fi
# 步骤 5: 清理 sshd_config 中 OpenSSH 安装版本不再支持的 GSSAPI 选项
yellow_echo "步骤 5: 清理 sshd_config 中 OpenSSH ${OPENSSH_VERSION} 不再支持的 GSSAPI 选项"
# 备份当前配置(虽然脚本已备份,但再备一次更安全)
cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak.$(date +%Y%m%d-%H%M%S)
# 注释掉所有 GSSAPI 行
sed -i '/^[[:space:]]*GSSAPI/s/^/#/' /etc/ssh/sshd_config
# 允许管理员密码登录
sed -i 's/^[[:space:]]*PasswordAuthentication.*/#&/' /etc/ssh/sshd_config
echo "PasswordAuthentication yes" >> /etc/ssh/sshd_config
sed -i 's/^[[:space:]]*PermitRootLogin.*/#&/' /etc/ssh/sshd_config
echo "PermitRootLogin yes" >> /etc/ssh/sshd_config
# 3. 修复主机密钥权限
chmod 600 /etc/ssh/ssh_host_*_key
chown root:root /etc/ssh/ssh_host_*_key
chmod 644 /etc/ssh/ssh_host_*_key.pub
# 重新加载 systemd
systemctl daemon-reload
# 步骤 6: 测试并重启
yellow_echo "步骤 6: 测试 SSH 配置..."
if ! /usr/sbin/sshd -t; then
red_echo "SSH 配置测试失败!请检查配置文件。"
exit 1
fi
yellow_echo "重启 SSHD 服务..."
systemctl restart sshd
sleep 2
if systemctl is-active --quiet sshd; then
green_echo "SSHD 服务已成功重启。"
else
red_echo "SSHD 服务重启失败!请立即通过控制台检查!"
exit 1
fi
# 验证版本
INSTALLED_VERSION=$(/usr/sbin/sshd -V 2>&1 | head -n1)
if echo "$INSTALLED_VERSION" | grep -q "OpenSSH_${OPENSSH_VERSION}"; then
green_echo "✅ OpenSSH 已成功升级到 ${OPENSSH_VERSION}!"
echo "当前版本: $INSTALLED_VERSION"
else
yellow_echo "⚠️ 版本信息获取异常,但服务已启动。"
echo "实际版本可能为: $(ssh -V 2>&1)"
fi
yellow_echo "建议操作:"
echo "1. 在另一个终端测试 SSH 登录是否正常。"
green_echo "OpenSSH 升级流程结束。"
OpenSSH 9.9p2 升级脚本 适用于 CentOS7 系统
#!/bin/bash
# OpenSSH 升级脚本 —— 专为 CentOS 7 适配
# 注意:由于 CentOS 7 OpenSSL 版本过低(1.0.2),必须编译 OpenSSL 1.1.1w 或更高
set -e
red_echo() { echo -e "\033[31m$1\033[0m"; }
green_echo() { echo -e "\033[32m$1\033[0m"; }
yellow_echo() { echo -e "\033[33m$1\033[0m"; }
if [ "$EUID" -ne 0 ]; then
red_echo "请以 root 用户运行此脚本。"
exit 1
fi
# === 新增:检测是否为 CentOS 7 ===
if ! grep -q "CentOS Linux 7" /etc/os-release; then
red_echo "此脚本仅适用于 CentOS 7。"
exit 1
fi
CURRENT_DIR=$(pwd)
OPENSSH_VERSION="9.9p2"
OPENSSL_VERSION="1.1.1w" # 兼容 OpenSSH 9.9p2 的最低推荐版本
OPENSSH_TAR="openssh-${OPENSSH_VERSION}.tar.gz"
OPENSSL_TAR="openssl-${OPENSSL_VERSION}.tar.gz"
OPENSSH_URL="https://mirrors.aliyun.com/pub/OpenBSD/OpenSSH/portable/${OPENSSH_TAR}"
OPENSSL_URL="https://www.openssl.org/source/${OPENSSL_TAR}"
# 检查当前版本
if /usr/sbin/sshd -V 2>&1 | head -n1 | grep -q "OpenSSH_${OPENSSH_VERSION}"; then
green_echo "✅ 已是目标版本,无需升级。"
exit 0
fi
green_echo "开始为 CentOS 7 升级 OpenSSH ${OPENSSH_VERSION}(含 OpenSSL ${OPENSSL_VERSION} 编译)..."
# 步骤 1: 安装编译依赖(使用 yum)
yellow_echo "步骤 1: 安装编译依赖..."
yum install -y gcc make wget tar gzip perl perl-devel zlib-devel pam-devel systemd-devel autoconf automake libtool
# 步骤 2: 备份 SSH 配置
yellow_echo "步骤 2: 备份 SSH 配置..."
cp -r /etc/ssh /etc/ssh.bak.$(date +%Y%m%d-%H%M%S)
cp /usr/lib/systemd/system/sshd.service /usr/lib/systemd/system/sshd.service.bak.$(date +%Y%m%d-%H%M%S) || true
# 步骤 3: 下载并编译 OpenSSL(静态库,不覆盖系统)
yellow_echo "步骤 3: 编译 OpenSSL ${OPENSSL_VERSION}(安装到 /opt/openssl)..."
if [ ! -f "$OPENSSL_TAR" ]; then
wget -O "$OPENSSL_TAR" "$OPENSSL_URL"
fi
tar -zxf "$OPENSSL_TAR"
cd "openssl-${OPENSSL_VERSION}"
./config --prefix=/opt/openssl --openssldir=/opt/openssl shared no-ssl3
make -j$(nproc)
make install
cd "$CURRENT_DIR"
# 步骤 4: 下载并编译 OpenSSH(链接自定义 OpenSSL)
yellow_echo "步骤 4: 编译 OpenSSH ${OPENSSH_VERSION}..."
if [ ! -f "$OPENSSH_TAR" ]; then
wget -O "$OPENSSH_TAR" "$OPENSSH_URL"
fi
tar -zxf "$OPENSSH_TAR"
cd "openssh-${OPENSSH_VERSION}"
# 设置环境变量,指向新 OpenSSL
export PKG_CONFIG_PATH="/opt/openssl/lib/pkgconfig"
export LDFLAGS="-L/opt/openssl/lib -Wl,-rpath=/opt/openssl/lib"
export CPPFLAGS="-I/opt/openssl/include"
./configure \
--prefix=/usr \
--sysconfdir=/etc/ssh \
--with-zlib \
--with-pam \
--with-privsep-path=/var/lib/sshd \
--with-privsep-user=sshd \
--with-sandbox=yes \
--with-ssl-dir=/opt/openssl \
--with-md5-passwords=no \
--disable-strip
make -j$(nproc)
make install
cd "$CURRENT_DIR"
# 步骤 5: 配置系统用户和密钥
yellow_echo "步骤 5: 配置 sshd 用户和权限..."
id -u sshd >/dev/null 2>&1 || useradd -r -s /sbin/nologin -d /var/lib/sshd sshd
mkdir -p /var/lib/sshd
chown root:sshd /var/lib/sshd
chmod 755 /var/lib/sshd
if [ ! -f /etc/ssh/ssh_host_rsa_key ]; then
ssh-keygen -A
fi
# SELinux 上下文修复(可选)
if command -v restorecon >/dev/null; then
restorecon -R /etc/ssh/ /usr/sbin/sshd
fi
# 步骤 6: 清理 GSSAPI 配置(OpenSSH 9.9 不再支持某些选项)
# 1. 备份当前配置
cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak.$(date +%Y%m%d%H%M%S)
# 2. 注释掉所有 GSSAPI 行
sed -i '/^[[:space:]]*GSSAPI/s/^/#/' /etc/ssh/sshd_config
# 允许管理员密码登录
sed -i 's/^[[:space:]]*PasswordAuthentication.*/#&/' /etc/ssh/sshd_config
echo "PasswordAuthentication yes" >> /etc/ssh/sshd_config
sed -i 's/^[[:space:]]*PermitRootLogin.*/#&/' /etc/ssh/sshd_config
echo "PermitRootLogin yes" >> /etc/ssh/sshd_config
# 3. 修复主机密钥权限
chmod 600 /etc/ssh/ssh_host_*_key
chown root:root /etc/ssh/ssh_host_*_key
chmod 644 /etc/ssh/ssh_host_*_key.pub
systemctl daemon-reload
# 步骤 7: 测试并重启
yellow_echo "步骤 7: 测试配置并重启 sshd..."
if ! /usr/sbin/sshd -t; then
red_echo "❌ SSH 配置测试失败!"
exit 1
fi
systemctl restart sshd
sleep 2
if systemctl is-active --quiet sshd; then
green_echo "✅ SSHD 服务已成功重启。"
else
red_echo "❌ SSHD 重启失败!请立即通过控制台登录检查!"
exit 1
fi
# 验证版本
VERSION=$(/usr/sbin/sshd -V 2>&1 | head -n1)
if echo "$VERSION" | grep -q "OpenSSH_${OPENSSH_VERSION}"; then
green_echo "🎉 OpenSSH ${OPENSSH_VERSION} 升级成功!"
echo "当前版本: $VERSION"
else
yellow_echo "⚠️ 版本显示异常,但服务已启动。"
fi
green_echo "📌 重要提示:"
echo "1. 请务必在另一个终端测试 SSH 登录!"
echo "2. OpenSSL 安装在 /opt/openssl,未影响系统默认库。"
echo "3. 如遇问题,可从 /etc/ssh.bak.* 恢复配置。"