#!/bin/bash
# 如果出现换行符错误需要转换一下:set ff=unix
# 运行此脚本请确保脚本和源码包在同一目录下,并且只有一个版本的源码包,建议新建一个目录存放脚本和源码包。
# 停止selinux并修改selinux配置问题,使其重启后不启动
if [ ! $UID == 0 ]; then
echo "请切换到root用户下执行!"
exit 1
fi
setenforce 0
sed -i 's/SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config
# 停止SSHD
systemctl stop sshd
# 检测包管理器并安装依赖项
install_dependencies() {
if command -v yum > /dev/null; then
sudo yum groupinstall -y "Development Tools"
sudo yum install -y zlib-devel openssl-devel pam-devel
else
echo "不支持的包管理器,请手动安装 build-essential、zlib 和 openssl 开发包。"
exit 1
fi
}
# 检查依赖项是否已安装
check_dependencies() {
if ! (command -v gcc > /dev/null && command -v make > /dev/null); then
return 1
fi
echo "#include " | gcc -E - > /dev/null 2>&1 || return 1
echo "#include " | gcc -E - > /dev/null 2>&1 || return 1
return 0
}
if ! check_dependencies; then
install_dependencies
fi
# 设置当前日期
current_date=$(date +"%Y-%m-%d-%s")
# 备份现有的 SSH 配置和二进制文件
backup_dir="openssh_backup_$current_date"
mkdir -p "$backup_dir"
# 备份并删除 SSH 和 SSHD 配置文件及二进制文件
#backup_and_remove() {
# files_to_backup=(
# "/etc/ssh/sshd_config"
# "/usr/sbin/sshd"
# "/etc/ssh/ssh_config"
# "/usr/bin/ssh"
# )
#
# for file in "${files_to_backup[@]}"; do
# cp "$file" "$backup_dir"
# if [ -f "$backup_dir/$(basename "$file")" ]; then
# rm -rf "$file"
# echo "备份$file成功"
# else
# echo "备份 $file 失败,请检查文件权限。"
# exit 1
# fi
# done
#}
# 备份并删除 SSH 和 SSHD 配置文件及二进制文件
#backup_and_remove
cp /usr/bin/ssh $backup_dir/ || cp /usr/local/bin/ssh $backup_dir/
cp /usr/bin/scp $backup_dir/ || cp /usr/local/bin/scp $backup_dir/
cp /usr/bin/ssh-add $backup_dir/ || cp /usr/local/bin/ssh-add $backup_dir/
cp /usr/bin/ssh-agent $backup_dir/ || cp /usr/local/bin/ssh-agent $backup_dir/
cp /usr/bin/ssh-keygen $backup_dir/ || cp /usr/local/bin/ssh-keygen $backup_dir/
cp /usr/bin/ssh-keyscan $backup_dir/ || cp /usr/local/bin/ssh-keyscan $backup_dir/
cp /usr/sbin/sshd $backup_dir/ || cp /usr/local/sbin/sshd $backup_dir/
mkdir $backup_dir/etc
cp -ar /etc/ssh $backup_dir/etc/
rm -rf /usr/bin/ssh
rm -rf /usr/bin/scp
rm -rf /usr/bin/ssh-add
rm -rf /usr/bin/ssh-agent
rm -rf /usr/bin/ssh-keygen
rm -rf /usr/bin/ssh-keyscan
rm -rf /usr/sbin/sshd
if -f /usr/lib/systemd/system/sshd.service; then
systemctl disable sshd
mv /usr/lib/systemd/system/sshd.service $backup_dir/
fi
sum_cpu=$(cat /proc/cpuinfo | grep "processor"|wc -l)
# 在当前目录中查找最新的 OpenSSH tarball
openssh_tarball=$(ls -t openssh-[0-9.]*.tar.gz | head -n 1)
if [ -z "$openssh_tarball" ]; then
echo "未找到 OpenSSH tarball,请确保它位于当前目录中。"
exit 1
fi
# 解压缩 tarball 并进入源代码目录
tar -zxf "$openssh_tarball"
cd openssh-[0-9.]*/
if -d /usr/local/openssl; then
# 编译和安装同时记录错误,如果只升级ssh需要把--with-ssl-dir=/usr/local/openssl删除
if ! ./configure 2>../configure_errors.log; then
echo "配置失败,请检查 configure_errors.log。"
exit 1
fi
if ! make -j $sum_cpu 2>../make_errors.log; then
echo "编译失败,请检查 make_errors.log。"
exit 1
fi
# 安装新版本的 OpenSSH
if ! make install 2>../make_errors.log; then
echo "安装失败,请检查 make_errors.log。"
exit 1
fi
else
# 编译和安装同时记录错误,如果只升级ssh需要把--with-ssl-dir=/usr/local/openssl删除
if ! ./configure --with-ssl-dir=/usr/local/openssl 2>../configure_errors.log; then
echo "配置失败,请检查 configure_errors.log。"
exit 1
fi
if ! make -j $sum_cpu 2>../make_errors.log; then
echo "编译失败,请检查 make_errors.log。"
exit 1
fi
# 安装新版本的 OpenSSH
if ! make install 2>../make_errors.log; then
echo "安装失败,请检查 make_errors.log。"
exit 1
fi
fi
cat > /etc/systemd/system/sshd.service <&1 | awk '{print $1}' | sed 's/[^0-9.]*//' | sed 's/,//g')
source_version=$(echo "$openssh_tarball" | sed 's/.*-\([0-9]\.[0-9a-zA-Z]*\).*/\1/')
if [ "$installed_version" == "$source_version" ]; then
echo "升级成功,当前 SSH 版本为 $installed_version。"
else
echo "升级失败,当前 SSH 版本为 $installed_version,期望版本为 $source_version。"
echo "请检查日志文件 configure_errors.log 和 make_errors.log。"
echo "回退脚本:"
echo "cd openssh-*/ "
echo "make uninstall"
echo "rpm -aq | grep openssh | xargs yum -y reinstall"
echo "systemctl restart sshd"
exit 1
fi
}
# 检查 SSH 版本并显示结果
check_ssh_version
systemctl status sshd
# 删除openssh-*/目录
#rm -rf openssh-*/
# 记录整个脚本的执行日志
#exec > >(tee -a script_execution.log) 2>&1