本文整理自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 查看相关表:

`filter` 表查看

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 处理流程

`netfilter-packet-filter`

iptableskube-proxy 的处理流程

`kube-proxy-iptables`

关于 kube-proxy 的规则处理,可以借鉴博文理解kube-proxyiptable规则

如上表解析:
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的流量 (filterINPUT 链)

2、 丢弃去往XXX的流量 (filterOUTPUT链)

3、 只接收来自XXX的流量 (filterINPUT 链)

4、 在流量刚流入时,将目的地址改写成其他地址(natpreouting链)

5、 在流量即将流出时,将源地址改写成其他地址(natpostouting链)

6、 将发往 A 的数据包,转发给B(filterforward链)

iptables-flow-zsy(出自https://www.zsythink.net/archives/1199)

iptable-flow

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
2
# 其中的20:30表示20和30之间的所有端口
iptables -t ${表名} ${commands} ${chain} ${规则号} --dport 20:30 -j ${动作}

想指定多个不连续的端口可以使用iptablesmultiport

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 查看帮助文档
~]# iptables -m multiport --help
...
multiport match options:
[!] --source-ports port[,port:port,port...]
--sports ...
match source port(s)
[!] --destination-ports port[,port:port,port...]
--dports ...
match destination port(s)
[!] --ports port[,port:port,port]
match both source and destination port(s)


#命令例子
iptables -t ${表名} ${commands} ${chain} ${规则号}
${-p 协议} -m multiport --dports 20,30 -j ${动作}


#相当于如下两行命令
iptables -t ${表名} ${commands} ${chain} ${规则号} -p ${协议} --dprot 20 -j ${动作}
iptables -t ${表名} ${commands} ${chain} ${规则号} -p ${协议} --dprot 30 -j ${动作}
  • ip 范围
1
2
3
4
~]# iptables -m iprange --help
iprange match options:
[!] --src-range ip[-ip] Match source IP in the specified range
[!] --dst-range ip[-ip] Match destination IP in the specified range
  • 连接状态
1
2
3
~]# iptables -m state --help
state match options:
[!] --state [INVALID|ESTABLISHED|NEW|RELATED|UNTRACKED][,...]

参考借鉴