Linux iptables 防火墙原理与实操——从四表五链到 NAT 配置

iptables 简介

iptables 是 Linux 系统内核集成的包过滤防火墙工具,通过操作内核中的 Netfilter 框架实现网络流量控制。它基于规则链(如 INPUT、OUTPUT、FORWARD)和表(如 filter、nat、mangle)来管理数据包的过滤、转发和修改。

功能特性

  • 支持基于端口、IP、协议等条件的流量过滤。
  • 提供 NAT(网络地址转换)和端口转发能力。
  • 直接操作内核网络栈,性能高效。

firewall(如 firewalld、ufw)简介

firewall 是更上层的防火墙管理工具,通常作为 iptables/nftables 的前端,提供简化配置和动态规则管理。常见实现包括:

firewalld:默认用于 RHEL/CentOS/Fedora,支持动态更新和区域(zone)概念。

一.实验环境

主机名 网卡 用途
node1 nat-172.25.254.10 外网主机
node2 nat-172.25.254.100|hostonly-192.168.0.100 路由器
node3 hostonly-192.168.0.10 内网主机

二.iptables启用

bash 复制代码
[root@node2 ~]# dnf install iptables-nft-services.noarch -y
[root@node2 ~]# systemctl start iptables.service	
[root@node2 ~]# iptables -nL
Chain INPUT (policy ACCEPT)
target     prot opt source               destination
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0            state RELATED,ESTABLISHED
ACCEPT     icmp --  0.0.0.0/0            0.0.0.0/0
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0
ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0            state NEW tcp dpt:22
REJECT     all  --  0.0.0.0/0            0.0.0.0/0            reject-with icmp-host-prohibited

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination
REJECT     all  --  0.0.0.0/0            0.0.0.0/0            reject-with icmp-host-prohibited

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

.四张表五条链

1.四大表(优先级:raw > mangle > nat > filter)

1. filter 过滤表(默认表,最常用)

作用

:包过滤,放行 / 拒绝数据包,防火墙核心

内置链

:INPUT、OUTPUT、FORWARD

  • INPUT:发给本机的数据包
  • OUTPUT:本机向外发出的数据包
  • FORWARD:经过本机转发的数据包(网关 / 路由场景)

2. nat 网络地址转换表

作用

:修改数据包源 / 目的 IP、端口,实现共享上网、端口映射

内置链

:PREROUTING、POSTROUTING、OUTPUT

  • PREROUTING:数据包刚进网卡,改目的 IP(DNAT 端口映射)
  • POSTROUTING:数据包离开网卡前,改源 IP(SNAT/ MASQUERADE 共享上网)
  • OUTPUT:本机自身发出包的 DNAT 转换

3. mangle 修正表

作用

:修改数据包报文头特殊标记(TTL、TOS、MARK 标记),QoS 流量控制

内置链

:PREROUTING、INPUT、FORWARD、OUTPUT、POSTROUTING

唯一覆盖全部五条内置链的表

4. raw 原始表(优先级最高)

作用

:关闭连接追踪(conntrack),规避 nf_conntrack 性能开销

内置链

:PREROUTING、OUTPUT

数据包先经过 raw 表,再走其他表

五大链

链名 raw mangle nat filter
PREROUTING
INPUT
FORWARD
OUTPUT
POSTROUTING

PREROUTING

数据包刚抵达网卡,还未路由判断

适用:DNAT、打流量标记、关闭连接追踪

INPUT

路由判断后,目标是本机进程的包进入此链

适用:防火墙拦截外部访问本机端口

FORWARD

路由判断后,源和目标都不是本机,需要本机转发

适用:路由器、二层防火墙过滤跨网段流量

OUTPUT

本机程序主动向外发送数据包

适用:限制本机对外访问、本地 DNAT

POSTROUTING

数据包路由完成,即将离开网卡

适用:SNAT/MASQUERADE 内网共享上网

数据包完整流转路径(两种场景)

场景 1:外部主机 → 本机服务(入站访问本机)

网卡 → raw:PREROUTING → mangle:PREROUTING → nat:PREROUTING → 路由判断 → mangle:INPUT → filter:INPUT → 本机应用

场景 2:本机程序向外发包(本机出站)

本机应用 → raw:OUTPUT → mangle:OUTPUT → nat:OUTPUT → 路由判断 → mangle:POSTROUTING → nat:POSTROUTING → 网卡发出

场景 3:外网 → 本机路由 → 内网(转发流量)

网卡入 → raw:PREROUTING → mangle:PREROUTING → nat:PREROUTING → 路由判断 → mangle:FORWARD → filter:FORWARD → mangle:POSTROUTING → nat:POSTROUTING → 网卡出

四.filter表

在本机设定apache只能被192.168.0.0/24网段访问

bash 复制代码
[root@node2 ~]# echo 172.25.254.100 > /var/www/html/index.html
[root@node2 ~]# systemctl enable --now httpd
Created symlink /etc/systemd/system/multi-user.target.wants/httpd.service → /usr/lib/systemd/system/httpd.service.
# 使用apache 辅助测试


[root@node2 ~]# iptables -t filter -I INPUT 5  -p tcp --dport 80 -s 192.168.0.0/24  -m state --state  new -j ACCEPT
#-t 					指定所修改的表,默认filter可选(nat mangle raw)
#-I INPUT 5 			操作指令 + 链名 + 规则序号
# (可选操作指令)			-A -D -F清空链所有规则 -N新建自定义链 -X删除自定义空链
#-p tcp					基础匹配:协议 
#--dprot 80  			协议专属扩展匹配:目标端口
#-s 					基础匹配:源地址
#-m state --state new	加载扩展匹配模块 state 模块参数
# (连接状态 4 种)NEW 新建连接首包 ESTABLISHED 已建立的连接 RELATED 关联连接 INVALID 非法异常数据包
#-j 					jump 跳转处理动作ACCEPT DROP(丢包) REJECT

[root@node2 ~]# iptables -nL
Chain INPUT (policy ACCEPT)
target     prot opt source               destination
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0            state RELATED,ESTABLISHED
ACCEPT     icmp --  0.0.0.0/0            0.0.0.0/0
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0
ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0            state NEW tcp dpt:22
ACCEPT     tcp  --  192.168.0.0/24       0.0.0.0/0            tcp dpt:80 state NEW
REJECT     all  --  0.0.0.0/0            0.0.0.0/0            reject-with icmp-host-prohibited

​ 测试:

bash 复制代码
[root@node1 ~]# curl  172.25.254.100
curl: (7) Failed to connect to 172.25.254.100 port 80: 没有到主机的路由

[root@node3 ~]# curl  192.168.0.100
172.25.254.100

五.nat表

1.内网访问外网

1.在node3 192.168.0.10主机中

bash 复制代码
[root@node3 ~]# ping 172.25.254.10
ping: connect: 网络不可达

#设定网关
[root@node3 ~]# nmcli connection modify eth0 ipv4.gateway 192.168.0.100
[root@node3 ~]# route  -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
192.168.0.0     0.0.0.0         255.255.255.0   U     100    0        0 eth0
[root@node3 ~]# nmcli connection reload
[root@node3 ~]# nmcli connection up eth0
连接已成功激活(D-Bus 活动路径:/org/freedesktop/NetworkManager/ActiveConnection/6)
[root@node3 ~]# route  -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         192.168.0.100   0.0.0.0         UG    100    0        0 eth0
192.168.0.0     0.0.0.0         255.255.255.0   U     100    0        0 eth0

在双网卡主机中设置出站策略

把所有从此主机中出去的数据包来源都转换成eth0网卡的ip

bash 复制代码
[root@node2 ~]# iptables -D FORWARD 1

[root@node2 ~]# iptables -t nat -A POSTROUTING -o eth0 -j SNAT  --to-source 172.25.254.100
#-o eth0:匹配从 eth0 网卡发出的数据包 output
#-j SNAT:匹配成功执行目的地址转换动作
#--to-source 172.25.254.100:把数据包的源头 IP强制改成 172.25.254.100

[root@node2 ~]# iptables -t nat -nL
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
SNAT       all  --  0.0.0.0/0            0.0.0.0/0            to:172.25.254.100


#打开内核路由功能
[root@node2 ~]# sysctl  -a | grep ip_forward
net.ipv4.ip_forward = 0

[root@node2 ~]# vim /etc/sysctl.conf
net.ipv4.ip_forward=1	
[root@node2 ~]# sysctl -p
net.ipv4.ip_forward = 1
[root@node2 ~]# sysctl  -a | grep ip_forward
net.ipv4.ip_forward = 1

测试:

复制代码
[root@node3 ~]# ping 192.168.0.100
PING 192.168.0.100 (192.168.0.100) 56(84) 比特的数据。
64 比特,来自 192.168.0.100: icmp_seq=1 ttl=64 时间=0.292 毫秒


[root@node1 ~]# w -i
 11:37:55 up  1:36,  3 users,  load average: 0.00, 0.00, 0.00
USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT
root     tty1     -                10:02    1:35m  0.01s  0.01s -bash
root     pts/0    172.25.254.1     10:32    2.00s  0.04s  0.00s w -i
root     pts/1    172.25.254.100   11:37    6.00s  0.00s  0.00s -bash

2.外网访问内网

bash 复制代码
[root@node2 ~]# iptables -t nat -A PREROUTING -i eth0  -j DNAT  --to-dest 192.168.0.10
#-i eth0:匹配从 eth0 网卡收到的数据包 input
#-j DNAT:匹配成功执行目的地址转换动作
#--to-dest 192.168.0.10:把数据包的目标 IP强制改成 192.168.0.10

[root@node2 ~]# iptables -t nat -nL
Chain PREROUTING (policy ACCEPT)
target     prot opt source               destination
DNAT       all  --  0.0.0.0/0            0.0.0.0/0            to:192.168.0.10

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
SNAT       all  --  0.0.0.0/0            0.0.0.0/0            to:172.25.254.100

测试:

bash 复制代码
[root@node1 ~]# ssh -l root 172.25.254.100
Activate the web console with: systemctl enable --now cockpit.socket

Register this system with Red Hat Insights: rhc connect

Example:
# rhc connect --activation-key <key> --organization <org>

The rhc client and Red Hat Insights will enable analytics and additional
management capabilities on your system.
View your connected systems at https://console.redhat.com/insights

You can learn more about how to register your system
using rhc at https://red.ht/registration
Last login: Tue Jul 21 10:33:22 2026 from 192.168.0.1
[root@node3 ~]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether 00:0c:29:1e:58:f3 brd ff:ff:ff:ff:ff:ff
    altname enp3s0
    altname ens160
    inet 192.168.0.10/24 brd 192.168.0.255 scope global noprefixroute eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::575a:d7ac:c15a:3503/64 scope link noprefixroute
       valid_lft forever preferred_lft forever
相关推荐
A洛1 小时前
Codex 实战:一句话完成 Temu 商品图采集与印花抠图自动化
运维·人工智能·自动化·codex
wdfk_prog1 小时前
嵌入式面试真题第 15 题:不可恢复异常后的通用崩溃快照、调用栈保存与离线分析架构
linux·开发语言·面试·架构
Urbano1 小时前
服装工厂卫衣量产提质增效方案:工序自动化替代、产能优化、多品牌设备选型及落地案例
运维·自动化
GlobalSign数字证书2 小时前
自动化时代,如何高效部署SSL证书?
运维·自动化·ssl
大侠锅锅5 小时前
第 19 篇:远程运维体系——指标、SSH、日志与 OTA 升级
运维·ssh
灵机一物6 小时前
企业选型参考:2026 CXL 内存扩展方案六强测评与落地指南
服务器·网络·数据库·人工智能
Web极客码6 小时前
如何用三段式确定性剪枝,为 LLM Agent 砍掉 35% 的 Token 成本?
服务器·人工智能·算法·机器学习
yeflx6 小时前
速腾Airy雷达使用记录
java·服务器·网络
公众号:fuwuqiBMC7 小时前
(转自“服务器BMC”)服务器BMC芯片——多Die(芯片)封装
运维·服务器·人工智能