iptables防火墙
- 一、防火墙基础概念
-
- [1.1 什么是防火墙?](#1.1 什么是防火墙?)
- [1.2 Netfilter 与 iptables](#1.2 Netfilter 与 iptables)
- [1.3 防火墙的分类](#1.3 防火墙的分类)
- 二、iptables4表5链
-
- [2.1 规则表](#2.1 规则表)
-
- [1. raw 表](#1. raw 表)
- [2. mangle 表](#2. mangle 表)
- [3. nat 表](#3. nat 表)
- [4. filter 表](#4. filter 表)
- [2.2 规则链](#2.2 规则链)
-
- [1. PREROUTING 链](#1. PREROUTING 链)
- [2. INPUT 链](#2. INPUT 链)
- [3. FORWARD 链](#3. FORWARD 链)
- [4. OUTPUT 链](#4. OUTPUT 链)
- [5. POSTROUTING 链](#5. POSTROUTING 链)
- [2.3 表与链的关系](#2.3 表与链的关系)
- 三、命令使用
一、防火墙基础概念
1.1 什么是防火墙?
防火墙是一种网络安全系统,它根据预定义的安全规则,监控并控制进出网络的数据流。其核心功能是数据过滤,就像一个网络"安检员",只允许符合规则的数据包通过,阻止潜在的威胁。
1.2 Netfilter 与 iptables
在 Linux 系统中,防火墙功能主要由两个核心组件协同实现:
-
Netfilter :这是 Linux 内核中的一个软件框架,是防火墙的"阵法"或"引擎"。它位于内核态,负责实际的数据包过滤、网络地址转换(NAT)和连接跟踪等底层操作。你可以把它想象成一个功能强大但需要指令才能运转的"八卦阵"或"十八铜人阵"。
-
iptables :这是一个运行在用户空间的命令行管理工具 。它的主要作用是给 Netfilter 这个"阵法"传递参数和规则 。用户通过 iptables 命令定义规则(如允许、拒绝、记录),这些规则会被 iptables 工具翻译并传递给内核中的 Netfilter 框架去执行。简单说,
iptables是配置和管理Netfilter的工具。
关系总结 :
Netfilter(内核态,执行者) + iptables(用户态,配置者) = 完整的 Linux 防火墙体系。
1.3 防火墙的分类
按工作层次分
-
包过滤防火墙
- 工作层次:网络层和传输层(OSI模型的第3、4层)。
- 检查内容:主要检查数据包的 IP 头部(源/目标IP)和 TCP/UDP 头部(源/目标端口号)。
- 特点:速度快,但无法识别应用层协议的具体内容。
-
应用层防火墙(代理防火墙/七层防火墙)
- 工作层次:应用层(OSI模型的第7层)。
- 检查内容:深度检查应用层协议内容,如 HTTP、FTP、QQ 等协议的数据包。
- 特点:安全性高,能防御应用层攻击,但处理速度相对较慢,对性能要求高。
按实现形式分
- 硬件防火墙:通常是独立的网络设备,部署在网络出口/入口,性能强大,常用于企业核心网络边界。
- 软件防火墙 :运行在通用操作系统(如 Windows、Linux)上的防火墙软件。Linux 的
iptables/nftables、Windows 的 Windows Defender 防火墙都属于此类。
二、iptables4表5链
2.1 规则表
规则表是具有某一类相似用途的防火墙规则的集合。在 iptables 中,规则按照不同的处理时机被组织到不同的"链"中,而这些链又被归置到不同的"表"中。简单来说,表是规则的分类容器,链是规则的处理流程节点。
iptables 默认包含四个核心规则表,每个表都有其特定的用途:
1. raw 表
决定是否对数据包进行状态跟踪的豁免处理
- 应用场景:主要用于高性能网络测试工具或实时性要求极高的网络通信应用。通过 raw 表可以绕过连接跟踪机制,避免状态跟踪带来的资源消耗和时间延迟,从而优化性能
2. mangle 表
用于对数据包进行修改、标记等操作
- 应用场景 :
- 流量标记:企业网络中可使用 mangle 表对来自特定部门或应用的网络流量进行标记,以便后续进行流量整形(如限制带宽、优先处理)
- 修改包头字段:可以修改数据包 IP 头部的某些字段,如 TTL(生存时间)值
3. nat 表
主要负责网络地址转换(NAT) 相关的操作,包括:
- 源地址转换(SNAT):修改数据包的源 IP 地址
- 目的地址转换(DNAT):修改数据包的目的 IP 地址或端口
- 典型应用 :
- SNAT:内部使用私有 IP 地址的设备访问外部网络时,通过 nat 表中的 SNAT 规则将私有 IP 地址转换为公共 IP 地址(出口 NAT)
- DNAT:外部网络访问内部服务器时,通过 DNAT 规则将外部请求的目标 IP 地址转换为内部服务器的私有 IP 地址(端口转发或内网服务暴露)
4. filter 表
主要用于过滤数据包 ,决定是否允许数据包通过或者丢弃,是实现基本防火墙功能的最常用表
- 应用场景 :
- 在 filter 表的 INPUT 链中设置规则,可以阻止来自特定 IP 地址或端口的数据包进入内部网络
- 在 OUTPUT 链中设置规则,可以限制内部系统向外发送某些类型的数据包
2.2 规则链
规则链是数据包在流经防火墙时的处理路径点。iptables 默认有五条内置链,分别对应数据包流经的不同阶段:
1. PREROUTING 链
在数据包进入路由决策之前进行处理。
- 主要用途 :网络地址转换(NAT)功能中的目的地址转换(DNAT) 通常在此链中实现
- 示例:企业内部服务器使用私有 IP 地址,通过在 PREROUTING 链中设置 DNAT 规则,可将外部网络访问请求的目标地址转换为内部服务器的私有 IP 地址
2. INPUT 链
用于处理进入本地系统的数据包
- 工作流程:当其他设备发送数据到本地 Linux 系统时,数据包经过网络协议栈初步处理后,会进入 INPUT 链进行进一步过滤和决策,决定是否允许数据包进入本地系统
3. FORWARD 链
负责处理需要转发的数据包,即那些目标地址不是本地系统,而是要转发到其他设备的数据包
- 应用场景:在一个作为路由器或具备路由功能的 Linux 系统中,根据路由规则判断数据包需转发时,该数据包就会进入 FORWARD 链,根据设定规则决定是否允许转发
4. OUTPUT 链
主要处理本地系统产生的向外发送的数据包
- 工作流程:当本地系统中的应用程序发起网络请求时,请求数据包在系统内部经过一系列准备工作后,会进入 OUTPUT 链,在 OUTPUT 链中可根据需要对数据包进行过滤和修改
5. POSTROUTING 链
在数据包经过路由决策并且即将离开本地系统时进行处理
- 主要用途 :常见操作是进行源地址转换(SNAT)
- 示例:企业网络中内部多个设备使用私有 IP 地址共享一个公共 IP 地址访问外部网络时,可在 POSTROUTING 链中设置 SNAT 规则,将内部设备的私有 IP 地址转换为公共 IP 地址
2.3 表与链的关系
不同的表包含不同的链,并非所有链都存在于每个表中。下表总结了各表包含的链:
| 表(Table) | 包含的链(Chains) | 主要功能 |
|---|---|---|
| raw | PREROUTING, OUTPUT | 连接跟踪豁免 |
| mangle | PREROUTING, INPUT, FORWARD, OUTPUT, POSTROUTING | 数据包修改与标记 |
| nat | PREROUTING, INPUT, OUTPUT, POSTROUTING | 网络地址转换 |
| filter | INPUT, FORWARD, OUTPUT | 数据包过滤(允许/拒绝) |
注意 :
nat表不包含FORWARD链,因为 NAT 转换通常发生在路由决策前后(PREROUTING、POSTROUTING)或本地产生的数据包(OUTPUT),而转发流量一般不涉及地址转换

查看规则
bash
[root@dns-nfs-prom-ansible ~]# iptables -t nat -L
Chain PREROUTING (policy ACCEPT)
target prot opt source destination
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
Chain POSTROUTING (policy ACCEPT)
target prot opt source destination
[root@dns-nfs-prom-ansible ~]# iptables -t filter -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
[root@dns-nfs-prom-ansible ~]# iptables -t raw -L
Chain PREROUTING (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
[root@dns-nfs-prom-ansible ~]# iptables -t mangle -L
Chain PREROUTING (policy ACCEPT)
target prot opt source destination
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
Chain POSTROUTING (policy ACCEPT)
target prot opt source destination
三、命令使用
3.1 SSH日志测试
bash
# 追加SSH日志规则
[root@dns-nfs-prom-ansible ~]# iptables -A INPUT -p tcp --dport 22 -j LOG
# 插入SSH日志规则(放到链开头,优先级更高)
[root@dns-nfs-prom-ansible ~]# iptables -I INPUT -p tcp --dport 22 -j LOG --log-level 6
[root@dns-nfs-prom-ansible ~]# iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
LOG tcp -- anywhere anywhere tcp dpt:ssh LOG level info
LOG tcp -- anywhere anywhere tcp dpt:ssh LOG level warn
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
[root@dns-nfs-prom-ansible ~]# ping 192.168.168.139
# 日志验证
[root@dns-nfs-prom-ansible ~]# tail -f /var/log/messages
Sep 16 16:37:02 dns-nfs-prom-ansible kernel: IN=ens33 OUT= MAC=00:0c:29:11:6f:6b:00:50:56:c0:00:08:08:00 SRC=192.168.168.1 DST=192.168.168.139 LEN=40 TOS=0x00 PREC=0x00 TTL=64 ID=62036 DF PROTO=TCP SPT=50569 DPT=22 WINDOW=4095 RES=0x00 ACK URGP=0
Sep 16 16:37:02 dns-nfs-prom-ansible kernel: IN=ens33 OUT= MAC=00:0c:29:11:6f:6b:00:50:56:c0:00:08:08:00 SRC=192.168.168.1 DST=192.168.168.139 LEN=40 TOS=0x00 PREC=0x00 TTL=64 ID=62037 DF PROTO=TCP SPT=53979 DPT=22 WINDOW=4098 RES=0x00 ACK URGP=0
Sep 16 16:37:02 dns-nfs-prom-ansible kernel: IN=ens33 OUT= MAC=00:0c:29:11:6f:6b:00:50:56:c0:00:08:08:00 SRC=192.168.168.1 DST=192.168.168.139 LEN=40 TOS=0x00 PREC=0x00 TTL=64 ID=62038 DF PROTO=TCP SPT=53979 DPT=22 WINDOW=4097 RES=0x00 ACK URGP=0
3.2 编写防火墙脚本
bash
[root@dns-nfs-prom-ansible iptables]# vim iptables_rules.sh
#!/bin/bash
iptables="/usr/sbin/iptables"
$iptables -t nat -F
$iptables -t filter -F
$iptables -P INPUT ACCEPT
$iptables -X SCLOG
#开放的端口
$iptables -A INPUT -p tcp --dport 80 -j ACCEPT
$iptables -A INPUT -p udp --dport 53 -j ACCEPT
$iptables -A INPUT -p tcp -m multiport --dport 443,22,3306,21,20 -j ACCEPT
$iptables -A INPUT -p icmp -j ACCEPT
$iptables -A INPUT -s 123.12.1.0/24 -j DROP
$iptables -A INPUT -s 181.12.13.14 -p tcp -m multiport --dport 80,443,22 -j DROP
$iptables -P INPUT DROP
#创建自定义的链,并且添加规则
$iptables -t filter -N SCLOG
$iptables -t filter -A SCLOG -p tcp -j LOG --log-level 4 --log-prefix " **sc-tcp** "
$iptables -t filter -A SCLOG -p udp -j LOG --log-level 4 --log-prefix " **sc-udp** "
$iptables -t filter -A SCLOG -p icmp -j LOG --log-level 4 --log-prefix " **sc-icmp** "
#从INPUT链将流量引到SCLOG自定义链
$iptables -t filter -I INPUT -p tcp --dport 80 -j SCLOG
$iptables -t filter -I INPUT -p udp --dport 53 -j SCLOG
$iptables -t filter -I INPUT -p icmp --icmp-type 8 -j SCLOG
[root@dns-nfs-prom-ansible iptables]# iptables -L --line -n
Chain INPUT (policy DROP)
num target prot opt source destination
1 SCLOG icmp -- 0.0.0.0/0 0.0.0.0/0 icmptype 8
2 SCLOG udp -- 0.0.0.0/0 0.0.0.0/0 udp dpt:53
3 SCLOG tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:80
4 ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:80
5 ACCEPT udp -- 0.0.0.0/0 0.0.0.0/0 udp dpt:53
6 ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 multiport dports 443,22,3306,21,20
7 ACCEPT icmp -- 0.0.0.0/0 0.0.0.0/0
8 DROP all -- 123.12.1.0/24 0.0.0.0/0
9 DROP tcp -- 181.12.13.14 0.0.0.0/0 multiport dports 80,443,22
Chain FORWARD (policy ACCEPT)
num target prot opt source destination
Chain OUTPUT (policy ACCEPT)
num target prot opt source destination
Chain SCLOG (3 references)
num target prot opt source destination
1 LOG tcp -- 0.0.0.0/0 0.0.0.0/0 LOG flags 0 level 4 prefix " **sc-tcp** "
2 LOG udp -- 0.0.0.0/0 0.0.0.0/0 LOG flags 0 level 4 prefix " **sc-udp** "
3 LOG icmp -- 0.0.0.0/0 0.0.0.0/0 LOG flags 0 level 4 prefix " **sc-icmp** "
[root@dns-nfs-prom-ansible ~]# ping 192.168.168.139
[root@dns-nfs-prom-ansible ~]# tail -f /var/log/messages
Sep 16 19:11:48 dns-nfs-prom-ansible kernel: **sc-icmp** IN=lo OUT= MAC=00:00:00:00:00:00:00:00:00:00:00:00:08:00 SRC=192.168.168.139 DST=192.168.168.139 LEN=84 TOS=0x00 PREC=0x00 TTL=64 ID=5119 DF PROTO=ICMP TYPE=8 CODE=0 ID=2 SEQ=40
Sep 16 19:11:49 dns-nfs-prom-ansible kernel: **sc-icmp** IN=lo OUT= MAC=00:00:00:00:00:00:00:00:00:00:00:00:08:00 SRC=192.168.168.139 DST=192.168.168.139 LEN=84 TOS=0x00 PREC=0x00 TTL=64 ID=5566 DF PROTO=ICMP TYPE=8 CODE=0 ID=2 SEQ=41
Sep 16 19:11:50 dns-nfs-prom-ansible kernel: **sc-icmp** IN=lo OUT= MAC=00:00:00:00:00:00:00:00:00:00:00:00:08:00 SRC=192.168.168.139 DST=192.168.168.139 LEN=84 TOS=0x00 PREC=0x00 TTL=64 ID=5663 DF PROTO=ICMP TYPE=8 CODE=0 ID=2 SEQ=42
导出防火墙规则
bash
[root@dns-nfs-prom-ansible iptables]# iptables-save > /iptables/rules.txt
[root@dns-nfs-prom-ansible iptables]# cat rules.txt
# Generated by iptables-save v1.8.10 (nf_tables) on Tue Sep 16 19:14:54 2025
*filter
:INPUT DROP [5:1752]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:SCLOG - [0:0]
-A INPUT -p icmp -m icmp --icmp-type 8 -j SCLOG
-A INPUT -p udp -m udp --dport 53 -j SCLOG
-A INPUT -p tcp -m tcp --dport 80 -j SCLOG
-A INPUT -p tcp -m tcp --dport 80 -j ACCEPT
-A INPUT -p udp -m udp --dport 53 -j ACCEPT
-A INPUT -p tcp -m multiport --dports 443,22,3306,21,20 -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A INPUT -s 123.12.1.0/24 -j DROP
-A INPUT -s 181.12.13.14/32 -p tcp -m multiport --dports 80,443,22 -j DROP
-A SCLOG -p tcp -j LOG --log-prefix " **sc-tcp** "
-A SCLOG -p udp -j LOG --log-prefix " **sc-udp** "
-A SCLOG -p icmp -j LOG --log-prefix " **sc-icmp** "
COMMIT
# Completed on Tue Sep 16 19:14:54 2025
导入防火墙规则
bash
[root@dns-nfs-prom-ansible iptables]# bash clear_iptables_rules.sh
[root@dns-nfs-prom-ansible iptables]# iptables-restore < /iptables/rules.txt
[root@dns-nfs-prom-ansible iptables]# iptables -L --line -n
Chain INPUT (policy DROP)
num target prot opt source destination
1 SCLOG icmp -- 0.0.0.0/0 0.0.0.0/0 icmptype 8
2 SCLOG udp -- 0.0.0.0/0 0.0.0.0/0 udp dpt:53
3 SCLOG tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:80
4 ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:80
5 ACCEPT udp -- 0.0.0.0/0 0.0.0.0/0 udp dpt:53
6 ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 multiport dports 443,22,3306,21,20
7 ACCEPT icmp -- 0.0.0.0/0 0.0.0.0/0
8 DROP all -- 123.12.1.0/24 0.0.0.0/0
9 DROP tcp -- 181.12.13.14 0.0.0.0/0 multiport dports 80,443,22
Chain FORWARD (policy ACCEPT)
num target prot opt source destination
Chain OUTPUT (policy ACCEPT)
num target prot opt source destination
Chain SCLOG (3 references)
num target prot opt source destination
1 LOG tcp -- 0.0.0.0/0 0.0.0.0/0 LOG flags 0 level 4 prefix " **sc-tcp** "
2 LOG udp -- 0.0.0.0/0 0.0.0.0/0 LOG flags 0 level 4 prefix " **sc-udp** "
3 LOG icmp -- 0.0.0.0/0 0.0.0.0/0 LOG flags 0 level 4 prefix " **sc-icmp** "
查看内核防火墙模块
bash
[root@dns-nfs-prom-ansible netfilter]# pwd
/lib/modules/5.14.0-570.17.1.el9_6.x86_64/kernel/net/netfilter
[root@dns-nfs-prom-ansible netfilter]# uname -r
5.14.0-570.17.1.el9_6.x86_64