iptables 入门出坑
本文整理自
iptables
长文详解,值得收藏细读
整理此篇博文的初衷还是因为目前很多k8s
的内部的service
路由规则还是通过iptables
来实现的,否则最终还是只停留在使用层面,能够让我们对某个服务夯住又多了个排查利器。
Linux
的网络控制模块在内核中,叫做netfilter
。而iptables
是位于用户空间的一个命令行工具,它作用在OIS7层网络模型中的第四层[物理层,数据链路层,网络层,传输层,会话层,表示层,应用层],用来和内核的netfilter
交互,配置netfilter
进而实现对网络的控制、流量的转发。
主要功能:
- 流量转发:
DNAT
实现IP
地址和端口的映射 - 负载均衡:
statistic
模块为每个后端设置权重 - 会话保持:
recent
模块设置会话保持时间
基本两要素
表和链路,5表5链路。
5张表分别是:raw
,filter
,nat
,mangle
,security
5条链路分别是:prerouting
,input
,forward
,output
,postrouting
通过 iptables -t ${table} -nL
查看相关表:
graph LR R[iptables]-->FT(filter表) FT-->FTFIC(input链) FTFIC-->在入口对流量做过滤 FT-->FTFC(forward链) FTFC-->做流量转发 FT-->FTOC(output链) FTOC-->在出口对流量做过滤 FT-->作用:常用于控制到达某条链路上的数据是继续放行,丢弃,拒绝 R-->NT(nat表) NT-->NTPREC(prerouting链) NTPREC-->做dnat目标地址转换 NT-->NTIC(input链) NT-->NTOC(output链) NT-->NTPOSTC(postouting链) NTPOSTC-->做snat源地址转换 NT-->常用于修改数据包的原地址,目的地址 R-->MT(mangle表) MT-->MTPREC(prerouting) MT-->MTIC(input链) MT-->MTFC(forward链) MT-->MTOC(output链) MT-->MTPOSTC(postouting链) MT-->常用于修改ip数据包的头信息 R-->RT(raw表) RT-->RTPREC(prerouting链) RT-->RTOC(output链) RT-->对连接的状态进行追踪,常见的状态有new,established R-->ST(security表) ST-->是新加入的表,用于将数据包应用在selinux上
流量走向分析
对于流量的分析,我们可以考虑两个场景:
- 来及本机的流量经过了
iptables
的哪些节点,最终又到哪里去了? - 来自互联网的外界流量,是如何经历
iptables
的,然后最终的去处?
iptables
处理流程
iptables
在 kube-proxy
的处理流程
关于
kube-proxy
的规则处理,可以借鉴博文理解kube-proxy
中iptable
规则
如上表解析:
1、 红,蓝,绿,紫分别代表上iptables
的四张表,如果开启了seLinux
,会多出一个security
表。
2、上图左上角部分:incoming packet
,表示这是从互联网设备过来的流量,会经历各个表的preouting
阶段,再由routing decision
(路由选择)决定这些流量是由本机处理还是forward
转发走。
3、上图左上角部分:incoming packet
在做 routing descision
之前会经过nat preouting
阶段,在此阶段可以做dnat
,可以简单理解为:比如这个数据包原来的dst ip
是百度的,经过routing desicion
之后进入forward
转发阶段,这个时候改写目标地址为自己本机,让数据进入input
通路,可以在本机截获这个数据包。
4、上图右上角部分:locally generated packet
,表示这是本机自己生成的流量。它会一路经过各个表的output
链,然后流到output interface
(网卡)上。你注意下,流量在被打包成outgoing packet
之前,会有个localhost dest
的判断,如果它判断流量不是发往本机的话,流量会经过nat
表的postrouting
阶段。一般会在这里做DNAT源地址改写。
理解如上流程,我们可以灵活的对流量进行自定义控制,通常的流量控制无非如下:
1、 丢弃来自XXX的流量 (filter
表 INPUT
链)
2、 丢弃去往XXX的流量 (filter
表 OUTPUT
链)
3、 只接收来自XXX的流量 (filter
表 INPUT
链)
4、 在流量刚流入时,将目的地址改写成其他地址(nat
表preouting
链)
5、 在流量即将流出时,将源地址改写成其他地址(nat
表postouting
链)
6、 将发往 A
的数据包,转发给B
(filter
表forward
链)
iptables commands
1 | iptabls -t ${表名} ${Commands} ${链名} ${链中规则} ${匹配条件} ${目标动作} |
命令行属性 | 属性列表 | 说明 |
---|---|---|
表名 | raw | iptables 是有状态的,其对数据包有链接追踪机制,链接追踪信息在/proc/net/nf_conntrack 中可以看到记录 |
filter | 用于控制到达某条链接上的数据包是继续放行,直接丢弃还是拒绝 | |
mangle | 用于修改数据包的IP头信息 | |
nat | network address translation 网络地址转换,用于修改数据包的源地址和目的地址 | |
security | 不常用的表,用在SeLinux上 | |
Commands | PREOUTING | 数据包进入之前,可以在此进行DNAT |
POSTOUTING | 发送到网卡之前,可以在此处进行SNAT | |
INPUT | 一般处理本地进程的数据包,目的地址为本机 | |
OUTPUT | 原地址为本机,向外发送,一般处理本地进程的数据数据包 | |
FORWARD | ||
POSTROUTING | ||
Commands | -A | 添加 |
-C | 检查 | |
-C | 检查 | |
-D | 删除 | |
-I | 在头部插入 | |
-R | 替换 | |
-L | 查看全部 | |
-F | 清空 | |
-N | 新建 | |
-P | 默认是ACCEPT | |
匹配条件 | -p | 协议,-4,-6 |
-s | 源地址 | |
-d | 目的地址 | |
-i | 网络接口名称 | |
目标动作 | -j REJECT | 拒绝访问 |
-j ACCEPT | 允许通过 | |
-j DROP | 丢弃 | |
-j LOG | 记录日志 | |
-j SNAT | 源地址转换 | |
-j DNAT | 目标地址转换 | |
RETURN,QUEUE |
iptables
的匹配规则
常见的规则如下:
源地址:-s 192.168.1.0/24
目标地址:-d 192.168.1.11
协议:-p tcp|udp|icmp
从哪个网卡进来:-i eth0|lo
从哪个网卡出去:-o eth0|lo
目标端口(必须制定协议):-p tcp|udp --dport 8080
源端口(必须制定协议):-p tcp|udp --sport 8080
iptables
中的每条规则顺序都是由上至下顺序执行的,除非碰到了 DROP
,REJECT
,RETURN
。
还有就是如果定义的动作是JUMP
,那就会相应的 jump
到指定链路上的指定规则:
graph TB chain1((chain1)) --> rule1-1((rule1-1)) chain2((chain2)) --> rule2-1((rule2-1)) rule1-1 --> rule1-2((rule1-2)) rule1-2 --> rule1-3((rule1-3)) rule2-1 --> rule2-2((rule2-2)) rule2-2 --> rule2-3((rule2-3)) rule1-2 --JUMP--> rule2-1 rule2-3 --JUMP--> rule1-3
iptables
中的模块
- 多端口
可以如下执行命令:
1 | # 其中的20:30表示20和30之间的所有端口 |
想指定多个不连续的端口可以使用iptables
的multiport
。
1 | # 查看帮助文档 |
ip
范围
1 | ~]# iptables -m iprange --help |
- 连接状态
1 | ~]# iptables -m state --help |
参考借鉴