Netfilter
Netfilter 概括
-
Linux核心中的一个通用 架构
-
工作在内核空间
-
在此框架上实现 包过滤、NAT 等模块功能
-
设置的规则存放在 内核 中
Iptables
Iptables 概括
-
Netfilter上层的编写规则工具
-
工作在用户空间
-
由 tables、chain、rule设置规则,集合成规则集,即 过滤条件
-
通过Netfilter暴露的内核接口 对 存放在内核中的Netfilter配置表进行修改
Iptables 四表五链
Iptables由 一系列表(tables)、每个表中由若干链(chain)、每条链中由一条或者多条规则(rule)组成,最常用到的是 四表五链
tables
tables具有 优先级 顺序: filter < NAT < mangle < raw
tables | 说明 | 支持的链 |
---|---|---|
filter | 默认的表,包含过滤规则 | INPUT |
FORWARD | ||
OUTPUT | ||
NAT | 包含源、目的地址和端口转换使用的规则 | PREROUTING |
OUTPUT | ||
POSTROUTING | ||
mangle | 设置特殊的数据包路由标志的规则 | 五个链都可以 |
raw | 实现数据跟踪 | PREROUTING |
OUTPUT |
filter表
-
默认表
-
对数据包过滤
filter在内核中调用iptables_filter,该模块的初始化在 net/ipv4/netfilter/iptables_filter.c -->iptables_filter_init中
从以下代码看,filter在初始化是注册了三个Hook point
# 部分代码 static struct nf_hook_ops ipt_ops[] __read_mostly = { # 这是注册的 INPUT 的链 { .hook = ipt_local_in_hook, .owner = THIS_MODULE, .pf = NFPROTO_IPV4, .hooknum = NF_INET_LOCAL_IN, .priority = NF_IP_PRI_FILTER, }, # 这是注册的 FORWARD 的链 { .hook = ipt_hook, .owner = THIS_MODULE, .pf = NFPROTO_IPV4, .hooknum = NF_INET_FORWARD, .priority = NF_IP_PRI_FILTER, }, # 这里注册的是 OUTPUT 的链 { .hook = ipt_local_out_hook, .owner = THIS_MODULE, .pf = NFPROTO_IPV4, .hooknum = NF_INET_LOCAL_OUT, .priority = NF_IP_PRI_FILTER, }, }; # 最终调用代码 /* Returns one of the generic firewall policies, like NF_ACCEPT. */ unsigned int ipt_do_table(struct sk_buff *skb, unsigned int hook, const struct net_device *in, const struct net_device *out, struct xt_table *table)
NAT表
-
Network Address Translation 网络地址转换
-
目的:将内部网络IP 转换为 合法公网IP的技术
-
方法:修改数据包报头IP、port信息,实现数据包的伪装、平衡负载、端口转发以及透明代理。
-
NAT的三种类型
-
静态NAT(Static NAT):一对一转换
-
动态NAT(dynamic NAT): 多对多转换
-
NAPT(Network Address Port Translation): 通过端口转换实现多对一。可进行如下细分
-
源NAT(SNAT):修改数据包的源地址。改变数据流第一个数据包的来源地址,比如数据包伪装
-
-
条件:数据包被送往POSTROUTING链
- **目的NAT**(DNAT):修改数据包的目的地址,改变第一个数据包的目的地址,比如**负载均衡、端口转发、透明代理**
条件:数据包被送往PREROUTING链
-
NAT的工作原理:
-
NAT的例子
# DNAT,把对192.168.42.1的访问转发到192.168.0.2上 sudo iptables -t nat -A PREROUTING -d 192.168.42.1 -j DNAT --to-destination 192.168.0.2 # SNAT,把要流出本机的数据源地址改成192.168.42.3 sudo iptables -t nat -A POSTROUTING -s 192.168.0.0/24 -j SNAT --to-source 192.168.42.3
mangle表
raw表
chains
chains | describe |
---|---|
PREROUTING | 用于路由判断前的规则,如修改目的地址(DNAT) |
INPUT | 数据包通过路由计算判断出目的地为本地的Linux系统,则通过此链检查 |
OUTPUT | 用来针对所有本地生成的包 |
FORWARD | 目的地不为本机地址,需要转发 |
POSTROUTING | 用于路由判断后的规则,如修改源地址(SNAT) |
target
target中大部分规则通用,此处列举常用
target | describe |
---|---|
ACCEPT | 满足匹配条件就接受数据包 |
DROP | 满足匹配条件就丢弃数据包 |
REJECT | 和DROP类似,拦截数据包,并返回错误信息 |
SNAT | 源网络地址转换 |
DNAT | 目的网络地址转换 |
MASQUERADE | 和SNAT类似,区别是 不需要指定 -to-source |
REDIRECT | 满足匹配条件就将转发数据包到另一个端口 |
MIRROR | 颠倒IP头部中的源目地址,然后再转发包 |
Iptables 状态
数据包被跟踪连接有4种不同的 Status:
-
NEW : 数据包开始一个新连接 (重新连接或将连接重定向)
-
RELATED : 数据包是基于已经建立的连接 而建立的新连接
-
EATABLISHED : 只要发送并接到应答,一个数据连接就从NEW变为ESTABLISHED。
-
INVALID : 异常的数据包,无法确认属于那个连接 或 没有任何状态(内存溢出可能造成这个情况)。该类包会被DROP掉。
Iptables 语法
标准语法
iptables [-t tables] COMMAND chains CRETIRIA -j target
-
-t table : filter \ nat \ mangle \ raw
-
COMMAND : 执行的操作
-
chain : 定义规则链上的操作
-
CRETIRIA : 指定匹配标准
-
-j target : 指定数据包的处理方式
COMMAND
COMMAND | describe |
---|---|
-A | 新增规则,在当前链的最后新增一个规则 |
-I | 插入规则,把当前规则插入为第几条 |
-R | 替换/修改第几条规则 |
-D | 删除第几条规则 |
-P | 设置默认策略 |
-L | 显示指定表和指定链的规则 |
CRETIRIA
CRETIRIA | describe |
---|---|
-i | 数据包进入本机的网络接口(比如eth0) |
-o | 数据包离开本机的网络接口 |
-p | 匹配数据包的协议类型 |
-s | 匹配数据包源IP地址 |
-d | 匹配数据包目的IP地址 |
--sport | 源端口号 |
--dport | 目的端口号 |
Iptables 常用命令
如何查看,插入规则
# 查看已有的规则 -n numric数字化 -v verbose详细 iptables -nvL
# 将所有访问 40:80 端口的数据包都丢掉 sudo iptables -t filter -I INPUT -p tcp --dport 40:80 -j DROP # 只是查看 INPUT 链是否加入了这条规则 sudo iptables -nvL INPUT
iptables-save
方便的看到已经插入规则的语句
iptables-save