Compare commits

6 Commits
dev ... main

View File

@ -1,4 +1,6 @@
#!/bin/bash #!/bin/bash
set -e
set -o pipefail
########## 一些配置 ########## ########## 一些配置 ##########
@ -11,10 +13,10 @@ script_url="{{ SCRIPT_URL }}"
############ 脚本区 ########## ############ 脚本区 ##########
script_params=$* script_params=("$@")
has_param() { has_param() {
for param in $script_params; do for param in "${script_params[@]}"; do
for tParam in $@; do for tParam in "$@"; do
if [ "$tParam" == "$param" ]; then if [ "$tParam" == "$param" ]; then
echo "true" echo "true"
return return
@ -26,15 +28,16 @@ has_param() {
get_param_value() { get_param_value() {
local find=false local find=false
for param in $script_params; do for param in "${script_params[@]}"; do
if [ "$find" == "true" ]; then if [ "$find" == "true" ]; then
if [[ $param == -* ]]; then if [[ $param == -* ]]; then
return return
fi fi
echo $param
echo "$param"
return return
fi fi
for tParam in $@; do for tParam in "$@"; do
if [ "$tParam" == "$param" ]; then if [ "$tParam" == "$param" ]; then
find=true find=true
break break
@ -44,18 +47,19 @@ get_param_value() {
} }
# 帮助信息. # 帮助信息.
if [ $(has_param "-h" "--help") == "true" ]; then if [ "$(has_param "-h" "--help")" == "true" ]; then
echo "Usage: $0 [options]" echo "Usage: $0 [options]"
echo "Options:" echo "Options:"
echo " -h, --help Print this help message." echo " -h, --help Print this help message."
echo "" echo ""
echo "Available to any user: " echo "Available to any user: "
echo " -c, --cron [cron | false] Configure Crontab to automatically update ssh keys," echo " -c, --cron \"<cron> | false\" Configure Crontab to automatically update ssh keys."
echo " Cron expression can be specified, If false is specified, " echo " Cron expression MUST be quoted (e.g., \"* 0 * * *\")."
echo " Crontab settings will be deleted automatically." echo " If 'false' is specified, Crontab settings will be deleted."
echo "" echo ""
echo " -o, --only-update-keys Only update SSH keys, do not configure ssh server." echo " -o, --only-update-keys Only update SSH keys, do not configure ssh server."
echo " -u, --update-self Update this script to the latest version." echo " -u, --update-self Update this script to the latest version."
echo " --uninstall Uninstall this script (remove cron and local files)."
echo "" echo ""
echo "only available when the script is executed as root:" echo "only available when the script is executed as root:"
echo " -n, --no-install-sshd Do not install SSH Server." echo " -n, --no-install-sshd Do not install SSH Server."
@ -65,46 +69,143 @@ if [ $(has_param "-h" "--help") == "true" ]; then
fi fi
update_sshkeys() { update_sshkeys() {
if [ "$sshkey_url" == "" ]; then if [ "$sshkey_url" == "" ] || [[ "$sshkey_url" == "{{"* ]]; then
echo "Please specify the URL of the SSH public key." echo "ERROR: sshkey_url is not configured."
exit 1 exit 1
fi fi
echo "Downloading SSH public key from '$sshkey_url'" echo "Downloading SSH public key from '$sshkey_url'"
mkdir -p ~/.ssh mkdir -p ~/.ssh
local ssh_keys=$(curl -s $sshkey_url) chmod 700 ~/.ssh
if [ $? -ne 0 ] || [ "$ssh_keys" == "" ]; then
local dl_tmp_file=~/.ssh/authorized_keys.dl.tmp
if ! curl -sL "$sshkey_url" -o "$dl_tmp_file"; then
echo "Failed to download SSH public key at $(date '+%Y-%m-%d %H:%M:%S')" echo "Failed to download SSH public key at $(date '+%Y-%m-%d %H:%M:%S')"
rm -f "$dl_tmp_file"
exit 1 exit 1
fi fi
if [ ! -s "$dl_tmp_file" ] || ! grep -qE "(ssh-rsa|ssh-ed25519|ecdsa-sha2-nistp)" "$dl_tmp_file"; then
echo "Downloaded file is empty or does not contain valid SSH key types at $(date '+%Y-m-d %H:%M:%S')"
echo "Aborting update to prevent lockout."
rm -f "$dl_tmp_file"
exit 1
fi
echo "-------------------- SSH Keys --------------------" echo "-------------------- SSH Keys --------------------"
echo "$ssh_keys" cat "$dl_tmp_file"
echo "--------------------------------------------------" echo "--------------------------------------------------"
echo "$ssh_keys" > ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys local auth_file=~/.ssh/authorized_keys
# 输出更新成功,需要附带时间日期 local new_auth_file=~/.ssh/authorized_keys.new.tmp
echo "SSH public key updated successfully at $(date '+%Y-%m-%d %H:%M:%S')"
# 受管理文本块标记
local begin_marker="# --- BEGIN MANAGED BY CONF-SSHD SCRIPT ---"
local end_marker="# --- END MANAGED BY CONF-SSHD SCRIPT ---"
local managed_block_found=false
local inside_managed_block=false
touch "$auth_file"
true > "$new_auth_file"
while IFS= read -r line; do
if [ "$line" == "$begin_marker" ]; then
managed_block_found=true
inside_managed_block=true
{
echo "$begin_marker"
cat "$dl_tmp_file"
echo "$end_marker"
} >> "$new_auth_file"
elif [ "$line" == "$end_marker" ]; then
inside_managed_block=false
elif [ "$inside_managed_block" == "false" ]; then
echo "$line" >> "$new_auth_file"
fi
done < "$auth_file"
if [ "$managed_block_found" == "false" ]; then
if [ -s "$new_auth_file" ]; then
if [ "$(tail -c 1 "$new_auth_file")" != "" ]; then
# 最后一个字符不是换行符,添加一个
echo "" >> "$new_auth_file"
fi
fi
{
echo "$begin_marker"
cat "$dl_tmp_file"
echo "$end_marker"
} >> "$new_auth_file"
fi
mv "$new_auth_file" "$auth_file"
rm -f "$dl_tmp_file"
chmod 600 "$auth_file"
echo "SSH public key updated successfully (managed block only) at $(date '+%Y-%m-%d %H:%M:%S')"
} }
# 检查是否指定了 --uninstall
if [ "$(has_param "--uninstall")" == "true" ]; then
echo "Uninstalling conf-sshd (disabling auto-updates)..."
if [ "$(command -v crontab)" != "" ]; then
echo "Removing Crontab entry..."
( (crontab -l 2>/dev/null || true) | grep -F -v "conf-sshd.sh") | crontab -
else
echo "Crontab utility not found, skipping Crontab removal."
fi
script_dir="$HOME/.conf-sshd"
if [ -d "$script_dir" ]; then
echo "Removing script files from $script_dir..."
rm -rf "$script_dir"
else
echo "Script directory $script_dir not found, skipping removal."
fi
echo "Uninstall complete."
echo "Note: authorized_keys managed block and sshd_config were NOT affected."
exit 0
fi
# 检查是否只更新密钥. # 检查是否只更新密钥.
if [ $(has_param "-o" "--only-update-keys") == "true" ]; then if [ "$(has_param "-o" "--only-update-keys")" == "true" ]; then
update_sshkeys update_sshkeys
exit 0 exit 0
fi fi
# 检查是否指定了 --update-self # 检查是否指定了 --update-self
if [ $(has_param "-u" "--update-self") == "true" ]; then if [ "$(has_param "-u" "--update-self")" == "true" ]; then
echo "Updating conf-sshd script..." echo "Updating conf-sshd script..."
cp $0 ~/.conf-sshd/conf-sshd.sh.bak mkdir -p ~/.conf-sshd
curl -s $script_url > $0 || cp ~/.conf-sshd/conf-sshd.sh.bak $0 && echo "Script update failed at $(date '+%Y-%m-%d %H:%M:%S')" && exit 1 target_script=~/.conf-sshd/conf-sshd.sh
chmod +x ~/.conf-sshd/conf-sshd.sh
if [ -f "$target_script" ]; then
cp "$target_script" "$target_script.bak"
fi
# 下载到临时文件
if ! curl -sL "$script_url" -o "$target_script.tmp"; then
echo "Script download failed at $(date '+%Y-%m-%d %H:%M:%S')"
rm -f "$target_script.tmp"
exit 1
fi
mv "$target_script.tmp" "$target_script"
chmod +x "$target_script"
echo "Script updated successfully at $(date '+%Y-%m-%d %H:%M:%S')" echo "Script updated successfully at $(date '+%Y-%m-%d %H:%M:%S')"
exit 0 exit 0
fi fi
# 检查 /usr/sbin/sshd 是否存在,且 /usr/sbin/sshd 执行后退出代码为 0 # 检查 SSHD 是否安装.
/usr/sbin/sshd -T > /dev/null if ! /usr/sbin/sshd -T > /dev/null 2>&1 && [ "$(has_param "-n" "--no-install-sshd")" == "false" ]; then
if [ $? -ne 0 ] && [ $(has_param "-n" "--no-install-sshd") == "false" ]; then if [ "$(id -u)" -eq 0 ]; then
if [ $(id -u) -eq 0 ]; then
echo "The ssh server is not installed, and the script is executed as root, so it will be installed." echo "The ssh server is not installed, and the script is executed as root, so it will be installed."
if [ -f /etc/redhat-release ]; then if [ -f /etc/redhat-release ]; then
yum install -y openssh-server yum install -y openssh-server
@ -122,23 +223,32 @@ else
fi fi
# 检查是否指定了 --allow-root-passwd # 检查是否指定了 --allow-root-passwd
if [ $(has_param "-p" "--allow-root-passwd") == "true" ]; then if [ "$(has_param "-p" "--allow-root-passwd")" == "true" ]; then
# 检查当前用户是否为 root # 检查当前用户是否为 root
if [ $(id -u) -eq 0 ]; then if [ "$(id -u)" -eq 0 ]; then
# 获取参数值
allow_root_passwd=$(get_param_value "-p" "--allow-root-passwd" | tr '[:upper:]' '[:lower:]') allow_root_passwd=$(get_param_value "-p" "--allow-root-passwd" | tr '[:upper:]' '[:lower:]')
sshd_config_file="/etc/ssh/sshd_config"
new_sshd_permit_root_login_setting=""
if [ "$allow_root_passwd" == "yes" ]; then if [ "$allow_root_passwd" == "yes" ]; then
# 设置允许 root 使用密码登录 new_sshd_permit_root_login_setting="PermitRootLogin yes"
sed -i 's/^#?PermitRootLogin.*/PermitRootLogin yes/g' /etc/ssh/sshd_config echo "Setting: Root user is allowed to log in with password."
echo "Root user is allowed to log in with password."
elif [ "$allow_root_passwd" == "no" ]; then elif [ "$allow_root_passwd" == "no" ]; then
# 设置禁止 root 使用密码登录 new_sshd_permit_root_login_setting="PermitRootLogin prohibit-password"
sed -i 's/^#?PermitRootLogin.*/PermitRootLogin prohibit-password/g' /etc/ssh/sshd_config echo "Setting: Root user is prohibited from logging in with password."
echo "Root user is prohibited from logging in with password."
else else
echo "Please specify whether to allow root to log in with a password." echo "Please specify 'yes' or 'no' for --allow-root-passwd."
exit 1 exit 1
fi fi
if grep -qE '^#?PermitRootLogin' "$sshd_config_file"; then
sed -i "s@^#?PermitRootLogin.*@$new_sshd_permit_root_login_setting@g" "$sshd_config_file"
else
echo "$new_sshd_permit_root_login_setting" >> "$sshd_config_file"
fi
echo "SSHD config updated. Please restart sshd service to apply changes."
else else
echo "The script is executed as a non-root user and cannot set whether to allow root to log in with a password." echo "The script is executed as a non-root user and cannot set whether to allow root to log in with a password."
exit 1 exit 1
@ -149,10 +259,10 @@ fi
update_sshkeys update_sshkeys
# 检查是否指定了 --cron # 检查是否指定了 --cron
if [ $(has_param "-c" "--cron") == "true" ]; then if [ "$(has_param "-c" "--cron")" == "true" ]; then
# 检查 Crontab 是否已安装 # 检查 Crontab 是否已安装
if [ "$(command -v crontab)" == "" ]; then if [ "$(command -v crontab)" == "" ]; then
if [ $(id -u) -eq 0 ]; then if [ "$(id -u)" -eq 0 ]; then
echo "The crontab is not installed, and the script is executed as a root user, so it will be installed." echo "The crontab is not installed, and the script is executed as a root user, so it will be installed."
if [ -f /etc/redhat-release ]; then if [ -f /etc/redhat-release ]; then
yum install -y crontabs yum install -y crontabs
@ -171,11 +281,11 @@ if [ $(has_param "-c" "--cron") == "true" ]; then
cron=$(get_param_value "-c" "--cron" | tr '[:upper:]' '[:lower:]') cron=$(get_param_value "-c" "--cron" | tr '[:upper:]' '[:lower:]')
if [ "$cron" == "false" ]; then if [ "$cron" == "false" ]; then
# 检查 Crontab 是否已经设置 # 检查 Crontab 是否已经设置
if [ "$(crontab -l | grep "conf-sshd.sh")" == "" ]; then if [ "$( (crontab -l 2>/dev/null || true) | grep -F -c "conf-sshd.sh" )" -eq 0 ]; then
echo "Crontab will not be configured." echo "Crontab already clean. Will not be configured."
exit 0 exit 0
else else
crontab -l | grep -v "conf-sshd.sh" | crontab - (crontab -l 2>/dev/null || true) | grep -F -v "conf-sshd.sh" | crontab -
echo "Crontab has been removed." echo "Crontab has been removed."
exit 0 exit 0
fi fi
@ -185,21 +295,29 @@ if [ $(has_param "-c" "--cron") == "true" ]; then
fi fi
# 将当前脚本移动到 ~/.conf-sshd/conf-sshd.sh 中. # 将当前脚本移动到 ~/.conf-sshd/conf-sshd.sh 中.
mkdir -p ~/.conf-sshd mkdir -p ~/.conf-sshd
# 检查当前脚本是否为文件 target_script=~/.conf-sshd/conf-sshd.sh
if [ ! -f $0 ]; then if [ ! -f "$0" ]; then
echo "Downloading conf-sshd script..." echo "Downloading conf-sshd script..."
curl -o ~/.conf-sshd/conf-sshd.sh $script_url if ! curl -sL "$script_url" -o "$target_script.tmp"; then
echo "Script download failed at $(date '+%Y-m-d %H:%M:%S')"
rm -f "$target_script.tmp"
exit 1
fi
mv "$target_script.tmp" "$target_script"
else else
echo "Copying conf-sshd script..." echo "Copying conf-sshd script..."
cp $0 ~/.conf-sshd/conf-sshd.sh cp "$0" "$target_script"
fi fi
chmod +x ~/.conf-sshd/conf-sshd.sh
chmod +x "$target_script"
echo "Install conf-sshd script successfully." echo "Install conf-sshd script successfully."
# 将当前脚本追加到当前用户的 Crontab 中 # 将当前脚本追加到当前用户的 Crontab 中
crontab -l > ~/.conf-sshd/crontab.old echo "Configuring Crontab..."
echo '$cron "/bin/bash ~/.conf-sshd/conf-sshd.sh -o" >> ~/.conf-sshd/run.log' >> ~/.conf-sshd/crontab.old cron_command="\"/bin/bash $target_script -o\" >> $HOME/.conf-sshd/run.log 2>&1"
crontab ~/.conf-sshd/crontab.old cron_job="$cron $cron_command"
rm ~/.conf-sshd/crontab.old
( (crontab -l 2>/dev/null || true) | grep -F -v "conf-sshd.sh") | { cat; echo "$cron_job"; } | crontab -
echo "Crontab has been configured.(Cron: '$cron')" echo "Crontab has been configured.(Cron: '$cron')"
fi fi
fi fi