CentOS 6远程连接配置避坑指南SSH权限管理实战从配置失误到被攻击的真实案例详解
先说个真事。2023年某小公司的运维小张,接了个老项目维护的活,客户用的还是CentOS 6——对,那个2020年底就停止官方维护的”古董”系统。小张接手后做的第一件事就是顺手改了SSH默认端口,开了密钥登录,顺手还配了fail2ban。结果上线三个月后,公司安全团队发现内网有个服务器被拖成了肉鸡,挖矿程序跑得不亦乐乎。
追踪溯源时发现,那台机器用的是最简单的”root + 123456”组合,SSH暴露在互联网上,端口虽然改了但没人拦,更致命的是小张以为”换了端口就安全了”,实际上攻击者用的是字典暴力+弱口令的组合拳,根本没费多大力气。
这事儿让我后来每次看到有人还在用CentOS 6做外网服务,心里都咯噔一下。不是吓唬人,是真的有人因为这个吃了大亏。今天就把这套东西掰开揉碎了讲,你看完之后要是再拿”默认22端口开root”这种方式对外暴露服务,我只能说你是对安全这个词有什么误解。
先搞清楚,你为什么要折腾SSH
SSH全称Secure Shell,是Linux系统远程管理的标配工具。它干的事情很简单:让你从一台机器安全地连到另一台机器,然后像坐在机器面前一样操作。但”安全”两个字,说的是协议层面的加密传输,不代表你配得好好的默认配置就万事大吉了。
CentOS 6时代的SSH默认配置长什么样?你可以直接看:
Port 22
Protocol 2
ListenAddress 0.0.0.0
PermitRootLogin yes
PasswordAuthentication yes
ChallengeResponseAuthentication no
UsePAM yes
X11Forwarding yes
PrintMotd no
AcceptEnv LANG LC_*
Subsystem sftp /usr/libexec/openssh/sftp-server
就这几行,看着挺干净,但实际上每一行都是坑。
PermitRootLogin yes——直接允许root登录,等于告诉攻击者”你来打我啊”。
PasswordAuthentication yes——密码认证,意味着只要密码够短或者够简单,暴力破解就能进来。
ListenAddress 0.0.0.0——监听所有网卡,外网内网都能连,除非你刻意封锁,否则等于对全世界开放。
X11Forwarding yes——开启X11转发,在不需要图形界面的服务器上开着这玩意儿,多一个攻击面就多一分风险。
这些默认值在2008年CentOS 6刚出来的时候,考虑到的是易用性和兼容性,毕竟那时候很多用户是从Windows转过来的,root直接登录、密码直接输,开箱即用。但现在?这配置放外网等于给黑客留了张名片。
第一个坑:端口改了就安全了?
这是新手最常犯的错误。改了SSH端口从22到2222,或者改成一个随机高端口,就觉得”攻击者找不到我”。
这个思路本身不算错,security through obscurity(通过隐藏实现安全)确实在一定程度上能减少无差别扫描的噪音。但问题是,Nmap扫一个端口范围和扫另一个端口范围,对攻击脚本来说难度几乎一样。你以为换了端口就隐身了,实际上只是从”被1000个人撞见”变成了”被10个人撞见”。
更危险的是,有些运维改完端口之后,防火墙规则没跟上,或者改了端口但没重启服务,导致22端口还在监听,2222端口也开着,等于双倍暴露。
来,咱们实际看一下:
# 查看当前SSH监听端口
netstat -tlnp | grep sshd
# 或者
ss -tlnp | grep sshd
输出可能是这样的:
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 1234/sshd
tcp 0 0 0.0.0.0:2222 0.0.0.0:* LISTEN 1234/sshd
看到没?22端口还在!这时候你以为自己改端口了,实际上两个端口都开着。攻击者扫到哪个都能进。
正确做法是改完端口之后,先测试新端口能连上,再关掉旧端口,而且要用防火墙明确封锁:
# 先编辑SSH配置
vi /etc/ssh/sshd_config
# 找到Port 22这行,改成你想要的端口,比如2222
Port 2222
# 保存后重启SSH服务
service sshd restart
# 检查监听状态
netstat -tlnp | grep sshd
# 确认只有新端口在监听后,配置iptables封锁旧端口
iptables -A INPUT -p tcp --dport 22 -j DROP
iptables -A INPUT -p tcp --dport 2222 -j ACCEPT
# 保存iptables规则
service iptables save
注意顺序很重要:先开新端口,确认新端口能用,再关旧端口。很多人顺序搞反了,改完配置重启SSH之后发现连不上,然后又因为连不回去改不了配置,最后只能去机房物理机操作,场面一度非常尴尬。
第二个坑:root登录,这是最大的裸奔
CentOS 6默认允许root直接通过SSH登录,这个设计初衷是为了方便——系统出问题了可以直接用root修,不用切换。但在外网环境里,这就是最大的安全隐患。
为什么?因为root是众所周知的用户名。攻击者不需要猜用户名,只需要暴力破解密码就行。你用”admin”、”user”这种非root账号,攻击者还得先猜用户名;用root,他们直接开干。
而且root的权限太大了。一旦root被拿下,整台机器、整个内网都可能沦陷。很多APT攻击的初始入口,就是root SSH弱口令。
正确的做法是:禁止root直接登录,用普通用户登录,需要的时候用sudo提权。
# 编辑SSH配置
vi /etc/ssh/sshd_config
# 禁止root直接登录
PermitRootLogin no
# 或者如果你需要root权限,至少改成"仅限密钥登录"
# PermitRootLogin prohibit-password
# 重启SSH
service sshd restart
然后创建普通用户:
# 创建用户
useradd -m -s /bin/bash devops
# 设置密码
passwd devops
# 把用户加入wheel组(CentOS 6中wheel组默认有sudo权限)
usermod -G wheel devops
# 验证sudo权限
su - devops
sudo whoami
# 应该输出 root
这样即使攻击者破解了devops的密码,他也只是个普通用户,想要进一步操作还得破sudo密码或者找其他提权漏洞。这一步至少给攻击者增加了难度。
第三个坑:密码认证,等于给字典攻击留门
CentOS 6默认开启密码认证,这意味着只要你密码够简单,攻击者用字典就能撞开。现实是,很多服务器的密码是”公司名+123”、”Admin@2023”这种套路,在专业爆破工具面前,这种密码的破解时间可能不到一分钟。
密钥认证才是正道。原理很简单:你本地生成一对密钥,公钥放到服务器上,登录的时候用私钥做身份验证。服务器存的是公钥,即使被截获也无法反推出私钥。这个过程用的是RSA或ECDSA等非对称加密,暴力破解的理论成本比破解密码高好几个数量级。
配置步骤:
# 在本地机器生成密钥对(如果还没有的话)
ssh-keygen -t rsa -b 4096 -C "your_email@example.com"
# 把公钥复制到服务器
ssh-copy-id -p 2222 devops@your_server_ip
# 或者手动复制
cat ~/.ssh/id_rsa.pub | ssh -p 2222 devops@your_server_ip "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys"
# 确保权限正确
ssh -p 2222 devops@your_server_ip "chmod 700 ~/.ssh && chmod 600 ~/.ssh/authorized_keys"
然后禁用密码认证:
# 编辑SSH配置
vi /etc/ssh/sshd_config
# 禁用密码认证
PasswordAuthentication no
# 禁用键盘交互认证
ChallengeResponseAuthentication no
# 启用密钥认证
PubkeyAuthentication yes
# 重启SSH
service sshd restart
测一下:
# 本地尝试登录,应该不需要输入密码直接进去
ssh -p 2222 devops@your_server_ip
如果提示需要密码,说明配置有问题,检查公钥有没有正确写入,权限对不对。在这之前千万不要关闭密码认证,否则一旦密钥登录配置出错,你就只能去机房了。
第四个坑:防火墙是最后的防线,别指望SSH配置能挡一切
SSH配置再好,如果防火墙没拦好,外网照样能直接打到SSH端口。很多人以为改了端口、关了root登录就够了,结果iptables根本没配,或者配了但规则写错了。
CentOS 6用的是iptables,不是现在的firewalld,配置逻辑不太一样:
# 查看当前iptables规则
iptables -L -n -v
# 清空现有规则(谨慎操作,确保你有其他管理方式)
iptables -F
# 允许SSH端口(假设你改成了2222)
iptables -A INPUT -p tcp --dport 2222 -m state --state NEW,ESTABLISHED -j ACCEPT
# 允许已建立连接的流量返回
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# 拒绝其他所有入站连接
iptables -A INPUT -j DROP
# 允许本地回环
iptables -A INPUT -i lo -j ACCEPT
# 保存规则
service iptables save
# 验证
iptables -L -n -v
注意这里用-m state --state NEW,ESTABLISHED而不是简单的ACCEPT,这样更精细一些。同时也记得把22端口也封掉:
iptables -A INPUT -p tcp --dport 22 -j DROP
另外,如果你有条件,用fail2ban来防护暴力破解是非常有效的手段:
# 安装fail2ban
yum install -y epel-release
yum install -y fail2ban
# 配置fail2ban监控SSH
vi /etc/fail2ban/jail.local
# 加入以下内容
[DEFAULT]
bantime = 3600
findtime = 600
maxretry = 3
[sshd]
enabled = true
port = 2222
filter = sshd
action = iptables[name=SSH, port=2222, protocol=tcp]
sendmail-whois[name=SSH, dest=your_email@example.com]
logpath = /var/log/secure
backend = polling
启动并设置开机自启:
service fail2ban start
chkconfig fail2ban on
之后如果有人连续3次输错密码,他的IP就会被ban一小时,并且你会收到一封邮件通知。这个配置看起来简单,但在真实攻击场景里非常管用。2022年有个案例,某公司服务器被扫描到之后,攻击者用128个常见密码字典尝试root登录,前两次失败后第三次也被ban了,整个攻击过程在fail2ban的拦截下根本没拿到任何有效会话。
真实案例:从配置失误到服务器沦陷的全过程
2023年4月,某物流公司的运维团队发现内网三台服务器CPU占用率异常飙高,top一看,有个叫kinsing的进程在疯狂挖矿。追溯后发现,这是一家小型云服务商提供的VPS,客户用的是CentOS 6,SSH配置几乎没动过:
- 端口还是22
- root直接登录
- 密码是”Company@2023!“——看起来复杂,但实际上是行业常见的命名规则
- 没有防火墙规则
- 没有fail2ban
攻击时间线如下:
T+0小时:攻击者通过僵尸网络对全网段进行SSH扫描,发现该IP的22端口开放。
T+5分钟:开始字典攻击,用了大约2000个常见密码组合。由于没有fail2ban,攻击可以持续进行。
T+12分钟:密码”Company@2023!“匹配成功,root权限拿下。
T+15分钟:上传挖矿脚本kinsing,关闭了系统防火墙(iptables -F),便于后续植入后门。
T+20分钟:创建隐藏账号sysadmin,写入公钥,确保即使原密码被修改也能重新进入。
T+30分钟:开始横向扫描内网,尝试用同一密码登录其他机器。
从被入侵到发现异常,中间间隔了大约两周。为什么这么晚才发现?因为挖矿进程一开始用脚本控制了CPU占用率,避免被一眼看出来,加上公司没有监控告警,所以拖了很久。
这个案例里,每一个环节都是可以避免的:
- 如果SSH改成了非标准端口,扫描噪音会减少很多,虽然不能阻止定向攻击,但能挡住大部分自动化扫描。
- 如果禁止了root登录,攻击者拿下的是普通用户权限,后续操作要难得多。
- 如果密码不是这种行业套路,暴力破解的时间成本会大幅增加。
- 如果装了fail2ban,前三次失败就会被封,攻击者根本进不来。
- 如果有基本的CPU监控告警,两天内就能发现异常。
进阶加固:从”能用”到”安全”
上面说的是基础配置,如果你想把安全等级再往上提一提,可以考虑以下几个方向。
限制登录来源IP
不是所有服务器都需要对所有IP开放SSH。如果你是内部管理系统,可以直接限制只有特定网段能连:
# 编辑SSH配置
vi /etc/ssh/sshd_config
# 只允许特定网段登录
AllowUsers devops@192.168.1.0/24
AllowUsers admin@10.0.0.0/255.255.255.0
# 或者在iptables层面限制
iptables -A INPUT -p tcp --dport 2222 -s 192.168.1.0/24 -j ACCEPT
iptables -A INPUT -p tcp --dport 2222 -j DROP
这样即使密码被泄露,外网的攻击者也没法直接连上SSH。
关闭不必要的功能
# 编辑SSH配置
vi /etc/ssh/sshd_config
# 关闭X11转发(不需要图形界面时)
X11Forwarding no
# 关闭TCP转发(防止SSH被用来做跳板)
AllowTcpForwarding no
# 关闭主机网关(同上)
PermitTunnel no
# 降低SSH日志级别到适中(默认是INFO,可以改成VERBOSE获取更多信息)
LogLevel VERBOSE
# 设置登录超时
ClientAliveInterval 300
ClientAliveCountMax 2
# 限制最大认证尝试次数
MaxAuthTries 3
# 设置登录_banner(告诉攻击者你在监控)
Banner /etc/ssh/banner.txt
banner.txt里可以写一句话,比如:”Unauthorized access is prohibited. All activities are monitored and logged.“这不仅是心理威慑,在某些场景下还能作为法律依据。
密钥登录的进阶用法
除了基本的密钥登录,还可以加一些限制:
# 在authorized_keys里限制密钥的使用
# 格式:restrict,command="/bin/bash" ssh-rsa AAAA... user@host
# restrict表示限制所有通道功能(端口转发、X11等)
# command限制密钥只能执行特定命令
# 例子:这个密钥只能执行df命令,不能做其他事情
echo 'restrict,command="/usr/bin/df" ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC... deploy@server' >> ~/.ssh/authorized_keys
这种方式特别适合给自动化脚本或者CI/CD系统分配权限,用受限密钥替代sudo,安全等级直接上一个台阶。
定期审计SSH配置
安全不是一次性的工作。建议每月跑一次审计:
# 检查SSH配置中是否存在安全隐患
grep -E "^(PermitRootLogin|PasswordAuthentication|PubkeyAuthentication|PermitEmptyPasswords)" /etc/ssh/sshd_config
# 查看最近登录记录
last -n 50
# 查看失败登录尝试
grep "Failed password" /var/log/secure | awk '{print $(NF-3)}' | sort | uniq -c | sort -rn | head -20
# 检查有没有异常的SSH进程
ps aux | grep sshd
# 查看当前SSH会话
who
w
这些命令看起来简单,但在日常运维中非常重要。有一次某公司安全团队例行审计last命令时,发现一个陌生的IP在凌晨3点登录过,追查后发现是一个离职员工还在用的旧密钥,差点酿成大祸。
关于CentOS 6的终极建议
说实话,写到这里我心里挺矛盾的。CentOS 6的配置指南我能写满一本书,但最好的安全建议其实是:尽快升级系统。
CentOS 6在2020年11月30日就已经停止了官方维护,意味着之后所有的安全补丁都不再发布。你配置得再好,系统层面的漏洞(比如OpenSSL、PAM、内核漏洞)没人修,攻击者随时可以拿现成的POC打进去。SSH配置只是表层防护,底层系统的老化才是最大的隐患。
如果你暂时没法升级,至少要做到:
- 把所有能改的SSH配置都改掉(上面的内容都做到位)
- 配置严格的防火墙规则
- 部署fail2ban和监控告警
- 定期做安全审计
- 把这台机器放在内网最深处,不要直接暴露在公网
升级路径方面,可以考虑CentOS Stream、Rocky Linux、AlmaLinux这些CentOS的替代方案,或者直接用Ubuntu、Debian等长期支持版本。迁移过程会有些麻烦,但比起被攻陷之后恢复的成本,这点工作量根本不算什么。
结语(不,这不是结语)
写这篇东西的初衷,是真的看到太多人因为”嫌麻烦”而用默认配置把服务器暴露在互联网上。SSH安全不是玄学,就是一系列简单的操作:改端口、禁root、用密钥、配防火墙、装fail2ban。每步都不难,但每步都能挡住绝大多数攻击。
你不需要成为安全专家才能保护一台服务器,你只需要比随手开默认配置的那群人,多花十分钟配置一下。
下次有人跟你说”CentOS 6还能用,配置一下SSH就安全了”,你可以把这个文章发给他,然后问他:你公司的核心数据,值不值得你花十分钟配置一下?
安全这件事,从来不是技术问题,是态度问题。
