一、iptables前言
1.什么是防火墙呢?
简单的说,防火墙就是工作于主机或网络的边缘,对于进出的报文根据事先定义的规则作检查,将那些能够被规则所匹配到的报文作出相应处理的组件。防火墙在做信息包过滤决定时,有一套遵循和组成的规则,这些规则存储在专用的信 息包过滤表中,而这些表集成在 Linux 内核中。在信息包过滤表中,规则被分组放在我们所谓的链(chain)中。防火墙分为两种:主机防火墙和网络防火墙。
2.什么是iptables呢?
直观的说,iptables是一个软件程序。真正防火墙组件是:netfilter,全称叫网络过滤器,防火墙(Firewall),也称防护墙,是由Check Point创立者Gil Shwed于1993年发明并引入国际互联网。它是一种位于内部网络与外部网络之间的网络安全系统。我们知道资源子网在用户空间,而通信子网在内核空间,所以iptables常常工作在内核中,因为tcp/ip协议栈工作在内核中。iptables共有四表五链,等会下面我会介绍.
二、关于netfilter架构
通俗的说,netfilter的架构就是在整个网络流程的若干位置放置了一些检测点(HOOK),而在每个检测点上登记了一些处理函数进行处理(包括包过滤filter,地址转换NAT等,甚至可以是 用户自定义的功能)。netfilter提供了一个抽象、通用化的框架,作为中间件,为每种网络协议(IPv4、IPv6等)定义一套钩子函数。Ipv4定义了5个钩子函数,这些钩子函数在数据报流过协议栈的5个关键点被调用。钩子函数,英文全称叫hook funcion,ipv4定义的5个钩子函数如下:
hook函数 | 函数意义 |
prerouting | 表示进入本机后路由功能发生之前 |
input | 表示到达本机内部 |
output | 表示由本机发出 |
forward | 表示由本机转发 |
postrouting | 表示路由功能发生之后,即将离开本机之前 |
我们都知道,路由发生时刻分两种:报文进入本机后和报文离开本机之前。报文进入本机之后,我们可以判断目标地址;而报文离开本机之前,我们可以判断经由哪个网卡发出的。这些我们可以用如下图来表示:
上面我们提到了(即钩子函数),在iptables中,每个钩子点可以放置N条规则,每个钩子点上的这些规则组合起来就称为:链(chain)。同时,每个功能有多个链,所以就称为:表(table),包括如4种:
filter(过滤功能)---主要在3个点:input, forward, output
nat(地址转换功能)---主要在3个点:prerouting, output, postrouting
mangle(修改报文首部中的某些信息)----主要在5个点:prerouting, input, forward, output, postrouting
raw(关闭nat表上启用的连接追踪功能)---主要2个点:prerouting, output
三、iptables命令配置防火墙
iptables命令生成规则,送往netfilter; 规则通过内核接口直接送至内核,因此,会立即生效。但不会永久有效;如果期望有永久有效,需要保存至配置文件中,此文件还开机时加载和由用户手工加载;
命令:iptables [-t TABLE] SUBCOMMAND CHAIN CRETERIA -j TARGET
-t TABLE:默认为filter, 共有filter, nat, mangle, raw四个可用;
SUBCOMMAND CHAIN (子命令 链):
-F:flush,清空指定表的指定链上所有规则;省略链名时,清空表中的所有链;
-N:new, 新建一个用户自定义的链;自定义链只能作为默认链上的跳转对象,即在默认链通过引用来生效自定义链;
-X:drop,删除用户自定义的空链;非空自定义链和内置链无法删除;
-Z:zero,将规则的计数器置0;
-P:policy,设置链的默认处理机制;当所有都无法匹配或有匹配有无法做出有效处理机制时,默认策略即生效;filter表的可用策略:ACCEPT, DROP, REJECT
-E:rename,重命名自定义链;
【注意:被引用中的链,无法删除和改名】
CRETERIA(规则):
-A:append,在链尾追加一条规则;
-I:insert,在指定位置插入一条规则;
-D:delete,删除指定的规则;
-R:replace,替换指定的规则;
-L:list,列出指定链上的所有规则;
-L -n: numeric,以数字格式显示地址和端口号,即不反解;
-L -v: verbose,详细格式,显示规则的详细信息,包括规则计数器等;
-L -vv:
-L -vvv:
-L --line-numbers: 显示规则编号;
-L -x: exactly,显示计数器的精确值;
相关练习1:
1.#清空nat表上的所有链(-F后面省略链名时,表示清空表上的所有链)
[root@localhost~]# iptables -t nat-F
2.#自定义一个新链webrules,并查看创建的新链
[root@localhost~]# iptables -Nwebrules [root@localhost ~]# iptables -L -n -v #显示定义的规则、链、以及链上的计数器 Chain INPUT (policy ACCEPT 271 packets,21034 bytes) #表示被默认策略匹配到的包有271个,字节数有21034pkts bytes target(处理目标) prot(协议) opt(选项) in(数据包流入接口) out(流出接口) source(包源地址) destination(包目标地址) ChainFORWARD (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination 0 0 REJECT all -- * * 0.0.0.0/0 0.0.0.0/0 reject-withicmp-host-prohibited ChainOUTPUT (policy ACCEPT 13 packets, 1520 bytes) pkts bytes target prot opt in out source
3.#删除已存在的的空链webrules【注意:不能删除内置链和非空链】
[root@localhost~]# iptables -X webrules
4.#清空规则上的计数器,并查看计数器
[root@localhost~]# iptables -Z [root@localhost~]# iptables -L -n -v Chain INPUT (policy ACCEPT 7 packets,474 bytes) #默认策略为ACEPT pkts bytes target prot opt in out source
5.在filter表中input链中的默认策略改为DROP(禁忌这样做,相当危险,你的shell会被挡在门外,要记得放行ssh的访问)
[root@localhost~]# iptables -tfilter -P INPUT DROP
6.将定义了的链webrules改名为httpdrules【注意:已经被引用的链不能被改名,也不能删除】
[root@localhost~]# iptables -N webrules [root@localhost~]# iptables -n -L -v ChainINPUT (policy ACCEPT 132 packets, 9366 bytes) ……. Chainwebrules (0 references) pkts bytes target prot opt in out source destination [root@localhost~]# iptables -E webrules httpdrules [root@localhost~]# iptables -n -L -v ChainINPUT (policy ACCEPT 6 packets, 396 bytes) ………. Chainhttpdrules (0 references) pkts bytes target prot opt in out source destination
CRETERIA: 匹配条件,用于检查IP首部,检查TCP、UDP或ICMP首部;基于扩展机制,也可以进行额外的检查;如做连接追踪;
【注意:可同时指定多个条件,默认多条件要同时被满足;】
四、匹配条件
1.通用匹配:
-s, --src, --source IP|Network:检查报文中的源IP地址; -d, --dst, --destination:检查报文中的目标IP地址;
-p, --protocol:检查报文中的协议,即ip首部中的protocols所标识的协议;tcp、udp或icmp三者之一;
-i, --in-interface:数据报文的流入接口;通常只用于PREROUTING, INPUT, FORWARD链上的规则;
-o, --out-interface:检查报文的流出接口;通常只用于FORWARD, OUTPUT, POSTROUTING链上的规则;
2.扩展匹配(指使用iptables的模块实现扩展性检查机制)
(1)隐式扩展:如果在通用匹配上使用-p选项指明了协议的话,则使用-m选项指明对其协议的扩展就变得可有可无了;
tcp:
--dport PORT[-PORT]
--sport
--tcp-flags LIST1 LIST2
LIST1: 要检查的标志位;
LIST2:在LIST1中出现过的,且必须为1标记位;而余下的则必须为0;
例如:--tcp-flags syn,ack,fin,rst syn
--syn:用于匹配tcp会话三次握手的第一次;
udp:
--sport
--dport
icmp:
--icmp-types {8|0},其中8: echo request,表示请求;0:echo reply,表示回应
【注意:以上都可以指明连续端口,不能指明离散端口】
相关练习2:
5.控制33.4的主机对33.199的主机的web访问统统拒绝,插入第一条规则(-I),源ip为33.4,目标ip为33.199,协议为tcp协议,-m tcp --dport 80:表示web服务器端口为tcp/80,客户端源端口随机(不能指)
[root@localhost ~]#iptables -I INPUT 1 -s 172.16.33.4 -d 172.16.33.199 -p tcp -m tcp --dport 80 -jREJECT [root@localhost ~]#iptables -L -n -v Chain INPUT (policyACCEPT 41 packets, 3137 bytes) pkts bytes target prot opt in out source destination 0 0 REJECT tcp -- * * 172.16.33.4 172.16.33.199 tcp dpt:80reject-with icmp-port-unreachable
6.表示在第一个位置添加一条规则,控制33.4的主机对33.199的主机ssh访问(ssh访问端口为22号)
#iptables -I INPUT 1 -s 172.16.33.4 -d 172.16.33.199 -p tcp -m tcp --dport 22 -jREJECT 此时我们发现我们的ssh已经断开。这时候我们就只能回到主机上面进行如下操作改回来就可用ssh远程连上了 # iptables -R INPUT 1 -s172.16.33.4 -d172.16.33.199 -ptcp -m tcp --dport 22 -j ACCEPT ( -m tcp可省) [root@localhost ~]#iptables -L -n -v Chain INPUT (policyACCEPT 439 packets, 42445 bytes) pkts bytes target prot opt in out source destination 0 0 ACCEPT tcp -- * * 172.16.33.4 172.16.33.199 tcp dpt:20 6 304 REJECT tcp -- * * 172.16.33.4 172.16.33.199 tcp dpt:80reject-with icmp-port-unreachable
7.让所有主机都能ping 通33.199的主机
[root@localhost ~]#iptables -I INPUT 3 -d 172.16.33.199 -p icmp -j ACCEPT
8.控制199主机的ssh(即22号端口)响应报文能够响应出去
[root@localhost~]# iptables -A OUTPUT -s 172.16.33.199 -p tcp --sport 22 -j ACCEPT
9.设置OUTPUT的默认处理机制为DROP
[root@localhost ~]#iptables -P OUTPUTDROP [root@localhost ~]#iptables -L -n -v Chain INPUT (policyACCEPT 447 packets, 33434 bytes) pkts bytes target prot opt in out source destination 0 0 ACCEPT tcp -- * * 172.16.33.4 172.16.33.199 tcp dpt:20 6 304 REJECT tcp -- * * 172.16.33.4 172.16.33.199 tcp dpt:80reject-with icmp-port-unreachable 5 420 ACCEPT icmp -- * * 172.16.33.200 172.16.33.199 Chain FORWARD(policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination 0 0 REJECT all -- * * 0.0.0.0/0 0.0.0.0/0 reject-withicmp-host-prohibited Chain OUTPUT (policyDROP 6 packets, 504 bytes) pkts bytes target prot opt in out source destination 126 14958 ACCEPT tcp -- * * 172.16.33.199 0.0.0.0/0 tcp spt:22
此时我们的ping操作既ping不出去,别人又ping不进来
10.允许199主机能ping任何主机,即从OUTPUT 出去的是request,从INPUT进来的是REPLY(如果允许别人ping本机,则是从INPUT进来的是request,从OUTPUT 进来的是REPLY,请求的是8,响应的是0)
[root@localhost ~]#ping 172.16.33.200 PING 172.16.33.200(172.16.33.200) 56(84) bytes of data. ping: sendmsg:Operation not permitted ping: sendmsg:Operation not permitted ^C --- 172.16.33.200ping statistics --- 2 packetstransmitted, 0 received, 100% packet loss, time 1081ms [root@localhost ~]# iptables -A OUTPUT -s 172.16.33.199 -p icmp --icmp-type 8 -j ACCEPT #让自己的ping请求报文能够出去 [root@localhost ~]#ping 172.16.33.200 PING 172.16.33.200(172.16.33.200) 56(84) bytes of data. 64 bytes from172.16.33.200: icmp_seq=1 ttl=64 time=3.17 ms 64 bytes from172.16.33.200: icmp_seq=2 ttl=64 time=0.276 ms [root@localhost ~]# iptables-I INPUT 3 -d 172.16.33.199 -p icmp --icmp-type 0 -j ACCEPT #让人家响应的ping响应报文能够到达本机199 [root@localhost ~]# iptables -I INPUT 4 -d 172.16.33.199 -p icmp --icmp-type 8 -j ACCEPT #让人家的ping报文请求能够到达本机 [root@localhost ~]# iptables -A OUTPUT -s 172.16.33.199 -p icmp --icmp-type 0 -j ACCEPT #让自己的ping报文响应能够出去
(2)多端口扩展:multiport扩展,以离散定义多端口匹配;最多指定15个端口;
专用选项:
--source-ports,--sports PORT[,PORT,...]
--destination-ports,--dports PORT[,PORT,...]
--portsPORT[,PORT,...]
示例1.控制开放其他主机对199主机的80、443、22号端口的访问
#开放其他外面主机对199主机的tcp协议的22、80、443端口的请求访问 [root@localhost~]# iptables -t filter -I INPUT1 -d 172.16.33.199 -p tcp -m multiport --dports 22,80,443 -j ACCEPT #开放199主机对外响应的的tcp的22、80、443端口 [root@localhost ~]#iptables -t filter -I OUTPUT 1 -s 172.16.33.199 -p tcp -m multiport --sports 22,80,443 -jACCEPT
(3)iprange扩展:指定连续的ip地址范围;在匹配非整个网络地址时使用;
专用选项:
[!]--src-range IP[-IP]
[!]--dst-range IP[-IP]
示例2.放行172.16.33.1-172.16.33.100 主机对33.199主机的tcp协议的23号端口的访问
[root@localhost ~]#iptables -A INPUT -d 172.16.33.199 -p tcp --dport 23 -m iprange --src-range172.16.33.1-172.16.33.100 -j ACCEPT #同时也放行这些网段的主机出站 [root@localhost ~]#iptables -A OUTPUT -s 172.16.33.199 -p tcp --sport 23 -m iprange --dst-range172.16.33.1-172.16.33.100 -j ACCEPT #放行33.199主机对其他外机的80端口的访问, [root@localhost ~]#iptables -A OUTPUT -s 172.16.33.199 -p tcp --dport 80 -j ACCEPT #同时也允许外机的80端口能响应本机 [root@localhost ~]#iptables -A INPUT -d 172.16.33.199 -p tcp --sport 80-j ACCEPT
(4)string扩展,检查报文中出现的字符串,与给定的字符串作匹配;
字符串匹配检查算法:kmp,bm
专用选项:
--algo{kmp|bm}
--string"STRING"
--hex-string "HEX_STRING":HEX_STRING为编码成16进制格式的字串;
示例3.关闭199主机80端口被访问的资源中含有“sex”字符的响应出去
[root@localhost ~]#iptables -R OUTPUT 1 -s 172.16.33.199 -p tcp --sport 80 -m string --string "sex"--algo kmp -j REJECT
(5)time扩展:基于时间区间做访问控制
专用选项:
--datestartYYYY[-MM][-DD][hh[:mm[:ss]]]
--dattestop
--timestart
--timestop
--weekdaysDAY1[,DAY2,...]
示例4.#拒绝199主机web服务在周一到周五的8:30-18:30点的访问,其他时间可以
[root@localhost~]# iptables -R INPUT 1 -d 172.16.33.199 -p tcp --dport80 -m time --timestart 08:30 --timestop 18:30 --weekdays Mon,Tue,Thu,Win,Fri -j REJECT
(6)connlimit扩展:基于连接数作限制;对每个IP能够发起的并发连接数作限制;
专用选项:
--connlimit-above [n] #大于n个就执行规则匹配
示例5.#让并发访问199主机的22号端口的并发连接数大于5个以后统统REJECT(设置完以后,可以用ssh复制超过5个来测试(原来存在的连接不算在内))
[root@localhost ~]#iptables -A INPUT -d 172.16.33.199 -p tcp --dport 22 -m connlimit --connlimit-above 5 -jREJECT
(7)limit扩展:基于发包速率作限制;
专用选项:令牌桶算法
--limit n[/second|/minit|/hour|/day]
--limit-burst n #突发量,一次可以发出去多少个
示例6.控制其他主机ping199主机请求操作,每5分钟5个,突发量为4个(可以用ping操作测试)
[root@localhost~]# iptables -I INPUT -d 172.16.33.199 -p icmp --icmp-type 8 -m limit--limit 5/minute --limit-burst 4 -j ACCEPT
最后这里解释一下,查看iptables时,各参数意义:
[root@localhost ~]# iptables -L -n -v Chain INPUT (policy ACCEPT 12399 packets, 26M bytes) pkts bytes target prot opt in out source destination
pkts bytes target prot opt in out source destination
pkts: 被本规则所匹配到的包个数;
bytes:被本规则所匹配到的所包的大小之和;
target: 处理目标 (目标可以为用户自定义的链)
prot: 协议 {tcp, udp, icmp}
opt: 可选项
in: 数据包流入接口
out: 数据包流出接口
source: 源地址
destination: 目标地址;
原文地址:http://tanjie.blog.51cto.com/10027618/1643614