iptables的核心概念
iptables是Linux系统中用来配置防火墙的命令。iptables是工作在TCP/IP的二、三、四层,当主机收到一个数据包后,数据包先在内核空间处理,若发现目标地址是自身,则传到用户空间中交给对应的应用程序处理,若发现目标不是自身,则会将包丢弃或进行转发。
四表:
- filter(用于过滤)
- nat(用于 NAT)
- mangle(用于修改分组数据)
- raw(用于原始数据包)
最常用的是filter 和 nat。对应下图中的绿色块。
五链:
- PREROUTING:用于路由判断前所执行的规则,比如,对接收到的数据包进行 DNAT。
- POSTROUTING:用于路由判断后所执行的规则,比如,对发送或转发的数据包进行 SNAT 或 MASQUERADE。
- OUTPUT: 类似于 PREROUTING,但只处理从本机发送出去的包。
- INPUT: 类似于 POSTROUTING,但只处理从本机接收的包。
- FORWARD
- 流入本机:PREROUTING --> INPUT-->用户空间进程
- 流出本机:用户空间进程 -->OUTPUT--> POSTROUTING
- 转发:PREROUTING --> FORWARD --> POSTROUTING
内网至外网用postrouting SNAT 外网至内网用prerouting DNAT
下图中白色背景方框,则表示链(chain)
iptables命令
一、链管理:
-N: new 自定义一条新的规则链
-X: delete 删除自定义的空的规则链
-P:policy 设置默认策略
ACCEPT:接受
DROP:丢弃
-E:重命名自定义链
二、查看:
-L: list
-n:以数字格式显示地址和端口号
-v:详细信息
三、规则管理:
-A : append 追加
-I:insert 插入
-D:delete 删除
-F:flush 清空指定规则链
-R:replace 替换指定链上的规则编号
-Z: zero :置零
iptables -L 列出规则,默认为filter表的规则。
[root@node100 ~]# iptables -L Chain INPUT (policy ACCEPT) target prot opt source destination Chain FORWARD (policy DROP) target prot opt source destination DOCKER-USER all -- anywhere anywhere DOCKER-ISOLATION-STAGE-1 all -- anywhere anywhere ACCEPT all -- anywhere anywhere ctstate RELATED,ESTABLISHED DOCKER all -- anywhere anywhere ACCEPT all -- anywhere anywhere ACCEPT all -- anywhere anywhere Chain OUTPUT (policy ACCEPT) target prot opt source destination Chain DOCKER (1 references) target prot opt source destination Chain DOCKER-ISOLATION-STAGE-1 (1 references) target prot opt source destination DOCKER-ISOLATION-STAGE-2 all -- anywhere anywhere RETURN all -- anywhere anywhere Chain DOCKER-ISOLATION-STAGE-2 (1 references) target prot opt source destination DROP all -- anywhere anywhere RETURN all -- anywhere anywhere Chain DOCKER-USER (1 references) target prot opt source destination RETURN all -- anywhere anywhere
iptables -t nat -L 列出nat表的规则。
[root@node100 ~]# iptables -t nat -L Chain PREROUTING (policy ACCEPT) target prot opt source destination DOCKER all -- anywhere anywhere ADDRTYPE match dst-type LOCAL Chain INPUT (policy ACCEPT) target prot opt source destination Chain OUTPUT (policy ACCEPT) target prot opt source destination DOCKER all -- anywhere !loopback/8 ADDRTYPE match dst-type LOCAL Chain POSTROUTING (policy ACCEPT) target prot opt source destination MASQUERADE all -- 172.17.0.0/16 anywhere Chain DOCKER (2 references) target prot opt source destination RETURN all -- anywhere anywhere
iptables中的第一个选项可以是-A, 表明向链(chain)中添加一条新的规则,也可以是-I,表明将新的规则插入到规则集的开头。接下来的参数指定了链。
所谓链就是若干条规则的集合
OUTPUT链它可以控制所有的出站流量(outgoing traffic)。
INPUT链它能够控制所有的入站流量(incoming traffic)。
-d指定了所要匹配的分组目的地址,
-s指定了分组的源地址。
-j指示iptables执行到特定的处理(action)
实战
需求:
在192.168.56.3 上启动一个nginx,暴露8088端口
想要在192.168.56.4 上使用8099访问192.168.56.3 上的nginx服务。使用iptables如何实现?
1、192.168.56.3 拉起nginx服务,并暴露8088端口
2、在192.168.56.4上配置iptables
- 配置iptables将192.168.56.3 nginx 8088的数据包转发到192.168.56.4的8099端口上
- 把.192.168.56.3发送到.3:8088的数据包源地址修改为192.168.56.4 的地址。
pre 路由前
post路由后
-j 后跟执行的action
# -j表示iptables要执行的动作; DANT 目的地址转换为 部署的nginx ]# iptables -t nat -A PREROUTING -p tcp --dport 8099 -j DNAT --to 192.168.56.3:8088 # -d指定了所要匹配的分组目的地址,此处应该是可以支持cidr的 ]# iptables -t nat -A POSTROUTING -p tcp -d 192.168.56.3 --dport 8088 -j SNAT --to 192.168.56.4
查看iptables nat表
此时访问192.168.56.4:8099 无法看到nginx访问页面。
查看linux主机是否开启了ip转发功能
]# cat /proc/sys/net/ipv4/ip_forward
0
开启主机的转发功能
sysctl -w net.ipv4.ip_forward=1
net.ipv4.ip_forward = 1
成功转发
流程图:
iptables和docker的关系?
vagrant拉起一台虚拟机
vagrant up
查看iptables nat表
我们应该关注postrouting链和docker链比较启动nginx前后的对比
启动一个nginx命令
~]#docker run -d -p 8088:80 --name=nginx251 nginx
比较iptables
iptables中的内容均为docker 自动新增的.
解读新增的nat链
nginx容器启动后分别在postrouting 链和docker chain新增了SANT 和DANT。
先解读DANT
DNAT tcp -- anywhere anywhere tcp dpt:radan-http to:172.17.0.2:80
这个对应的iptables 命令为:
# -j表示iptables要执行的动作; DANT 目的地址转换为 部署在容器中的nginx
]# iptables -t nat -A PREROUTING -p tcp --dport 80 -j DNAT --to 172.17.0.2:80
postroting链新增
MASQUERADE tcp -- 172.17.0.2 172.17.0.2 tcp dpt:http
这个对应的iptables 命令为:
# -d指定了所要匹配的目的地址, -j执行的action,-j后也可以写成 SNAT --to 10.50.10.251
# Linux 选择默认的出口 IP。这实际上就是经常说的 MASQUERADE
]#iptables -t nat -A POSTROUTING -p tcp -d 172.17.0.2 --dport 80 -j MASQUERADE
如何禁止docker的默认行为-修改 iptables?
--iptables=false
docker启动命令加入如上参数然后关闭默认添加iptables的功能.
参考:
https://www.ichenfu.com/2018/09/09/packet-flow-in-netfilter/