Compare commits

...

6 Commits

View File

@ -1,4 +1,6 @@
#!/bin/bash
set -e
set -o pipefail
########## 一些配置 ##########
@ -11,10 +13,10 @@ script_url="{{ SCRIPT_URL }}"
############ 脚本区 ##########
script_params=$*
script_params=("$@")
has_param() {
for param in $script_params; do
for tParam in $@; do
for param in "${script_params[@]}"; do
for tParam in "$@"; do
if [ "$tParam" == "$param" ]; then
echo "true"
return
@ -26,15 +28,16 @@ has_param() {
get_param_value() {
local find=false
for param in $script_params; do
for param in "${script_params[@]}"; do
if [ "$find" == "true" ]; then
if [[ $param == -* ]]; then
return
fi
echo $param
echo "$param"
return
fi
for tParam in $@; do
for tParam in "$@"; do
if [ "$tParam" == "$param" ]; then
find=true
break
@ -44,67 +47,165 @@ get_param_value() {
}
# 帮助信息.
if [ $(has_param "-h" "--help") == "true" ]; then
if [ "$(has_param "-h" "--help")" == "true" ]; then
echo "Usage: $0 [options]"
echo "Options:"
echo " -h, --help Print this help message."
echo " -h, --help Print this help message."
echo ""
echo "Available to any user: "
echo " -c, --cron [cron | false] Configure Crontab to automatically update ssh keys,"
echo " Cron expression can be specified, If false is specified, "
echo " Crontab settings will be deleted automatically."
echo " -c, --cron \"<cron> | false\" Configure Crontab to automatically update ssh keys."
echo " Cron expression MUST be quoted (e.g., \"* 0 * * *\")."
echo " If 'false' is specified, Crontab settings will be deleted."
echo ""
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 " -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 " --uninstall Uninstall this script (remove cron and local files)."
echo ""
echo "only available when the script is executed as root:"
echo " -n, --no-install-sshd Do not install SSH Server."
echo " -p, --allow-root-passwd <yes | no> Allow Root to log in with a password."
echo " -n, --no-install-sshd Do not install SSH Server."
echo " -p, --allow-root-passwd <yes | no> Allow Root to log in with a password."
echo ""
exit 0
fi
update_sshkeys() {
if [ "$sshkey_url" == "" ]; then
echo "Please specify the URL of the SSH public key."
if [ "$sshkey_url" == "" ] || [[ "$sshkey_url" == "{{"* ]]; then
echo "ERROR: sshkey_url is not configured."
exit 1
fi
echo "Downloading SSH public key from '$sshkey_url'"
mkdir -p ~/.ssh
local ssh_keys=$(curl -s $sshkey_url)
if [ $? -ne 0 ] || [ "$ssh_keys" == "" ]; then
chmod 700 ~/.ssh
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')"
rm -f "$dl_tmp_file"
exit 1
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"
cat "$dl_tmp_file"
echo "--------------------------------------------------"
echo "$ssh_keys" > ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys
# 输出更新成功,需要附带时间日期
echo "SSH public key updated successfully at $(date '+%Y-%m-%d %H:%M:%S')"
local auth_file=~/.ssh/authorized_keys
local new_auth_file=~/.ssh/authorized_keys.new.tmp
# 受管理文本块标记
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
exit 0
fi
# 检查是否指定了 --update-self
if [ $(has_param "-u" "--update-self") == "true" ]; then
if [ "$(has_param "-u" "--update-self")" == "true" ]; then
echo "Updating conf-sshd script..."
cp $0 ~/.conf-sshd/conf-sshd.sh.bak
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
chmod +x ~/.conf-sshd/conf-sshd.sh
mkdir -p ~/.conf-sshd
target_script=~/.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')"
exit 0
fi
# 检查 /usr/sbin/sshd 是否存在,且 /usr/sbin/sshd 执行后退出代码为 0
/usr/sbin/sshd -T > /dev/null
if [ $? -ne 0 ] && [ $(has_param "-n" "--no-install-sshd") == "false" ]; then
if [ $(id -u) -eq 0 ]; then
# 检查 SSHD 是否安装.
if ! /usr/sbin/sshd -T > /dev/null 2>&1 && [ "$(has_param "-n" "--no-install-sshd")" == "false" ]; 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."
if [ -f /etc/redhat-release ]; then
yum install -y openssh-server
@ -122,23 +223,32 @@ else
fi
# 检查是否指定了 --allow-root-passwd
if [ $(has_param "-p" "--allow-root-passwd") == "true" ]; then
if [ "$(has_param "-p" "--allow-root-passwd")" == "true" ]; then
# 检查当前用户是否为 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:]')
sshd_config_file="/etc/ssh/sshd_config"
new_sshd_permit_root_login_setting=""
if [ "$allow_root_passwd" == "yes" ]; then
# 设置允许 root 使用密码登录
sed -i 's/^#?PermitRootLogin.*/PermitRootLogin yes/g' /etc/ssh/sshd_config
echo "Root user is allowed to log in with password."
new_sshd_permit_root_login_setting="PermitRootLogin yes"
echo "Setting: Root user is allowed to log in with password."
elif [ "$allow_root_passwd" == "no" ]; then
# 设置禁止 root 使用密码登录
sed -i 's/^#?PermitRootLogin.*/PermitRootLogin prohibit-password/g' /etc/ssh/sshd_config
echo "Root user is prohibited from logging in with password."
new_sshd_permit_root_login_setting="PermitRootLogin prohibit-password"
echo "Setting: Root user is prohibited from logging in with password."
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
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
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
@ -149,10 +259,10 @@ fi
update_sshkeys
# 检查是否指定了 --cron
if [ $(has_param "-c" "--cron") == "true" ]; then
if [ "$(has_param "-c" "--cron")" == "true" ]; then
# 检查 Crontab 是否已安装
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."
if [ -f /etc/redhat-release ]; then
yum install -y crontabs
@ -171,11 +281,11 @@ if [ $(has_param "-c" "--cron") == "true" ]; then
cron=$(get_param_value "-c" "--cron" | tr '[:upper:]' '[:lower:]')
if [ "$cron" == "false" ]; then
# 检查 Crontab 是否已经设置
if [ "$(crontab -l | grep "conf-sshd.sh")" == "" ]; then
echo "Crontab will not be configured."
if [ "$( (crontab -l 2>/dev/null || true) | grep -F -c "conf-sshd.sh" )" -eq 0 ]; then
echo "Crontab already clean. Will not be configured."
exit 0
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."
exit 0
fi
@ -185,21 +295,29 @@ if [ $(has_param "-c" "--cron") == "true" ]; then
fi
# 将当前脚本移动到 ~/.conf-sshd/conf-sshd.sh 中.
mkdir -p ~/.conf-sshd
# 检查当前脚本是否为文件
if [ ! -f $0 ]; then
target_script=~/.conf-sshd/conf-sshd.sh
if [ ! -f "$0" ]; then
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
echo "Copying conf-sshd script..."
cp $0 ~/.conf-sshd/conf-sshd.sh
cp "$0" "$target_script"
fi
chmod +x ~/.conf-sshd/conf-sshd.sh
chmod +x "$target_script"
echo "Install conf-sshd script successfully."
# 将当前脚本追加到当前用户的 Crontab 中
crontab -l > ~/.conf-sshd/crontab.old
echo '$cron "/bin/bash ~/.conf-sshd/conf-sshd.sh -o" >> ~/.conf-sshd/run.log' >> ~/.conf-sshd/crontab.old
crontab ~/.conf-sshd/crontab.old
rm ~/.conf-sshd/crontab.old
echo "Configuring Crontab..."
cron_command="\"/bin/bash $target_script -o\" >> $HOME/.conf-sshd/run.log 2>&1"
cron_job="$cron $cron_command"
( (crontab -l 2>/dev/null || true) | grep -F -v "conf-sshd.sh") | { cat; echo "$cron_job"; } | crontab -
echo "Crontab has been configured.(Cron: '$cron')"
fi
fi