Debian服务器刚装好系统,默认的防火墙策略往往是全开放的,或者只开放了SSH端口。这在生产环境中无异于裸奔。要构建可靠的网络访问安全过滤规则,核心工具就是系统自带的iptables,以及它的现代化管理前端nftables。现在新版本的Debian已经默认使用nftables作为后端,但iptables命令仍然可以通过兼容层使用。我们直接讲具体配置方法,从最基础的规则讲起,逐步构建一套完整的防护体系。
理解iptables与nftables的关系在Debian 10及以后的版本中,系统底层已经切换到nftables框架。当你执行iptables命令时,实际上是在操作nftables的兼容层。不过对于大多数管理员来说,直接用iptables语法写规则依然是最顺手的方式。如果你想用原生nftables,命令行工具是nft。两者都能达到同样的过滤效果,选择哪个取决于你的习惯。本文会同时给出两种语法的示例,方便你对照使用。
安装必要的防火墙管理工具如果你习惯用iptables语法,需要安装iptables-persistent包来保存规则,否则重启后规则会丢失。如果你决定用原生nftables,系统已经自带了nft命令,只需要启用nftables服务即可。下面是安装命令:
apt update apt install iptables-persistent -y
安装过程中会提示你是否保存当前规则,选择是即可。对于nftables用户,执行:
systemctl enable nftables systemctl start nftables清空现有规则,建立默认拒绝策略
安全配置的第一原则是白名单思维:默认拒绝所有流量,只放行明确需要的。在开始添加规则之前,先把现有的规则清空,然后设置默认策略为DROP。注意,如果你是通过SSH远程连接的,一定要先放行SSH端口,否则会立刻断开连接。正确的操作顺序如下:
# 先放行SSH端口,假设你用的是22端口 iptables -A INPUT -p tcp --dport 22 -j ACCEPT # 放行回环接口 iptables -A INPUT -i lo -j ACCEPT # 放行已建立连接的流量 iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT # 现在安全地设置默认策略 iptables -P INPUT DROP iptables -P FORWARD DROP iptables -P OUTPUT ACCEPT
这里OUTPUT链保持ACCEPT是因为服务器主动发出的流量通常是安全的,如果你有更高的安全要求,也可以对OUTPUT做限制。用nftables实现同样的逻辑:
nft add table inet filter
nft add chain inet filter input { type filter hook input priority 0 \; policy drop \; }
nft add chain inet filter forward { type filter hook forward priority 0 \; policy drop \; }
nft add chain inet filter output { type filter hook output priority 0 \; policy accept \; }
nft add rule inet filter input iif lo accept
nft add rule inet filter input ct state established,related accept
nft add rule inet filter input tcp dport 22 accept
按服务类型精确放行端口
默认拒绝策略建立后,服务器上任何服务都需要显式放行才能被外部访问。你需要梳理服务器上运行的服务,逐一开放对应端口。常见的Web服务器需要开放80和443端口:
iptables -A INPUT -p tcp --dport 80 -j ACCEPT iptables -A INPUT -p tcp --dport 443 -j ACCEPT
如果你运行了MySQL数据库且需要远程访问,应该限制来源IP,而不是向全网开放3306端口:
iptables -A INPUT -p tcp -s 192.168.1.100 --dport 3306 -j ACCEPT
这里的-s参数指定了只有来自192.168.1.100的连接才会被放行。对于nftables,对应的规则是:
nft add rule inet filter input tcp dport 80 accept nft add rule inet filter input tcp dport 443 accept nft add rule inet filter input ip saddr 192.168.1.100 tcp dport 3306 accept限制SSH访问,防止暴力破解
SSH是服务器管理的生命线,也是攻击者重点扫描的目标。除了改掉默认的22端口外,用iptables做访问频率限制非常有效。下面的规则限制每个IP每分钟只能新建3个SSH连接,超过的会被拒绝:
iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --set --name SSH iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --update --seconds 60 --hitcount 4 --name SSH -j DROP
第一条规则把新连接记录到名为SSH的列表中,第二条规则检查60秒内是否有超过3次新连接,超过就丢弃。如果你只允许特定IP段访问SSH,可以更彻底地降低风险:
iptables -A INPUT -p tcp -s 203.0.113.0/24 --dport 22 -j ACCEPT iptables -A INPUT -p tcp --dport 22 -j DROP
这样只有来自203.0.113.0/24网段的IP才能连接SSH,其他一律拒绝。nftables的限速写法更简洁:
nft add rule inet filter input tcp dport 22 ct state new limit rate 3/minute accept nft add rule inet filter input tcp dport 22 drop防范常见网络攻击
SYN洪水攻击是常见的拒绝服务攻击手段。启用SYN Cookie是内核层面的防护,在Debian上默认已经开启,你可以确认一下:
sysctl net.ipv4.tcp_syncookies
输出为1表示已启用。此外,用iptables限制SYN包的速率可以进一步缓解攻击:
iptables -A INPUT -p tcp --syn -m limit --limit 100/s --limit-burst 200 -j ACCEPT iptables -A INPUT -p tcp --syn -j DROP
这条规则允许每秒最多100个SYN包,突发上限200个,超出部分直接丢弃。对于ICMP协议,完全禁止ping虽然能隐藏主机,但会影响网络诊断。建议做速率限制而不是全部丢弃:
iptables -A INPUT -p icmp --icmp-type echo-request -m limit --limit 1/s -j ACCEPT iptables -A INPUT -p icmp --icmp-type echo-request -j DROP
碎片包攻击和无效状态包也应该过滤掉:
iptables -A INPUT -f -j DROP iptables -A INPUT -m state --state INVALID -j DROP使用ipset管理大规模IP列表
当需要封禁的IP数量达到成百上千时,逐条添加iptables规则会严重影响性能。ipset使用哈希表存储IP地址,匹配效率极高。先安装ipset工具:
apt install ipset -y
创建一个名为blacklist的IP集合,类型为hash:ip:
ipset create blacklist hash:ip
向集合中添加要封禁的IP:
ipset add blacklist 192.168.1.200 ipset add blacklist 10.0.0.50
然后在iptables规则中引用这个集合:
iptables -A INPUT -m set --match-set blacklist src -j DROP
这样所有来自blacklist集合中IP的流量都会被丢弃。ipset还支持超时自动过期,适合临时封禁:
ipset create tempblock hash:ip timeout 3600 ipset add tempblock 192.168.1.200 timeout 1800
这条命令创建了一个默认1小时过期的集合,添加的IP在1800秒后自动移除。结合前面讲的SSH限速,可以把触发频率限制的IP自动加入临时黑名单。
保存规则并设置开机自启规则配置完成后,必须持久化保存。使用iptables-persistent的话,执行:
iptables-save > /etc/iptables/rules.v4 ip6tables-save > /etc/iptables/rules.v6
ipset的集合也需要单独保存:
ipset save > /etc/iptables/ipset.conf
然后确保ipset服务开机加载:
systemctl enable ipset systemctl start ipset
对于nftables用户,配置文件在/etc/nftables.conf,直接编辑该文件写入规则,然后:
systemctl enable nftables nft -f /etc/nftables.conf构建应用层过滤规则
网络层的过滤只能控制IP和端口,应用层的攻击需要更精细的规则。string模块可以匹配数据包内容,用来拦截特定特征的恶意请求。比如拦截对特定路径的扫描:
iptables -A INPUT -p tcp --dport 80 -m string --string "/wp-admin" --algo bm -j DROP
这条规则会丢弃HTTP请求中包含/wp-admin字符串的包。不过string模块对加密流量无效,而且会消耗CPU资源,不适合高流量场景。更高效的做法是把应用层防护交给Web服务器或专门的WAF模块处理,iptables专注于网络层和传输层的快速过滤。
日志记录与监控配置完规则后,需要记录被拒绝的流量以便分析攻击来源和调整策略。在DROP规则之前添加LOG规则:
iptables -A INPUT -j LOG --log-prefix "IPTABLES-DROP: " --log-level 4
这条规则要放在INPUT链的最后,DROP策略之前。日志会输出到/var/log/kern.log,可以用grep查看:
grep "IPTABLES-DROP" /var/log/kern.log
注意日志量可能很大,建议只对特定类型的流量做记录,或者使用limit限制日志频率:
iptables -A INPUT -m limit --limit 5/min -j LOG --log-prefix "IPTABLES-DROP: " --log-level 4IPv6流量的安全配置
很多管理员只配置了IPv4的防火墙,完全忽略了IPv6。攻击者经常利用IPv6绕过防火墙。Debian默认启用了IPv6,你必须用ip6tables或nftables对IPv6流量做同样的限制。基本配置逻辑和IPv4一致:
ip6tables -A INPUT -i lo -j ACCEPT ip6tables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT ip6tables -A INPUT -p tcp --dport 22 -j ACCEPT ip6tables -P INPUT DROP ip6tables -P FORWARD DROP ip6tables -P OUTPUT ACCEPT
如果你不需要IPv6,最安全的做法是在内核层面禁用它,编辑/etc/sysctl.conf添加:
net.ipv6.conf.all.disable_ipv6 = 1 net.ipv6.conf.default.disable_ipv6 = 1
然后执行sysctl -p使其生效。
定期审计与规则优化防火墙规则不是一劳永逸的。服务器上安装新软件、调整服务端口后,都需要同步更新规则。建议每个月检查一次规则列表,删除不再需要的放行条目。用iptables -L -n -v可以查看每条规则的匹配次数,那些计数为零的放行规则可能就是可以清理的。对于nftables,使用nft list ruleset查看完整规则集。保持规则集精简,不仅能提高性能,也降低了配置错误导致安全漏洞的概率。把防火墙配置纳入配置管理工具中,比如Ansible或Puppet,可以确保多台服务器规则一致且可追溯。
这套配置方法覆盖了从基础策略到高级防护的完整流程。关键是先建立默认拒绝的底线,再按需开放,配合速率限制和IP信誉管理,最后别忘了IPv6和日志监控。规则配置好后,用nmap从外部扫描一下你的服务器,验证只有预期的端口是开放的,这是检验配置是否生效的最直接方式。
