在日常服务器运维中,SSH服务作为最常见的远程管理入口,其安全性至关重要。面对层出不穷的SSH漏洞扫描与攻击,直接升级SSH服务端版本有时会因操作系统版本限制而遇到阻碍。一个更为直接且有效的加固思路是:既然SSH通常只允许特定的运维或开发人员访问,那么通过严格的网络层访问控制来限定源IP,就能极大地收缩攻击面,提升整体安全水位。
本文将详细介绍如何利用Linux系统内置的iptables防火墙,通过创建自定义链的方式,实现SSH端口访问的精细化管理。这种方法不仅能有效防御恶意扫描,还能让防火墙规则结构更清晰、管理更安全。
一键部署脚本:快速设置SSH访问白名单
首先,我们通过一个可执行的Shell脚本快速实现核心功能。将以下脚本保存到服务器并执行,即可创建只允许指定IP访问SSH及相关端口的规则。
cat > /usr/local/bin/ssh_access.sh <<‘EOF‘
#! /bin/bash
# 核心命令:iptables -N 自定义链名
/sbin/iptables -N SSH_ACCESS
# 核心语法:iptables -I INPUT 行号 -p 协议 --dport 端口 -j 自定义链名
# 增加到INPUT链,转发SSH相关端口端口的TCP流量到SSH_ACCESS
# 先删除该策略,防止重复增加.单次执行不需要
/sbin/iptables -D INPUT -p tcp -m multiport --dport 22,1***1,1**2,1***3 -j SSH_ACCESS
/sbin/iptables -A INPUT -p tcp -m multiport --dport 22,1***1,1**2,1***3 -j SSH_ACCESS
# 先清理规则,防止重复增加规则,单次执行不需要.
/sbin/iptables -F SSH_ACCESS
# 允许访问(插入到自定义链最前面,优先匹配)
/sbin/iptables -I SSH_ACCESS 1 -p tcp -s 10.***.***.252 -m multiport --dport 22,1***1,1**2,1***3 -j ACCEPT
/sbin/iptables -I SSH_ACCESS 1 -p tcp -s 10.***.***.253 -m multiport --dport 22,1***1,1**2,1***3 -j ACCEPT
/sbin/iptables -I SSH_ACCESS 1 -p tcp -s 10.***.***.254 -m multiport --dport 22,1***1,1**2,1***3 -j ACCEPT
/sbin/iptables -I SSH_ACCESS 1 -p tcp -s 127.0.0.1 -m multiport --dport 22,1***1,1**2,1***3 -j ACCEPT
# 禁止其他所有IP访问这几个端口
/sbin/iptables -A SSH_ACCESS -p tcp -m multiport --dport 22,1***1,1**2,1***3 -j DROP
EOF
chmod u+x /usr/local/bin/ssh_access.sh
/usr/local/bin/ssh_access.sh
# 为了防止访问控制失效,定时启用该控制
echo “00 02 * * * /usr/local/bin/ssh_access.sh >/dev/null 2>&1” >> /var/spool/cron/root
脚本解析:
- 创建自定义链
SSH_ACCESS,用于专门管理SSH访问规则。
- 在
INPUT链中添加规则,将目标端口为22,1*1,1*2,13的TCP流量跳转到SSH_ACCESS链处理。
- 在
SSH_ACCESS链中,首先插入规则(-I)允许特定IP(如10.***.***.252-254和本地回环127.0.0.1)。
- 最后追加规则(
-A)拒绝所有其他来源的IP访问这些端口。
- 通过
cron定时任务确保规则每天生效,避免因重启或其他操作导致规则丢失。
原理解析:为什么使用自定义链?
直接在INPUT链中堆砌大量规则会让管理变得混乱,增删改时容易误操作,影响其他服务。使用自定义链的核心优势在于规则隔离与归类管理。
核心思路:
- 创建专属链:为特定功能(如SSH访问控制)创建一个独立的链(例如
PORT_ACCESS)。
- 流量跳转:在
INPUT链中只用一条规则,将符合条件的流量(如访问22端口)JUMP到自定义链。
- 独立管理:所有关于该功能的规则(允许谁、拒绝谁)都在自定义链内进行增删改查,与
INPUT链的其他规则互不干扰。
- 逻辑清晰:自定义链只处理转发来的流量,不影响
INPUT链上其他服务(如Web服务的80/443端口)的原有规则。
下面,我们以CentOS 6系统为例,分解这一标准管理方式的每一步操作。
实战演练:逐步配置iptables自定义链
以下命令均需root权限执行。
步骤1:创建自定义链
使用-N(New)选项创建新链,链名应具有描述性。
iptables -N PORT_ACCESS
执行后,使用 iptables -L -n 可以看到列表中新增了PORT_ACCESS链。
这是连接INPUT主链与自定义链的关键步骤。我们需要在INPUT链的合适位置插入一条跳转规则。
# 核心语法:iptables -I INPUT 行号 -p 协议 --dport 端口 -j 自定义链名
# 插入到INPUT链第5行(具体行号请根据实际情况调整)
iptables -I INPUT 5 -p tcp --dport 22 -j PORT_ACCESS
关键点:
- 确定行号:先用
iptables -L INPUT --line-numbers -n 查看现有规则,将跳转规则插入到不影响已有核心规则(如允许localhost、已有白名单)的位置。
- 跳转逻辑:匹配到该规则的流量将进入
PORT_ACCESS链进行判决,执行完该链的规则后,若未匹配,则返回INPUT链继续向下匹配。
步骤3:在自定义链内添加规则
现在,所有关于22端口的访问规则都可以安全地添加到PORT_ACCESS链中。
# 1. 允许特定IP访问(插入到链首,优先匹配)
iptables -I PORT_ACCESS 1 -p tcp -s 10.***.***.*** --dport 22 -j ACCEPT
# 2. 禁止其他所有IP访问(追加到链尾,作为兜底策略)
iptables -A PORT_ACCESS -p tcp --dport 22 -j DROP
注意:PORT_ACCESS链内的规则仅对从INPUT链跳转过来的22端口流量生效,不会干扰到INPUT链上80、443等其他端口的规则。
步骤4:验证规则配置
检查规则是否按预期生效。
# 查看INPUT链,确认跳转规则存在
iptables -L INPUT --line-numbers -n
# 查看PORT_ACCESS自定义链的所有规则
iptables -L PORT_ACCESS --line-numbers -n
PORT_ACCESS链的预期输出示例:
num target prot opt source destination
1 ACCEPT tcp -- 10.***.***.*** 0.0.0.0/0 tcp dpt:22
2 DROP tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:22
步骤5:保存规则(CentOS 6)
配置完成后,必须保存到配置文件,否则重启后规则会丢失。
service iptables save
# 验证保存结果
cat /etc/sysconfig/iptables | grep PORT_ACCESS
自定义链的日常管理
规则隔离后,日常运维操作就变得安全且简单。
1. 新增规则
# 追加一条规则到链尾
iptables -A PORT_ACCESS -p tcp -s 192.168.1.100 --dport 22 -j ACCEPT
# 插入一条规则到链的指定行(如第2行)
iptables -I PORT_ACCESS 2 -p tcp -s 192.168.1.200 --dport 22 -j ACCEPT
2. 删除规则(推荐按行号删除)
# 第一步:查看规则行号
iptables -L PORT_ACCESS --line-numbers -n
# 第二步:按行号删除(例如删除第3条规则)
iptables -D PORT_ACCESS 3
3. 修改规则
iptables没有直接修改命令,需要通过“删除旧规则,插入新规则”来实现。
iptables -D PORT_ACCESS 3
iptables -I PORT_ACCESS 3 -p tcp -s 10.0.1.0/24 --dport 22 -j ACCEPT
如何安全地删除自定义链?
如果你想移除整个自定义链及其规则,必须按顺序执行以下三步:
- 删除INPUT链中的跳转规则。
- 清空自定义链内的所有规则。
- 删除空的自定义链。
# 1. 删除跳转规则(假设它在INPUT链第5行)
iptables -D INPUT 5
# 2. 清空自定义链PORT_ACCESS
iptables -F PORT_ACCESS
# 3. 删除自定义链PORT_ACCESS
iptables -X PORT_ACCESS
# 4. 保存配置
service iptables save
优势总结与注意事项
✅ 核心优势:
- 安全隔离:避免在
INPUT链中直接操作时误删、误改影响服务器远程连接或其他业务的关键规则。
- 管理清晰:将不同功能的规则(如端口访问控制、IP黑名单、CDN白名单)归类到不同自定义链,结构一目了然。
- 灵活控制:只需在
INPUT链中启用或禁用跳转规则,即可快速开关整套自定义规则集。
⚠️ 注意事项:
- 跳转规则是前提:创建了自定义链,必须在
INPUT或FORWARD等主链中添加-j跳转,否则自定义链不会生效。
- 行号需谨慎:插入跳转规则时,要避开已有规则的关键位置,防止打乱默认的放行策略(如
lo接口、已建立的连接)。
- 配置要保存:任何变更后,别忘记执行
service iptables save(CentOS 6)或 iptables-save > /etc/sysconfig/iptables(其他发行版)来持久化。
- 匹配要精准:跳转规则的条件(如端口、协议)应精确限定,避免将无关流量引入自定义链,导致意外拒绝。
总结与命令速查
在生产环境中,使用iptables自定义链来管理规则是一种标准且推荐的最佳实践。它特别适用于规则数量较多、需要精细化管理访问控制的场景。
| 操作 |
命令示例 |
| 创建自定义链 |
iptables -N PORT_ACCESS |
| 设置流量跳转 |
iptables -I INPUT 5 -p tcp --dport 22 -j PORT_ACCESS |
| 自定义链内加规则 |
iptables -A PORT_ACCESS -s 192.168.1.1 -j ACCEPT |
| 查看链规则(带行号) |
iptables -L PORT_ACCESS --line-numbers -n |
| 按行号删除规则 |
iptables -D PORT_ACCESS 3 |
| 清空自定义链 |
iptables -F PORT_ACCESS |
| 删除自定义链 |
iptables -X PORT_ACCESS |
| 永久保存配置(CentOS6) |
service iptables save |
通过上述方法,你可以 confidently(有信心地)管理服务器防火墙规则,在提升安全性的同时,确保运维操作本身的安全与高效。如果你在实践中遇到更复杂的场景或有其他想法,欢迎在云栈社区的相关板块与大家交流探讨。