惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Engineering at Meta
Engineering at Meta
月光博客
月光博客
WordPress大学
WordPress大学
C
Cisco Blogs
Recent Commits to openclaw:main
Recent Commits to openclaw:main
博客园 - 【当耐特】
大猫的无限游戏
大猫的无限游戏
The GitHub Blog
The GitHub Blog
Google DeepMind News
Google DeepMind News
The Cloudflare Blog
有赞技术团队
有赞技术团队
Microsoft Azure Blog
Microsoft Azure Blog
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
小众软件
小众软件
H
Heimdal Security Blog
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
W
WeLiveSecurity
量子位
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
F
Fortinet All Blogs
T
Threat Research - Cisco Blogs
Attack and Defense Labs
Attack and Defense Labs
P
Privacy & Cybersecurity Law Blog
D
Darknet – Hacking Tools, Hacker News & Cyber Security
NISL@THU
NISL@THU
Forbes - Security
Forbes - Security
L
Lohrmann on Cybersecurity
C
CERT Recently Published Vulnerability Notes
L
LINUX DO - 热门话题
Google Online Security Blog
Google Online Security Blog
S
Security Affairs
V2EX - 技术
V2EX - 技术
TaoSecurity Blog
TaoSecurity Blog
N
News and Events Feed by Topic
N
News | PayPal Newsroom
S
Security @ Cisco Blogs
宝玉的分享
宝玉的分享
Project Zero
Project Zero
The Hacker News
The Hacker News
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
PCI Perspectives
PCI Perspectives
G
GRAHAM CLULEY
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Y
Y Combinator Blog
N
Netflix TechBlog - Medium
S
Schneier on Security
Application and Cybersecurity Blog
Application and Cybersecurity Blog
www.infosecurity-magazine.com
www.infosecurity-magazine.com
博客园 - 聂微东

蛮荆

如何获取更多的免费服务器 Kubernetes 调度器队列 - 设计与实现 Kubernetes 调度器 - 核心流程 Kubernetes Networking Model & CNI Kubernetes 控制器管理总结 Kubernetes CronJob 设计与实现 Kubernetes Job 设计与实现 Kubernetes HPA 设计与实现 Kubernetes Deployment 滚动更新实现原理 Kubernetes GC 设计与实现 Kubernetes Pod 驱逐 - 设计与实现 Kubernetes Daemonset 设计与实现 Kubernetes ReplicaSet 设计与实现 Kubernetes EndPoint 设计与实现 Kubernetes Informer 设计与实现 降本增效之应用优化 (三) 日志存储与检索 Kubernetes Pod 设计与实现 - 创建流程 Kubernetes 探针设计与实现 Unix 编程艺术名句摘录 Kubernetes - CRI 概述 Golang 编译速度为什么这么快? Kubernetes Pod 设计与实现 - Pause 容器 Kubernetes - kube-proxy 代理模式工程优化 Kubernetes 应用最佳实践 - 优雅关闭长连接 Kubernetes Service 类型和会话亲和性 Kubernetes 为什么需要 Ingress Kubernetes 架构 - 控制平面和数据平面 降本增效之应用优化 (二) 大报表 Go 语言如何获取 CPU 利用率 降本增效之应用优化 (一) Redis 业务规则引擎演变过程简述 微服务中的熔断算法 漏桶算法和令牌桶算法 jsonparser 为什么比标准库的 encoding/json 快 10 倍 ? zap 高性能设计与实现 HTTP Router 算法演进 fastcache 高性能设计与实现 Web 常见的三个安全问题 ants Code Reading Go 线程安全 map 方案选型 布隆过滤器 死锁、活锁、饥饿、自旋锁 sync.Pool Code Reading Go 内存管理概述 Go netpoll Code Reading goroutine 泄漏与检测 time/Timer Code Reading GMP Scheduler Code Reading Go channel 的 15 条规则和底层实现 为什么 Linux “一切皆文件” context.Context Code Reading runtime/HACKING.md Goland 最佳实践 互联网开发与金庸武学 为什么 Redis 6.0 引入多线程模型? Kubernetes 应用最佳实践 - 金丝雀发布 容器中如何正确配置 GOMAXPROCS ? singleflight Code Reading sync.Map Code Reading sync.Cond Code Reading sync.WaitGroup Code Reading sync.RWMutex Code Reading sync.Mutex Code Reading sync.Once Code Reading Go 无锁编程 sync/atomic Code Reading goroutine 交替打印奇偶数 GODEBUG Go 并发模式 Go 汇编 UUID 通用技术选型 Kubernetes 应用最佳实践 - 水平自动伸缩 Go 高性能 Tips fasthttp 为什么比标准库 net/http 快 10 倍 ? 技术文章配图指南 ChatGPT 初体验 Docker 网络原理概览 Kubernetes 应用最佳实践 - 亲和性和污点容忍度 Go 的反射与三大定律 Docker 官方提供的最佳实践 Go 语言内置的设计模式 HTTP1 到 HTTP3 的工程优化 Kubernetes 应用最佳实践 - Sidecar 模式 Kubernetes 应用最佳实践 - init 容器和钩子函数 为什么 recover 必须在 defer 中调用? 为什么 defer 的执行顺序和注册顺序不同? Go map 设计与实现 Go 切片扩容底层实现 Go 语言中的零拷贝 Go Delve 云原生和边缘计算简介 Kubernetes Pod 服务质量等级 Kubernetes 应用最佳实践 - 探针 Kubernetes 应用最佳实践 - 资源请求和限制 CDN 原理 Kubernetes 应用最佳实践 - 开篇 缓存策略和模式 Go 内存模型 Kubernetes 核心概念 软件版本语义化
iptables 的五表五链
2023-04-03 · via 蛮荆

2023-04-03 计算机网络

概述

iptables 是一个配置 Linux 内核防火墙的命令行工具,它基于内核的包过滤框架(packet filtering framework) netfilter, 主要用于管理数据包过滤和 NAT 规则。

图片来源: https://upload.wikimedia.org/wikipedia/commons/3/37/Netfilter-packet-flow.svg

如图所示:

绿色背景的方框,表示表(table), 用来管理链,Linux 支持 4 种表,包括 filter(用于过滤)、nat(用于 NAT)、mangle(用于修改分组数据) 和 raw(用于原始数据包)。

白色背景方框,表示链(chain), 用来管理具体的 iptables 规则,每个表中可以包含多条链 filter 表中,内置 INPUT、OUTPUT 和 FORWARD nat 表中,内置 PREROUTING、POSTROUTING、OUTPUT。

灰色背景方框,表示连接跟踪模块通过内核中的连接跟踪表(也就是哈希表),记录网络连接的状态,是 iptables 状态过滤(-m state)和 NAT 的实现基础。

iptables 与协议栈内有包过滤功能的 hook 交 互来完成工作。这些内核 hook 构成了 netfilter 框架。每个进入网络系统的包(接收或发送)在经过协议栈时都会触发这些 hook, 程序可以通过注册 hook 函数的方式在一些关键路径上处理网络流量iptables 相关的内核模块在这些 hook 点注册了处理函数,因此可以通过配置 iptables 规则来使得网络流量符合防火墙规则。

理解 iptables 是学习 Docker, Kubernetes 等开源项目中网络功能实现的基础。

规则

规则 就是网络管理员预定义的条件,一般的定义为 如果数据包头符合当前条件,处理这个数据包,反之执行下一个判断条件规则 存储在内核空间的过滤表中,这些规则分别指定了 源地址目的地址传输协议(如TCP、UDP、ICMP)和 服务类型(如 HTTP、FTP 和 SMTP)等, 当数据包与 规则 匹配时,内核会执行具体的 行为

配置防火墙的主要工作就是添加、修改和删除规则

行为

动作 描述
ACCEPT 接收数据包
DROP 丢弃数据包,进行完此动作后,将直接中断检测过程,不再检测其它规则
REDIRECT 将封包重新导向到另一个端口(PNAT),进行完此动作后,继续比对其它规则,这个功能可以用来实现透明代理或用来保护应用服务器
SNAT 源地址转换
DNAT 目的地址转换
MASQUERADE IP伪装(NAT),用于 ADSL
LOG 日志记录
SEMARK 添加 SEMARK 标记以供网域内强制访问控制(MAC)
QUEUE 将数据包传递到用户空间
REJECT 拦截数据包,并返回数据包通知对方
RETURN 防火墙停止执行当前链中的后续规则,并返回到调用链中继续检测

5链

是数据包传播的路径,每一个 中可以有 N 个 规则 (N >= 0)。当数据包到达一个 时,iptables 就会从链中第一个规则开始检测, 如果数据包满足规则所定义的条件,系统会执行具体的 行为,否则 iptables 继续检查下一个规则。 如果数据包不符合链中任一个规则,iptables 就会根据该链预先定义的默认策略来处理数据包。

名称 描述
INPUT 处理接收的数据包
OUTPUT 处理发送的数据包
FORWARD 处理转发的数据包,常用于 网络隔离, NAT, 负载均衡
PREROUTING 修改到达且还未转发的数据包,常用于 DNAT, 端口映射, 源地址转换
POSTOUTING 修改发送前的的数据包,常用于 SNAT

5 表

表有 N 个链,链有 N 个规则。

大部分场景仅需使用 Filter 表 和 NAT 表

Raw 表

Raw 表用于在 连接跟踪、NAT 和路由表处理之前 对数据包进行处理,包含 2 种内置链:

  • PREROUTING
  • OUTPUT

因为优先级最高,所以如果使用了 Raw 表,那么在 Raw 表处理完后, 将跳过 NAT 表和 ip_conntrack 处理, 也就是避免了 连接跟踪、NAT 和路由表前置 处理。

Filter 表

Filteriptables 的默认表,用于过滤数据包,如果没有定义表的情况下将使用 Filter 表,包含 3 种内置链:

  • INPUT
  • OUTPUT
  • FORWARD

Filter 表中只允许对数据包进行接受,丢弃的操作,而无法对数据包进行更改。

NAT 表

NAT 用于实现网络地址转换,包含 3 种内置链:

  • PREROUTING
  • POSTROUTING
  • OUTPUT

Mangle 表

Mangle 用于对指定数据包报头进行修改、标记或重定向,包含 5 种内置链:

  • INPUT
  • OUTPUT
  • FORWARD
  • PREROUTING
  • POSTROUTING

Security 表

Security 用于给包打上 SELinux 标记,以此影响 SELinux 或其他可以解读 SELinux 安全上下文的系统处理包的行为。这些标记可以基于单个包,也可以基于连接。

表和链关系图

表和链关系图

表的检测优先级

Raw -> Mangle -> Nat -> Filter

图片来源: https://www.frozentux.net/iptables-tutorial//images/tables_traverse.jpg

任何一个数据包必然经过 5 个链中的其中一个

  • 一个数据包进入网卡时,首先进入 PREROUTING 链,内核根据数据包目的 IP 判断是否需要转发
  • 如果数据包是进入本机的,它就会沿着图向下移动,到达 INPUT 链,数据包到了INPUT链后,任何进程都会收到它,本机上程序可以发送数据包,这些数据包会经过 OUTPUT 链,然后到达 POSTROUTING 链输出
  • 如果数据包是转发出去的,且内核允许转发,数据包会经过 FORWARD 链,然后到达 POSTROUTING 链输出

常用命令

查看类

# 查看所有防火墙规则
$ iptables --list

# 示例输出如下
Chain DOCKER (8 references)
target     prot opt source               destination
ACCEPT     tcp  --  anywhere             172.27.0.2           tcp dpt:10010
ACCEPT     tcp  --  anywhere             172.22.0.2           tcp dpt:http
ACCEPT     tcp  --  anywhere             172.29.0.4           tcp dpt:memcached
ACCEPT     tcp  --  anywhere             172.17.0.2           tcp dpt:redis
ACCEPT     tcp  --  anywhere             172.17.0.2           tcp dpt:nginx
ACCEPT     tcp  --  anywhere             172.17.0.4           tcp dpt:8080
ACCEPT     tcp  --  anywhere             172.17.0.5           tcp dpt:mysql
ACCEPT     tcp  --  anywhere             172.17.0.5           tcp dpt:http

# 查看 mangle 表规则
$ iptables -t mangle --list

# 查看 nat 表规则
$ iptables -t nat --list
字段名称 描述
target 规则行为
prot 协议
opt 选项
source 源 IP 地址
destination 目的 IP 地址

操作类

# 查看说明

$ iptables --help

# 查看命令
iptables -L:查看规则链

# 规则管理命令
iptables -A:在规则链的末尾加入新规则
iptables -D:删除某个规则
iptables -I:在规则链的头部加入新规则
iptables -R:替换规则链中的规则

# 链管理命令
iptables -F:清空规则链
iptables -Z:清空规则链中的数据包计算器和字节计数器
iptables -N:创建新的用户自定义规则链
iptables -P:设置规则链中的默认策略

# 通用匹配参数
-t
    对指定的表 table 进行操作
    如果不指定此选项,默认的是 filter 表

-p 协议
    指定规则的协议,如 tcp, udp, icmp 等,可以使用all来指定所有协议
    如果不指定 -p 参数,默认的是 all 值

-s 源地址
    指定数据包的源地址
    参数可以使IP地址、网络地址、主机名
    例如:-s 192.168.1.101 指定IP地址
    例如:-s 192.168.1.10/24 指定网络地址

-d 目的地址
    指定数据包的目的地址,规则和 -s 类似

-j 执行目标
    指定规则匹配时如何处理数据包
    可能的值是ACCEPT, DROP, QUEUE, RETURN 等

-i 输入接口
    指定要处理来自哪个接口的数据包,这些数据包将进入 INPUT, FORWARD, PREROUTE 链
    例如:-i eth0指定了要处理经由eth0进入的数据包
    如果不指定 -i参数,那么将处理进入所有接口的数据包
    如果指定 ! -i eth0,那么将处理所有经由eth0以外的接口进入的数据包
    如果指定 -i eth+,那么将处理所有经由eth开头的接口进入的数据包

-o 输出
    指定了数据包由哪个接口输出,这些数据包将进入 FORWARD, OUTPUT, POSTROUTING链
    如果不指定-o选项,那么所有接口都可以作为输出接口
    如果指定 ! -o eth0,那么将从eth0以外的接口输出
    如果指定 -i eth+,那么将仅从eth开头的接口输出
  
# 扩展参数
-sport 源端口
    针对 -p tcp 或者 -p udp,默认情况下,将匹配所有端口
    可以指定端口号或者端口名称、端口范围,例如 –sport 22, –sport ssh,–sport 22:100 
    从性能上讲,使用端口号更好, /etc/services 文件描述了映射关系

-dport 目的端口
    规则和 –sport 类似

-tcp-flags TCP 标志
    针对 -p tcp
    可以指定由逗号分隔的多个参数
    取值范围:SYN, ACK, FIN, RST, URG, PSH, ALL, NONE

-icmp-type ICMP 标志
    针对 -p icmp
    icmp-type 0 表示 Echo Reply
    icmp-type 8 表示 Echo

命令选项输入顺序

iptables -t 表名 <-A/I/D/R> 规则链名 [规则号] <-i/o 网卡名> -p 协议名 <-s 源IP/源子网> --sport 源端口 <-d 目标IP/目标子网> --dport 目标端口 -j 动作

示例

以下命令在生产环境中谨慎使用

查看已添加的iptables规则

$ iptables -L -n -v

Chain INPUT (policy DROP 48106 packets, 2690K bytes)
 pkts bytes target     prot opt in     out     source               destination         
 5075  589K ACCEPT     all  --  lo     *       0.0.0.0/0            0.0.0.0/0           
 191K   90M ACCEPT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0           tcp dpt:22
1499K  133M ACCEPT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0           tcp dpt:80
4364K 6351M ACCEPT     all  --  *      *       0.0.0.0/0            0.0.0.0/0           state RELATED,ESTABLISHED
 6256  327K ACCEPT     icmp --  *      *       0.0.0.0/0            0.0.0.0/0           

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain OUTPUT (policy ACCEPT 3382K packets, 1819M bytes)
 pkts bytes target     prot opt in     out     source               destination         
 5075  589K ACCEPT     all  --  *      lo      0.0.0.0/0            0.0.0.0/0  

清空当前的所有规则和计数

$ iptables -F  # 清空所有的防火墙规则
$ iptables -X  # 删除用户自定义的空链
$ iptables -Z  # 清空计数

设置默认规则

$ iptables -P INPUT DROP    # 配置默认的不让进
$ iptables -P FORWARD DROP  # 默认的不允许转发
$ iptables -P OUTPUT ACCEPT # 默认的可以出去

开放指定端口

$ iptables -A INPUT -s 127.0.0.1 -d 127.0.0.1 -j ACCEPT               # 允许本地回环接口(即运行本机访问本机)
$ iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT    # 允许已建立的或相关连的通行
$ iptables -A OUTPUT -j ACCEPT                                        # 允许所有本机向外的访问
$ iptables -A INPUT -p tcp --dport 22 -j ACCEPT                       # 允许访问22端口
$ iptables -A INPUT -p tcp --dport 80 -j ACCEPT                       # 允许访问80端口
$ iptables -A INPUT -p tcp --dport 21 -j ACCEPT                       # 允许ftp服务的21端口
$ iptables -A INPUT -p tcp --dport 20 -j ACCEPT                       # 允许FTP服务的20端口
$ iptables -A INPUT -j reject                                         # 禁止其他未允许的规则访问
$ iptables -A FORWARD -j REJECT                                       # 禁止其他未允许的规则访问

白名单

$ iptables -A INPUT -p all -s 192.168.1.0/24 -j ACCEPT            # 允许机房内网机器可以访问
$ iptables -A INPUT -p all -s 192.168.140.0/24 -j ACCEPT          # 允许机房内网机器可以访问
$ iptables -A INPUT -p tcp -s 183.121.3.7 --dport 3380 -j ACCEPT  # 允许 183.121.3.7 访问本机的 3380 端口

黑名单

iptables -I INPUT -s 123.45.6.7 -j DROP       # 屏蔽单个 IP
iptables -I INPUT -s 123.0.0.0/8 -j DROP      # 屏蔽 IP 网段 从 123.0.0.1  到 123.255.255.254
iptables -I INPUT -s 124.45.0.0/16 -j DROP    # 屏蔽 IP 网段 从 123.45.0.1 到 123.45.255.254
iptables -I INPUT -s 123.45.6.0/24 -j DROP    # 屏蔽 IP 网段 从 123.45.6.1 到 123.45.6.254

防止 SYN 洪水攻击

$ iptables -A INPUT -p tcp --syn -m limit --limit 5/second -j ACCEPT

小结

iptables 是一个配置 Linux 内核防火墙的命令行工具,可以根据设定的规则对网络数据包进行过滤、修改和重定向等操作,工作在 OSI 模型 中的网络层和传输层。

撰写本文过程中,笔者发现中文内容几乎说的都是 四表五链,不知是作者刻意跳过 Security 表,还是抄袭导致的同质化太严重。 虽然 Security 表不是常用功能,但是我们不能忽略其存在。

Reference