iptables 详解

前言

  关于iptables个人感觉里面还是有很多东西的,早几年有学过,后来因为工作的原因,就逐渐淡忘。
最近打算重拾一下,然后各种查阅文献(参考网络),找运维老师傅发参考文档研究,同时整理下此文。
希望看到该文的读者能大概有所了解.
 
​iptables是Linux上常用的类似于windows防火墙的一个命令
iptables的前身叫ipfirewall,最早是从FreeBSD移植过来的
后来软件更名为ipchains,它可以定义多条规则,将他们串起来,共同发挥作用。
现在,它叫做iptables,可以将规则组成一个列表,实现绝对详细的访问控制功能


0x01 NetFilter规定的五个规则链

它们定义的规则,可以让在内核空间当中的netfilter来读取,并且实现让防火墙工作。
而放入内核的地方必须要是特定的位置,必须是tcp/ip的协议栈经过的地方。
而这个tcp/ip协议栈必须经过的地方,可以实现读取规则的地方就叫做 netfilter.(网络过滤器)
 
iptables 作者一共在内核空间中选择了5个位置
1.内核空间中:从一个网络接口进来,到另一个网络接口去的
2.数据包从内核流入用户空间的
3.数据包从用户空间流出的
4.进入/离开本机的外网接口
5.进入/离开本机的内网接口

 
这五个位置也被称为五个钩子函数(hook functions),也叫五个规则链。
1.PREROUTING (路由前)
2.INPUT (数据包流入口)
3.FORWARD (转发管卡)
4.OUTPUT(数据包出口)
5.POSTROUTING(路由后)

任何一个数据包,只要经过本机,必将经过这五个链中的其中一个链


0x02 iptables 的表

iptables包含4个表,5个链。其中表是按照对数据包的操作区分的
4个表:filter,nat,mangle,raw
默认表是filter(没有指定表的时候就是filter表)
表的处理优先级: raw>mangle>nat>filter。
filter:一般的过滤功能
nat:用于nat功能(端口映射,地址映射等)
mangle:用于对特定数据包的修改
raw:优先级最高,设置raw时一般是为了不再让iptables做数据包的链接跟踪处理,提高性能


表与链的关系图


0x03 数据包走向流程


数据包先经过PREOUTING,由该链确定数据包的走向:
1、目的地址是本地,则发送到INPUT,让INPUT决定是否接收下来送到用户空间,流程为①—>②;
2、若满足PREROUTING的nat表上的转发规则,则发送给FORWARD,然后再经过POSTROUTING发送出去,流程为: ①—>③—>④—>⑥
3、主机发送数据包时,流程则是⑤—>⑥


0x03 iptables 操作指令

基本语法:iptables [-t 表] [操作命令] [链][规则匹配器][-j 目标动作]

操作命令
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
-t:指定要操纵的表;
-A:向规则链中添加条目;
-D:从规则链中删除条目;
-i:向规则链中插入条目;
-R:替换规则链中的条目;
-L:显示规则链中已有的条目;
-F:清楚规则链中已有的条目;
-Z:清空规则链中的数据包计算器和字节计数器;
-N:创建新的用户自定义规则链; //例:iptables -N allowed
-E: 更改自定义链的名称 //例:iptables -E allowed disallowed
-P:定义规则链中的默认目标;
-h:显示帮助信息;
-p:指定要匹配的数据包协议类型;
-s:指定要匹配的数据包源ip地址;
-j<目标>:指定要跳转的目标;
-i<网络接口>:指定数据包进入本机的网络接口;
-o<网络接口>:指定数据包要离开本机所使用的网络接口。

规则匹配器
1
2
3
4
5
6
7
8
9
-p tcp|udp|icmp|all //匹配协议,all会匹配所有协议
-s addr[/mask] //匹配源地址
-d addr[/mask] //匹配目标地址
--sport port1[:port2] //匹配源端口(可指定连续的端口)
--dport port1[:port2] //匹配目的端口(可指定连续的端口)
-o interface //匹配出口网卡,只适用FORWARD、POSTROUTING、OUTPUT.
-i interface //匹配入口网卡,只使用PREROUTING、INPUT、FORWARD。
--icmp-type //匹配icmp类型(使用iptables -p icmp -h可查看可用的ICMP类型)
--tcp-flags mask comp //匹配TCP标记,mask表示检查范围,comp表示匹配mask中的哪些标记如SYN

目标动作
1
2
3
4
5
6
7
8
9
10
11
12
13
14
ACCEPT //允许数据包通过
DROP //丢弃数据包
REJECT //丢弃数据包,并且将拒绝信息发送给发送方
SNAT //源地址转换(在nat表上)
    //例:iptables -t nat -A POSTROUTING -d 192.168.0.102 -j SNAT --to 192.168.0.1
DNAT //目标地址转换(在nat表上)
    //例:iptables -t nat -A PREROUTING -d 202.202.202.2 -j DNAT --to-destination 192.168.0.102
REDIRECT //目标端口转换(在nat表上)
    //例:iptables -t nat -D PREROUTING -p tcp --dport 8080 -i eth2.2 -j REDIRECT --to 80
MARK //将数据包打上标记
    //例:iptables -t mangle -A PREROUTING -s 192.168.1.3 -j MARK --set-mark 60
注意要点:
1、目标地址转换一般在PREROUTING链上操作
2、源地址转换一般在POSTROUTING链上操作


0x04 iptables 规则编写

默认规则

图上,iptables -L 查看规则链,可以看到3个3个常用默认链INPUT、OUTPUT和FORWARD
iptables -S可以看到每个链的缺省策略(每个链对默认策略都是接受)
从规则编写的大局观来谈的话,应当对每个链默认策略采取丢弃(主要针对INPUT链),只放行需要的数据(可能这需要好好规划一下)。
每个包都是有来有回的(可能下面不会列举过多的OUTPUT链的设置),如果全是拒绝的话 可能响应包也不能正常返回到请求主机,这是需要注意的点.
测试角度,因为我是测试环境,默认策略就不做更改,下面只列举可能需要丢弃的数据
 
丢弃某个协议流量

1
iptables -A INPUT -p icmp -j REJECT

这里如果使用DROP的话 请求主机(Linux)的ping状态一直会出现闪烁状态,请求主机(Win)则会出现请求超时
如果是REJECT 则会出现如下图所示 目标端口不可达
禁Ping的话可以杜绝大部分黑客工具的探测行为

 
丢弃某个端口协议流量

1
iptables -A INPUT -p tcp --dport 22 -j REJECT

针对端口(对应某个服务)需要了解到该服务传输方式是udp还是tcp.

 
访问控制 (源)

1
iptables -A INPUT -s 192.168.118.135 -p icmp -j ACCEPT //可定义某个IP段(-s 192.168.118.0/24)

需要注意的是:我在前面定义了 丢弃icmp协议(因此上面这条不会被匹配到)
所有我们在定义规则的时候 需要正确的优先顺序 iptables -F 可以让我们从来.

1
2
iptables -A INPUT -s 192.168.118.135 -p icmp -j ACCEPT
iptables -A INPUT -p imcp -j DROP

这样的话来自192.168.118.135的主机才被允许,而来自其它主机的imcp请求则会被拒绝
如图下(两个不同IP地址主机的测试截图)

 
访问控制(目标)

1
iptables -A OUTPUT -p tcp --dport 80 -d www.lsafe.org -j DROP

上面这种拒绝形式应该不常用,这里拿我朋友的博客做演示,图下

关于转发这里就不细究了,可以参考
http://blog.csdn.net/shuzui1985/article/details/45879257
http://blog.csdn.net/hcancientmoon/article/details/40158969
http://www.cnblogs.com/junshen/p/6022207.html


0x05 注意事项

Redhat系列
iptables启动后会从/etc/sysconfig/iptables 配置文件读取进内存加载运行.
所以使用vim 修改iptables配置文件的时候,切记不要使用/etc/init.d/iptables save这个命令
这样会导致你辛苦修改的配置文件内存正在运行(也就是修改前的配置)的iptables规则给覆盖
正确做法,修改完配置文件,然后再service iptables restart重启iptables读取修改后的配置文件.
而如果是使用iptables命令直接在内存中修改规则的话
则要注意修改完成后,调用/etc/init.d/iptables save保存回配置文件中以便下次开机生效。
若不是 RedHat 系列
可以使用下面方法手动保存/恢复配置
iptables-save > /root/iptables.conf //保存
iptables-restore < /root/iptables.conf //恢复
 
一般服务器都不会在身边,而是采用SSH进去做iptables规则的方式
千万得小心注意每一步,搞错后SSH链接不上就很麻烦了!所以首先要做的是给SSH进行ACCEPT配置
以避免直接无法连接的情况发生
 
最好提前用文档逐次规划好要放行的服务器上的端口、协议等。做到最小权限放行,再拒绝所有连接。
还要注意数据有去有回,INPUT和OUTPUT都要考虑设置好