接手一台暴露在公网的CentOS服务器,默认的SSH 22端口和密码登录无异于在门口挂了一把随时能被撬开的锁。安全加固不是可选项,而是上线前的必修课。我们直接切入正题,从最薄弱的环节开始,把远程访问的风险降到最低。

修改SSH默认端口,避开扫描枪口

全网扫描工具24小时不停歇地探测22端口,一旦发现,紧接着就是暴力破解。把端口改成一个高位、不常用的数值,能直接过滤掉90%以上的自动化攻击。编辑SSH配置文件:

vi /etc/ssh/sshd_config

找到 #Port 22 这一行,去掉注释符 #,把22改成50000到65535之间的一个数字,比如 Port 26890。不要使用2222、22222这类已被攻击者纳入字典的常见替代端口。修改后保存退出,务必在防火墙中放行新端口,并保留当前连接,重启SSH服务前先不要断开现有会话,否则一旦配置出错,服务器就失联了。

SELinux端口上下文与防火墙规则联动

很多人改完端口重启SSH服务失败,排查半天发现是SELinux在阻拦。非标准端口需要向SELinux注册上下文,否则sshd进程无法绑定。执行以下命令添加策略:

semanage port -a -t ssh_port_t -p tcp 26890

如果系统提示semanage命令不存在,先安装policycoreutils-python包。完成后,再配置防火墙。如果使用firewalld,直接移除ssh服务,改用端口规则更精确:

firewall-cmd --permanent --remove-service=ssh
firewall-cmd --permanent --add-port=26890/tcp
firewall-cmd --reload

现在可以安全地重启SSH服务了:

systemctl restart sshd

新开一个终端,用新端口测试登录,确认无误后再关闭旧连接。

彻底禁用密码登录,只信任密钥

无论密码多复杂,都存在被猜解或截获的可能。密钥对认证是目前最可靠的远程验证机制。在本地电脑生成密钥对,如果已经有密钥则跳过:

ssh-keygen -t ed25519 -C "your-server-admin"

ed25519算法比传统RSA更安全且性能更好。将公钥上传到服务器:

ssh-copy-id -i ~/.ssh/id_ed25519.pub -p 26890 root@服务器IP

成功用密钥登录后,再次编辑 /etc/ssh/sshd_config,进行三项关键修改:

PubkeyAuthentication yes
PasswordAuthentication no
PermitRootLogin prohibit-password

这三行分别表示启用密钥认证、关闭密码认证、仅允许root用密钥登录。如果不想root直接登录,可以把第三项设为 no,然后创建一个普通用户并赋予sudo权限。修改后重启sshd服务生效。从此,任何没有对应私钥的访问尝试都会被直接拒绝,暴力破解工具连尝试密码的机会都没有。

配置Fail2Ban构建动态防御

即使改了端口,仍然会有扫描器发现并尝试连接。Fail2Ban通过监控日志,在短时间内检测到多次失败尝试后,自动在防火墙层面封禁来源IP一段时间。安装并配置:

yum install epel-release -y
yum install fail2ban -y

复制默认配置文件进行自定义:

cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local

编辑 jail.local,重点关注SSH相关配置段。建议设置如下参数:

[sshd]
enabled = true
port = 26890
maxretry = 3
bantime = 86400
findtime = 600

含义是在600秒内,如果有任何IP向26890端口发起3次失败登录,就封禁该IP一整天。这个封禁时长足以让大多数自动化工具放弃目标。启动并设置开机自启:

systemctl enable fail2ban
systemctl start fail2ban

用 fail2ban-client status sshd 可以随时查看当前封禁列表。这套机制让你的服务器从被动挨打变成了主动还击。

利用TCP Wrappers做访问控制兜底

CentOS自带的TCP Wrappers提供了主机级别的访问控制,在iptables和firewalld之前生效,可作为最后一道闸门。编辑 /etc/hosts.allow,只允许特定IP或IP段访问SSH:

sshd: 192.168.1.0/24
sshd: 你的固定办公IP

再编辑 /etc/hosts.deny,拒绝所有其他来源:

sshd: ALL

规则是按顺序匹配的,先检查allow文件,命中即放行,未命中再检查deny文件。如果你的办公网络IP不固定,这条策略需要谨慎使用,否则可能把自己锁在外面。对于有固定跳板机或堡垒机的环境,这是成本最低的访问控制手段。

锁定关键系统文件,防止篡改

攻击者一旦获取权限,往往会替换系统命令或植入后门。使用chattr命令将关键配置文件锁定,即使是root用户也无法修改,除非先解锁。加固SSH配置文件:

chattr +i /etc/ssh/sshd_config

同样锁定 /etc/hosts.allow 和 /etc/hosts.deny。需要修改时,用 chattr -i 临时解锁,改完立即重新锁定。这个操作虽然简单,却能有效阻止攻击者修改SSH配置开启密码登录或添加后门账户。

实施最小权限原则与用户审计

远程访问安全不仅是防外部入侵,内部权限管理同样重要。检查系统中所有可登录的用户,清理无用账户:

cat /etc/passwd | grep -v nologin | grep -v false

除了必要的管理用户,其余全部设为nologin。对于必须登录的用户,严格限制其sudo权限范围,不要随意赋予ALL权限。编辑 /etc/sudoers 时务必使用 visudo 命令,它会进行语法检查,防止配置错误导致sudo瘫痪。例如,只允许某个用户执行特定重启服务的命令:

username ALL=(ALL) /usr/bin/systemctl restart nginx

开启命令历史记录审计,在 /etc/profile 末尾添加:

export HISTTIMEFORMAT="%F %T `whoami` "

这样每条历史命令都会带上精确到秒的时间戳和执行用户,事后追溯有据可查。

SSH连接空闲超时与会话管理

运维人员经常开着SSH会话离开工位,这给物理层面的未授权访问留下了窗口。在 /etc/ssh/sshd_config 或用户的 ~/.ssh/config 中配置客户端存活探测和超时断开:

ClientAliveInterval 300
ClientAliveCountMax 0

服务器每300秒向客户端发送一个探测包,如果客户端无响应,立即断开连接。这个设置能有效防止因网络中断或人为疏忽导致的会话悬挂。同时,在个人电脑的SSH客户端配置中加上 ServerAliveInterval 60,防止因为本地网络波动而频繁断开。

日志监控与实时告警

所有加固措施部署完毕后,持续的监控才能保证安全状态不退化。配置logwatch或直接编写简单的脚本监控 /var/log/secure 中的异常模式。至少要做到每天检查一次认证日志,关注关键词“Failed password”和“Invalid user”。如果发现大量来自同一IP的尝试,即使Fail2Ban已经在处理,也要手动分析一下这个IP的来源和尝试的用户名规律,这往往是攻击者在对你的服务器进行针对性探测。将日志同步到远程日志服务器或云日志服务,防止攻击者入侵后清理本地日志销毁证据。

完成以上步骤后,你的CentOS服务器远程访问安全等级已经超越了绝大多数公网主机。安全是一个持续对抗的过程,定期检查配置是否被篡改、关注新发布的漏洞信息、及时更新系统补丁,这些日常工作同样重要。把每一步都落到实处,而不是仅仅当作一次性的配置任务,才能真正守住服务器的第一道防线。