功能简介
作者注:脚本默认作用于
root账户。
在日常运维工作中,启用基于 SSH 公钥的认证方式是一种更加安全且推荐的做法。不仅可以提高登录效率,还能有效防止暴力破解密码攻击。
本文通过一个 Bash 脚本,手把手教你如何在 Ubuntu 服务器上启用 SSH 密钥认证,并彻底关闭密码登录。
脚本自动完成以下任务:
✅ 生成 SSH 密钥对(非交互式)
✅ 设置 ~/.ssh/authorized_keys 权限并添加公钥
✅ 配置 /etc/ssh/sshd_config 文件,实现只允许密钥登录
✅ 重启 ssh 服务以使修改生效
脚本内容
创建一个 setup_ssh_key.sh 脚本文件
vim setup_ssh_key.sh将以下内容保存并执行它即可完成所有配置。
#!/bin/bash
set -e
# ==========================================
# Usage:
#
# 默认 22 端口:
# bash setup_ssh_key.sh
#
# 指定 2222 端口:
# bash setup_ssh_key.sh 2222
#
# 指定 10022 端口:
# bash setup_ssh_key.sh 10022
# ==========================================
SSH_PORT="${1:-22}"
SSH_DIR="/root/.ssh"
KEY_FILE="$SSH_DIR/id_ed25519"
AUTHORIZED_KEYS="$SSH_DIR/authorized_keys"
SSHD_CONFIG="/etc/ssh/sshd_config"
# SSH 密钥密码
KEY_PASSPHRASE="这里输入密钥密码"
# ==========================================
# Step 0: Validate SSH port
# ==========================================
echo "SSH port: $SSH_PORT"
# 必须是数字
if ! [[ "$SSH_PORT" =~ ^[0-9]+$ ]]; then
echo "ERROR: SSH port must be a number."
exit 1
fi
# 端口范围检查
if [ "$SSH_PORT" -lt 1 ] || [ "$SSH_PORT" -gt 65535 ]; then
echo "ERROR: SSH port must be between 1 and 65535."
exit 1
fi
# ==========================================
# Step 1: Create SSH directory
# ==========================================
echo "Creating SSH directory..."
mkdir -p "$SSH_DIR"
chmod 700 "$SSH_DIR"
chown root:root "$SSH_DIR"
# ==========================================
# Step 2: Generate SSH key pair
# ==========================================
echo "Generating SSH key pair..."
if [ ! -f "$KEY_FILE" ]; then
ssh-keygen \
-t ed25519 \
-a 64 \
-N "$KEY_PASSPHRASE" \
-f "$KEY_FILE"
else
echo "SSH key already exists:"
echo "$KEY_FILE"
fi
# ==========================================
# Step 3: Configure authorized_keys
# ==========================================
echo "Configuring authorized_keys..."
touch "$AUTHORIZED_KEYS"
chmod 600 "$AUTHORIZED_KEYS"
PUBLIC_KEY=$(cat "${KEY_FILE}.pub")
# 防止重复添加
if ! grep -qxF "$PUBLIC_KEY" "$AUTHORIZED_KEYS"; then
echo "$PUBLIC_KEY" >> "$AUTHORIZED_KEYS"
fi
chmod 700 "$SSH_DIR"
chmod 600 "$AUTHORIZED_KEYS"
chown -R root:root "$SSH_DIR"
# ==========================================
# Step 4: Backup SSH config
# ==========================================
echo "Backing up SSH config..."
BACKUP_FILE="${SSHD_CONFIG}.bak.$(date +%Y%m%d_%H%M%S)"
cp "$SSHD_CONFIG" "$BACKUP_FILE"
echo "Backup:"
echo "$BACKUP_FILE"
# ==========================================
# Step 5: Configure SSH
# ==========================================
echo "Configuring SSH..."
cat > "$SSHD_CONFIG" << EOF
# ==============================
# SSH Server Configuration
# ==============================
# SSH Listen Port
Port $SSH_PORT
# ------------------------------
# Basic
# ------------------------------
KbdInteractiveAuthentication no
UsePAM yes
X11Forwarding yes
PrintMotd no
AcceptEnv LANG LC_*
Subsystem sftp /usr/lib/openssh/sftp-server
# ------------------------------
# Authentication
# ------------------------------
MaxAuthTries 6
# Root can login using SSH key
PermitRootLogin prohibit-password
# Disable password login
PasswordAuthentication no
# Enable public key authentication
PubkeyAuthentication yes
# Only allow public key authentication
AuthenticationMethods publickey
EOF
# ==========================================
# Step 6: Check SSH configuration
# ==========================================
echo "Checking SSH configuration..."
if ! sshd -t; then
echo ""
echo "ERROR: SSH configuration is invalid!"
echo ""
echo "Restoring backup..."
cp "$BACKUP_FILE" "$SSHD_CONFIG"
echo "SSH service will NOT be restarted."
exit 1
fi
echo "SSH configuration is valid."
# ==========================================
# Step 7: Configure firewall
# ==========================================
if command -v ufw >/dev/null 2>&1; then
echo "Checking UFW..."
if ufw status | grep -q "Status: active"; then
echo "Opening SSH port $SSH_PORT in UFW..."
ufw allow "${SSH_PORT}/tcp"
else
echo "UFW is not active. Skip firewall configuration."
fi
else
echo "UFW not installed. Skip firewall configuration."
fi
# ==========================================
# Step 8: Restart SSH
# ==========================================
echo "Reloading systemd..."
systemctl daemon-reload
# Ubuntu 24.04 / 22.10+ may use ssh.socket
if systemctl list-unit-files | grep -q '^ssh.socket'; then
if systemctl is-active --quiet ssh.socket; then
echo "Detected active ssh.socket"
echo "Restarting ssh.socket..."
systemctl restart ssh.socket
fi
fi
# Restart normal SSH service as well
if systemctl list-unit-files | grep -q '^ssh.service'; then
echo "Restarting ssh.service..."
systemctl restart ssh
elif systemctl list-unit-files | grep -q '^sshd.service'; then
echo "Restarting sshd.service..."
systemctl restart sshd
else
echo "ERROR: SSH service not found!"
exit 1
fi
# ==========================================
# Step 9: Verify listening port
# ==========================================
echo ""
echo "=========================================="
echo "Checking SSH listening port"
echo "=========================================="
ss -lntp | grep -E "(:${SSH_PORT}[[:space:]])" || true
# ==========================================
# Step 10: Show SSH status
# ==========================================
echo ""
systemctl --no-pager --full status ssh 2>/dev/null || \
systemctl --no-pager --full status sshd 2>/dev/null || true
# ==========================================
# Complete
# ==========================================
echo ""
echo "=========================================="
echo "SSH configuration completed"
echo "=========================================="
echo ""
echo "SSH Port:"
echo "$SSH_PORT"
echo ""
echo "Private key:"
echo "$KEY_FILE"
echo ""
echo "Public key:"
echo "${KEY_FILE}.pub"
echo ""
echo "Connect example:"
echo "ssh -p $SSH_PORT -i $KEY_FILE root@SERVER_IP"
echo ""
echo "IMPORTANT:"
echo "Do NOT close the current SSH connection"
echo "until you verify the new SSH port works."
echo ""执行脚本文件 后面加端口号 可指定端口
bash ./setup_ssh_key.sh注意事项
✅ 将id_ed25519文件内容 下载到本地-登录使用的密钥文件
vim ~/.ssh/id_ed25519✅ 生成的密钥类型为 RSA,长度 4090 位,适用于大多数客户端。
✅ 若已有密钥文件,请注意备份 ~/.ssh/id_ed25519 和 id_ed25519.pub。
✅ 修改 sshd_config 存在风险,请谨慎操作,建议保留当前终端连接直到验证成功。
✅ 公钥也可复制到其他用户账户,实现多账户免密登录。
重启失败
Failed to restart sshd.service: Unit sshd.service not found.
那可能没有安装 SSH Server。Ubuntu/Debian 可以安装:
sudo apt update
sudo apt install -y openssh-server
sudo systemctl enable --now ssh作者:Joseph Lee 创建时间:2026-08-13 17:36
最后编辑:Joseph Lee 更新时间:2026-09-14 16:51
最后编辑:Joseph Lee 更新时间:2026-09-14 16:51