您的位置:首页 > 路由器知识路由器知识

2025Linux防火墙与流量控制完全指南:从入门到精通的网络管理手册

2026-02-25人已围观

2025 Linux防火墙与流量控制完全指南:从入门到精通的网络管理手册

一、Linux网络总览:数据如何在你的系统中旅行

想象你的Linux系统是一座繁忙的网络交通枢纽,每个数据包就像一辆需要进出这座枢纽的小汽车。不管是你浏览网页的请求,还是服务器对外提供的服务,所有数据都必须沿着特定路线行驶,遵守各种交通规则。理解这些路线和规则,是掌握防火墙和流量控制的第一步。

1.1 数据包的"旅行路线"

在Linux系统中,任何数据流动都遵循严格的"交通路线"。最关键的规则是:只要数据包的目的地是本机IP地址,就一定会走Loopback(回环)设备,就像本地快递不需要出小区大门一样。比如你在服务器上用`curl localhost:8080`访问本机服务,这些数据会直接通过回环设备处理,根本不会经过物理网卡。

数据的主要"旅行路线"有三种:

- 本地接收:外部数据→PREROUTING→INPUT→本机应用(如浏览器、SSH)

- 本地发送:本机应用→OUTPUT→POSTROUTING→外部网络

- 转发数据:外部数据→PREROUTING→FORWARD→POSTROUTING→目标机器

这些路线就像城市的交通主干道,每个路口(技术上叫"钩子点")都设有检查站,这就是我们后面要讲的防火墙规则发挥作用的地方。

1.2 网络中的"交通管制"

在这些数据路线上,有两套主要的"交通管制系统":

- iptables/netfilter:相当于遍布全城的交通警察,在各个主要路口检查和引导车辆(数据包)

- tc(流量控制):相当于道路上的红绿灯和车道控制器,决定车辆通行的速度和优先级

简单说,iptables决定"谁能过",而tc决定"过得有多快"。这两套系统配合工作,共同维护网络的安全和秩序。

二、iptables/netfilter:Linux系统的"网络保安"

2.1 什么是iptables和netfilter?

很多新手会把iptables和netfilter混为一谈,其实它们是"硬件"和"软件"的关系:

- netfilter:是Linux内核中内置的"关卡设施",就像小区门口的安保亭,所有进出的数据包都必须经过这些关卡

- iptables:是用户空间的命令行工具,相当于保安手里的登记本和指令手册,用来告诉netfilter如何检查和处理数据包

打个比方:netfilter是机场的安检设备,而iptables是安检人员手里的操作指南,规定了哪些人可以通过、哪些需要开箱检查、哪些直接禁止入内。

2.2 iptables的核心概念:四表五链

理解iptables的关键是掌握"四表五链",这就像医院的科室和就诊流程——不同的问题要去不同的科室,按顺序接受检查。

五链:数据包的"必经之路"

想象数据包进入服务器要经过五个检查站,每个检查站负责不同阶段的检查:

- PREROUTING:数据包刚到网卡就进行的检查(入境检查)

- INPUT:准备进入本机应用的数据包(进入大楼前检查)

- FORWARD:需要转发给其他机器的数据包(过境车辆检查)

- OUTPUT:本机应用发出的数据包(离开大楼检查)

- POSTROUTING:即将离开服务器的最终检查(出境检查)

特别注意:内核4.2版本后新增了NF_INET_INGRESS钩子,这个检查点在PREROUTING之前,能更早地处理数据包,不过主要用于nftables。

四表:不同功能的"执法部门"

这四个表就像四个专业执法部门,各有分工,优先级从高到低为:raw → mangle → nat → filter:

1. raw表:最高优先级,专门处理不需要跟踪的连接,就像机场的快速通道,某些VIP数据包可以跳过常规安检。它只在PREROUTING和OUTPUT链上工作。

2. mangle表:数据包"整形"部门,可以修改数据包的标记位,就像给不同包裹贴标签,方便后续处理。它在所有链上都能工作。

3. nat表:地址转换部门,负责修改数据包的源地址或目的地址。比如家里的路由器把内网IP转换为外网IP,就是nat表的功劳。它主要在PREROUTING(目标地址转换)和POSTROUTING(源地址转换)链上工作。

4. filter表:最常用的"过滤部门",决定数据包是放行(ACCEPT)、拒绝(REJECT)还是丢弃(DROP)。它是默认表,如果你不指定表,iptables命令就默认操作这个表。

数据包处理顺序:当数据包经过某个链时,会按raw→mangle→nat→filter的顺序依次检查各表的规则,前一个表处理完了才会进入下一个表。

2.3 连接状态:防火墙的"记忆功能"

现代防火墙聪明的地方在于它有"记忆",能识别连接的状态,而不只是单个数据包。这就像保安认识常客,不需要每次都重新检查证件。

ip_conntrack模块负责记录连接状态,主要有以下几种:

- NEW:新建立的连接,就像第一次来访的客人

- ESTABLISHED:已建立的连接,就像已经登记入住的客人

- RELATED:与已建立连接相关的新连接,比如FTP的数据传输连接

- INVALID:无效连接,无法识别或无法路由的数据包

- UNTRACKED:在raw表中标记为不跟踪的连接

- SNAT:源地址被修改后的连接状态

- DNAT:目的地址被修改后的连接状态

这个"记忆功能"非常重要,但也是有代价的——连接跟踪表满了会导致新连接无法建立。就像酒店客满了就无法接待新客人一样,这时需要调整系统参数扩大容量。

2.4 iptables基础配置:从零开始设置防火墙

安装与启动

大多数Linux发行版预装了iptables,若没有则需要安装:

CentOS/RHEL:

```bash

安装iptables服务

yum install -y iptables iptables-services

启动服务

systemctl start iptables

设置开机自启

systemctl enable iptables

```

Ubuntu/Debian:

```bash

安装iptables

apt-get install -y iptables iptables-persistent

保存初始规则(避免重启失效)

netfilter-persistent save

```

基本命令格式

iptables命令的基本结构是:

```bash

iptables [-t 表名] 操作选项 [链名] [匹配条件] [-j 动作]

```

常用操作选项:

- `-A`:在链末尾添加规则

- `-I`:在链开头插入规则

- `-D`:删除规则

- `-L`:列出规则

- `-F`:清空规则

- `-P`:设置链的默认策略

必备基础规则

1. 允许已建立的连接

这是最重要的规则之一,否则你SSH连接服务器后可能马上断开:

```bash

iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT

```

这条规则告诉防火墙:"已经认识的朋友(已建立的连接)可以进来"。

2. 允许本地回环访问

本地服务之间的通信需要通过回环设备,必须放行:

```bash

iptables -A INPUT -i lo -j ACCEPT

iptables -A OUTPUT -o lo -j ACCEPT

```

3. 开放SSH端口

否则你下次就无法远程连接服务器了:

```bash

允许所有IP访问SSH

iptables -A INPUT -p tcp --dport 22 -j ACCEPT

更安全:只允许特定IP段访问

iptables -A INPUT -p tcp -s 192.168.1.0/24 --dport 22 -j ACCEPT

```

4. 设置默认策略

对于不匹配任何规则的数据包,应该默认拒绝:

```bash

iptables -P INPUT DROP 默认拒绝所有入站流量

iptables -P FORWARD DROP 默认拒绝所有转发流量

iptables -P OUTPUT ACCEPT 默认允许所有出站流量

```

规则顺序的重要性

防火墙规则是按顺序匹配的,一旦命中就不再检查后续规则。这一点新手很容易犯错!

错误示例:

```bash

先允许所有IP访问SSH

iptables -A INPUT -p tcp --dport 22 -j ACCEPT

再拒绝某个IP

iptables -A INPUT -s 10.0.0.5 -j DROP

```

上面的拒绝规则永远不会生效,因为前面已经允许了22端口的所有访问。

正确做法:把限制性规则放在前面:

```bash

先拒绝特定IP

iptables -A INPUT -s 10.0.0.5 -j DROP

再允许SSH访问

iptables -A INPUT -p tcp --dport 22 -j ACCEPT

```

或者使用`-I`将规则插入到链首:

```bash

iptables -I INPUT 1 -s 10.0.0.5 -j DROP 插入到第一条

```

规则持久化

临时添加的规则在重启后会丢失,需要保存:

CentOS/RHEL:

```bash

service iptables save

iptables-save > /etc/sysconfig/iptables

```

Ubuntu/Debian:

```bash

netfilter-persistent save

```

2.5 高级应用:NAT转换与端口转发

NAT(网络地址转换)是路由器的核心功能之一,让多台设备共享一个公网IP上网。在Linux上用iptables也能实现。

1. SNAT:源地址转换(共享上网)

当内网机器要访问外网时,把源IP(内网IP)转换为服务器的公网IP:

```bash

假设eth0是公网网卡,192.168.1.0/24是内网网段

iptables -t nat -A POSTROUTING -o eth0 -s 192.168.1.0/24 -j SNAT --to-source 203.0.113.5

```

2. DNAT:目的地址转换(端口转发)

把公网IP的某个端口转发到内网机器:

```bash

把公网203.0.113.5的8080端口转发到内网192.168.1.100的80端口

iptables -t nat -A PREROUTING -d 203.0.113.5 -p tcp --dport 8080 -j DNAT --to-destination 192.168.1.100:80

```

2.6 firewalld:更现代的防火墙管理工具

如果你觉得iptables太复杂,可以试试firewalld——它是iptables的前端工具,更易用,默认在CentOS 7+、Fedora等系统上使用。

基本操作

```bash

启动并设置开机自启

systemctl enable --now firewalld

查看状态

firewall-cmd --state

查看活跃区域

firewall-cmd --get-active-zones

```

区域(Zone)概念

firewalld通过"区域"来管理不同场景的规则,就像预设了不同的安全模式:

- trusted:信任区域,允许所有流量

- public:公共区域,只允许必要的服务(默认)

- home:家庭网络,允许更多服务

- work:工作网络

- dmz:隔离区,用于公开服务

- drop:丢弃所有入站流量,只允许出站

切换区域:

```bash

将eth0网卡切换到public区域

firewall-cmd --change-interface=eth0 --zone=public

```

开放服务/端口

```bash

临时开放HTTP服务(重启后失效)

firewall-cmd --add-service=http

永久开放HTTPS服务

firewall-cmd --add-service=https --permanent

开放特定端口(如8080/tcp)

firewall-cmd --add-port=8080/tcp --permanent

应用更改

firewall-cmd --reload

```

三、Traffic Control(TC):Linux的"交通信号灯"

如果说iptables是"谁能过"的保安,那么TC(Traffic Control)就是"怎么过"的交通信号灯和车道控制器。它能控制网络流量的速度、延迟,甚至模拟网络故障,非常适合测试和优化网络应用。

3.1 TC的基本概念

TC的核心思想是队列规则(qdisc)——想象你家小区门口的车辆排队系统:

- 无类队列(Classless qdisc):所有人一起排队,不区分身份

- 分类队列(Classful qdisc):有VIP通道、普通通道、货车通道等不同队列

TC主要控制出站(egress)流量,对入站(ingress)流量的控制比较有限,但可以通过ifb虚拟网卡间接实现。

3.2 常用队列规则详解

无类队列:简单直接的流量控制

1. pfifo_fast:默认队列,有3个优先级(band),高优先级的数据包先发送。就像高速公路的应急车道,紧急车辆(高优先级包)可以优先通行。

2. TBF(Token Bucket Filter):令牌桶过滤器,最常用的限速工具。想象你去游乐园玩,需要先拿到代币(token)才能玩项目。TBF以固定速率生成代币,数据包需要消耗代币才能发送,从而控制速度。

适用场景:限制某个接口的总带宽

```bash

限制eth0出口带宽为10Mbps,突发流量不超过20Mbps

tc qdisc add dev eth0 root tbf rate 10mbit burst 20mbit latency 50ms

```

3. SFQ(Stochastic Fair Queuing):随机公平队列,确保每个连接(如每个TCP会话)公平分配带宽。就像超市的多个收银台,每个顾客(连接)轮流被服务,避免某个连接霸占所有带宽。

4. netem:网络模拟器,能模拟延迟、丢包、抖动等网络状况,非常适合测试应用在恶劣网络下的表现。

```bash

模拟100ms延迟,10%丢包率

tc qdisc add dev eth0 root netem delay 100ms loss 10%

模拟20-40ms的抖动延迟

tc qdisc add dev eth0 root netem delay 30ms 10ms

```

分类队列:精细控制不同流量

分类队列允许你为不同类型的流量创建"专用车道",比如给视频会议分配更多带宽,限制P2P下载的速度。

HTB(Hierarchical Token Bucket):最常用的分类队列,支持创建层次化的带宽分配结构。就像城市交通系统,有主干道、次干道和支路,每条路有自己的速度限制,但主干道也能临时借道给次干道。

HTB的关键概念:

- 类(class):不同的流量类别,如HTTP类、SSH类

- 速率(rate):保证给该类的最小带宽

- ceil:该类能使用的最大带宽(可以借用其他类的空闲带宽)

3.3 实战:用TC限制特定IP的带宽

假设我们要限制192.168.1.10这个IP的下载速度不超过1Mbps,同时保证SSH连接(22端口)不受影响。

步骤1:创建根队列

```bash

tc qdisc add dev eth0 root handle 1: htb default 10

```

步骤2:创建父类(总带宽限制)

```bash

tc class add dev eth0 parent 1: classid 1:1 htb rate 100mbit ceil 100mbit

```

步骤3:为不同流量创建子类

```bash

创建默认类(未匹配的流量)

tc class add dev eth0 parent 1:1 classid 1:10 htb rate 50mbit ceil 100mbit

创建限制类(针对192.168.1.10)

tc class add dev eth0 parent 1:1 classid 1:20 htb rate 1mbit ceil 1mbit

```

步骤4:添加过滤器,匹配特定IP

```bash

tc filter add dev eth0 parent 1: protocol ip prio 1 u32 \

match ip src 192.168.1.10/32 flowid 1:20

```

步骤5:查看和删除规则

```bash

查看所有规则

tc qdisc show dev eth0

tc class show dev eth0

tc filter show dev eth0

删除所有规则

tc qdisc del dev eth0 root

```

3.4 入站流量控制:使用ifb虚拟网卡

TC本身主要控制出站流量,要控制入站流量需要借助ifb(Intermediate Functional Block)虚拟网卡,把入站流量"重定向"到ifb设备,再对ifb应用TC规则。

配置步骤:

1. 加载ifb模块:

```bash

modprobe ifb

ip link set dev ifb0 up

```

2. 将入站流量重定向到ifb0:

```bash

tc qdisc add dev eth0 ingress handle ffff:

tc filter add dev eth0 parent ffff: protocol ip u32 match u32 0 0 action mirred egress redirect dev ifb0

```

3. 在ifb0上应用TC规则(和出站控制一样):

```bash

tc qdisc add dev ifb0 root htb default 10

tc class add dev ifb0 parent 1: classid 1:1 htb rate 100mbit ceil 100mbit

tc class add dev ifb0 parent 1:1 classid 1:10 htb rate 50mbit ceil 100mbit

```

四、常见问题解决与优化技巧

4.1 iptables常见问题

问题1:配置规则后无法远程连接服务器

可能原因:

- 没有允许SSH端口(22)的规则

- 默认策略设置为DROP但没有开放必要端口

- 规则顺序错误,拒绝规则放在了允许规则前面

解决方法:

```bash

紧急情况下清除所有规则(谨慎使用)

iptables -F

添加允许SSH的规则(放在最前面)

iptables -I INPUT 1 -p tcp --dport 22 -j ACCEPT

```

问题2:连接跟踪表溢出导致无法建立新连接

现象:系统日志出现`ip_conntrack: table full, dropping packet`

解决方法:调整连接跟踪的最大数量:

```bash

临时修改

sysctl -w net.ipv4.ip_conntrack_max=100000

永久生效(添加到/etc/sysctl.conf)

echo "net.ipv4.ip_conntrack_max=100000" >> /etc/sysctl.conf

sysctl -p

```

4.2 TC常见问题

问题:限速不生效或效果不符合预期

可能原因:

- 队列类型选择不当(如用TBF限制多连接流量效果不好)

- 父类和子类的速率设置冲突

- 没有正确应用过滤器,流量没有进入目标类

解决方法:

- 对多用户/多连接场景,优先使用HTB+SFQ组合

- 检查类的rate和ceil参数,确保层级关系正确

- 用`tc -s qdisc show dev eth0`查看队列统计,确认流量是否进入目标类

4.3 性能优化技巧

1. 减少连接跟踪负担:

- 对不需要跟踪的服务(如NTP)使用raw表跳过跟踪:

```bash

iptables -t raw -A PREROUTING -p udp --dport 123 -j NOTRACK

```

2. 优化TC队列参数:

- SFQ的`perturb`参数定期重新分配哈希,避免某个连接长期霸占带宽:

```bash

tc qdisc add dev eth0 parent 1:10 sfq perturb 10

```

3. 合理设置TCP参数:

```bash

增加TCP缓冲区大小

sysctl -w net.core.rmem_max=16777216

sysctl -w net.core.wmem_max=16777216

```

五、新手避坑清单

1. 不要在远程服务器上直接清空规则:`iptables -F`会立即切断你的连接,应先添加允许SSH的规则

2. 规则顺序至关重要:限制性规则(DROP/REJECT)必须放在允许规则前面

3. 记得保存规则:所有iptables命令默认是临时的,重启后失效,一定要执行保存命令

4. 慎用默认DROP策略:设置`iptables -P INPUT DROP`前,确保已经开放了必要端口(至少SSH)

5. 理解连接状态:永远先放行`RELATED,ESTABLISHED`状态,否则会中断已有连接

6. TC限速不影响本地流量:lo接口的流量不受TC控制,测试时用两台机器

7. 避免过度限制:带宽限制要留有余地,突发流量可能导致连接中断

8. 定期备份规则:重要服务器的防火墙规则应备份到文件,避免意外丢失

9. 使用工具辅助:对复杂规则,考虑使用`firewalld`或`ufw`等前端工具

10. 测试规则效果:添加规则后用`ping`、`curl`等工具测试连通性,用`tcpdump`抓包分析

六、10个实用小技巧

1. 快速查看活动连接:`ss -tun` 显示所有TCP/UDP连接状态

2. 临时开放端口:`iptables -A INPUT -p tcp --dport 8080 -j ACCEPT` 测试完成后记得删除

3. 查看规则命中次数:`iptables -L -v` 可以看到每条规则匹配了多少数据包

4. 复制现有规则:`iptables-save > rules.bak` 备份,`iptables-restore < rules.bak` 恢复

5. 限制SSH尝试次数:结合`recent`模块防止暴力破解:

```bash

iptables -A INPUT -p tcp --dport 22 -m recent --name ssh --rcheck --seconds 60 --hitcount 5 -j DROP

iptables -A INPUT -p tcp --dport 22 -m recent --name ssh --set -j ACCEPT

```

6. 模拟弱网环境:`tc qdisc add dev eth0 root netem delay 300ms loss 20%` 测试应用在弱网下的表现

7. 限制单个IP连接数:防止DoS攻击:

```bash

iptables -A INPUT -p tcp --dport 80 -m connlimit --connlimit-above 10 -j REJECT

```

8. 端口转发到本地:开发测试时很有用:

```bash

iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 8080

```

9. 查看连接跟踪表:`cat /proc/net/ip_conntrack` 了解当前跟踪的连接

10. 用firewalld快速切换环境:家里用home区域,外面用public区域:

```bash

firewall-cmd --set-default-zone=home 在家时

firewall-cmd --set-default-zone=public 在公共场所时

```

七、总结:构建安全高效的Linux网络

Linux防火墙和流量控制是系统管理员的必备技能,就像同时掌握了网络的"门禁系统"和"交通调度"。iptables让你精准控制谁能访问系统,TC让你合理分配网络资源,两者结合能打造既安全又高效的网络环境。

记住,网络管理没有放之四海而皆准的配置——最好的实践是根据实际需求调整规则,定期审查和优化。从简单规则开始,逐步构建复杂策略,你会发现Linux网络管理其实并不难,而且充满乐趣。

最后问自己:你的服务器防火墙规则有多久没审查了?连接跟踪表是否需要扩容?关键服务的带宽是否得到了保障?现在就动手检查和优化吧!