为实现报文的安全传输,屏蔽某些攻击;或是转换报文的源、目标地址,内核开发者在5个精心选择的位置开发了钩子函数(即netfilter功能模块),用于实现在不同位置检查、处理流经的网络报文。相当于路上的卡点。
iptables称这些钩子函数为“链”(chain)。iptables就是在这些链上定义规则的工具。
5个链的位置:
说明:
1、为叙述方便,把网卡设备也使用图形表示出来,虽然它们并不是进程;以网卡1作为报文流入的接口,网卡2作为报文流出的接口;
2、其他如各链、路由选择、各应用进程,都是在主机上运行的进程。前者由内核实现,后者由各应用程序实现。
3、因为网卡1、2分别作为流入和流出报文的接口,所以将PREROUTING和POSTROUTING分别放在了两网卡边。实际上不论是哪个网卡,只要是流入的报文,都会立即经过PREROUTING链“检查”;流出的报文流出前,都会经过POSTROUTING链“检查”。
下面也是以此模型展开。
要在不同的链上定义切实能起作用的规则,就要理解各链上规则的生效时机:
链 | 生效时机 |
---|---|
PREROUTING | 报文到达主机网卡的一刹那,就会被主机的PREROUTING链上的规则检查 |
INPUT | 经过PREROUTING的报文,之后进行路由选择1。如果是要发给主机某进程的报文,则经过INPUT链上定义的规则检查 |
FORWARD | 经过PREROUTING的报文,进行路由选择。如果是要发给其他主机的报文,则经过FORWARD链上定义的规则检查2 |
OUTPUT | 主机要发送给其他主机的报文(不论是响应对方还是向对方主动发),首先经过OUTPUT链 |
POSTROUTING | 在本机报文发送出主机前一刹那,经过POSTROUTING链上的规则检查 |
下面分别说明流入、流出、转发的报文所经流程:
这里仅列出与流入报文有关的链,其他忽略,下同。
其他主机向当前主机某进程通信,流入报文:
一主机发送报文,经当前主机转发给另一主机:
注意,PREROUTING和POSTROUTING和具体网卡没有关系,这里只是为了方便展示,使用了两网卡,一个用来接一个用来发。
而实际上,即便是仅有一个网卡(或多个网卡),PREROUTING链总数第一时间检查流入报文;POSTROUTING也会在报文流出前检查即将流出的报文。
当前主机某进程与其他主机通信,发出报文:
本文仅讨论支持ipv4的iptables命令,支持ipv6的为ip6tables。
iptables各功能称为“表”:
表 | 作用 |
---|---|
raw | 用于关闭连接追踪机制3 |
mangle | 用于修改报文中的部分信息 |
nat | 用于地址转换 |
filter | 用于按规则过滤报文 |
各表是独立的。为完成各自功能,各表对报文的处理动作不一样。
各表就是iptables的各功能,之所以称为“表”,是因为它们可以各自在不同的链上实现各自定义的规则,一种功能在各链定义的规则组合起来就像一张表。
iptables各表(即各功能)实现,是依靠在不同的链上定义规则,各表的规则所能定义在的链:
表 | 可定义规则的链 |
---|---|
raw | PEROUTING、OUTPUT |
mangle | PREROUTING、INPUT、FORWARD、OUTPUT、POSTROUTING |
nat | PREROUTING、INPUT4、OUTPUT、POSTROUTING |
filter | INPUT、FORWARD、OUTPUT |
如标题2.2所示,有的链上可定义多个表的规则。
如果多个表的规则出现在同一链上,生效次序:
raw > mangle > nat > filter
在同一链上可定义多条同一表的规则(比如filter表),这些规则是自上而下依次匹配,如果找到匹配到的规则,则按此规则处理,后续规则不再匹配。
上述的5个链,PREROUTING、INPUT、FORWARD、OUTPUT、POSTROUTING,称为内置链。
还可根据需要自定义链,自定义链上的规则无法直接生效,要被某个内置链引用才可以。
创建自定义链:iptables -N CHAIN_NAME
调用格式(以INPUT链调用为例):iptables …… -j CHAIN_NAME
这样做的目的,就是可以把某一类规则定义于一个自定义链中,从而可以一并引用或一并删除,而不用逐条规则处理。
由于最常用的是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
这些都比较容易理解,不再专门示例。在下文的规则定义、管理等,会体现到各选项作用。
类似选项,不过都是大写字母:
选项 | 意义 |
---|---|
-N | 新建一自定义链 |
-X | 删除自定义的空链,如上面定义了规则是无法删除的 |
-F | 清空规则。可清空所有链上的规则,也可清空指定链的所有规则,也可清空指定链的指定规则(这就和-D一样了) |
-P | 定义默认策略。即如果一个报文不符合所有规则的匹配条件,应采取的动作 |
-E | 重命名未被内置链引用的自定义链(reference为0) |
-L | 列出规则 |
-A | 追加(append)添加规则。即添加的规则会在原有规则的最后 |
-I | 插入规则。默认插入原有规则的第一个,也可指定插入第几个 |
-D | 删除指定规则。参数可以是数字,表示删除第几条 |
-R | 用一个新规则替换指定规则 |
-Z | 每个规则都有两计数器:一个用于该规则匹配到的报文总个数,另一个用于记录匹配到的报文总大小。-Z的意义是把这两数归零 |
-S | 输出定义当前所有规则所使用的命令。可把这些命令重定向至某文件,这样运行这个文件中的命令,就能恢复之前定义的规则5 |
列出规则-L子命令,格式为:
iptables [-t table] -L [chain [rulenum]] [options...]
有一些专门用于列出规则的-L的子选项,常用的有:
选项 | 意义 |
---|---|
-n | 以数字格式显示IP和端口。否则会尝试根据IP、端口反解主机名、服务名 |
-v,-vv,-vvv | 显示详细信息 |
-x | 每个规则的两计数器(分别用于记录匹配到报文的总数和总大小),数过大时会使用其他单位(比如MB)从而四舍五入。此选项表示显示精确数值,不换算、四舍五入 |
–line-number | 显示链上的规则的编号,方便引用。比如-D进行删除指定规则时,可指定规则内容也可指定编号 |
这些子选项要写在-L的左侧,否则会报错。
只有根据一定条件匹配报文,才能对之做出相应处理。
下面列出常见匹配条件,有的条件并不适用于所有的链,所以不是所有的表都能使用下述各匹配条件,具体情况要具体分析。
大部分匹配条件,均可在其前面加“!”表示取反。
iptables自带的匹配条件:
匹配条件 | 意义 |
---|---|
-s | 匹配源地址是指定IP(也可以是IP段)的报文。0/0或省略此选项均表示匹配所有源IP |
-d | 匹配目标地址是指定IP的报文 |
-i | 参数是网卡名(如eth0),用于匹配从指定网卡流入的报文。注意因为是流入报文,所以只能定义在PREROUTING、INPUT、FORWARD链 |
-o | 匹配从指定网卡流出的报文。因为是流出报文,所以只能定义在FORWARD、OUTPUT、POSTROUTING链 |
扩展匹配指的是需要使用额外模块,才能使用的匹配条件。
隐式扩展是指不用"-m"显式引用的模块,不过也可以用-m来引用。
隐式扩展最常用的就是"-p",用于匹配使用指定的协议的报文。
最常用的协议就是tcp、udp、icmp,它们有各自的子选项。用于匹配使用指定协议,且满足协议子选项指定条件的报文。
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更简单,子选项常用的只有源端口和特殊端口,不再赘述
由于icmp报文有不同的类型状态码(记为"类型/状态码",都是从0开始记),所以可根据类型、状态码来匹配报文。
子选项 | 意义 |
---|---|
–icmp-type | 匹配指定icmp类型的报文 |
ping报文的匹配比较常用,它的类型、状态码为:ping请求为8/0,ping应答为0/0。不过由于0和8类型的状态码都只有0,所以直接写类型也可匹配到。
显式扩展必须使用-m指定对应模块,才能使用该模块的各子选项进行各匹配。
multiport模块,用于匹配多个端口。相对于基本匹配中的sport或dport,这里端口号无需连续,最多15个。不过必须在使用"-p"指定了协议的情况下使用,否则报错。
这样可将多个用端口作为匹配条件的规则合并为一个,减少规则数目,从而提高检查效率。
子选项 | 意义 |
---|---|
–source-port | 匹配源端口是指定端口的报文 |
–destination-port | 匹配目标端口是指定端口的报文 |
–ports | 匹配源端口是所列端口的报文(无论源或目标) |
iprange模块,用于匹配一段连续的IP地址。而基本匹配中,只能匹配指定IP或这个网段。
子选项 | 意义 |
---|---|
–src-range | 匹配源地址 |
–dst-range | 匹配目标地址 |
time模块,用于匹配报文到达时间。
子选项 | 意义 |
---|---|
–datestart | 指定开始的日期和时间 |
–datestop | 指定结束的日期和时间 |
–timestart | 指定开始的时间(不含日期,指定每天的时间) |
–timestop | 指定结束的时间 |
–monthdays | 匹配每个月中的哪些天 |
–weekdays | 匹配一周的哪些天 |
模块string,用于匹配报文中的指定字符串。
子选项 | 意义 |
---|---|
–algo | 用于指定匹配字符串使用哪种算法(bm或kmp)。此选项是string模块必须使用的,否则会报错7。 |
–from OFFSET | 指定从报文的某位置(OFFSET)开始,检查是否有匹配的字符串。不是从开始处检查,可提高效率 |
–to OFFSET | 指定到报文某位置为止,检查是否有匹配的字符串。也是为提高检查效率 |
–string PATTERN | 匹配是否有符合指定模式(正则表达式PATTERN)的字符串 |
模块connlimit,用于限定单个IP发起的并发连接数。
比如httpd服务器,配置文件中的MaxClients虽然限定了最大连接总数,但并没有对单个主机发起的连接数进行限制。单个主机如果发起过多线程来发起请求(即过多连接数),会影响其他主机访问。通过iptables的connlimit模块可解决此问题。
子选项 | 意义 |
---|---|
–connlimit-above | 限制连接数大于等于某数(更常用的是去反,令某主机发起的连接小于等于某数) |
模块limit,基于令牌桶算法8,匹配指定的报文速率。
子选项 | 意义 |
---|---|
–limit RATE[/second | /minute |
–limit-burst | 控制报文传输时的峰值速率(发生在开始传输时)。参数也是报文数,默认是5 |
模块state,用于匹配指定状态的连接。从而实现连接追踪机制,它是contrack模块的子模块。
在内存中的一段空间用于作连接追踪表(文件**/proc/net/nf_conntrack**),记录指定的一段时间内,发生的连接的信息(连接状态、地址、端口、协议等)。每条记录也都有生存周期。
连接追踪表大小有限,由**/proc/sys/net/nf_conntrack_max**定义。如启用连接追踪,表中的记录如果已满,则当前主机就无法再建立新的连接,服务也无法再被访问(即便服务正常)9。
连接追踪机制记录的连接状态:
状态 | 意义 |
---|---|
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。这样对异常报文起到过滤作用
匹配到的报文,要按规则做响应的处理动作(man文档中叫做"target")。
有的处理动作也有自己的子选项。
filter表和nat表用到的处理动作不尽相同:
处理动作 | 意义 | 子选项 |
---|---|---|
LOG | 把匹配到的报文信息记录日志(/var/log/messages) | –log-level,定义日志级别,就和httpd的类似 |
- | - | –log-prefix,在每条日志前添加一些字符用于提示,最多不超过29字母 |
RETURN | 返回调用链 |
RETURN效果如下。
比如是在INPUT链上定义的规则,第2条规则是调用某一自定义链。如果自定义链的第3条执行动作就是RETURN,那么如果报文匹配到这个规则,就会返回INPUT链的调用处,继续执行INPUT的第3条规则:
实际上自定义链也正是这样发挥作用的。默认情况下自定义链的最后一条规则就是执行RETURN动作,使得没有规则匹配到时,能返回调用它的链。
处理动作 | 意义 |
---|---|
ACCEPT | 放行匹配到的报文 |
DROP | 丢弃匹配到的报文 |
REJECT | 丢弃匹配到的报文,并告知发送方被拒绝 |
处理动作 | 意义 |
---|---|
DNAT | 目标地址转换 |
SNAT | 源地址转换 |
MASQERADE | 地址伪装。作用也是源地址转换,用于在转换成的地址不确定时使用。详见7.1.1 |
REDIRECT | 端口映射 |
防火墙是一种隔离工具,用于屏蔽攻击操作,防范非授权访问。
iptables之所以有防火墙作用,就是因为filter表。根据指定的匹配条件,做出放行、忽略等动作。
filter表是iptables最常用功能,下面验证标题4中各匹配条件效果:
主机防火墙,就是在指定主机上配置规则,作用范围是本主机。
环境:
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:
下面进行各种常用规则定义(默认策略是拒绝,所以演示的是白名单,黑名单做相反设置即可):
1、在主机104,无法访问105的页面,因为默认策略是DROP:
2、在105主机,允许104主机对本机访问:
这里注意,开放放行是双向的,不仅要放行客户端发来的请求报文,还要放行目标地址是客户端地址的响应报文。否则客户端仍接收不到。
3、于是104主机再访问:
客户端访问时,报文的源端口是随机的,所以一般无法对源端口限定。
可对服务器的端口进行限定,用于限制客户端对指定服务的访问。
为方便展示,本文全部使用httpd服务,只是令其监听在多个端口,以验证效果。
在105主机,配置httpd服务监听在80和6666、7777:
Listen 80
Listen 6666
Listen 7777
1、在105主机,清空所有规则,变为默认的DROP:
2、在105主机,放行访问6666、7777端口的报文:
3、在104主机,访问105主机的http服务。端口6666和7777均正常,80拒绝:
下面实现,令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:
为对比效果,在主机105,添加一页面文件/var/www/html/number.html,内容为"hello123":
下面操作目的,是令104主机访问105主机的http服务,有数字"123"的页面不能被访问,没有数字的正常:
1、清空之前的规则。放行访问105主机的报文,放行105主机回应的报文:
2、104主机访问105主机的两页面:
3、在105主机,定义页面内容中匹配到数字的,不予回应。注意,要定义在OUTPUT链,INPUT链只能作用到请求报文,而请求报文是否有数字也是无法预知的:
4、此时使用104主机访问105的两页面:
下面操作的目的,是令104主机使用ssh登录105主机,但最多不能超过2个:
1、在105主机上设置规则,主要是INPUT链上,限制了任何单个主机能够和105主机建立的连接数:
2、在104主机,启动多个终端。使用ssh登录:
前两终端发起的ssh请求,均要求输入密码。第3个终端则无法连接。
下面操作目的,是令从104主机,访问105主机的报文,以指定速率访问:
1、清空之前的规则后,放行目标IP是105的报文,并放行105的响应报文:
2、在104主机,直接ping主机105,通过seq可知是正常速率:
3、在105主机,把第1步的允许访问,变为允许访问且限制接收报文速率为每分钟8个,峰值速率3(默认是5):
4、这时再用104主机ping,间隔时间就会变长了(前3个的间隔不会变长,因为有峰值速率3):
起到了限制访问速率的效果。也能够防范故意利用巨量报文的攻击。
一主机处于某网络的边缘,该网络进出报文都经过该主机。则可在这个主机设置规则,按条件过滤进出此网络的报文。
和主机防火墙不同的是,网络防火墙主机中的进程往往不会和其他主机通信,仅仅是转发其他主机的报文。所以要达到过滤目的,规则要设置在FORWARD链上。INPUT和OUTPUT链上的规则对转发的报文不起作用。
下面用3个虚拟机,验证网络防火墙作用:
环境:
为方便起见,内网主机仅用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.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回应
在node1,没有收到node3的ping请求:
在node2的eth1,收到了node2的ping请求:
在node2的eth0,却没有,说明在中间被过滤了:
4、如果把node3到node1的ping请求也开放,添加规则:
则可在node1看到node3的ping请求,和给node3的ping回应:
但此时node3仍收不到响应报文,因为给node3的响应没有放行。在node2的eth1可看到还是只有node3的请求报文:
在node2再添加规则,放行由内网node1响应的报文:
此时在node3收到回应:
5、如果根据连接状态设置规则,效果比用IP更好:
这样node3还是能ping通node1,且能过滤掉异常报文:
虽然nat表作用的链是PREROUTING、INPUT、OUTPUT、POSTROUTING,下面仅说明在PREROUTING、POSTROUTING设置规则的情况。
仍以node1、node2、node3虚拟机为例:
node1为内网主机,node2为网关主机,node3为外网主机。环境同标题6.2.1。
网络地址转换可以是:
1、node1作为客户端,访问node3时,经过node2把源地址转换;
2、node1作为服务端,向外部主机提供服务,向外发布的是node2主机的eth1上的IP。外部主机访问的目标地址是eth1,在node2转换为node1的IP。
最初的目的:
第1种情况是为了隐藏访问来源,第2种是为了隐藏服务器真正地址防止被攻击。
但后来的发展是在另一方面起了更大作用:
使得众多在内网使用私有地址的主机,可以借助网关主机的公网地址访问互联网;或是众多使用私有地址的内网服务器,通过网关同一向互联网发布服务。解决了地址不够的问题。
下面分别配置源地址转换、目标地址转换规则并查看效果:
在node3上启动httpd,node1作为客户端。IP地址环境同标题6.2.1:
报文流向:
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:
实际上也可把源端口一并转换,但源端口本来就是随机的,转换也没什么意义。
使用PPPoE拨号上网的用户,用于上网的外网地址,可能每次拨号都不一样。
所以按上述情况,如果node2主机就是这种拨号上网,则把源地址转换写成固定规则,可能会不起作用。因为node2的地址就不一定。
这种情况:
1、在node2编写脚本周期性地获取外网IP,并相应地更新iptables规则;
2、使用处理动作MASQUERADE代替SNAT,它的作用就是将源地址转换为本机的外网地址(它的机制和1一样,也是要时常检查IP是否变化)
同源地址转换差不多,只不过相反操作。
目标地址转换要定义在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端口。使用的命令和选项都一样,不再赘述。
当然,也可以在本机直接设置端口映射,使用处理动作REDIRECT即可。
如果用node2来作为客户端,node1是服务端。node1监听地址仍是8000。则node2就无法访问默认的80端口:
在node1本机上做端口映射,使访问80的都转到8000端口:
node2再访问:
最后,再强调下规则设置的原则:
1、同一表的同一链,规则自上而下依次匹配生效。只要匹配到,则执行对应处理动作,后续规则不再匹配。
2、原则上讲,对于同是ACCEPT处理动作的规则,匹配条件范围越大,越放在前。否则如果前N条不匹配,第N+1条匹配到了仍要放行,前面的规则匹配白白开销资源。
3、原则上讲,对于同是DROP、REJECT处理动作的规则,匹配条件范围越大,越放在前。
4、放行规则和拒绝规则相比,哪个匹配的范围越小,越放在前(范围小的可视为是做特殊处理,所以放在前面匹配)。
5、规则越少越好,多条规则如能合并,就合并。
6、匹配越频繁的规则,越写在前面。以减少该规则之前无效匹配的频率
(完)
路由选择就是判断报文接下来要向哪发。或许是本机的某进程,也可能是要转发等。 ↩︎
要实现转发,就要把本机的转发功能开启,设置参数/proc/sys/net/ipv4/ip_forward为1。
不过这和在iptables的FORWARD链上设置规则是两回事。 ↩︎
连接追踪机制是指,为加快定义在各链上的规则的检查效率,为某一已经经过检查的连接进行记录(包括IP、使用的协议等信息),一段时间内,只要还是这个IP、并使用相同协议(就是和之前的连接条件一致),则不再检查 ↩︎
从CentOS7开始,nat才可定义于INPUT链 ↩︎
也可直接使用命令存储规则。
iptables-save > FILE,表示把当前规则定义至某文件。默认重定向至文件**/etc/sysconfig/iptables**
iptables-restore < FILE,表示使用某文件中存储的规则。/etc/sysconfig/iptables中的规则,开机会被自动加载,否则就写脚本令系统加载指定文件中的规则。
开机自动生效,只需将加载命令写在开机运行的自定义脚本/etc/rc.d/rc.local即可 ↩︎
比如"-tcp-flags syn,fin,ack,rsk syn"表示匹配syn、fin、ack、rsk四个标志位,其中syn为1,其他都为0的报文。显然这就是匹配三次握手中的第一次握手的报文。由于匹配这个报文比较常用,所以干脆做成了一个单独选项–syn。 ↩︎
如果不选择算法,使用字符串逐字匹配效率太低,这里必须指定 ↩︎
此处对算法实现不做介绍了。
算法目的,就是通过令牌生成速率(令牌可理解为一种标记、通行证),令持有令牌的报文才能传输,从而控制报文的传输速率。特别地,允许突发数据的发送(即某一时刻发放比正常速率更多的令牌),从而达到峰值速率(比设定的常态传输速率高,一般发生在刚开始传输时)。 ↩︎
此时可采取:调大/proc/sys/net/nf_conntrack_max的值;要么调低每个连接追踪记录的生存时长(在/proc/sys/net/netfilter下各timeout文件来对不同协议的连接定义)。 ↩︎
就是说两端主机在近期是正常连接过的。只要连接过,那么在记录未删除的时间内,无论哪端发、哪端收报文,报文状态都是ESTABLISHED ↩︎
默认策略使用DROP,在客户端上访问的效果就是被卡住一段时间,被提示拒绝,而不会立刻提示拒绝。
实际要达到屏蔽目的,一般就是使用DROP。因为REJECT,服务端还要封装拒绝报文发送给客户机,增大开销。而且REJECT也不能作为默认策略,会报错。 ↩︎
虽然理论上,一个网卡也可配置两地址来完成 ↩︎
这样指向之后,会发现node1主机也能ping通node2的eth1的地址,虽然不同网段。这是因为IP是内核属性,node1去ping主机node2的eth1,由于是不同网段,所以会把报文发至网关。而node1的网关指向正好就是node2主机,node2主机发现是发给自己的地址的(虽然是另一地址),于是给予了回应。
这里没有牵扯到转发,并不是node2主机的eth0转发给了自己的eth1 ↩︎
由于node3作为外网主机,就不把网关指向node2的eth1了。但要添加一个路由条目,可看作是外网主机node3经过外部网络的路由,报文才送达node2。 ↩︎
避免其他报文干扰,抓包时使用grep过滤下 ↩︎