1. 为什么需要精细化SSH访问控制
每次服务器被暴力破解攻击时,看着日志里密密麻麻的失败登录尝试,我都恨不得把SSH端口直接关掉。但现实是运维团队需要远程管理,开发人员偶尔也要排查问题。这时候基于IP段的精细化访问控制就成了救命稻草。
传统的做法是直接开放整个SSH端口,或者简单限制几个固定IP。前者等于把大门敞开,后者在人员流动或出差时就变得非常麻烦。去年我们公司就发生过因为某位运维同事居家办公,临时添加了他的家庭IP,结果忘记删除导致的安全隐患。
firewall-cmd的rich-rule功能让我找到了平衡点。比如可以把北京办公室的IP段(203.0.113.0/24)、上海研发中心的IP段(198.51.100.0/22)分别加入白名单。这样既不用为每个员工单独配置,又能避免开放整个SSH端口带来的风险。
2. 基础环境准备与配置检查
2.1 确认firewalld运行状态
在开始之前,先确保你的系统已经安装并运行着firewalld。我遇到过不少新手直接照着教程敲命令,最后发现服务根本没启动的尴尬情况。用这个命令检查:
systemctl status firewalld如果看到"active (running)"就说明服务正常。如果没安装,在CentOS/RHEL上可以这样安装:
yum install firewalld -y systemctl enable --now firewalld2.2 备份当前防火墙规则
修改防火墙规则前一定要备份!这是我用血泪教训换来的经验。有次误操作导致自己也被锁在服务器外面,最后只能去机房接显示器操作。备份命令很简单:
firewall-cmd --list-all > firewall_backup_$(date +%Y%m%d).txt这个命令会把当前所有规则保存到带日期的文件里。建议同时备份默认区域配置文件:
cp /etc/firewalld/zones/public.xml /etc/firewalld/zones/public.xml.bak3. 三种IP限制模式实战
3.1 单IP授权模式
适合给特定管理员或固定设备使用。比如只允许运维主管的办公电脑(IP:192.168.1.100)访问:
# 先移除默认开放的SSH服务 firewall-cmd --permanent --remove-service=ssh # 添加精细规则 firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.1.100" port protocol="tcp" port="22" accept' # 重新加载配置 firewall-cmd --reload验证规则是否生效:
firewall-cmd --list-rich-rules这个模式最大的问题是容错性差。如果IP发生变化(比如从WiFi切换到有线网络),就会立即失去连接。我建议至少配置两个IP,比如办公室固定IP+笔记本电脑当前IP。
3.2 连续IP范围授权
当需要授权给一个小型团队,且他们的IP地址连续时特别有用。比如允许测试团队(IP从192.168.1.50到192.168.1.60)访问:
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.1.50-192.168.1.60" port protocol="tcp" port="22" accept'这种写法的好处是不需要计算子网掩码,直接指定起止IP即可。但要注意范围不要太大,否则就失去了精细化管理的意义。
3.3 CIDR网段授权
这是企业环境中最常用的方式。比如允许整个技术部子网(192.168.2.0/24)访问:
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.2.0/24" port protocol="tcp" port="22" accept'CIDR notation的妙处在于可以灵活控制范围大小。/24表示前24位固定(即255.255.255.0),/16表示前16位固定(255.255.0.0)。我们公司就是按部门划分网段的,技术部用192.168.2.x,市场部用192.168.3.x,这样配置规则时特别清晰。
4. 动态IP环境解决方案
4.1 结合DDNS的动态规则更新
对于在家办公的员工,IP可能经常变化。这时候可以结合DDNS服务(比如花生壳)和脚本自动化更新。假设员工使用hostname: staff001.ddns.net:
#!/bin/bash NEW_IP=$(dig +short staff001.ddns.net) OLD_RULE=$(firewall-cmd --list-rich-rules | grep "staff001") # 删除旧规则 if [ -n "$OLD_RULE" ]; then firewall-cmd --permanent --remove-rich-rule="$OLD_RULE" fi # 添加新规则 firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="'"$NEW_IP"'" port protocol="tcp" port="22" accept' firewall-cmd --reload把这个脚本加入cron,每小时执行一次即可。我在团队内部推广这个方法后,VPN使用量直接下降了70%,因为大家发现SSH访问已经足够安全便捷。
4.2 临时访问令牌机制
对于第三方合作人员临时访问的情况,可以设计一个临时令牌系统。基本思路是:
- 生成一个6小时有效期的规则
- 到期自动删除
- 通过邮件或IM发送给请求者
实现脚本示例:
#!/bin/bash REQUESTER_IP="203.0.113.45" EXPIRY=$(date -d "+6 hours" +%s) # 添加临时规则 firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="'"$REQUESTER_IP"'" port protocol="tcp" port="22" accept' # 创建定时删除任务 echo "firewall-cmd --permanent --remove-rich-rule='rule family=\"ipv4\" source address=\"$REQUESTER_IP\" port protocol=\"tcp\" port=\"22\" accept'" | at $(date -d "+6 hours" +"%H:%M")5. 高级管理与故障排查
5.1 规则优先级管理
当规则越来越多时,可能会出现冲突。比如既想屏蔽某个IP段,又想允许其中的某个特定IP。这时候规则的顺序就很重要:
# 先拒绝整个网段 firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.4.0/24" reject' # 再允许特定IP(这条规则优先级更高) firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.4.100" accept'可以通过--list-rich-rules查看当前规则顺序。如果发现规则顺序不对,可以先全部删除再按正确顺序添加。
5.2 常见问题排查
问题1:规则添加了但不生效
- 检查是否加了--permanent参数但忘记--reload
- 确认默认区域(firewall-cmd --get-default-zone)是否正确
- 查看完整日志:journalctl -u firewalld -f
问题2:把自己锁在外面
- 提前配置好带外管理(iDRAC/iLO)
- 保留一个备用管理端口(比如2222)给应急使用
- 设置cronjob每5分钟检查一次主规则,如果被删就自动恢复
问题3:规则太多导致性能下降
- 尽量合并CIDR块(把多个/24合并为/23)
- 考虑改用zone来管理不同来源
- 定期清理过期规则
6. 企业级最佳实践
在管理超过200台服务器的金融行业客户项目中,我们总结出这套流程:
- 分级管理:将服务器分为核心、重要、普通三个级别,核心级只允许跳板机IP访问
- 时间维度:办公时间(9:00-18:00)开放更大范围的IP,非工作时间限制为运维办公室IP
- 审批流程:所有规则变更需要通过工单系统审批,并自动同步到CMDB
- 自动同步:使用Ansible定期同步所有服务器的防火墙规则,确保一致性
- 审计日志:所有firewall-cmd操作记录到SIEM系统,与员工账号关联
实现时间维度控制的示例:
# 工作日9:00-18:00允许大网段访问 firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.0.0/16" port protocol="tcp" port="22" accept' --time=9:00-18:00 --weekday=Mon,Tue,Wed,Thu,Fri # 其他时间只允许运维网段 firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="10.1.1.0/24" port protocol="tcp" port="22" accept'这套方案实施后,客户服务器的SSH暴力破解尝试下降了98%,同时运维效率提高了40%,因为再也不用处理各种临时访问请求了。