香港服务器CentOS如何配置SSH密钥登录?含权限检查与回滚步骤
在香港服务器的 CentOS 7、CentOS Stream 8/9 上,SSH 密钥登录的安全上线顺序是:先保留当前 SSH 会话,创建或确认具备 sudo 权限的管理账号,生成并安装公钥,修正目录与文件权限,验证新终端可以使用密钥登录,再关闭密码认证,最后通过 sshd -t、日志和第二个终端完成验收。
密钥登录本身不能阻止所有 SSH 连接,但关闭密码认证、禁止 root 直接登录、限制认证尝试次数,并配合 firewalld 与 Fail2ban,可以显著减少密码爆破风险。整个过程中不要先关闭当前连接,也不要在未验证密钥登录前直接执行 systemctl restart sshd。
一、适用环境与上线目标
本文适用于以下环境:
| 项目 | 适用范围或参考值 |
|---|---|
| 操作系统 | CentOS 7、CentOS Stream 8/9 |
| SSH 服务 | OpenSSH Server,服务名通常为 sshd |
| 服务管理 | systemd,使用 systemctl 管理服务 |
| 防火墙 | firewalld,可选配 Fail2ban |
| 客户端 | Linux、macOS、Windows OpenSSH Client |
| 登录目标 | 使用普通运维账号的 Ed25519 密钥登录 |
| 安全目标 | 禁用密码认证,减少 root 直接登录和重复爆破 |
CentOS 7 与 CentOS Stream 8/9 的 SSH 配置项大体一致,但交互式认证配置项可能存在差异。开始修改前,应先核对系统版本、OpenSSH 版本、当前 SSH 端口和登录账号。
1. 保留当前管理会话
使用 SSH 连接服务器后,不要关闭当前终端。后续即使新配置导致密钥登录失败,仍可以利用当前会话回滚配置。
建议同时准备以下一种备用入口:
- 云平台或服务器管理面板提供的 Web 控制台;
- 独立的串口、VNC 或救援终端;
- 已经验证可以使用密钥登录的第二个管理账号。
如果当前只有 root 密码登录,先创建普通管理账号并安装密钥,确认普通账号可用后,再禁用 root 直接登录。
2. 检查系统、服务和端口
以下命令在服务器端执行:
cat /etc/centos-release
uname -r
ssh -V
sudo systemctl status sshd --no-pager
sudo ss -lntp | grep -E 'sshd|:22'
不同结果的含义如下:
- 能看到
sshd服务处于active (running),表示 SSH 服务正在运行; ss -lntp显示0.0.0.0:22或[::]:22,表示服务监听 22 端口;- 如果监听的是其他端口,后续客户端连接时需要使用
-p 端口号; - 如果服务未运行,不要急于修改认证策略,应先确认当前 SSH 服务能正常启动。
检查当前生效的认证配置:
sudo sshd -T | grep -E '^(port|pubkeyauthentication|passwordauthentication|kbdinteractiveauthentication|challengeresponseauthentication|permitrootlogin|authorizedkeysfile|maxauthtries|logingracetime)'
sshd -T 会解析主配置及其包含文件,结果比单纯查看某一行配置更接近 SSH 服务实际使用的值。
3. 确认管理账号和 sudo 权限
如果已经有可用的普通运维账号,可以跳过创建步骤,直接确认账号信息:
id opsadmin
getent passwd opsadmin
sudo -l -U opsadmin
没有账号时,可以在当前 root 或具备 sudo 权限的会话中创建:
sudo useradd -m -s /bin/bash opsadmin
sudo usermod -aG wheel opsadmin
id opsadmin
CentOS 通常通过 wheel 组授予 sudo 权限,但具体权限仍应以 /etc/sudoers 和 /etc/sudoers.d/ 中的配置为准。确认账号能正常使用密钥登录、并能执行必要的 sudo 命令后,才适合关闭 root 直接登录。
二、在本地生成 SSH 密钥
密钥应在自己的管理电脑上生成。私钥只保存在本地,不要上传到服务器,不要通过工单、聊天工具或网页表单传递。
1. Linux 或 macOS 客户端
在本地终端执行:
ssh-keygen -t ed25519 -a 100 -f ~/.ssh/id_ed25519_hk -C "opsadmin@hk-server"
参数说明:
-t ed25519:使用 Ed25519 算法;-a 100:增加私钥口令的 KDF 计算轮数,降低私钥文件泄露后的离线猜测效率;-f:指定密钥文件名,避免覆盖已有的默认密钥;-C:添加便于识别的注释,不参与认证。
执行后会提示输入私钥口令。建议设置口令,即使私钥文件被复制,也不能直接使用。
生成结果通常包括:
~/.ssh/id_ed25519_hk # 私钥,只保存在本地
~/.ssh/id_ed25519_hk.pub # 公钥,可以写入服务器
检查文件权限:
chmod 700 ~/.ssh
chmod 600 ~/.ssh/id_ed25519_hk
chmod 644 ~/.ssh/id_ed25519_hk.pub
查看公钥内容时,只查看 .pub 文件:
cat ~/.ssh/id_ed25519_hk.pub
公钥应当是单行文本,通常以 ssh-ed25519 开头。私钥文件不要执行 cat,也不要将私钥内容粘贴到服务器。
2. Windows 客户端
Windows 10/11 通常已经包含 OpenSSH Client。可以在 PowerShell 中执行:
ssh-keygen -t ed25519 -a 100 -f "$env:USERPROFILE\.ssh\id_ed25519_hk" -C "opsadmin@hk-server"
公钥文件通常位于:
C:\Users\当前用户名\.ssh\id_ed25519_hk.pub
可以使用以下命令查看公钥:
Get-Content "$env:USERPROFILE\.ssh\id_ed25519_hk.pub"
如果提示找不到 ssh-keygen,需要先在 Windows 的“可选功能”中安装 OpenSSH Client,或使用已有的 OpenSSH 环境。不要为了生成密钥而把私钥上传到服务器。
三、将公钥安装到 CentOS 服务器
1. 使用 ssh-copy-id 安装
如果客户端存在 ssh-copy-id,可以执行:
ssh-copy-id -i ~/.ssh/id_ed25519_hk.pub opsadmin@服务器IP
如果 SSH 使用非 22 端口:
ssh-copy-id -i ~/.ssh/id_ed25519_hk.pub -p 端口号 opsadmin@服务器IP
该命令通常会要求输入一次当前账号密码,然后将公钥追加到服务器的:
/home/opsadmin/.ssh/authorized_keys
如果登录账号是 root,则文件通常位于:
/root/.ssh/authorized_keys
但生产运维更建议将密钥安装到普通管理账号,而不是长期使用 root 直接登录。
2. 没有 ssh-copy-id 时手动追加公钥
在本地执行以下命令,将公钥通过当前可用的 SSH 会话追加到服务器:
cat ~/.ssh/id_ed25519_hk.pub | ssh opsadmin@服务器IP \
'umask 077; mkdir -p ~/.ssh; cat >> ~/.ssh/authorized_keys; chmod 700 ~/.ssh; chmod 600 ~/.ssh/authorized_keys'
如果当前只能使用 root 登录,也可以先追加到目标账号,但需要确保路径和属主正确:
cat ~/.ssh/id_ed25519_hk.pub | ssh root@服务器IP \
'umask 077; mkdir -p /home/opsadmin/.ssh; cat >> /home/opsadmin/.ssh/authorized_keys; chown -R opsadmin:opsadmin /home/opsadmin/.ssh; chmod 700 /home/opsadmin/.ssh; chmod 600 /home/opsadmin/.ssh/authorized_keys'
这类追加操作可能造成同一公钥重复出现。重复通常不影响登录,但会增加后续审计难度。正式上线前应检查 authorized_keys,删除重复或不再使用的密钥。
3. 检查公钥是否完整
在服务器端执行:
sudo wc -l /home/opsadmin/.ssh/authorized_keys
sudo sed -n '1,5p' /home/opsadmin/.ssh/authorized_keys
每个公钥必须独占一行,不能因为复制换行、少字符或多出不可见字符而被拆开。可以在本地查看公钥指纹:
ssh-keygen -lf ~/.ssh/id_ed25519_hk.pub
服务器上的 authorized_keys 应包含相同的公钥内容或相同的指纹。
四、检查目录、文件和 SELinux 权限
SSH 服务默认会执行严格权限检查。如果家目录、.ssh 目录或 authorized_keys 对其他用户可写,sshd 可能拒绝使用公钥登录。
1. 查看路径上每一级目录的权限
服务器端执行:

namei -l /home/opsadmin/.ssh/authorized_keys
重点检查:
/home/opsadmin的属主应为opsadmin或符合实际账号设计;/home/opsadmin/.ssh通常应为700;authorized_keys通常应为600;.ssh和authorized_keys的属主、属组应属于目标登录账号;- 家目录不应被其他用户或组写入。
查看详细状态:
sudo stat -c '%A %a %U:%G %n' \
/home/opsadmin \
/home/opsadmin/.ssh \
/home/opsadmin/.ssh/authorized_keys
典型的安全结果类似:
drwx------ 700 opsadmin:opsadmin /home/opsadmin/.ssh
-rw------- 600 opsadmin:opsadmin /home/opsadmin/.ssh/authorized_keys
2. 修正密钥目录权限
确认路径确实属于目标账号后,可以执行:
sudo chown -R opsadmin:opsadmin /home/opsadmin/.ssh
sudo chmod 700 /home/opsadmin/.ssh
sudo chmod 600 /home/opsadmin/.ssh/authorized_keys
如果家目录被设置为组或其他用户可写,应先记录原始权限,再根据实际业务需要修正。常见修正方式如下:
sudo chmod go-w /home/opsadmin
不要对整个 /home 目录执行递归权限修改,也不要在不了解业务权限的情况下使用 chmod -R 777。权限变更范围应限定在目标账号的 SSH 目录。
3. 修正 SELinux 文件标签
检查 SELinux 状态和文件上下文:
getenforce
ls -Zd /home/opsadmin /home/opsadmin/.ssh /home/opsadmin/.ssh/authorized_keys
如果 SELinux 处于 Enforcing,或者公钥内容和权限都正确但仍然无法登录,可以恢复默认上下文:
sudo restorecon -Rv /home/opsadmin/.ssh
再检查是否有 SELinux 拒绝记录:
sudo ausearch -m avc -ts recent
restorecon 只恢复安全标签,不会改变文件内容。若目录是通过特殊挂载、网络文件系统或自定义路径提供,还需要根据实际路径配置相应的 SELinux 上下文,不能简单复制其他目录的标签。
五、先验证密钥登录,再关闭密码认证
1. 使用新终端验证公钥登录
保持原有 SSH 会话不动,在本地打开第二个终端,执行:

ssh -i ~/.ssh/id_ed25519_hk \
-o IdentitiesOnly=yes \
opsadmin@服务器IP
如果 SSH 使用其他端口:
ssh -i ~/.ssh/id_ed25519_hk \
-o IdentitiesOnly=yes \
-p 端口号 \
opsadmin@服务器IP
登录后执行:
whoami
hostname
id
预期结果应显示目标账号为 opsadmin,主机名和用户组信息与服务器实际情况一致。
为了确认客户端没有偷偷使用其他密钥,可以开启详细日志:
ssh -vv \
-i ~/.ssh/id_ed25519_hk \
-o IdentitiesOnly=yes \
opsadmin@服务器IP
日志中通常可以看到类似信息:
Offering public key: /home/local/.ssh/id_ed25519_hk
Server accepts key
Authentication succeeded (publickey)
示例仅用于说明判断方式,不代表某台服务器的实际执行记录。
2. 为 SSH 配置文件做备份
在服务器端执行:
sudo cp -a /etc/ssh/sshd_config \
/etc/ssh/sshd_config.bak.$(date +%Y%m%d%H%M%S)
sudo ls -l /etc/ssh/sshd_config.bak.*
如果系统通过 Include 引用了其他配置目录,也应一并确认:
sudo grep -nE '^[[:space:]]*Include|^[[:space:]]*(Port|PubkeyAuthentication|PasswordAuthentication|PermitRootLogin)' \
/etc/ssh/sshd_config /etc/ssh/sshd_config.d/* 2>/dev/null
不要直接把一整段配置无条件追加到文件末尾。OpenSSH 配置中重复项可能导致实际生效值与预期不同。应先搜索已有配置,修改原有项,或者确认包含文件的加载顺序后再新增配置。
3. 第一阶段只启用公钥,不立即关闭密码
在已经确认新账号可以使用公钥登录后,先将 SSH 配置调整为安全过渡状态:
PubkeyAuthentication yes
AuthorizedKeysFile .ssh/authorized_keys
PasswordAuthentication yes
PermitRootLogin prohibit-password
MaxAuthTries 3
LoginGraceTime 30
UsePAM yes
其中:
PubkeyAuthentication yes:允许公钥认证;AuthorizedKeysFile:指定公钥文件位置;PasswordAuthentication yes:过渡阶段保留密码认证,便于回滚;PermitRootLogin prohibit-password:root 不允许密码登录,但仍允许 root 使用密钥;MaxAuthTries 3:限制单次连接的认证尝试次数;LoginGraceTime 30:限制连接建立后停留在认证阶段的时间;UsePAM yes:保留 CentOS 常用的 PAM 账号策略。
修改后先检查语法:
sudo sshd -t -f /etc/ssh/sshd_config
没有任何输出通常表示语法检查通过。出现错误时不要 reload,先根据错误行号修正。
4. 验证配置并平滑加载
确认语法通过后,使用 reload 而不是直接重启:
sudo systemctl reload sshd
sudo systemctl status sshd --no-pager
reload 会让新连接使用新配置,通常不会主动断开已经建立的 SSH 会话。检查生效值:
sudo sshd -T | grep -E '^(pubkeyauthentication|passwordauthentication|permitrootlogin|maxauthtries|logingracetime|usepam)'
然后再次从第二个本地终端测试:
ssh -i ~/.ssh/id_ed25519_hk \
-o IdentitiesOnly=yes \
opsadmin@服务器IP 'whoami && hostname'
5. 第二阶段关闭密码认证
确认以下条件全部满足后,再关闭密码认证:

- 新建的普通账号可以使用密钥登录;
- 当前 root 或旧账号会话仍然保持连接;
- 新账号具有所需的 sudo 权限;
- 已经保存了
sshd_config备份; - 已确认 SSH 端口和防火墙状态;
- 至少有一种控制台或备用登录方式。
修改为:
PubkeyAuthentication yes
AuthorizedKeysFile .ssh/authorized_keys
PasswordAuthentication no
PermitRootLogin no
MaxAuthTries 3
LoginGraceTime 30
UsePAM yes
CentOS 7 常见的交互式认证配置项为:
ChallengeResponseAuthentication no
CentOS Stream 8/9 可以检查并设置:
KbdInteractiveAuthentication no
可以先查看系统是否识别某个配置项:
sudo sshd -T | grep -Ei 'kbdinteractiveauthentication|challengeresponseauthentication'
如果 sshd -t 报告 Bad configuration option,删除不被当前 OpenSSH 版本识别的配置项,只保留该版本支持的对应项。不要为了套用其他系统的配置而强行保留未知参数。
修改后执行:
sudo sshd -t -f /etc/ssh/sshd_config
sudo systemctl reload sshd
sudo sshd -T | grep -E '^(pubkeyauthentication|passwordauthentication|permitrootlogin)'
预期结果应包含:
pubkeyauthentication yes
passwordauthentication no
permitrootlogin no
再次使用新终端验证:
ssh -i ~/.ssh/id_ed25519_hk \
-o IdentitiesOnly=yes \
-o PasswordAuthentication=no \
-o KbdInteractiveAuthentication=no \
opsadmin@服务器IP
还可以测试禁用密码后的结果:
ssh -o BatchMode=yes \
-o PreferredAuthentications=password \
-o PubkeyAuthentication=no \
opsadmin@服务器IP 'true'
该命令预期返回非零状态,并出现认证失败信息。测试时不要反复尝试,以免触发 Fail2ban 或其他封禁规则。
六、检查 firewalld 与 SSH 端口
关闭密码认证后,仍需确保防火墙允许合法的 SSH 连接。先查看活动区域:
sudo firewall-cmd --state
sudo firewall-cmd --get-active-zones
假设实际活动区域是 public,检查已开放服务:
sudo firewall-cmd --zone=public --list-services
sudo firewall-cmd --zone=public --list-ports
如果 SSH 使用默认 22 端口且 ssh 服务尚未开放,可以执行:
sudo firewall-cmd --zone=public --permanent --add-service=ssh
sudo firewall-cmd --reload
sudo firewall-cmd --zone=public --list-services
如果当前使用自定义端口,应以 sshd -T 的 port 结果为准,例如:
sudo firewall-cmd --zone=public --permanent --add-port=2222/tcp
sudo firewall-cmd --reload
防火墙规则变更前应确认区域名称和实际监听端口。不要在远程会话中直接删除当前 SSH 端口,也不要在没有控制台的情况下同时修改 SSH 端口、SELinux 和 firewalld,否则很容易造成远程失联。
固定管理地址时限制 SSH 来源
如果运维出口拥有固定公网 IP,可以将 SSH 访问限制为指定地址。以下地址 203.0.113.10/32 只是文档示例,实际操作时必须替换为真实管理出口地址:
sudo firewall-cmd --zone=public --permanent \
--add-rich-rule='rule family="ipv4" source address="203.0.113.10/32" service name="ssh" accept'
确认新规则已经加入并且从该地址测试成功后,再考虑移除面向所有来源的 ssh 服务规则:
sudo firewall-cmd --zone=public --permanent --remove-service=ssh
sudo firewall-cmd --reload
sudo firewall-cmd --zone=public --list-all
管理出口地址经常变化时,不建议直接采用这类白名单,否则可能因为出口变化而无法登录。密钥认证和 Fail2ban 应作为主要控制措施,非标准端口只能减少部分自动化扫描,不能替代密钥认证。
七、使用 Fail2ban 限制重复爆破
密钥登录可以阻止密码猜测成功,但攻击者仍可能持续建立 SSH 连接。Fail2ban 会读取 SSH 失败日志,在指定时间内失败次数超过阈值时,通过 firewalld 临时封禁来源地址。
1. 安装软件包
CentOS 7 使用 yum,CentOS Stream 8/9 使用 dnf。软件包名称和仓库可用性应以当前系统仓库为准。
CentOS 7 示例:
sudo yum install -y epel-release
sudo yum install -y fail2ban
CentOS Stream 8/9 示例:
sudo dnf install -y epel-release
sudo dnf install -y fail2ban
如果软件包无法找到,不要随意添加来源不明的第三方仓库。可以先检查仓库和软件包信息:
sudo yum repolist
sudo yum info fail2ban 2>/dev/null || sudo dnf info fail2ban
如果无法安装 Fail2ban,仍然可以通过“密钥登录、关闭密码认证、禁止 root 直接登录、限制认证次数”完成基础防护。
2. 配置 SSH 监控规则
先确认 CentOS 是否有 SSH 安全日志:
sudo ls -l /var/log/secure
如果文件存在,可创建配置文件:
sudo install -d -m 755 /etc/fail2ban/jail.d
sudo vi /etc/fail2ban/jail.d/sshd.local
写入以下内容:
[sshd]
enabled = true
port = ssh
backend = auto
logpath = /var/log/secure
maxretry = 5
findtime = 10m
bantime = 1h
banaction = firewallcmd-rich-rules
ignoreip = 127.0.0.1/8 ::1 203.0.113.10
参数含义:
maxretry = 5:在统计窗口内失败 5 次后封禁;findtime = 10m:统计最近 10 分钟的失败记录;bantime = 1h:首次封禁 1 小时;ignoreip:不封禁本机、回环地址和固定管理出口;banaction:使用 firewalld rich rule 执行封禁。
其中 203.0.113.10 仍是示例地址,应替换为真实管理出口;如果管理出口不固定,不要把不确定的地址加入白名单。
如果系统没有 /var/log/secure,而 SSH 日志主要由 journald 保存,可以将配置调整为:
[sshd]
enabled = true
port = ssh
backend = systemd
maxretry = 5
findtime = 10m
bantime = 1h
banaction = firewallcmd-rich-rules
ignoreip = 127.0.0.1/8 ::1 203.0.113.10
不要同时保留不适用的 logpath。选择配置后先进行检查:
sudo fail2ban-client -t
检查通过后启动并设置开机启动:
sudo systemctl enable --now fail2ban
sudo systemctl status fail2ban --no-pager
sudo fail2ban-client status
sudo fail2ban-client status sshd
正常情况下可以看到 sshd jail,以及当前失败次数和封禁数量。
3. 处理误封管理地址
如果管理出口被误封,必须从未被封禁的终端或控制台执行:
sudo fail2ban-client set sshd unbanip 203.0.113.10
查看当前封禁状态:
sudo fail2ban-client status sshd
sudo firewall-cmd --zone=public --list-rich-rules
Fail2ban 的封禁时长、失败阈值应结合实际运维情况调整。阈值过低可能误伤共享出口、办公网络或自动化任务,阈值过高则会降低对重复扫描的抑制效果。
八、按日志定位常见失败
1. Permission denied (publickey)
先在本地确认使用的是正确私钥和账号:
ssh -vv \
-i ~/.ssh/id_ed25519_hk \
-o IdentitiesOnly=yes \
opsadmin@服务器IP
服务器端同步查看日志:
sudo journalctl -u sshd -n 100 --no-pager
sudo tail -n 100 /var/log/secure
重点排查:
sudo namei -l /home/opsadmin/.ssh/authorized_keys
sudo stat -c '%A %U:%G %n' /home/opsadmin/.ssh /home/opsadmin/.ssh/authorized_keys
sudo restorecon -Rv /home/opsadmin/.ssh
常见原因包括:
- 连接时使用了错误的账号;
- 私钥与服务器上的公钥不是一对;
authorized_keys被换行或内容不完整;.ssh或authorized_keys权限过宽;- 文件属主不是目标账号;
- SELinux 标签不正确;
AuthorizedKeysFile被改成了其他路径;- Fail2ban 已封禁当前出口地址。
2. Connection refused
检查 SSH 服务和监听端口:
sudo systemctl status sshd --no-pager
sudo ss -lntp | grep sshd
sudo sshd -T | grep '^port '
如果修改配置后服务没有重新加载,先检查语法:
sudo sshd -t -f /etc/ssh/sshd_config
Connection refused 通常表示目标主机可以到达,但该端口没有服务监听,或服务主动拒绝连接,不应优先从密钥权限入手。
3. 连接超时
检查 firewalld 当前区域和规则:
sudo firewall-cmd --get-active-zones
sudo firewall-cmd --zone=public --list-all
确认客户端使用的端口与 sshd -T 输出一致,并检查是否因为来源白名单或 Fail2ban 规则而被拒绝。远程修改防火墙时必须保留当前会话或使用控制台,避免在错误区域上删除 SSH 访问规则。
4. 关闭密码后仍然出现密码提示
检查最终生效配置,而不是只查看配置文件中某一行:
sudo sshd -T | grep -Ei 'passwordauthentication|kbdinteractiveauthentication|challengeresponseauthentication|authenticationmethods'
可能原因包括:
PasswordAuthentication仍为yes;KbdInteractiveAuthentication或ChallengeResponseAuthentication仍允许交互式认证;- 配置文件存在重复项或
Include文件覆盖; - 客户端使用了旧的连接复用会话;
- 实际连接到了另一台服务器或另一个端口。
可以在本地强制只使用公钥:
ssh -o IdentitiesOnly=yes \
-o PasswordAuthentication=no \
-o KbdInteractiveAuthentication=no \
-i ~/.ssh/id_ed25519_hk \
opsadmin@服务器IP
5. sshd -t 检查失败
不要执行 reload 或 restart。记录报错行号后恢复最近一次备份,或者只撤销最近修改的配置项:
sudo ls -lt /etc/ssh/sshd_config.bak.*
恢复后再次检查:
sudo cp -a /etc/ssh/sshd_config.bak.时间戳 /etc/ssh/sshd_config
sudo sshd -t -f /etc/ssh/sshd_config
备份文件名中的“时间戳”需要替换为实际文件名,不能直接照抄。
九、上线验收检查
完成部署后,建议按以下顺序验收:
- 从新终端使用指定私钥登录普通管理账号。
- 确认
whoami、hostname、id输出正确。 - 确认普通账号能够执行所需的
sudo操作。 - 确认
sshd -t返回成功。 - 确认
systemctl status sshd为运行状态。 - 确认
sshd -T显示pubkeyauthentication yes。 - 确认
passwordauthentication no。 - 确认
permitrootlogin no,或仍处于明确评估过的过渡状态。 - 确认 firewalld 开放的是实际 SSH 端口和实际活动区域。
- 确认 Fail2ban 的
sshdjail 已启用,且管理出口未被封禁。 - 确认
/home/账号/.ssh为700,authorized_keys为600,属主正确。 - 确认已保存 SSH 配置备份和密钥变更记录。
可以使用以下命令进行集中复核:
sudo sshd -t
sudo systemctl is-active sshd
sudo sshd -T | grep -E '^(port|pubkeyauthentication|passwordauthentication|permitrootlogin|maxauthtries)'
sudo firewall-cmd --get-active-zones
sudo fail2ban-client status sshd 2>/dev/null || true
十、失败时的回滚步骤
1. SSH 服务仍可通过当前会话操作
先不要退出当前会话。找到最近的配置备份:
sudo ls -lt /etc/ssh/sshd_config.bak.*
恢复指定备份:
sudo cp -a /etc/ssh/sshd_config.bak.实际时间戳 /etc/ssh/sshd_config
sudo sshd -t -f /etc/ssh/sshd_config
sudo systemctl reload sshd
如果只是误关闭密码认证,也可以进行定向回滚,将以下配置恢复为过渡状态:
PubkeyAuthentication yes
PasswordAuthentication yes
PermitRootLogin prohibit-password
然后执行:
sudo sshd -t -f /etc/ssh/sshd_config
sudo systemctl reload sshd
只有语法检查通过后才 reload。不要直接执行 systemctl restart sshd 作为第一步。
2. 回滚错误或失效的公钥
先备份当前文件:
sudo cp -a /home/opsadmin/.ssh/authorized_keys \
/home/opsadmin/.ssh/authorized_keys.bak.$(date +%Y%m%d%H%M%S)
使用编辑器删除对应的单行公钥:
sudoedit /home/opsadmin/.ssh/authorized_keys
不要根据模糊的用户名或注释批量删除,最好依据本地公钥指纹和完整密钥内容确认目标行。删除后重新检查权限:
sudo chown opsadmin:opsadmin /home/opsadmin/.ssh/authorized_keys
sudo chmod 600 /home/opsadmin/.ssh/authorized_keys
sudo restorecon -v /home/opsadmin/.ssh/authorized_keys
3. 回滚 Fail2ban
如果 Fail2ban 配置导致误封或服务启动失败,可以先停止服务:
sudo systemctl disable --now fail2ban
然后检查 firewalld 中是否还残留由 Fail2ban 产生的临时规则:
sudo firewall-cmd --zone=public --list-rich-rules
不要直接清空整个 firewalld 配置。只删除能够确认属于 Fail2ban、且不会影响正常 SSH 访问的临时规则。完成后确认 SSH 端口仍然开放。
4. 已经失去 SSH 连接时
如果所有 SSH 会话都断开,应使用服务器控制台或救援终端:
- 登录控制台;
- 检查 SSH 配置备份;
- 恢复最近一次可用的
sshd_config; - 执行
sshd -t; - 重新加载
sshd; - 检查
.ssh目录属主和权限; - 检查 firewalld 和 Fail2ban 是否封禁管理出口;
- 使用第二个终端验证恢复结果。
回滚的核心原则是:保留当前会话、先恢复配置、再验证语法、最后 reload;不要通过删除整个 .ssh 目录或清空防火墙规则来处理单一故障。这样既能恢复 SSH 密钥登录,也能避免把原有的访问控制和其他服务规则一并破坏。



