iptables

0 目录

文章目录

  • 0 目录
  • 1 netfilter机制
    • 1.1 各链的生效时机(重要)
    • 1.2 流入报文的流程
    • 1.3 转发报文的流程
    • 1.4 流出报文的流程
  • 2 iptables表、链
    • 2.1 iptables各表
    • 2.2 iptables各表定义规则的链
    • 2.3 各表、各链规则生效的优先级
    • 2.4 自定义链
  • 3 iptables格式及子命令
    • 3.1 子命令
      • 3.1.1 列出各规则
  • 4 常见匹配条件
    • 4.1 基本匹配
    • 4.2 隐式扩展匹配
      • 4.2.1 tcp子选项
      • 4.2.2 icmp子选项
    • 4.3 显式扩展
      • 4.3.1 模块multiport及子选项
      • 4.3.2 模块iprange
      • 4.3.3 模块time
      • 4.3.4 模块string
      • 4.3.5 模块connlimit
      • 4.3.6 模块limit
      • 4.3.7 模块state
        • 4.3.7.1 连接追踪机制
        • 4.3.7.2 连接各状态及state模块子选项
  • 5 处理动作
    • 5.1 通用处理动作
    • 5.1 filter表的常用处理动作
    • 5.2 nat表常用处理动作
  • 6 filter表常用规则
    • 6.1 主机防火墙
      • 6.1.1 指定主机访问
      • 6.1.2 指定端口访问
      • 6.1.3 限制ping报文
      • 6.1.4 限制有指定字符串的报文
      • 6.1.5 限制主机发起的连接数
      • 6.1.6 限制报文速率
    • 6.2 网络防火墙
      • 6.2.1 环境说明
      • 6.2.2 验证效果
  • 7 nat表常用规则
    • 7.1 源地址转换
      • 7.1.1 拨号上网的情况
    • 7.2 目标地址转换
      • 7.2.1 在本机上做端口映射
  • 8 规则设置原则

1 netfilter机制

为实现报文的安全传输,屏蔽某些攻击;或是转换报文的源、目标地址,内核开发者在5个精心选择的位置开发了钩子函数(即netfilter功能模块),用于实现在不同位置检查、处理流经的网络报文。相当于路上的卡点。

iptables称这些钩子函数为“链”(chain)。iptables就是在这些链上定义规则的工具

5个链的位置:

iptables_第1张图片

说明:
1、为叙述方便,把网卡设备也使用图形表示出来,虽然它们并不是进程;以网卡1作为报文流入的接口,网卡2作为报文流出的接口;
2、其他如各链、路由选择、各应用进程,都是在主机上运行的进程。前者由内核实现,后者由各应用程序实现。
3、因为网卡1、2分别作为流入和流出报文的接口,所以将PREROUTING和POSTROUTING分别放在了两网卡边。实际上不论是哪个网卡,只要是流入的报文,都会立即经过PREROUTING链“检查”;流出的报文流出前,都会经过POSTROUTING链“检查”

下面也是以此模型展开。

1.1 各链的生效时机(重要)

要在不同的链上定义切实能起作用的规则,就要理解各链上规则的生效时机:

生效时机
PREROUTING 报文到达主机网卡的一刹那,就会被主机的PREROUTING链上的规则检查
INPUT 经过PREROUTING的报文,之后进行路由选择1。如果是要发给主机某进程的报文,则经过INPUT链上定义的规则检查
FORWARD 经过PREROUTING的报文,进行路由选择。如果是要发给其他主机的报文,则经过FORWARD链上定义的规则检查2
OUTPUT 主机要发送给其他主机的报文(不论是响应对方还是向对方主动发),首先经过OUTPUT链
POSTROUTING 在本机报文发送出主机前一刹那,经过POSTROUTING链上的规则检查

下面分别说明流入、流出、转发的报文所经流程:

1.2 流入报文的流程

这里仅列出与流入报文有关的链,其他忽略,下同。
其他主机向当前主机某进程通信,流入报文:

iptables_第2张图片

1.3 转发报文的流程

一主机发送报文,经当前主机转发给另一主机:

iptables_第3张图片

注意,PREROUTING和POSTROUTING和具体网卡没有关系,这里只是为了方便展示,使用了两网卡,一个用来接一个用来发。
而实际上,即便是仅有一个网卡(或多个网卡),PREROUTING链总数第一时间检查流入报文;POSTROUTING也会在报文流出前检查即将流出的报文。

1.4 流出报文的流程

当前主机某进程与其他主机通信,发出报文:

iptables_第4张图片

2 iptables表、链

2.1 iptables各表

本文仅讨论支持ipv4的iptables命令,支持ipv6的为ip6tables。

iptables各功能称为“表”:

作用
raw 用于关闭连接追踪机制3
mangle 用于修改报文中的部分信息
nat 用于地址转换
filter 用于按规则过滤报文

各表是独立的。为完成各自功能,各表对报文的处理动作不一样。
各表就是iptables的各功能,之所以称为“表”,是因为它们可以各自在不同的链上实现各自定义的规则,一种功能在各链定义的规则组合起来就像一张表。

2.2 iptables各表定义规则的链

iptables各表(即各功能)实现,是依靠在不同的链上定义规则,各表的规则所能定义在的链:

可定义规则的链
raw PEROUTING、OUTPUT
mangle PREROUTING、INPUT、FORWARD、OUTPUT、POSTROUTING
nat PREROUTING、INPUT4、OUTPUT、POSTROUTING
filter INPUT、FORWARD、OUTPUT

2.3 各表、各链规则生效的优先级

如标题2.2所示,有的链上可定义多个表的规则。
如果多个表的规则出现在同一链上,生效次序:

raw > mangle > nat > filter

在同一链上可定义多条同一表的规则(比如filter表),这些规则是自上而下依次匹配,如果找到匹配到的规则,则按此规则处理,后续规则不再匹配

2.4 自定义链

上述的5个链,PREROUTING、INPUT、FORWARD、OUTPUT、POSTROUTING,称为内置链。

还可根据需要自定义链,自定义链上的规则无法直接生效,要被某个内置链引用才可以。

创建自定义链:iptables -N CHAIN_NAME
调用格式(以INPUT链调用为例):iptables …… -j CHAIN_NAME

这样做的目的,就是可以把某一类规则定义于一个自定义链中,从而可以一并引用或一并删除,而不用逐条规则处理。

3 iptables格式及子命令

由于最常用的是filter表和nat表,本文仅讨论这两种表的规则。
这里仅列出各表的通用的格式。具体的匹配条件、处理动作,在标题4中说明。

常用格式:

iptables [-t table] subcommand chain rule-specification		# 参数也可能是指定链的命令号,而不是具体的rulespecification
rule-specification = [matches...] [target]					# 指定匹配条件,处理动作
match = -m matchname [per-match-options]					# 加载额外模块,使用该模块的匹配条件,从而使匹配条件更丰富
target = -j targetname [per-target-options]

其中:
1、subcommand是子命令,实际就是用各选项(选项字母大写)来实现,之所以称为子命令,是因为它们有的使用格式和上述不同,且还有各自选项。
2、chain,指定链
3、rule-specification,指定匹配条件(matches)和处理动作(target)
4、匹配条件有的是iptables自带的(如匹配源IP、目标IP等),有的需要指定额外模块,使匹配条件更丰富
5、-j target,对匹配到的报文的执行动作。有的动作也有自己的选项
6、-t table,用于指定是对哪个表进行操作,若省略表示操作的表是filter

3.1 子命令

这些都比较容易理解,不再专门示例。在下文的规则定义、管理等,会体现到各选项作用。

类似选项,不过都是大写字母:

选项 意义
-N 新建一自定义链
-X 删除自定义的空链,如上面定义了规则是无法删除的
-F 清空规则。可清空所有链上的规则,也可清空指定链的所有规则,也可清空指定链的指定规则(这就和-D一样了)
-P 定义默认策略。即如果一个报文不符合所有规则的匹配条件,应采取的动作
-E 重命名未被内置链引用的自定义链(reference为0)
-L 列出规则
-A 追加(append)添加规则。即添加的规则会在原有规则的最后
-I 插入规则。默认插入原有规则的第一个,也可指定插入第几个
-D 删除指定规则。参数可以是数字,表示删除第几条
-R 用一个新规则替换指定规则
-Z 每个规则都有两计数器:一个用于该规则匹配到的报文总个数,另一个用于记录匹配到的报文总大小。-Z的意义是把这两数归零
-S 输出定义当前所有规则所使用的命令。可把这些命令重定向至某文件,这样运行这个文件中的命令,就能恢复之前定义的规则5

3.1.1 列出各规则

列出规则-L子命令,格式为:

iptables [-t table] -L [chain [rulenum]] [options...]

有一些专门用于列出规则的-L的子选项,常用的有:

选项 意义
-n 以数字格式显示IP和端口。否则会尝试根据IP、端口反解主机名、服务名
-v,-vv,-vvv 显示详细信息
-x 每个规则的两计数器(分别用于记录匹配到报文的总数和总大小),数过大时会使用其他单位(比如MB)从而四舍五入。此选项表示显示精确数值,不换算、四舍五入
–line-number 显示链上的规则的编号,方便引用。比如-D进行删除指定规则时,可指定规则内容也可指定编号

这些子选项要写在-L的左侧,否则会报错

4 常见匹配条件

只有根据一定条件匹配报文,才能对之做出相应处理。
下面列出常见匹配条件,有的条件并不适用于所有的链,所以不是所有的表都能使用下述各匹配条件,具体情况要具体分析。

大部分匹配条件,均可在其前面加“!”表示取反

4.1 基本匹配

iptables自带的匹配条件:

匹配条件 意义
-s 匹配源地址是指定IP(也可以是IP段)的报文。0/0或省略此选项均表示匹配所有源IP
-d 匹配目标地址是指定IP的报文
-i 参数是网卡名(如eth0),用于匹配从指定网卡流入的报文。注意因为是流入报文,所以只能定义在PREROUTING、INPUT、FORWARD链
-o 匹配从指定网卡流出的报文。因为是流出报文,所以只能定义在FORWARD、OUTPUT、POSTROUTING链

4.2 隐式扩展匹配

扩展匹配指的是需要使用额外模块,才能使用的匹配条件。
隐式扩展是指不用"-m"显式引用的模块,不过也可以用-m来引用。

隐式扩展最常用的就是"-p",用于匹配使用指定的协议的报文。
最常用的协议就是tcp、udp、icmp,它们有各自的子选项。用于匹配使用指定协议,且满足协议子选项指定条件的报文。

4.2.1 tcp子选项

tcp有自己的子选项。用于匹配既使用tcp协议传输,又满足子选项指定条件的报文:

子选项 意义
–source-port或sport 匹配源端口是指定端口的报文。参数也可写为"数A:数B",表示匹配的端口是A到B之间的任一端口
–destination-port或dport 匹配目标端口是指定端口的报文。参数格式同sport
–tcp-flags MASK COMP 匹配由MASK指定TCP报文中的标志位,由COMP限定这些标志位为1的报文6
–syn 相当于"–tcp-flags syn,ack,fin,rsk syn"

udp相对于tcp更简单,子选项常用的只有源端口和特殊端口,不再赘述

4.2.2 icmp子选项

由于icmp报文有不同的类型状态码(记为"类型/状态码",都是从0开始记),所以可根据类型、状态码来匹配报文。

子选项 意义
–icmp-type 匹配指定icmp类型的报文

ping报文的匹配比较常用,它的类型、状态码为:ping请求为8/0,ping应答为0/0。不过由于0和8类型的状态码都只有0,所以直接写类型也可匹配到。

4.3 显式扩展

显式扩展必须使用-m指定对应模块,才能使用该模块的各子选项进行各匹配。

4.3.1 模块multiport及子选项

multiport模块,用于匹配多个端口。相对于基本匹配中的sport或dport,这里端口号无需连续,最多15个。不过必须在使用"-p"指定了协议的情况下使用,否则报错。
这样可将多个用端口作为匹配条件的规则合并为一个,减少规则数目,从而提高检查效率。

子选项 意义
–source-port 匹配源端口是指定端口的报文
–destination-port 匹配目标端口是指定端口的报文
–ports 匹配源端口是所列端口的报文(无论源或目标)

4.3.2 模块iprange

iprange模块,用于匹配一段连续的IP地址。而基本匹配中,只能匹配指定IP或这个网段。

子选项 意义
–src-range 匹配源地址
–dst-range 匹配目标地址

4.3.3 模块time

time模块,用于匹配报文到达时间。

子选项 意义
–datestart 指定开始的日期和时间
–datestop 指定结束的日期和时间
–timestart 指定开始的时间(不含日期,指定每天的时间)
–timestop 指定结束的时间
–monthdays 匹配每个月中的哪些天
–weekdays 匹配一周的哪些天

4.3.4 模块string

模块string,用于匹配报文中的指定字符串。

子选项 意义
–algo 用于指定匹配字符串使用哪种算法(bm或kmp)。此选项是string模块必须使用的,否则会报错7
–from OFFSET 指定从报文的某位置(OFFSET)开始,检查是否有匹配的字符串。不是从开始处检查,可提高效率
–to OFFSET 指定到报文某位置为止,检查是否有匹配的字符串。也是为提高检查效率
–string PATTERN 匹配是否有符合指定模式(正则表达式PATTERN)的字符串

4.3.5 模块connlimit

模块connlimit,用于限定单个IP发起的并发连接数。

比如httpd服务器,配置文件中的MaxClients虽然限定了最大连接总数,但并没有对单个主机发起的连接数进行限制。单个主机如果发起过多线程来发起请求(即过多连接数),会影响其他主机访问。通过iptables的connlimit模块可解决此问题。

子选项 意义
–connlimit-above 限制连接数大于等于某数(更常用的是去反,令某主机发起的连接小于等于某数)

4.3.6 模块limit

模块limit,基于令牌桶算法8,匹配指定的报文速率。

子选项 意义
–limit RATE[/second /minute
–limit-burst 控制报文传输时的峰值速率(发生在开始传输时)。参数也是报文数,默认是5

4.3.7 模块state

模块state,用于匹配指定状态的连接。从而实现连接追踪机制,它是contrack模块的子模块。

4.3.7.1 连接追踪机制

在内存中的一段空间用于作连接追踪表(文件**/proc/net/nf_conntrack**),记录指定的一段时间内,发生的连接的信息(连接状态、地址、端口、协议等)。每条记录也都有生存周期。

连接追踪表大小有限,由**/proc/sys/net/nf_conntrack_max**定义。如启用连接追踪,表中的记录如果已满,则当前主机就无法再建立新的连接,服务也无法再被访问(即便服务正常)9

4.3.7.2 连接各状态及state模块子选项

连接追踪机制记录的连接状态:

状态 意义
INVALID 无法识别的异常连接。比如某TCP报文的SYN、ACK、FIN等都值均为1,显然不可能,这种就属于INVALID状态
ESTABLISHED 一个网络连接和已在连接追踪表中记录的正常连接(未到删除时间)的相关信息(比如IP、端口、使用的协议等)相符合,则状态为ESTABLISHED10
NEW 一个网络连接在连接追踪表中查不到以往记录(未记录过或已删除),则状态为NEW
RELATED 相关联的连接。比如ftp服务的数据传输连接相对于命令连接就是RELATED

state模块只有1个子选项"–state",用于匹配符合指定连接状态的报文。

对于服务器和客户端来说(FILTER表):
1、服务端对NEW、设置为ACCEPT,因为要提供服务;
2、服务端到客户端方向的NEW状态报文,一般要设置为DROP。因为一般不允许服务端主动访问别的主机;
3、ESTABLISHED和RELATED的报文一般要设置为ACCEPT。连接过的一般视作是安全的;
4、INVALID状态的报文一般要DROP。这样对异常报文起到过滤作用

5 处理动作

匹配到的报文,要按规则做响应的处理动作(man文档中叫做"target")。
有的处理动作也有自己的子选项。

filter表和nat表用到的处理动作不尽相同:

5.1 通用处理动作

处理动作 意义 子选项
LOG 把匹配到的报文信息记录日志(/var/log/messages) –log-level,定义日志级别,就和httpd的类似
- - –log-prefix,在每条日志前添加一些字符用于提示,最多不超过29字母
RETURN 返回调用链

RETURN效果如下。
比如是在INPUT链上定义的规则,第2条规则是调用某一自定义链。如果自定义链的第3条执行动作就是RETURN,那么如果报文匹配到这个规则,就会返回INPUT链的调用处,继续执行INPUT的第3条规则:

iptables_第5张图片

实际上自定义链也正是这样发挥作用的。默认情况下自定义链的最后一条规则就是执行RETURN动作,使得没有规则匹配到时,能返回调用它的链。

5.1 filter表的常用处理动作

处理动作 意义
ACCEPT 放行匹配到的报文
DROP 丢弃匹配到的报文
REJECT 丢弃匹配到的报文,并告知发送方被拒绝

5.2 nat表常用处理动作

处理动作 意义
DNAT 目标地址转换
SNAT 源地址转换
MASQERADE 地址伪装。作用也是源地址转换,用于在转换成的地址不确定时使用。详见7.1.1
REDIRECT 端口映射

6 filter表常用规则

防火墙是一种隔离工具,用于屏蔽攻击操作,防范非授权访问。
iptables之所以有防火墙作用,就是因为filter表。根据指定的匹配条件,做出放行、忽略等动作

filter表是iptables最常用功能,下面验证标题4中各匹配条件效果:

6.1 主机防火墙

主机防火墙,就是在指定主机上配置规则,作用范围是本主机。

环境:
1、令虚拟机192.168.0.105作为服务端;192.168.0.104作为客户端,二者处于同一局域网。
2、105主机运行httpd服务

105主机httpd服务主页内容为"hello":

[root@localhost ~]% echo "hello" > /var/www/html/index.html

用104主机访问结果:

[root@node2 ~]% curl 192.168.0.105
hello

由于实际使用中,为安全起见,更常用的是做"白名单",所以105主机iptables默认策略设置为DROP11

这里写图片描述

下面进行各种常用规则定义(默认策略是拒绝,所以演示的是白名单,黑名单做相反设置即可):

6.1.1 指定主机访问

1、在主机104,无法访问105的页面,因为默认策略是DROP:

这里写图片描述

2、在105主机,允许104主机对本机访问:

这里写图片描述

这里注意,开放放行是双向的,不仅要放行客户端发来的请求报文,还要放行目标地址是客户端地址的响应报文。否则客户端仍接收不到。

3、于是104主机再访问:

这里写图片描述

6.1.2 指定端口访问

客户端访问时,报文的源端口是随机的,所以一般无法对源端口限定。
对服务器的端口进行限定,用于限制客户端对指定服务的访问

为方便展示,本文全部使用httpd服务,只是令其监听在多个端口,以验证效果。

在105主机,配置httpd服务监听在80和6666、7777:

Listen 80
Listen 6666
Listen 7777

1、在105主机,清空所有规则,变为默认的DROP:

iptables_第6张图片

2、在105主机,放行访问6666、7777端口的报文:

这里写图片描述

3、在104主机,访问105主机的http服务。端口6666和7777均正常,80拒绝:

这里写图片描述

6.1.3 限制ping报文

下面实现,令105主机可以ping通104主机,但104主机不能ping通105主机。

由于105主机的默认策略是DROP,所以ping不通104主机,104主机也ping不通105。

1、在105主机,设置OUTPUT链放行ping请求报文,INPUT链放行ping回应报文:

这里写图片描述

2、于是105主机可ping通104主机:

这里写图片描述

3、但104ping不通105,因为105的iptables并没有放行ping请求报文通过INPUT链,也没有放行ping回应报文通过OUTPUT:

这里写图片描述

6.1.4 限制有指定字符串的报文

为对比效果,在主机105,添加一页面文件/var/www/html/number.html,内容为"hello123":

这里写图片描述

下面操作目的,是令104主机访问105主机的http服务,有数字"123"的页面不能被访问,没有数字的正常:

1、清空之前的规则。放行访问105主机的报文,放行105主机回应的报文:

这里写图片描述

2、104主机访问105主机的两页面:

这里写图片描述

3、在105主机,定义页面内容中匹配到数字的,不予回应。注意,要定义在OUTPUT链,INPUT链只能作用到请求报文,而请求报文是否有数字也是无法预知的:

这里写图片描述

4、此时使用104主机访问105的两页面:

这里写图片描述

6.1.5 限制主机发起的连接数

下面操作的目的,是令104主机使用ssh登录105主机,但最多不能超过2个:

1、在105主机上设置规则,主要是INPUT链上,限制了任何单个主机能够和105主机建立的连接数:

这里写图片描述

2、在104主机,启动多个终端。使用ssh登录:

iptables_第7张图片

前两终端发起的ssh请求,均要求输入密码。第3个终端则无法连接。

6.1.6 限制报文速率

下面操作目的,是令从104主机,访问105主机的报文,以指定速率访问:

1、清空之前的规则后,放行目标IP是105的报文,并放行105的响应报文:

这里写图片描述

2、在104主机,直接ping主机105,通过seq可知是正常速率:

iptables_第8张图片

3、在105主机,把第1步的允许访问,变为允许访问且限制接收报文速率为每分钟8个,峰值速率3(默认是5):

这里写图片描述

4、这时再用104主机ping,间隔时间就会变长了(前3个的间隔不会变长,因为有峰值速率3):

iptables_第9张图片

起到了限制访问速率的效果。也能够防范故意利用巨量报文的攻击。

6.2 网络防火墙

一主机处于某网络的边缘,该网络进出报文都经过该主机。则可在这个主机设置规则,按条件过滤进出此网络的报文。

和主机防火墙不同的是,网络防火墙主机中的进程往往不会和其他主机通信,仅仅是转发其他主机的报文。所以要达到过滤目的,规则要设置在FORWARD链上。INPUT和OUTPUT链上的规则对转发的报文不起作用。

6.2.1 环境说明

下面用3个虚拟机,验证网络防火墙作用:

iptables_第10张图片

环境:
为方便起见,内网主机仅用1台,node1。
node2主机作为防火墙主机。一般网络防火墙主机都有2个以上的网卡,分别对应内网、外网12
node3主机,作为外网主机。当然这里它不是真的外网主机,只是给他配置一个不同于node1所在网段的地址,当作外网地址。

node1主机IP:192.168.0.105
node2主机IP:eth0为192.168.0.104,eth1为172.16.0.1
node3主机IP:172.16.0.100

如果node1作为客户端,node3作为服务端。则node2防火墙可以限制node1能访问哪些主机的哪些服务;
如果node3作为客户端,node1作为服务端。则node2防火墙可以限制node1允许哪些服务供外部主机访问。

下面仅以node1作为客户端的情况说明,反过来类似。

既然node1作为客户机,那么其网关地址应当指向node2的eth013
使用vmware设置node1的eth0与node2的eth0处于同一虚拟网络(host-only也是同样效果)。
注意,还要在node3上添加一路由条目,使得node3响应node1的报文要发给node2的eth1,否则无法回应node114

此外,要把node2的转发功能打开:

这里写图片描述

6.2.2 验证效果

在标题6.1中已经验证过各匹配条件的使用,这里只是验证网络防火墙是否起作用。

首先关闭node1和node3的iptables。然后把node2的iptables默认策略设置为DROP:

这里写图片描述

下面验证node2防火墙功能:

1、下面令内网node1能ping通node3,node3 ping不通内网node1。只需在node2操作:

这里写图片描述

2、node1和node3互相ping效果:

这里写图片描述

这里写图片描述

3、进一步,使用tcpdump抓包验证。当node1去ping node3时,报文均正常放行。
但在node3去ping node1时,分别在不同网卡,可验证防火墙作用:

首先启动node3的另一终端,而后在node3网卡上抓包15,可看到从该网卡流出的ping请求,但没有ping回应

iptables_第11张图片

在node1,没有收到node3的ping请求:

这里写图片描述

在node2的eth1,收到了node2的ping请求:

iptables_第12张图片

在node2的eth0,却没有,说明在中间被过滤了:

这里写图片描述

4、如果把node3到node1的ping请求也开放,添加规则:

这里写图片描述

则可在node1看到node3的ping请求,和给node3的ping回应:

iptables_第13张图片

但此时node3仍收不到响应报文,因为给node3的响应没有放行。在node2的eth1可看到还是只有node3的请求报文:

iptables_第14张图片

在node2再添加规则,放行由内网node1响应的报文:

这里写图片描述

此时在node3收到回应:

iptables_第15张图片

5、如果根据连接状态设置规则,效果比用IP更好:

这里写图片描述

这样node3还是能ping通node1,且能过滤掉异常报文:

iptables_第16张图片

7 nat表常用规则

虽然nat表作用的链是PREROUTING、INPUT、OUTPUT、POSTROUTING,下面仅说明在PREROUTING、POSTROUTING设置规则的情况。

仍以node1、node2、node3虚拟机为例:

iptables_第17张图片

node1为内网主机,node2为网关主机,node3为外网主机。环境同标题6.2.1。

网络地址转换可以是:
1、node1作为客户端,访问node3时,经过node2把源地址转换;
2、node1作为服务端,向外部主机提供服务,向外发布的是node2主机的eth1上的IP。外部主机访问的目标地址是eth1,在node2转换为node1的IP。

最初的目的:
第1种情况是为了隐藏访问来源,第2种是为了隐藏服务器真正地址防止被攻击。

但后来的发展是在另一方面起了更大作用:
使得众多在内网使用私有地址的主机,可以借助网关主机的公网地址访问互联网;或是众多使用私有地址的内网服务器,通过网关同一向互联网发布服务。解决了地址不够的问题。

下面分别配置源地址转换、目标地址转换规则并查看效果:

7.1 源地址转换

在node3上启动httpd,node1作为客户端。IP地址环境同标题6.2.1:

iptables_第18张图片

报文流向:
1、报文从node1到达node2的eth0;
2、在node2进行源地址转换后,从node2发送至node3;
3、node3响应报文给node2(是node2,因为是用node2的地址访问的);
4、在node2进行目标地址转换后(目标地址由node2转换为node1的地址),发送至node1.

注意:
第4步中的目标地址转换,是自动进行的。无需手动设置规则,它是根据第2步中记录在nat会话表中的信息做的对应的转换
源地址转换,应设置在node2的POSTROUTING链。因为在临发出的一刹那,才能决定是从哪个网口出,从而转换为对应地址。(虽然这里仅有eth1一个外网接口)

下面通过设置源地址转换规则,tcpdump抓包,验证node1访问node3时,被node2把源地址转换为自己的eth1的地址的效果:

1、避免filter表的干扰,在node2上设置filter的FORWARD链默认策略为ACCEPT:

这里写图片描述

2、启动node3的httpd,在测试页面写入内容:

这里写图片描述

3、因为此时node2转发功能打开,且没有开启防火墙,所以node1是直接可以访问到的:

这里写图片描述

在node3上的httpd的访问日志中,可以看到客户端IP是192.168.0.105:

这里写图片描述

4、在node2的POSTROUTING链,设置源地址为192.168.0.0/24网段的主机,均转换为node2的eth1的地址172.16.0.1:

这里写图片描述

此时使用node1访问node3的http页面,访问日志记录的客户端IP就变为172.16.0.1:

这里写图片描述

实际上也可把源端口一并转换,但源端口本来就是随机的,转换也没什么意义。

7.1.1 拨号上网的情况

使用PPPoE拨号上网的用户,用于上网的外网地址,可能每次拨号都不一样。
所以按上述情况,如果node2主机就是这种拨号上网,则把源地址转换写成固定规则,可能会不起作用。因为node2的地址就不一定。

这种情况:
1、在node2编写脚本周期性地获取外网IP,并相应地更新iptables规则;
2、使用处理动作MASQUERADE代替SNAT,它的作用就是将源地址转换为本机的外网地址(它的机制和1一样,也是要时常检查IP是否变化)

7.2 目标地址转换

同源地址转换差不多,只不过相反操作。
目标地址转换要定义在PREROUTING链上,否则因为报文最开始的目标是网关主机,如果不在第一时间转换目标地址,就会被视为是发给本机的报文,这样就不会转发了

目标地址转换的一个显著作用,就是根据客户端访问的端口,把访问报文转发至指定服务的主机。

下面仍以上述3台虚拟机作为示例:

1、内网node1主机,启动httpd服务,创建一个页面用于验证:

这里写图片描述

2、网关主机node2,在PREROUTING链上做目标地址转换,使得访问node2的请求,转发至node1:

这里写图片描述

3、在node3,访问node2的http服务(注意node2并没有开启httpd):

这里写图片描述

能够访问到,且就是node1主机的页面。
在再查看node1的httpd访问日志,可看到访问主机就是node3:

这里写图片描述

如果内网有多个主机,就可以利用这种方式,同一地向外部发布一公网地址,作为外网主机访问内网各服务器的地址。

如果node1主机由于种种原因,80端口不可用,而令httpd监听在8000端口。那么只要在node2设置规则,把目标端口是80的报文,都转发至node1的8000端口。使用的命令和选项都一样,不再赘述。

7.2.1 在本机上做端口映射

当然,也可以在本机直接设置端口映射,使用处理动作REDIRECT即可。

如果用node2来作为客户端,node1是服务端。node1监听地址仍是8000。则node2就无法访问默认的80端口:

这里写图片描述

在node1本机上做端口映射,使访问80的都转到8000端口:

这里写图片描述

node2再访问:

这里写图片描述

8 规则设置原则

最后,再强调下规则设置的原则:
1、同一表的同一链,规则自上而下依次匹配生效。只要匹配到,则执行对应处理动作,后续规则不再匹配。
2、原则上讲,对于同是ACCEPT处理动作的规则,匹配条件范围越大,越放在前。否则如果前N条不匹配,第N+1条匹配到了仍要放行,前面的规则匹配白白开销资源。
3、原则上讲,对于同是DROP、REJECT处理动作的规则,匹配条件范围越大,越放在前。
4、放行规则和拒绝规则相比,哪个匹配的范围越小,越放在前(范围小的可视为是做特殊处理,所以放在前面匹配)。
5、规则越少越好,多条规则如能合并,就合并。
6、匹配越频繁的规则,越写在前面。以减少该规则之前无效匹配的频率

(完)


  1. 路由选择就是判断报文接下来要向哪发。或许是本机的某进程,也可能是要转发等。 ↩︎

  2. 要实现转发,就要把本机的转发功能开启,设置参数/proc/sys/net/ipv4/ip_forward为1。
    不过这和在iptables的FORWARD链上设置规则是两回事。 ↩︎

  3. 连接追踪机制是指,为加快定义在各链上的规则的检查效率,为某一已经经过检查的连接进行记录(包括IP、使用的协议等信息),一段时间内,只要还是这个IP、并使用相同协议(就是和之前的连接条件一致),则不再检查 ↩︎

  4. 从CentOS7开始,nat才可定义于INPUT链 ↩︎

  5. 也可直接使用命令存储规则。
    iptables-save > FILE,表示把当前规则定义至某文件。默认重定向至文件**/etc/sysconfig/iptables**
    iptables-restore < FILE,表示使用某文件中存储的规则。/etc/sysconfig/iptables中的规则,开机会被自动加载,否则就写脚本令系统加载指定文件中的规则。
    开机自动生效,只需将加载命令写在开机运行的自定义脚本/etc/rc.d/rc.local即可 ↩︎

  6. 比如"-tcp-flags syn,fin,ack,rsk syn"表示匹配syn、fin、ack、rsk四个标志位,其中syn为1,其他都为0的报文。显然这就是匹配三次握手中的第一次握手的报文。由于匹配这个报文比较常用,所以干脆做成了一个单独选项–syn。 ↩︎

  7. 如果不选择算法,使用字符串逐字匹配效率太低,这里必须指定 ↩︎

  8. 此处对算法实现不做介绍了。
    算法目的,就是通过令牌生成速率(令牌可理解为一种标记、通行证),令持有令牌的报文才能传输,从而控制报文的传输速率。特别地,允许突发数据的发送(即某一时刻发放比正常速率更多的令牌),从而达到峰值速率(比设定的常态传输速率高,一般发生在刚开始传输时)。 ↩︎

  9. 此时可采取:调大/proc/sys/net/nf_conntrack_max的值;要么调低每个连接追踪记录的生存时长(在/proc/sys/net/netfilter下各timeout文件来对不同协议的连接定义)。 ↩︎

  10. 就是说两端主机在近期是正常连接过的。只要连接过,那么在记录未删除的时间内,无论哪端发、哪端收报文,报文状态都是ESTABLISHED ↩︎

  11. 默认策略使用DROP,在客户端上访问的效果就是被卡住一段时间,被提示拒绝,而不会立刻提示拒绝。
    实际要达到屏蔽目的,一般就是使用DROP。因为REJECT,服务端还要封装拒绝报文发送给客户机,增大开销。而且REJECT也不能作为默认策略,会报错。 ↩︎

  12. 虽然理论上,一个网卡也可配置两地址来完成 ↩︎

  13. 这样指向之后,会发现node1主机也能ping通node2的eth1的地址,虽然不同网段。这是因为IP是内核属性,node1去ping主机node2的eth1,由于是不同网段,所以会把报文发至网关。而node1的网关指向正好就是node2主机,node2主机发现是发给自己的地址的(虽然是另一地址),于是给予了回应。
    这里没有牵扯到转发,并不是node2主机的eth0转发给了自己的eth1 ↩︎

  14. 由于node3作为外网主机,就不把网关指向node2的eth1了。但要添加一个路由条目,可看作是外网主机node3经过外部网络的路由,报文才送达node2。 ↩︎

  15. 避免其他报文干扰,抓包时使用grep过滤下 ↩︎

你可能感兴趣的:(iptables)