文章
问答
冒泡
Iptables 入门出坑!

本文整理自iptables长文详解,值得收藏细读 如果需要高清大图也可以通过个人站点查看😉iptables入门出坑

整理此篇博文的初衷还是因为目前很多 k8s 的内部的 service 路由规则还是通过 iptables 来实现的,否则最终还是只停留在使用层面,能够让我们对某个服务夯住又多了个排查利器。 Linux 的网络控制模块在内核中,叫做netfilter。而iptables是位于用户空间的一个命令行工具,它作用在OSI7层网络模型中的第四层[物理层,数据链路层,网络层,传输层,会话层,表示层,应用层],用来和内核的netfilter交互,配置netfilter进而实现对网络的控制、流量的转发。

基本两要素

表和链路,5表5链路。

5张表分别是:raw,filter,nat,mangle,security 5条链路分别是:prerouting,input,forward,output,postrouting 通过 iptables -t ${table} -nL 查看相关表: 表查看 iptables-nt.png

流量走向分析

对于流量的分析,我们可以考虑两个场景:

  • 来及本机的流量经过了 iptables 的哪些节点,最终又到哪里去了?

  • 来自互联网的外界流量,是如何经历 iptables 的,然后最终的去处?

iptables 处理流程


iptableskube-proxy 的处理流程


关于 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链)

iptable-flow

iptables commands

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


Commands

-A

添加


-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 到指定链路上的指定规则: chain-jump.png

iptables 中的模块

  • 多端口

可以如下执行命令:

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

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

# 查看帮助文档
~]# 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 范围

~]# 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
  • 连接状态

~]# iptables -m state --help
state match options:
 [!] --state [INVALID|ESTABLISHED|NEW|RELATED|UNTRACKED][,...]

关于作者

Kirago
个人站点 https://kiragoo.github.io/
获得点赞
文章被阅读