jd_train/set_ssh_without_password.sh

99 lines
2.9 KiB
Bash
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

test@tn01:~$ cat setup_ssh_nopass.sh
#!/usr/bin/env bash
set -Eeuo pipefail
usage() {
cat <<'USAGE'
用法:
setup_ssh_nopass.sh [-u 远端用户] [-p 端口] [-k 私钥路径] 主机
或者:
setup_ssh_nopass.sh 用户@主机 [-p 端口] [-k 私钥路径]
示例:
setup_ssh_nopass.sh -u root -p 22 192.168.1.10
setup_ssh_nopass.sh alice@server.example.com
USAGE
}
REMOTE_USER="${USER}"
PORT=22
KEY_PATH="${HOME}/.ssh/id_ed25519"
# 解析形如 user@host 的参数
parse_user_host() {
local s="$1"
if [[ "$s" == *"@"* ]]; then
REMOTE_USER="${s%@*}"
HOST="${s#*@}"
else
HOST="$s"
fi
}
# 参数
while getopts ":u:p:k:h" opt; do
case "$opt" in
u) REMOTE_USER="$OPTARG" ;;
p) PORT="$OPTARG" ;;
k) KEY_PATH="$OPTARG" ;;
h) usage; exit 0 ;;
\?) echo "未知选项: -$OPTARG" >&2; usage; exit 2 ;;
:) echo "选项 -$OPTARG 需要参数" >&2; usage; exit 2 ;;
esac
done
shift $((OPTIND-1))
[[ $# -ge 1 ]] || { usage; exit 2; }
parse_user_host "$1"
# 生成密钥(若不存在)
if [[ ! -f "$KEY_PATH" ]]; then
mkdir -p "$(dirname "$KEY_PATH")"
ssh-keygen -t ed25519 -a 100 -N "" \
-C "${USER}@$(hostname -f 2>/dev/null || hostname)-$(date +%Y%m%d)" \
-f "$KEY_PATH"
fi
chmod 600 "$KEY_PATH" || true
PUB_KEY_CONTENT="$(cat "${KEY_PATH}.pub")"
PUB_KEY_B64="$(base64 -w0 2>/dev/null < "${KEY_PATH}.pub" || base64 < "${KEY_PATH}.pub" | tr -d '\n')"
# 可选:预先抓取远端主机指纹,避免交互确认(注意:生产环境请先核对指纹!)
mkdir -p "${HOME}/.ssh"
touch "${HOME}/.ssh/known_hosts"
if command -v ssh-keyscan >/dev/null 2>&1; then
ssh-keyscan -p "$PORT" -H "$HOST" >> "${HOME}/.ssh/known_hosts" 2>/dev/null || true
fi
# 把公钥追加到远端 authorized_keys去重、修权限、SELinux 兼容)
ssh -p "$PORT" "${REMOTE_USER}@${HOST}" bash -s <<'REMOTE' "$PUB_KEY_B64"
set -Eeuo pipefail
PUB_B64="$1"
umask 077
mkdir -p "$HOME/.ssh"
touch "$HOME/.ssh/authorized_keys"
chmod 700 "$HOME/.ssh"
chmod 600 "$HOME/.ssh/authorized_keys"
# 解码公钥并去重追加
PUB_DEC="$(printf '%s' "$PUB_B64" | (base64 -d 2>/dev/null || openssl base64 -d))"
if ! grep -qxF "$PUB_DEC" "$HOME/.ssh/authorized_keys"; then
printf '%s\n' "$PUB_DEC" >> "$HOME/.ssh/authorized_keys"
fi
# SELinux 环境修复上下文(如有)
command -v restorecon >/dev/null 2>&1 && restorecon -R "$HOME/.ssh" || true
REMOTE
# 自检免密是否生效
if ssh -p "$PORT" -o BatchMode=yes -o PasswordAuthentication=no \
"${REMOTE_USER}@${HOST}" 'echo OK' 2>/dev/null | grep -qx 'OK'; then
echo "✅ 已配置免密:${REMOTE_USER}@${HOST}(端口 ${PORT} 使用密钥 ${KEY_PATH}"
else
echo "⚠️ 看起来免密未生效。请检查远端 /etc/ssh/sshd_config 中的以下项:"
echo " PubkeyAuthentication yes"
echo " AuthorizedKeysFile .ssh/authorized_keys"
echo " (如果远端禁止密码登录,首次安装密钥需用其他方式复制过去)"
exit 1
fi