iptables 实际上包含两部分内容
一部分在 Linux 内核中 , 叫做 NetFilter
另一部分在用户空间中,也就是我们平时用来定义规则的 iptables
TABLE
- Filter 用于过滤数据包
- Nat 用于网络地址转换
- Mangle 用于修改TOS
- Raw 优先级最高,会跳过 NAT 和 ip_conntrack,只使用在PREROUTING chain 和 OUTPUT chain 上
CHAIN
- PREROUTING:对数据包进行路由选择前(nat表中,DNAT)
- INPUT:路由选择之后,发现数据包目的地址是本机,入站时(filter表中)
- FORWARD:路由选择之后接收到需要通过防火墙发送给其它主机(转发时)(filter表)
- POSTROUTING:对数据包进行路由选择后,数据包到路由器进行路由判断之后经过的链(nat表,SNAT)
- OUTPUT:出站时(nat,filter表)
iptables主要有以下动作:
- ACCEPT:接收数据包
- DROP:丢弃数据包
- REJECT:丢弃数据包并返回一个错误包
- SNAT:做源地址转化
- DNAT:做目的地址转化
- MASQUERADE:地址伪装,用于动态IP
- LOG:将这条匹配消息保存到系统日志中
- REDIRECT:在防火墙所在的机子内部转发包或流到另一个端口
- 用户自定义的链名(net2all):跳转到这条链下,进行匹配
确认系统的转发功能是打开的
echo 1 > /proc/sys/net/ipv4/ip_forward
1、iptables -L
查看filter表的iptables规则,包括所有的链。filter表包含INPUT、OUTPUT、FORWARD三个规则链。
说明:-L是--list的简写,作用是列出规则。
2、iptables -L [-t 表名]
只查看某个表的中的规则。
说明:表名一共有三个:filter,nat,mangle,如果没有指定表名,则默认查看filter表的规则列表(就相当于第一条命令)。
举例:iptables -L -t filter
3、iptables -L [-t 表名] [链名]
这里多了个链名,就是规则链的名称。
说明:iptables一共有INPUT、OUTPUT、FORWARD、PREROUTING、POSTROUTING五个规则链。
举例:iptables -L INPUT
注意:链名必须大写。在Linux系统上,命令的大小写很敏感。
4、iptables -n -L
说明:以数字形式显示规则。如果没有-n,规则中可能会出现anywhere,有了-n,它会变成0.0.0.0/0
5、iptables -nv -L
说明:你也可以使用“iptables -L -nv”来查看,这个列表看起来更详细,对技术人员更友好
下面是一些具体例子
SNAT 源地址转换
SNAT一般作用在 POSTROUTING 上,最典型的应用是,多个用户通过一个外网口上网
iptables -t nat -A POSTROUTING -s 192.168.10.0/24 -j SNAT --to-source 172.16.100.1
所有来自于 192.168.10.0/24网段的数据包,通过 anywhere 访问网络的,目标地址都会被转换成 172.16.100.1
说人话就是,一个 IP 是 192.168.10.2 的 虚拟机,通过任意网卡请求 baidu.com , 数据包都会进入 172.16.100.1
上图中的规则
MASQUERADE all -- 172.17.0.0/16 anywhere
是 docker 正在使用的规则
从 docker ip 段 172.17.0.0/16 发出的消息报,都会被发送到 MASQUERADE(动态伪装)
MASQUERADE(动态伪装) 可以实现自动寻找到外网地址,而自动将其改为正确的外网地址
例子
iptables -t nat -A POSTROUTING -s 192.168.10.0/24 -j MASQUERADE
DNAT: 目的IP地址转换(PREROUTING)
出口网关再将目的地址替换为私网的源主机地址,发回内部主机。
DNAT主要有两大用处
- 发布内部服务器,让外面的internet用户能访问到内网的服务器
- 网络重定向
最直观的例子是
docker run -i -t --name nginx -p 80:80 nginx
这样得了一个ip是 172.17.0.2 的容器
DNAT目标地址转换规则
0 0 DNAT tcp -- !docker0 * 0.0.0.0/0 0.0.0.0/0 tcp dpt:80 to:172.17.0.2:80
这条规则指的是
非 docker0 网卡发送到 tcp dpt:80 的地址 转发给 172.17.0.2:80
SNAT 规则
0 0 SNAT all -- * * 192.168.10.0/24 0.0.0.0/0 to:172.16.100.1
也就是我们之前配置的,所有来自于 192.168.10.0/24网段的数据包,通过 anywhere 访问网络的,目标地址都会被转换成 172.16.100.1
一般来说,单纯使用 iptables是不足以让docker的基础网络运行的,route也很重要
参考