iptables

1 iptables链

  • 内置链:五链
    • PREROUTING (报文刚刚进来时进行的处理)
    • INPUT (如果是访问本机)
    • FORWARD (经由本地转发)
    • OUTPUT (本机访问出去)
    • POSTROUTING (马上就要出去时进行的处理)
  • 自定义链:必须调用在内置链上,自定义链上的规则才会生效;

2 功能:4表

  • filter:实现过滤,防火墙;
  • nat:network address translation,相当于mangle中的一部分功能,(修改ip层地址,传输层地址);主要完成源和目标IP、源和目标端口的修改;
  • mangle:实现拆解报文,按需修改之后(ttl、上层协议等等),重新封装;打上一个mask标记;
  • raw:关闭在nat表上启用的连接追踪机制;

3 三种报文流向

  • 外网访问自己:网口-->PREROUTING-->INPUT
  • 经由自己转发:网口1--->PREROUTING-->FORWARD-->POSTROUTING--->网口2
  • 自己访问外网:OUTPUT-->POSTROUTING--->网口

4 数据包匹配流程

iptables的模块

  • iptables是高度模块化的,有诸多扩展模块实现其检查条件或处理动作的定义;
    • ipv4使用libip6t_*
    • ipv6使用libipt_,libxt_*
      xtables目录下以.so结尾的是模块文件,每一个模块用来实现一类或一种功能;名称为小写是用来做匹配条件的,名称为大写是用来做处理动作的;

5 iptables选项

5.1 链管理

-N	新建链
-X	删除链(只能删除自定义链,而且必须先清除所有规则)
-E	重命名
-P	设置链的默认策略,ACCEPT、DROP

示例

iptables -N INPUT_TEST	新建链INPUT_TEST
iptables -E INPUT_TEST OUTPUT_TEST	将自定义链INPUT_TEST改名为OUTPUT_TEST
iptables -X OUTPUT_TEST	删除链INPUT_TEST
iptables -P OUTPUT DROP	更改内置链的默认规则为DROP,自定义链不能有默认规则

5.2 规则管理

-A	追加为链中的最后一条规则
-I	插入,如不指定rule_number则默认插入到第一条
-R	替换,如不指定rule_number则默认替换第一条
-D	删除,可以指定删除某个rule_number,或指定删除满足某个匹配条件的rule
-F	清空规则表,可清空某个表上的所有链的规则,清空所有表上的所有链的规则,也可清空某个链上的所有表的规则
-Z	将规则的计数置0;iptables的每条规则,都有两个计数器:1、有本规则匹配到的所有的packets,2、由本规则匹配到的所有packets大小之和
-S	列出规则selected,以iptables-save命令的格式显示链上的规则;可重定向保存规则;相当于iptables-save命令;

示例

iptables -A OUTPUT_TEST -s 192.168.1.0/24 -d 192.168.1.9 -p tcp -j ACCEPT	##追加规则到OUTPUT_TEST链的最后
iptables -I OUTPUT_TEST 1 -s 192.168.2.0/24 -d 192.168.1.9 -p tcp -j ACCEPT	##插入规则到OUTPUT_TEST的最前,忽略rule_num默认插入到最前
iptables -R OUTPUT_TEST 2 -s 192.168.3.0/24 -d 192.168.1.9 -p tcp -j DROP	##将第二条规则替换
iptables -D OUTPUT_TEST 2		##删除OUTPUT_TEST链中的第二条规则
iptables -Z OUTPUT_TEST 1		##清空OUTPUT_TEST链中的第一条规则的计数
iptables -Z OUTPUT_TEST		##清空OUTPUT_TEST链中所有规则的计数
iptables -F 					##清空所有规则
iptables -F -t filter			##清空filter表的所有规则
iptables -F OUTPUT_TEST		##清空OUTPUT_TEST链中的所有规则
iptables -S -t nat				##显示nat表的所有规则,格式和iptables-save一样,如果不指定表,则为默认的filter表

5.3 查看

-L	list,列出规则
-n	以数字形式显示IP地址和端口
-v	查看详细信息,支持-vv,-vvv
-x	显示计数器的精确值而非单位换算后的结果;
--line-numbers		显示每个rule的rule number

示例

iptables -vxnL		##不指定的-t的话,就默认查看所有filter表的规则,所有-L要放到是最后,因为-L是命令,-n和-v是选项,用来修饰命令的;
iptables -vxnL INPUT --line-numbers		##显示INPUT链的过滤规则,并且显示规则ID;
每一个自定义链都有引用计数,在内置链上引用一次,引用计数就加1,之后引用计数为0时才可以删除;

6 iptables规则

iptables是由规则组成的;而规则就是根据匹配条件来尝试匹配报文,一旦匹配成功,就由定义的处理动作作出处理;

匹配条件

  • 基本匹配:根据IP地址与端口
  • 扩展匹配:通过协议端口与其他复杂的高级功能
    • 隐式扩展:使用-p选项指定匹配何种协议(这样会自动加载所指定协议需要的模块),从而可以不使用-m选项专门加载相应模块;
    • 显式扩展:必须使用-m选项专门指定加载相应模块;

处理动作

  • 基本处理动作
    • ACCEPT:允许数据包通过
    • DROP:将数据包丢弃,不返回任何信息
    • REJECT:拒绝数据包通过,默认情况下会返回一个ICMP-UNRECHABLE-PORT给访问者;
  • 扩展处理动作
    • RETURN:在自定义链中使用,用途是返回调用者(回到主链);;
    • REDIRECT:在本机做端口映射,端口重定向;
    • LOG:将日志记录在/var/log/message文件中,然后将数据包传递给下一条规则;
    • MARK:防火墙标记;
    • DNAT:目标地址转换;
    • SNAT:源地址转换;
    • MASQERADE:地址伪装;
  • 自定义处理动作
    • 自定义链:调用在内置链之后,自定义链中定义的规则才会生效;

6.1 显示扩展示例

允许192.168.1.0/24网段访问192.168.2.0/24网段的非UDP协议通过
iptables -A OUTPUT_TEST -s 192.168.1.0/24 -d 192.168.2.0/24 ! -p udp -j ACCEPT

允许192.168.1.0/24网段访问192.168.2.0/24网段的tcp SYN报文(只有SYN置位)通过
iptables -A OUTPUT_TEST -s 192.168.1.0/24 -d 192.168.2.0/24 -p tcp --syn -j ACCEPT

允许192.168.1.0/24网段访问192.168.2.0/24网段的icmp echo request报文通过
iptables -A OUTPUT_TEST -s 192.168.1.0/24 -d 192.168.2.0/24 -p icmp --icmp-type 8/0 -j ACCEPT

允许192.168.1.0/24网段访问192.168.2.1主机的tcp21、22、23端口
iptables -A OUTPUT_TEST -s 192.168.1.0/24 -d 192.168.2.1 -p tcp --dport 21:23 -j ACCEPT

允许192.168.2.1主机使用udp67口端访问所有主机
iptables -A OUTPUT_TEST -s 192.168.2.1 -p udp --sport 67 -j ACCEPT

6.2 隐式扩展示例

multiport示例

多端口一条规则指明:开放22和80端口:
iptables -I INPUT -s 0/0 -d 172.18.11.114 -p tcp -m multiport --dports 22,80 -j ACCEPT
iptables -I OUTPUT -d 0/0 -s 172.18.11.114 -p tcp -m multiport --sports 22,80 -j ACCEPT

如果想同时指定源端口范围和目的端口范围则需要指定两次-m选项
iptables -A OUTPUT_TEST -s 172.16.11.114 -p udp -m multiport --sports 67,68 -m multiport --dports 67,68 -j ACCEPT

iptange示例

允许172.16.11.114服务区使用udp67、68端口访问192.168.1.0-192.168.1.10这些IP的UDP67、68端口
iptables -A OUTPUT_TEST -s 172.16.11.114 -p udp -m iprange --dst-range 192.168.1.0-192.168.1.10 -m multiport --sports 67,68 -m multiport --dports 67,68 -j ACCEPT

string示例

例如:禁止响应页面内容有test字样
iptables -I OUTPUT -s 172.18.11.114 -d 0/0 -p tcp --sport 80 -m string --algo bm --string "test" -j REJECT

time示例

在工作工作日的9:00-16:00,放行访问telnet服务
iptables -R INPUT 4 -d 172.18.11.114 -p tcp --dport 23 -m iprange --src-range 172.18.11.1-172.18.11.111 -m time --timestart 09:00:00 --timestop 16:00:00 --kerneltz --weekdays 1,2,3,4,5 -j ACCEPT

connlimit示例

限制每台主机访问telnet最大并发数为2个
iptables -A INPUT -s 0/0 -d 172.18.11.114 -p tcp --dport 23 -m connlimit --connlimit-upto 2 -j ACCEPT

limit示例

允许别人ping,设置一分钟20包(表示一次ping需要3秒),突发值(桶大小)为3,;
除了最开始的3个包,其余报文均按照一次ping需要3秒的设定
iptables -R INPUT 5 -d 172.18.11.114 -p icmp --icmp-type 8 -m limit --limit 20/minute --limit-burst 3 -j ACCEPT

state

使用state使iptables支持FTP的被动模式

加载模块之后就支持ftp的连接追踪
[root@ftp ~]# modprobe nf_conntrack_ftp

下列配置可以支持ftp被动模式
[root@ftp ~]# iptables -vnL INPUT
Chain INPUT (policy ACCEPT 73 packets, 7631 bytes)
 pkts bytes target     prot opt in     out     source               destination         
    3   176 ACCEPT     tcp  --  *      *       0.0.0.0/0            192.168.1.131        tcp dpts:21:22 state NEW
  398 29161 ACCEPT     all  --  *      *       0.0.0.0/0            192.168.1.131        state ESTABLISHED
    1    60 ACCEPT     tcp  --  *      *       0.0.0.0/0            192.168.1.131        state RELATED
    8   472 DROP       all  --  eth0   *       0.0.0.0/0            192.168.1.131       
[root@ftp ~]# iptables -vnL OUTPUT
Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         
  313 38663 ACCEPT     all  --  *      *       192.168.1.131        0.0.0.0/0            state NEW,ESTABLISHED
    0     0 DROP       all  --  *      eth0    192.168.1.131        0.0.0.0/0           

7 FORWARD链配置规则

一个linux主机上两块网卡,分别是A、B,A后面接着的终端访问B网卡自身的IP时,即便不开启linux主机上的net.ipv4.ip_forward也可以通信。因为这两个IP地址虽然配置在网卡上了,但却是它们属于同一个内核的,内核内部的通信不算转发;
转发的意思是,从这个内核转出去,这种情况下才需要开启net.ipv4.ip_forward;
配置FORWARD链的filter表和配置INPUT/OUTPUT链的filter表是一样的,注意一下数据的流向即可;

临时开启转发
sysctl -w net.ipv4.ip_forward=1

永久开启转发
需要编辑/etc/sysctl.conf

配置转发规则是要注意的问题

  • 请求-响应报文均会经由FORWARD链,要注意规则的方向性;
  • 如果要启用contrack机制,建议将双方向的状态为ESTABLISHED的报文直接放行;

8 NAT

三台设备上没有任何策略;
三台设备的路由表如下
[root@a-server ~]# route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         172.16.1.1      0.0.0.0         UG    100    0        0 ens33
172.16.1.0      0.0.0.0         255.255.255.0   U     100    0        0 ens33

[root@b-server ~]# route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
10.207.51.0     0.0.0.0         255.255.255.0   U     100    0        0 ens37
172.16.1.0      0.0.0.0         255.255.255.0   U     100    0        0 ens33

[root@c-server ~]# route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
10.207.51.0     0.0.0.0         255.255.255.0   U     100    0        0 ens33

已在B-Server上开启了转发功能
sysctl -w net.ipv4.ip_forward=1		##此方法临时生效

8.1 SNAT

SNAT仅可以在POSTROUTING和INPUT链下nat表中使用;或者将SNAT定义在自定义链中,然后在POSTROUTING和INPUT链中的nat表下调用;
SNAT可以更改数据包的源地址和源端口
根据现在看到的效果,只有首包才会让rules的计数加1,例如ping -c 10 x.x.x.x 只会让规则的计数+1;ssh x.x.x.x后不管执行了多少操作,只会让规则的计数+1;

示例

让A可以访问C,就需要在B上做SNAT,将A访问C的数据包的源地址改为与C一个网段的IP地址;
iptables -t nat -A POSTROUTING -s 172.16.1.10 -d 10.207.51.92 -j SNAT --to-source 10.207.51.91

下面这种配置可以实现对10.207.51.90和10.207.51.91的循环使用,172.16.1.10使用10.207.51.90,172.16.1.11使用10.207.51.91;
已经提前在A和B上配置了子网卡
iptables -t nat -A POSTROUTING -m iprange --src-range 172.16.1.10-172.16.1.11 -d 10.207.51.92 -j SNAT --to-source 10.207.51.90-10.207.51.91

8.2 MASQUERADE

MASQUERADE只能在POSTROUTING和INPUT链下nat表中使用;
MASQUERADE只应该用在动态分配IP地址(拨号上网)的时候,如果有静态IP地址,就不应该使用SNAT,MASQUERADE是将数据包的源地址映射为接口的IP,可以理解为这就是PAT;
根据现在看到的效果,只有首包才会让rules的计数加1,例如ping -c 10 x.x.x.x 只会让规则的计数+1;ssh x.x.x.x后不管执行了多少操作,只会让规则的计数+1;

--to-ports port[-port] ##指定源端口范围,但只在制定了协议后有效(tcp, udp, dccp or sctp.)
--random ##随机映射端口(kernel >= 2.6.21)

示例

这将使用B的接口地址进行NAT转换
iptables -t nat -R POSTROUTING 1 -m iprange --src-range 172.16.1.10-172.16.1.13 -d 10.207.51.92 -j MASQUERADE

8.3 DNAT

DNAT只能配置在PREROUTING和OUTPUT链下;或者在自定义链中定义,然后在PREROUTING和OUTPUT链下调用。
DNAT可以更改数据包的目的地址和目的端口;
根据现在看到的效果,只有首包才会让rules的计数加1,例如ping -c 10 x.x.x.x 只会让规则的计数+1;ssh x.x.x.x后不管执行了多少操作,只会让规则的计数+1;
为服务器配置了DNAT之后,服务器自己向往访问并不会只用DNAT映射的地址,还是需要为其配置SNAT;

--to-destination [ipaddr[-ipaddr]][:port[-port]] ##如果指定了这些协议(tcp, udp, dccp or sctp),则可以指定端口或端口范围;如果没有指定端口范围,则目的端口不会更改;如果没有指定IP地址,则只修改目标端口;
--random ##将随机映射端口(kernel >= 2.6.22)
--persistent ##为每个连接提供相同的源目地址;固定的;Support for persistent mappings is available from 2.6.29-rc2.

示例

让C可以访问A,方法用DNAT是将10.207.51.89, 映射为172.16.1.10
已经提前在A和B上配置了子网卡
iptables -t nat -A PREROUTING -d 10.207.51.89 -j DNAT  --to-destination 172.16.1.10

C ssh 10.207.51.89:19970时,可以登录到172.16.1.10:22
iptables -t nat -A PREROUTING -p tcp -d 10.207.51.89 --dport 19970 -j DNAT --to-destination 172.16.1.10:22

8.4 REDIRECT

REDIRECT不能更改目的IP地址,只能更改目的端口,所以它可以将访问自己某个端口的数据包,重定向到自己的另一个端口上;

示例

目的端口为19970的数据包重定向到22端口;
iptables -t nat -R PREROUTING 1 -p tcp -d 10.207.51.89 --dport 19970 -j REDIRECT --to-port 22

使用DNAT也可以实现一样的效果
iptables -t nat -R PREROUTING 1 -p tcp -d 10.207.51.89 --dport 19970 -j DNAT --to-destination 10.207.51.89:22

9 保存和载入规则

保存:iptables-save > /PATH/FROM/SOME_RULE_FILE
重载:iptables-restore < /PATH/FROM/SOME_RULE_FILE

Centos 6专用方式
保存:service iptables save ##保存在/etc/sysconf/iptables文件中,覆盖保存;
重载:service iptables restart ##重新载入/etc/sysconf/iptables文件中的内容‘;

Centos7方式
使用iptables-save命令将规则导出到指定文件
在rc.local中定义脚本,使用iptables-restore回复规则

posted @ 2018-12-31 19:08  虚拟一点  阅读(556)  评论(0编辑  收藏  举报