1. 项目概述:为什么一个看似“老派”的 SSH 配置,今天依然值得花 20 分钟认真重做?
CentOS 系统下 SSH 服务配置指南——这个标题乍看平平无奇,甚至有点“过时感”。毕竟现在连新手都习惯用图形化远程桌面,云厂商控制台也自带 Web Shell,很多人觉得“SSH 就是装完系统默认开着的那玩意儿,输个密码就能连,有啥好配的?”我完全理解这种想法。五年前我也这么想,直到某天凌晨三点,某高校实验室的一台 CentOS 7 服务器被暴力扫描撞库成功,攻击者上传了挖矿脚本,CPU 满载到 99%,而日志里只留下一长串失败登录后紧跟着的那条成功的Accepted password for root记录。排查发现,问题根源不是密码弱,而是 SSH 服务全程跑在默认配置上:root 直接允许登录、密码认证未禁用、端口还是标准的 22、失败重试没限制、密钥登录压根没启用……整套防线,形同虚设。
这就是为什么“迅速上手”四个字在这里分量极重——它不意味着“快速跳过”,而是“用最短时间,建立一道真正能挡人的门”。CentOS(尤其是 7 和 8 的长期维护分支)至今仍是大量生产环境、教学实验平台、嵌入式网关设备的底层选择。它的稳定性和社区支持周期,决定了我们无法用“新系统替代”来逃避老系统的安全责任。而 SSH,作为这台机器唯一对外暴露的“钥匙孔”,其配置质量,直接决定了整台机器是铜墙铁壁,还是纸糊的窗户。本文要讲的,就是如何在 CentOS 系统下,用一套清晰、可验证、不依赖第三方工具的原生方案,把这扇门从“敞开欢迎”,变成“严进严出”。你会看到,从确认服务状态、修改核心配置项、生成与部署密钥,到设置登录策略、审计日志、最终验证效果,每一步都有明确的目的、可复现的操作和必须警惕的细节。这不是一份“安装教程”,而是一份“防御工事施工图”。无论你是刚接触 Linux 的学生,还是需要快速加固一批旧服务器的运维人员,只要花掉一杯咖啡的时间,就能让手里的 CentOS 机器,在网络世界里多一分底气。
2. 核心设计思路与方案选型:为什么我们坚持用 OpenSSH 原生配置,而不是一键脚本或 GUI 工具?
2.1 不选“一键加固脚本”的三个硬理由
市面上确实存在不少号称“三秒加固 SSH”的 Bash 脚本,它们会自动修改/etc/ssh/sshd_config并重启服务。但我在给某公司做安全审计时发现,其中两个脚本存在严重逻辑缺陷:一个在禁用密码认证前,没有先验证当前用户是否已成功配置密钥登录,导致管理员自己被锁在门外;另一个则错误地将PermitRootLogin设置为without-password,却忘了PubkeyAuthentication yes这一行,结果 root 用户既不能输密码,又没有密钥可用,彻底失联。这类脚本的问题在于,它把“配置”当成了“填空题”,而忽略了 SSH 配置是一个环环相扣的“逻辑链”。PasswordAuthentication no和PubkeyAuthentication yes必须成对出现,且密钥必须真实有效;Port修改后,防火墙规则必须同步更新,否则服务就“消失”了。所以,本文坚持手动编辑配置文件,不是为了炫技,而是为了让你看清每一行代码背后的因果关系。当你亲手敲下systemctl restart sshd之前,你已经知道哪几行改动生效了,哪几个依赖条件满足了。这是一种可控的、可追溯的安全实践。
2.2 为什么放弃图形化工具(如 Webmin、Cockpit)?
Webmin 是个老牌的 Linux 管理界面,Cockpit 则是 Red Hat 主推的现代化 Web 控制台。它们确实能点点鼠标就完成 SSH 配置。但问题在于,它们的 UI 层抽象掉了太多底层细节。比如,Cockpit 的“SSH 设置”页面里,有一个“允许 root 登录”的开关,但它不会告诉你,这个开关背后实际修改的是PermitRootLogin这个参数,而该参数还有prohibit-password和forced-commands-only这两种更精细的取值。当你未来需要排查一个奇怪的登录失败时,你得先去翻 Webmin 的源码,才能搞懂它到底往配置文件里写了什么。而直接操作/etc/ssh/sshd_config,你看到的就是最终生效的文本,没有任何中间层。更重要的是,所有图形化工具本身都是额外的服务进程,它们会监听新的端口(如 Cockpit 默认用 9090),增加攻击面。我们的目标是“最小化信任”,而不是“最大化便利”。因此,全文所有操作,均基于 CentOS 系统自带的sshd、ssh-keygen、firewall-cmd和systemctl四个命令,不引入任何额外软件包。
2.3 CentOS 7 与 CentOS 8/Stream 的关键差异处理
这是实操中极易踩坑的一点。CentOS 7 使用的是传统的iptables作为防火墙后端,而 CentOS 8 及其继任者 CentOS Stream 则全面转向nftables,并通过firewalld服务进行统一管理。这意味着,如果你在网上搜到一条“开放 SSH 端口”的命令iptables -I INPUT -p tcp --dport 22 -j ACCEPT,它在 CentOS 7 上有效,但在 CentOS 8 上执行后,firewalld下次重启,这条规则就会被清空。我们必须采用firewalld的原生命令。同样,服务管理命令也有变化:CentOS 7 用service sshd restart,而 CentOS 8+ 强制使用systemctl restart sshd。本文将明确区分两种场景,并提供对应的命令。我的经验是,先运行cat /etc/redhat-release或rpm -q centos-release确认系统版本,再决定后续步骤,比盲目套用网上的“万能命令”要稳妥得多。另外,CentOS 8 默认启用了SELinux的enforcing模式,而很多旧教程会建议你直接setenforce 0来“解决问题”。这是极其危险的妥协。正确的做法是,用semanage port -a -t ssh_port_t -p tcp 2222这样的命令,告诉 SELinux “这个新端口也是合法的 SSH 端口”,而不是关掉整个安全引擎。本文所有配置,均默认在SELinux enforcing模式下通过测试。
3. 核心配置项详解与实操要点:每一行sshd_config都有它的使命
3.1 配置文件结构与安全编辑原则
SSH 的主配置文件位于/etc/ssh/sshd_config。这是一个纯文本文件,以#开头的行是注释,非注释行是实际生效的指令。最关键的编辑原则是:永远不要直接修改原始配置行,而是复制一行,取消注释并修改其值。例如,原始文件里有#Port 22,你想改成2222,正确的做法是:
#Port 22 Port 2222而不是直接删掉#改成Port 2222。这样做的好处是,当未来需要回滚时,你只需删掉新添加的那行,保留原始的注释行即可,不会丢失任何上下文信息。此外,每次修改前,务必先备份:
sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak.$(date +%Y%m%d)这个命令会生成一个带日期的备份,比如sshd_config.bak.20241025。我见过太多人因为一个错别字(比如把yes写成yse)导致sshd无法启动,而没有备份就意味着只能进单用户模式抢救。备份,是所有系统管理员的第一道护身符。
3.2 最关键的五个安全参数及其深层逻辑
下面这五行配置,构成了 SSH 安全的基石。它们不是孤立的开关,而是一个协同工作的防御体系。
Port 2222(或任意非标准端口)
把 SSH 从众所周知的 22 端口挪走,是成本最低、效果最显著的“安全模糊”(Security Through Obscurity)手段。注意,这不是“安全”,而是“降低被扫到的概率”。互联网上每分钟都有数以万计的自动化脚本,专门扫描 IP 段的 22 端口。把端口改成 2222,你的服务器瞬间就从“热门目标列表”里消失了。但这招有个前提:你必须同步更新防火墙规则。否则,外部流量根本连不到你的sshd进程。在 CentOS 7 上,你需要:sudo iptables -I INPUT -p tcp --dport 2222 -j ACCEPT sudo service iptables save在 CentOS 8+ 上,则是:
sudo firewall-cmd --permanent --add-port=2222/tcp sudo firewall-cmd --reload提示:端口号选择有讲究。避免使用 1-1023 的知名端口(需要 root 权限),也避开 1024-49151 中已被其他服务占用的端口(如 3306 MySQL, 8080 Tomcat)。2222、22222、22022 都是常见且安全的选择。我习惯用 2222,因为它好记,且与 22 有强关联性,方便自己回忆。
PermitRootLogin no
这是“禁止 root 直接登录”的铁律。root是系统的最高权限账户,一旦它的密码被猜中或泄露,攻击者就获得了对整台机器的完全控制权。正确的做法是,创建一个普通用户(如admin),用它登录,然后通过sudo执行需要特权的操作。这样,即使admin账户被攻破,攻击者也无法直接获得root权限,必须再突破一层sudo的验证(通常需要输入admin自己的密码)。no是最严格的选项,它彻底关闭了root的所有登录途径(密码、密钥都不行)。如果你确实需要root密钥登录(例如某些自动化脚本),请务必使用PermitRootLogin prohibit-password,它只允许密钥登录,彻底禁用密码。PasswordAuthentication no
这是迈向“密钥认证”的关键一步。密码认证最大的弱点是“可暴力破解”。人类很难记住一长串随机密码,所以往往会用生日、单词组合等弱密码。而密钥认证,其安全性基于数学难题(RSA 或 ECDSA 算法),一个 2048 位的 RSA 私钥,其破解难度远超宇宙年龄。但请注意,PasswordAuthentication no必须在你已经成功配置好密钥登录之后才能启用。否则,你将失去所有登录方式。如何验证密钥已生效?最简单的方法是:在客户端(你的本地电脑)用ssh -i ~/.ssh/id_rsa user@server_ip测试连接。如果能免密登录,说明密钥没问题,此时再改这个参数。PubkeyAuthentication yes
这是密钥认证的总开关。它必须为yes,否则前面生成的密钥毫无意义。这个参数默认就是yes,但为了保险起见,我们还是要显式地写出来,确保它没有被意外注释掉。同时,它还依赖于另一个参数AuthorizedKeysFile,它指定了公钥存放的位置,默认是.ssh/authorized_keys。这意味着,你生成的公钥内容,必须被追加到目标用户的家目录下的这个文件里。sudo编辑时,一定要确认你编辑的是user用户的~/.ssh/authorized_keys,而不是root的。MaxAuthTries 3与LoginGraceTime 60
这两个参数共同构成了“防暴力破解”的第一道闸门。MaxAuthTries 3表示,一个连接会话内,最多允许尝试 3 次密码或密钥认证。超过 3 次,连接就会被强制断开。LoginGraceTime 60则规定,从 TCP 连接建立开始,用户只有 60 秒的时间来完成整个认证过程(输入用户名、密码、响应挑战等)。如果超时,连接也会被丢弃。这两个参数联手,极大地增加了自动化脚本暴力破解的难度和成本。想象一下,一个脚本每秒发起 10 个连接,每个连接只能试 3 次,那么要试完 1000 个密码,它至少需要1000 / 3 ≈ 334个连接,耗时远超 60 秒。而频繁的连接请求,很容易被fail2ban这样的工具捕获并封禁 IP。
3.3 其他不容忽视的增强型参数
除了上述五大核心,以下参数能进一步提升健壮性和可维护性:
ClientAliveInterval 300与ClientAliveCountMax 3:防止“僵尸连接”。前者表示服务器每 300 秒(5 分钟)向客户端发送一次心跳包;后者表示,如果连续 3 次心跳都得不到响应,服务器就主动断开这个连接。这能有效清理因网络中断、客户端崩溃等原因遗留的无效连接,释放系统资源。UseDNS no:禁用反向 DNS 查询。默认情况下,sshd会在每次登录时,尝试将客户端的 IP 地址解析成域名。这个过程在网络状况不佳时可能耗时数秒,导致登录卡顿。对于绝大多数内部网络或云环境,IP 地址本身已足够标识客户端,关闭此功能可显著提升登录响应速度。AllowUsers admin deploy:白名单机制。明确指定哪些用户可以登录 SSH。例如,AllowUsers admin deploy表示,只有admin和deploy这两个用户能通过 SSH 登录。这比DenyUsers(黑名单)更安全,因为白名单是“只放行已知可信者”,而黑名单是“阻止已知恶意者”,后者永远无法穷举所有潜在威胁。
4. 实操全流程:从零开始,完成一次完整的 SSH 安全加固
4.1 前期准备与环境确认
在动任何配置之前,我们必须确保手头有一条“逃生通道”。最稳妥的方式,是保持一个已登录的、具有sudo权限的会话窗口(我们称之为“守护窗口”)始终打开,不关闭。所有后续的修改和重启操作,都在另一个新打开的终端窗口(“操作窗口”)中进行。这样,万一sshd启动失败,你还能在“守护窗口”里抢救。
第一步,确认当前系统版本和 SSH 服务状态:
# 查看系统版本 cat /etc/redhat-release # 输出示例:CentOS Linux release 7.9.2009 (Core) # 查看 SSH 服务状态 sudo systemctl status sshd # 关键看两行:Active: active (running) 和 Loaded: loaded (/usr/lib/systemd/system/sshd.service; enabled) # 如果是 inactive,先启动:sudo systemctl start sshd && sudo systemctl enable sshd第二步,检查当前的 SSH 配置是否已被修改过:
# 查看当前生效的配置(会显示所有非注释、非默认值的行) sudo sshd -T | grep -E "(port|permitrootlogin|passwordauthentication|pubkeyauthentication)" # 输出示例: # port 22 # permitrootlogin yes # passwordauthentication yes # pubkeyauthentication yes这个命令非常有用,它能让你一眼看清当前的真实配置,而不必在长长的sshd_config文件里大海捞针。
4.2 创建普通用户与密钥对生成
我们不再用root登录,所以首先要创建一个普通用户。这里以admin为例:
# 创建用户 admin,并为其创建家目录和默认 shell sudo useradd -m -s /bin/bash admin # 为 admin 设置一个强密码(系统会提示你输入两次) sudo passwd admin # 将 admin 加入 wheel 组,使其拥有 sudo 权限 sudo usermod -aG wheel admin接下来,在你的本地电脑(即你将要用来连接服务器的那台机器)上,生成一对新的 SSH 密钥。切记,私钥永远只存在于你的本地电脑,绝不能上传到服务器!
# 在本地电脑的终端中执行(不是在服务器上!) # 生成一个 4096 位的 RSA 密钥对,-C 参数用于添加注释(通常是你的邮箱) ssh-keygen -t rsa -b 4096 -C "your_email@example.com" # 按回车接受默认保存路径 ~/.ssh/id_rsa # 此时会提示你输入一个“passphrase”(密钥密码)。强烈建议设置一个! # 这相当于给你的私钥加了一把锁。即使别人拿到了你的私钥文件,没有这个密码也打不开。执行完毕后,你的本地电脑上会生成两个文件:
~/.ssh/id_rsa:这是你的私钥,绝对保密,权限应为600(chmod 600 ~/.ssh/id_rsa)。~/.ssh/id_rsa.pub:这是你的公钥,可以放心分发,它会被放到服务器上。
4.3 公钥部署与密钥登录验证
现在,我们需要把公钥内容,安全地复制到服务器上admin用户的authorized_keys文件中。最推荐、最安全的方法是使用ssh-copy-id命令:
# 在本地电脑执行(替换 your_server_ip 为服务器的真实 IP) ssh-copy-id -i ~/.ssh/id_rsa.pub admin@your_server_ip # 它会提示你输入 admin 用户的密码。输入后,公钥就自动追加到服务器的 ~/.ssh/authorized_keys 里了。如果ssh-copy-id不可用(某些精简版系统),我们可以手动操作:
# 在本地电脑,查看公钥内容 cat ~/.ssh/id_rsa.pub # 复制输出的整行内容(以 ssh-rsa 开头,以你的邮箱结尾) # 登录到服务器(用密码方式) ssh admin@your_server_ip # 在服务器上,创建 .ssh 目录并设置正确权限 mkdir -p ~/.ssh chmod 700 ~/.ssh # 创建 authorized_keys 文件,并粘贴刚才复制的公钥内容 echo "ssh-rsa AAAAB3NzaC1yc2E...your_email@example.com" >> ~/.ssh/authorized_keys # 设置文件权限 chmod 600 ~/.ssh/authorized_keys # 退出 exit最后,回到本地电脑,测试密钥登录是否成功:
# 尝试用密钥登录(-i 指定私钥路径) ssh -i ~/.ssh/id_rsa admin@your_server_ip # 如果一切顺利,你应该能直接进入服务器,无需输入密码。 # 这时,你可以运行 `whoami` 确认身份,运行 `sudo whoami` 确认 `sudo` 权限是否正常。注意:如果遇到
Permission denied (publickey)错误,请按顺序排查:1. 确认sshd_config中PubkeyAuthentication yes已开启;2. 确认~/.ssh/authorized_keys文件权限是600;3. 确认~/.ssh目录权限是700;4. 确认id_rsa.pub的内容已完整、无误地复制到了authorized_keys中,没有多余的空格或换行。
4.4 修改核心配置并重启服务
现在,密钥登录已验证成功,我们可以放心地修改sshd_config了。在服务器上,用sudo vi /etc/ssh/sshd_config打开配置文件。
找到并修改以下行(按前面 3.2 节的建议,采用“注释+新增”的方式):
#Port 22 Port 2222 #PermitRootLogin yes PermitRootLogin no #PasswordAuthentication yes PasswordAuthentication no #PubkeyAuthentication yes PubkeyAuthentication yes #MaxAuthTries 6 MaxAuthTries 3 #LoginGraceTime 2m LoginGraceTime 60 #UseDNS yes UseDNS no #AllowUsers AllowUsers admin修改完成后,最重要的一步来了:语法检查。在重启服务前,必须确保配置文件没有语法错误,否则sshd会拒绝启动。
# 运行配置文件语法检查 sudo sshd -t # 如果输出为空,或者显示 "syntax ok",说明配置正确。 # 如果报错,例如 "line XX: Bad configuration option: xxx",请立即根据提示修正。语法检查通过后,重启 SSH 服务:
# CentOS 7 sudo service sshd restart # CentOS 8+ sudo systemctl restart sshd4.5 防火墙与 SELinux 的同步配置
SSH 端口变了,防火墙必须跟上。根据你的系统版本,执行对应命令:
CentOS 7:
# 添加新端口规则 sudo iptables -I INPUT -p tcp --dport 2222 -j ACCEPT # 保存规则,使其在重启后依然有效 sudo service iptables saveCentOS 8+:
# 添加永久规则 sudo firewall-cmd --permanent --add-port=2222/tcp # 重新加载防火墙配置 sudo firewall-cmd --reload # 验证规则是否生效 sudo firewall-cmd --list-ports # 输出应包含 2222/tcp如果SELinux处于enforcing模式(sudo sestatus查看),还需要告诉它新端口是合法的:
# 安装 policycoreutils-python-utils(如果尚未安装) sudo yum install -y policycoreutils-python-utils # 将 2222 端口添加到 ssh_port_t 类型 sudo semanage port -a -t ssh_port_t -p tcp 2222 # 验证 sudo semanage port -l | grep ssh_port_t # 输出应包含 2222 tcp4.6 最终验证与连接测试
现在,所有配置都已完成。我们需要用一个全新的、干净的连接来测试最终效果。
第一步:关闭所有已有的 SSH 连接窗口。包括那个“守护窗口”。我们要模拟一个完全陌生的访问者。
第二步:在本地电脑,尝试用新端口和密钥登录:
# 注意:-p 参数指定端口,-i 指定私钥 ssh -p 2222 -i ~/.ssh/id_rsa admin@your_server_ip如果能成功登录,恭喜,你的加固工作已经成功了 90%。
第三步:进行破坏性测试,验证安全策略是否生效:
- 尝试用
root用户登录:ssh -p 2222 root@your_server_ip—— 应该立刻被拒绝,提示Permission denied (publickey)。 - 尝试用
admin用户,但用密码登录:ssh -p 2222 admin@your_server_ip—— 应该提示Permission denied (publickey),因为密码认证已关闭。 - 尝试用错误的私钥登录:
ssh -p 2222 -i ~/.ssh/id_rsa_wrong admin@your_server_ip—— 应该失败,并且在服务器端的/var/log/secure日志里,能看到Failed publickey的记录。
第四步:检查日志,确认一切按预期运行:
# 在服务器上,实时查看 SSH 日志 sudo tail -f /var/log/secure # 然后在本地电脑,再发起一次成功的登录。 # 你应该能看到类似这样的记录: # Accepted publickey for admin from 192.168.1.100 port 54321 ssh2: RSA SHA256:xxx # 这证明,登录是通过公钥认证完成的,且记录了来源 IP 和端口,便于日后审计。5. 常见问题与独家排查技巧实录:那些文档里不会写的“血泪教训”
5.1 “Connection refused” 错误:端口不通的七种可能
这是最常遇到的错误,意味着你的客户端根本连不上服务器的sshd进程。原因远不止“端口没开”那么简单。
| 现象 | 最可能原因 | 排查命令 | 解决方案 |
|---|---|---|---|
ssh: connect to host x.x.x.x port 2222: Connection refused | sshd服务未运行 | sudo systemctl status sshd | sudo systemctl start sshd |
| 同上 | sshd正在监听 22 端口,而非 2222 | sudo ss -tlnp | grep :2222 | 检查sshd_config,确认Port 2222已生效并重启了服务 |
| 同上 | 防火墙(iptables/firewalld)未放行 2222 端口 | sudo ss -tlnp | grep :2222+sudo firewall-cmd --list-ports | 按 4.5 节配置防火墙 |
| 同上 | 云服务器安全组未放行 2222 端口 | 登录云厂商控制台,检查安全组规则 | 在控制台中添加入方向规则:端口 2222,协议 TCP,源 IP0.0.0.0/0(或你的 IP) |
| 同上 | SELinux阻止了新端口 | sudo sestatus+sudo ausearch -m avc -ts recent | grep ssh | 按 4.5 节配置semanage port |
| 同上 | sshd进程被kill -9后,systemd未自动拉起 | sudo systemctl status sshd | sudo systemctl enable sshd确保开机自启 |
| 同上 | 服务器监听的是127.0.0.1:2222(仅本地),而非0.0.0.0:2222(所有接口) | sudo ss -tlnp | grep :2222 | 检查sshd_config中是否有ListenAddress 127.0.0.1,如有,注释掉或改为ListenAddress 0.0.0.0 |
实操心得:我曾经在一个客户现场,花了整整两个小时排查这个问题。最后发现,是客户自己写的监控脚本,每天凌晨会自动执行
iptables -F清空所有规则,而他忘了把 SSH 规则加到持久化配置里。所以,firewall-cmd --reload或service iptables save这类“保存”操作,绝不是可选项,而是必选项。
5.2 “Permission denied (publickey)” 错误:密钥失效的四大元凶
这个错误表明,sshd接收到了你的密钥,但拒绝了它。原因通常很隐蔽。
元凶一:
~/.ssh/authorized_keys文件权限错误
这是最常见的原因。sshd出于安全考虑,会严格检查这个文件的权限。它必须是600(即-rw-------),且其父目录~/.ssh必须是700(drwx------)。如果权限太宽松(比如644或755),sshd会直接忽略该文件,仿佛它不存在。修复命令:chmod 600 ~/.ssh/authorized_keys && chmod 700 ~/.ssh。元凶二:
sshd_config中AuthorizedKeysFile路径被修改
默认路径是.ssh/authorized_keys,但有些管理员会为了集中管理,把它改成/etc/ssh/keys/%u/authorized_keys。如果你不知道这个改动,就会把公钥放错地方。排查方法:sudo sshd -T \| grep authorizedkeysfile。元凶三:SELinux 上下文错误
即使文件权限正确,如果~/.ssh/authorized_keys文件的 SELinux 上下文类型不对(比如是user_home_t而不是ssh_home_t),sshd也会拒绝读取。修复命令:sudo restorecon -Rv ~/.ssh。这个命令会递归地将~/.ssh目录及其内容恢复为正确的 SELinux 上下文。元凶四:客户端私钥格式不兼容
较新的 OpenSSH(8.8+)默认使用ed25519算法,而一些老旧的 CentOS 7 系统可能不支持。如果你在新电脑上生成了ed25519密钥,却在旧服务器上用,就会失败。解决方案:在生成密钥时,明确指定rsa算法,ssh-keygen -t rsa -b 4096。
5.3 “Connection closed by x.x.x.x port 22” 错误:登录后立即断开
这通常发生在你成功输入密码或密钥后,连接瞬间被服务器关闭。根本原因,是服务器端的sshd进程在认证成功后,试图启动一个 shell,但失败了。
最常见原因:用户的默认 shell 被禁用或不存在
检查admin用户的 shell:getent passwd admin。输出的最后一段应该是/bin/bash。如果它是/sbin/nologin或/bin/false,那就意味着这个用户被禁止登录交互式 shell。修复:sudo usermod -s /bin/bash admin。另一个原因:“守护窗口”被意外关闭
如果你在“守护窗口”里执行了sudo systemctl restart sshd,而这个窗口恰好是通过root用户建立的,那么重启后,root的会话会被终止,导致你看到“Connection closed”。这不是错误,只是会话生命周期结束。只要你的新配置是正确的,用admin用户重新连接即可。
5.4 日志分析速查表:读懂/var/log/secure的关键线索
/var/log/secure是 SSH 的“黑匣子”,所有登录尝试都会被记录。学会快速阅读它,是故障排查的核心技能。
| 日志片段 | 含义 | 安全含义 |
|---|---|---|
Failed password for root from 192.168.1.100 port 54321 ssh2 | root用户从该 IP 尝试密码登录失败 | 高风险!说明有人在暴力破解 root 密码。应立即检查该 IP 是否可疑,并考虑用fail2ban封禁。 |
Accepted publickey for admin from 192.168.1.100 port 54321 ssh2: RSA SHA256:xxx | admin用户通过公钥成功登录 | 正常行为。记录中的SHA256:xxx是公钥指纹,可用于事后核对登录者身份。 |
Connection closed by authenticating user admin 192.168.1.100 port 54321 [preauth] | 用户在认证完成前就断开了连接 | 通常是网络不稳定或客户端主动取消。但如果大量出现,可能是扫描器在探测。 |
fatal: Unable to negotiate with 192.168.1.100 port 54321: no matching key exchange method found | 客户端与服务端支持的加密算法不兼容 | 通常是客户端太新(如新版 OpenSSH),服务端太旧(如 CentOS 7 的 OpenSSH 5.3)。需在sshd_config中添加KexAlgorithms参数,启用更多算法。 |
个人体会:我养成了一个习惯,每次完成一次重要的 SSH 配置后,都会在
/var/log/secure里搜索自己的 IP 地址,看看过去 24 小时内,有没有任何异常的登录尝试。这就像给服务器装了一个简易的“入侵检测系统”。它不需要额外软件,只需要你养成一个简单的日志查看习惯。