#!/bin/bash
# 设置变量
OPENSSH_VERSION="9.8p1" # 请根据最新版本更新这个值
BACKUP_DIR="/root/ssh_backup_$(date +%Y%m%d_%H%M%S)"
INSTALL_DIR="/usr/local/ssh"
OLD_CONFIG="/etc/ssh/sshd_config"
NEW_CONFIG="/etc/ssh/sshd_config"
# 检查是否以root权限运行
if [ "$(id -u)" != "0" ]; then
echo "This script must be run as root" 1>&2
exit 1
fi
# 安装telnet服务作为备用
apt update
apt install -y telnetd
# 启动inetd服务(用于telnet)
systemctl start inetd
systemctl enable inetd
echo "Telnet service has been installed and inetd has been started. Please ensure you have a separate telnet connection before proceeding."
read -p "Press Enter to continue..."
# 创建备份目录
mkdir -p $BACKUP_DIR
# 备份当前SSH文件
cp -r /etc/ssh $BACKUP_DIR
cp /usr/sbin/sshd $BACKUP_DIR
cp /usr/bin/ssh $BACKUP_DIR
# 安装依赖
apt install -y build-essential zlib1g-dev libssl-dev libpam0g-dev libselinux1-dev
# 下载最新的OpenSSH源码
wget https://cdn.openbsd.org/pub/OpenBSD/OpenSSH/portable/openssh-$OPENSSH_VERSION.tar.gz
tar -xzvf openssh-$OPENSSH_VERSION.tar.gz
cd openssh-$OPENSSH_VERSION
# 配置和编译,指定使用Ubuntu默认的配置文件路径,并启用PAM和MD5支持
./configure --prefix=$INSTALL_DIR --sysconfdir=/etc/ssh --with-md5-passwords --with-pam
make
make install
# 停止SSH服务
systemctl stop ssh
# 备份并替换SSH二进制文件
mv /usr/sbin/sshd /usr/sbin/sshd.old
cp $INSTALL_DIR/sbin/sshd /usr/sbin/sshd
cp $INSTALL_DIR/bin/ssh /usr/bin/ssh
cp $INSTALL_DIR/bin/scp /usr/bin/scp
# 确保文件权限正确
chown root:root /usr/sbin/sshd /usr/bin/ssh /usr/bin/scp
chmod 755 /usr/sbin/sshd /usr/bin/ssh /usr/bin/scp
# 复制关键配置参数到新的配置文件
if [ -f "$OLD_CONFIG" ] && [ -f "$NEW_CONFIG" ]; then
# 获取旧配置中的关键参数
OLD_PORT=$(grep "^Port " "$OLD_CONFIG" | awk '{print \$2}')
OLD_PASSWORDAUTH=$(grep "^PasswordAuthentication " "$OLD_CONFIG" | awk '{print \$2}')
OLD_PUBKEYAUTH=$(grep "^PubkeyAuthentication " "$OLD_CONFIG" | awk '{print \$2}')
OLD_LISTENADDRESS=$(grep "^ListenAddress " "$OLD_CONFIG" | awk '{print \$2}')
# 更新新配置文件
sed -i "s/^#Port 22/Port ${OLD_PORT:-22}/" "$NEW_CONFIG"
sed -i "s/^#PasswordAuthentication yes/PasswordAuthentication ${OLD_PASSWORDAUTH:-yes}/" "$NEW_CONFIG"
sed -i "s/^#PubkeyAuthentication yes/PubkeyAuthentication ${OLD_PUBKEYAUTH:-yes}/" "$NEW_CONFIG"
sed -i "s/^#ListenAddress 0.0.0.0/ListenAddress ${OLD_LISTENADDRESS:-0.0.0.0}/" "$NEW_CONFIG"
# 确保UsePAM选项存在并设置为yes
if grep -q "^UsePAM" "$NEW_CONFIG"; then
sed -i "s/^UsePAM.*/UsePAM yes/" "$NEW_CONFIG"
else
echo "UsePAM yes" >> "$NEW_CONFIG"
fi
echo "Key configuration parameters have been transferred to the new config file."
else
echo "Warning: Could not transfer configuration parameters. Please check your SSH configuration manually."
fi
# 测试新的sshd配置
if /usr/sbin/sshd -t -f $NEW_CONFIG; then
echo "New sshd_config syntax is correct."
else
echo "Error: New sshd_config has syntax errors. Please check the configuration manually."
exit 1
fi
# 启动SSH服务
systemctl start ssh
# 检查SSH服务状态
if systemctl is-active --quiet ssh; then
echo "SSH service has been successfully updated and restarted."
else
echo "Error: SSH service failed to start. Rolling back to the old version."
mv /usr/sbin/sshd.old /usr/sbin/sshd
cp $BACKUP_DIR/ssh/sshd_config /etc/ssh/sshd_config
systemctl start ssh
exit 1
fi
# 如果一切正常,删除旧的二进制文件
rm /usr/sbin/sshd.old
echo "OpenSSH has been updated to version $OPENSSH_VERSION"
echo "Old SSH files have been backed up to $BACKUP_DIR"
# 提醒用户关闭telnet服务
echo "Please remember to disable the telnet service after confirming SSH is working correctly."
echo "You can do this by running: systemctl stop inetd && systemctl disable inetd"
最近发现联网下载有时候会失败,下面这个是改成从本地路径加载升级源码包,不再从网络下载了:
#!/bin/bash
# 设置变量
OPENSSH_VERSION="9.8p1" # 请确保这个版本号与本地文件名匹配
BACKUP_DIR="/root/ssh_backup_$(date +%Y%m%d_%H%M%S)"
INSTALL_DIR="/usr/local/ssh"
OLD_CONFIG="/etc/ssh/sshd_config"
NEW_CONFIG="/etc/ssh/sshd_config"
LOCAL_TARBALL="openssh-$OPENSSH_VERSION.tar.gz"
# 检查是否以root权限运行
if [ "$(id -u)" != "0" ]; then
echo "This script must be run as root" 1>&2
exit 1
fi
# 检查本地文件是否存在
if [ ! -f "$LOCAL_TARBALL" ]; then
echo "Error: $LOCAL_TARBALL not found in the current directory." 1>&2
exit 1
fi
# 安装telnet服务作为备用
apt update
apt install -y telnetd
# 启动inetd服务(用于telnet)
systemctl start inetd
systemctl enable inetd
echo "Telnet service has been installed and inetd has been started. Please ensure you have a separate telnet connection before proceeding."
read -p "Press Enter to continue..."
# 创建备份目录
mkdir -p $BACKUP_DIR
# 备份当前SSH文件
cp -r /etc/ssh $BACKUP_DIR
cp /usr/sbin/sshd $BACKUP_DIR
cp /usr/bin/ssh $BACKUP_DIR
# 安装依赖
apt install -y build-essential zlib1g-dev libssl-dev libpam0g-dev libselinux1-dev
# 解压本地OpenSSH源码
tar -xzvf $LOCAL_TARBALL
cd openssh-$OPENSSH_VERSION || { echo "Failed to change directory to openssh-$OPENSSH_VERSION"; exit 1; }
# 配置和编译,指定使用Ubuntu默认的配置文件路径,并启用PAM和MD5支持
./configure --prefix=$INSTALL_DIR --sysconfdir=/etc/ssh --with-md5-passwords --with-pam
make
make install
# 停止SSH服务
systemctl stop ssh
# 备份并替换SSH二进制文件
mv /usr/sbin/sshd /usr/sbin/sshd.old
cp $INSTALL_DIR/sbin/sshd /usr/sbin/sshd
cp $INSTALL_DIR/bin/ssh /usr/bin/ssh
cp $INSTALL_DIR/bin/scp /usr/bin/scp
# 确保文件权限正确
chown root:root /usr/sbin/sshd /usr/bin/ssh /usr/bin/scp
chmod 755 /usr/sbin/sshd /usr/bin/ssh /usr/bin/scp
# 复制关键配置参数到新的配置文件
if [ -f "$OLD_CONFIG" ] && [ -f "$NEW_CONFIG" ]; then
# 获取旧配置中的关键参数
OLD_PORT=$(grep "^Port " "$OLD_CONFIG" | awk '{print \$2}')
OLD_PASSWORDAUTH=$(grep "^PasswordAuthentication " "$OLD_CONFIG" | awk '{print \$2}')
OLD_PUBKEYAUTH=$(grep "^PubkeyAuthentication " "$OLD_CONFIG" | awk '{print \$2}')
OLD_LISTENADDRESS=$(grep "^ListenAddress " "$OLD_CONFIG" | awk '{print \$2}')
# 更新新配置文件
sed -i "s/^#Port 22/Port ${OLD_PORT:-22}/" "$NEW_CONFIG"
sed -i "s/^#PasswordAuthentication yes/PasswordAuthentication ${OLD_PASSWORDAUTH:-yes}/" "$NEW_CONFIG"
sed -i "s/^#PubkeyAuthentication yes/PubkeyAuthentication ${OLD_PUBKEYAUTH:-yes}/" "$NEW_CONFIG"
sed -i "s/^#ListenAddress 0.0.0.0/ListenAddress ${OLD_LISTENADDRESS:-0.0.0.0}/" "$NEW_CONFIG"
# 确保UsePAM选项存在并设置为yes
if grep -q "^UsePAM" "$NEW_CONFIG"; then
sed -i "s/^UsePAM.*/UsePAM yes/" "$NEW_CONFIG"
else
echo "UsePAM yes" >> "$NEW_CONFIG"
fi
echo "Key configuration parameters have been transferred to the new config file."
else
echo "Warning: Could not transfer configuration parameters. Please check your SSH configuration manually."
fi
# 测试新的sshd配置
if /usr/sbin/sshd -t -f $NEW_CONFIG; then
echo "New sshd_config syntax is correct."
else
echo "Error: New sshd_config has syntax errors. Please check the configuration manually."
exit 1
fi
# 启动SSH服务
systemctl start ssh
# 检查SSH服务状态
if systemctl is-active --quiet ssh; then
echo "SSH service has been successfully updated and restarted."
else
echo "Error: SSH service failed to start. Rolling back to the old version."
mv /usr/sbin/sshd.old /usr/sbin/sshd
cp $BACKUP_DIR/ssh/sshd_config /etc/ssh/sshd_config
systemctl start ssh
exit 1
fi
# 如果一切正常,删除旧的二进制文件
rm /usr/sbin/sshd.old
echo "OpenSSH has been updated to version $OPENSSH_VERSION"
echo "Old SSH files have been backed up to $BACKUP_DIR"
# 提醒用户关闭telnet服务
echo "Please remember to disable the telnet service after confirming SSH is working correctly."
echo "You can do this by running: systemctl stop inetd && systemctl disable inetd"
成功升级以后会提示
/usr/local/ssh/sbin/sshd -t -f /usr/local/ssh/etc/sshd_config
SSH service has been successfully updated and restarted.
OpenSSH has been updated to version 9.8p1
Old SSH files have been backed up to /root/ssh_backup_20240816_141707
Please remember to disable the telnet service after confirming SSH is working correctly.
You can do this by running: systemctl stop telnetd && systemctl disable telnetd