深入理解Iptables、Netfilter、SNAT和DNAT

深入理解Iptables、Netfilter、SNAT和DNAT

  • 一、规则表
  • 二、处理规则
  • 三、匹配的参数
  • 四、匹配后的动作
  • 五、规则管理工具:Iptables命令
  • 六、链管理命令
  • 七、规则管理命令
  • 八、查看管理命令
  • 九、详解-j ACTION
  • 十、匹配条件
  • 十一、扩展匹配
  • 十二、状态检测
  • 十三、iptables实例
  • 十四、SNAT和DNAT的实现
  • 十五、SNAT和DNAT实例

Linux提供了一套机制来为用户实现自定义的数据包处理过程。

在linux网络协议中有一组回调函数挂接点,通过这些挂接点挂接的钩子函数可以在linux网络栈处理数据包的过程中对数据进行一些操作,例如过滤、修改、丢弃等。整个挂接点技术叫作Netfilter和Iptables。

Netfilter负责在内核中执行各种挂接的规则,运行在内核模式中。而Iptables是在用户模式下运行的进程,负责协助维护内核中Netfilter的各种规则表。通过二者的配合来实现整个Linux网络协议栈中灵活的数据包处理机制。

Netfilter可以挂接的规则点有5个(链):

  • INPUT
  • OUTPUT
  • FORWARD
  • PREROUTING
  • POSTROUTING
  • 流入:PREROUTING -> INPUT
  • 流出:OUTPUT -> POSTROUTING
  • 转发:PREROUTING -> FORWARD -> POSTROUTING

在这里插入图片描述

一、规则表

挂接点能挂接的规则也分不同的类型(也就是规则表Table),可以在不同类型的Table中加入规则。目前主要支持的Table类型如下:

  • RAW:关闭nat表上启用的连接追踪机制
  • MANGLE:拆解报文,作出修改,封装报文
  • NAT:网络地址转换
  • FILTER:过滤、防火墙

上述4个Table(规则链)的优先级是RAW最高,FILTER最低。在实际应用中,不同的挂接点需要的规则类型通常不同。例如:在Input的挂接点上明显不需要FILTER过滤规则,因为根据目标地址,已经选择好本机的上层协议栈了,所以无需再挂接FILTER过滤规则。

当Linux协议栈的数据处理运行到挂接点时,会依次调用挂接点上所有的挂钩函数,直到数据包的处理结果是明确地接受或者拒绝。

  • 功能优先级次序:raw -> mangle -> nat -> filter
  • 对于filter来讲一般只能做在3个链上:INPUT ,FORWARD ,OUTPUT
  • 对于nat来讲一般也只能做在3个链上:PREROUTING ,OUTPUT ,POSTROUTING
  • 而mangle则是5个链都可以做:PREROUTING,INPUT,FORWARD,OUTPUT,POSTROUTING

规则的写法:

iptables [-t table] COMMAND chain CRETIRIA -j ACTION
  • -t table:3个filter nat mangle
  • COMMAND:定义如何对规划进行管理
  • chain:指定接下来的规则到底是在哪个链上操作,当定义策略的时候,是可以省略的
  • CRETIRIA:指定匹配标准
  • -j ACTION:指定如何进行处理

比如:不允许172.16.0.0/24进行访问

iptables -t filter -A INPUT -s 172.16.0.0/16 -p udp --dport 53 -j DROP

查看定义的详细规则

iptables -L -n -v

二、处理规则

每个规则的特性都分为以下几部分。

  • 表类型(准备干什么事情)
  • 什么挂接点(什么时候起作用)
  • 匹配的参数是什么(针对什么样的数据包)
  • 匹配后有什么动作(匹配后具体的操作是什么)

三、匹配的参数

匹配的参数用于对数据包或者TCP数据连接的状态进行匹配。当有多个条件存在时,它们一起起作用,来达到只针对某部分数据进行修改的目的。常见的匹配参数如下:

  • 流入、流出的网络接口
  • 来源、目的地址
  • 协议类型
  • 来源、目的端口

四、匹配后的动作

一旦数据匹配上,就会执行相应的动作。动作类型既可以是标准的预定义的几个动作,也可以是自定义的模块注册的动作,或者是一个新的规则链,以便更好地组织一组动作。

五、规则管理工具:Iptables命令

Iptables命令用于协助用户维护各种规则。查看系统中已有的规则的方法如下:

  • iptables-save:按照命令的方式打印Iptables的内容
  • Iptables-vnL:以另一种格式显示Netfilter表的内容

六、链管理命令

  • -F:flush,清空规则链,表示清空指定表上的所有链。iptables -t nat -F清空nat表的所有链
  • -N:new,创建新的自定义规则链
  • -X:drop,删除用户自定义的空的规则链
  • -P:policy,为指定链设置默认策略,对filter表中的链而言,默认策略通常有ACCEPT、DROP、REJECT。iptables -P INPUT (DROP|ACCEPT)
  • -E:重命名自定义链。

七、规则管理命令

  • -A:append,将新规则追加于指定链的尾部
  • -I num:insert,将新规则插入至指定链的指定位置。-I 3:插入为第三条
  • -D num:delete,删除指定链上的指定规则,明确制定删除第几条规则
  • -R num:replace,替换指定链上的指定规则

八、查看管理命令

  • -L:list,列出指定链上的所有规则
  • -n:numberic,以数字格式显示地址和端口号
  • -v:verbose,显示详细信息
  • -line-numbers:显示规则编号

九、详解-j ACTION

  • ACCEPT:接受
  • DROP:丢弃
  • REJECT:拒绝
  • RETURN:返回调用链
  • LOG:记录日志
  • MARK:做防火墙标记
  • DNAT:目标地址转换
  • SNAT:源地址转换
  • MASQUEPADE:地址伪装

十、匹配条件

  • [!] -s :指定作为源地址匹配,检查报文中源IP地址是否符合此处指定的地址范围。可以取反,表示除了哪个IP之外。
  • [!] -d:表示匹配目标地址,检查报文中目标IP地址是否符合此处指定的地址范围
  • -p:用于匹配协议的,检查报文中的协议,即ip首部中的protocols所标示的协议,通常有三种,TCP/UDP/ICMP
  • -i eth0:从这块网卡流入的数据,数据报文的流入接口,仅能用于PREROUTING、INPUT及FORWARD链上
  • -o eth0:从这块网卡流出的数据,数据报文的流出接口,仅能用于FORWARD、OUTPUT及POSTROUTING链上

十一、扩展匹配

  • -p tcp、udp、icmp:TCP、UDP、ICMP
  • -dport xx-xx:指定目标端口,不能指定多个非连续端口,只能指定单个端口,比如-dport 21 ,-dport 21-23
  • -sport:指定源端口
  • -m multiport:表示启用多端口扩展

十二、状态检测

对于整个TCP协议来讲,它是一个有连接的协议,三次握手中,第一次握手,就叫NEW连接。
第二次握手以后的,ack都为1,这是正常的数据传输,和tcp的第二次第三次握手,叫做已建立的连接(ESTABLISHED)
还有一种状态,比较诡异的,比如:SYN=1 ACK=1 RST=1,对于无法识别的,都称之为INVALID无法识别的。
还有第四种,FTP拥有的特征,每个端口都是独立的,21号和20号端口都是一去一回,他们之间是有关系的,这种关系我们称之为RELATED。

所以我们的状态一共有四种:

  • NEW
  • ESTABLISHED
  • RELATED
  • INVALID

十三、iptables实例

清空防火墙策略

iptables -F

凡是目标ip为172.25.254.1的tcp报文都接受

iptables -t filter -A INPUT -d 172.25.254.1 -p tcp -j ACCEPT

凡是从ip为172.25.254.1出去的tcp报文都放行

iptables -t filter -A OUTPUT -s 172.25.254.1 -p tcp -j ACCEPT

iptables -L

删除策略

iptables -L --line-mumbers
iptables -D INPUT 2
iptables -D OUTPUT 2

来自于172.16.0.0/16网段的都允许访问我本机的172.16.100.1的SSH服务。访问本机服务,最好是定义在INPUT链上,出去定义在output链上

将默认策略改成DROP
iptables -P INPUT DROP
iptables -P OUTPUT DROP
iptables -P FORWARD DROP

iptables -t filter -A INPUT -s 172.16.0.0/16 -d 172.16.100.1 -p tcp -dport 22 -j ACCEPT
iptables -t filter -A OUTPUT -s 172.16.100.1 -d 172.16.0.0/16 -p tcp -dport 22 -j ACCEPT

进来的只允许ESTABLISHED进来,出去只允许ESTABLISHED出去。
默认规则都使用拒绝。
iptables -L -n –line-number :查看之前的规则位于第几行

iptables -R INPUT 2 -s 172.16.0.0/16 -d 172.16.100.1 -p tcp –dport 22 -m state –state NEW,ESTABLISHED -j ACCEPT
iptables -R OUTPUT 1 -m state --state ESTABLISHED -j ACCEPT

再放行一个80端口

iptables -A INPUT -d 172.16.100.1 -p tcp --dport 80 -m state --state NEW,ESTABLISHED -j ACCEPT

iptables -R INPUT 1 -d 172.16.100.1 -p udp --dport 53 -j ACCEPT

十四、SNAT和DNAT的实现

SNAT是指在数据包从网卡发送出去的时候,把数据包中的源地址部分替换为指定的IP,这样,接收方就认为数据包的来源是被替换的那个IP的主机
MASQUERADE是用发送数据的网卡上的IP来替换源IP,因此,对于那些IP不固定的场合,比如拨号网络或者通过dhcp分配IP的情况下,就得用MASQUERADE
DNAT,就是指数据包从网卡发送出去的时候,修改数据包中的目的IP,表现为如果你想访问A,可是因为网关做了DNAT,把所有访问A的数据包的目的IP全部修改为B,那么,你实际上访问的是B
DNAT是在PREROUTING链上来进行的,而SNAT是在数据包发送出去的时候才进行,因此是在POSTROUTING链上进行的
SNAT基于原地址的转换:基于原地址的转换一般用在我们的许多内网用户通过一个外网的口上网的时候,这时我们将我们内网的地址转换为一个外网的IP,就可以实现连接其他外网IP的功能。

将所有192.168.10.0网段的IP在经过的时候全部转换成172.16.100.1这个外网地址:

iptables -t nat -A POSTROUTING -s 192.168.10.0/24 -j SNAT -to-source 172.16.100.1

来自本地网络的试图通过网卡访问网络的,都会被统统转换成172.16.100.1这个IP。
外网地址是动态变换的。就要将外网地址换成 MASQUERADE(动态伪装):它可以实现自动寻找到外网地址,而自动将其改为正确的外网地址。所以,我们就需要这样设置:

iptables -t nat -A POSTROUTING -s 192.168.10.0/24 -j MASQUERADE

DNAT目标地址转换:
对于目标地址转换,数据流向是从外向内的,外面的是客户端,里面的是服务器端通过目标地址转换,可以让外面的ip通过我们对外的外网ip来访问我们服务器不同的服务器,而我们的服务却放在内网服务器的不同的服务器上。

iptables -t nat -A PREROUTING -d 192.168.10.18 -p tcp --dport 80 -j DNAT --todestination 172.16.100.2

目标地址转换要做在到达网卡之前进行转换,所以要做在PREROUTING这个位置上

十五、SNAT和DNAT实例

现在只有一个IP(10.144.235.10)可以上internet,希望局域网中的三台机器通过SNAT均可上网。

iptables -t nat -A POSTROUTING -s  192.168.80.0/24 -j SNAT --to-source 10.144.235.10

eth0的IP为dhcp获取,IP不固可使用下面转发规则

iptables-t nat -A POSTROUTING -s 192.168.80.0/24 -o eth0 -j MASQUERADE

使用DNAT转发computer1的80端口到10.144.235.10的8088端口

iptables -t nat -A PREROUTING -i eth1 -p tcp --dport 8088 -j DNAT --to-destination 192.168.80.10:80

你可能感兴趣的:(日常分享专栏,linux,K8s,Iptables,SNAT和DNAT,Netfilter)