防火墙就是监控进入到我们网段内主机或网段的信息数据包的一种机制,更广义的说,只要能够分析与过滤进出我们管理网段的数据包数据,就可以称为防火墙。其工作在网络边缘(主机边缘),对进出本网络数据包基于一定的规则进行检查,并在匹配某规则时由规则定义的处理机制进行处理的。

防火墙分为硬件防火墙与软件防火墙两种:

       硬件防火墙:就是一台主机安装了以提供数据包过滤机制为主的操作系统。

       软件防火墙:就是保护系统网络安全的一套软件(或称为机制),下面将详细介绍iptables软件。

防火墙按另外一种方式又可以分成包过滤防火墙和应用层网关防火墙:

包过滤防火墙:工作在tcp/ip层,根据tcp首部或ip首部数据进行判断,安全性不好,但效率高。包过滤防火墙又可以分成简单包过滤和带状态检测的包过滤

应用层网关防火墙:工作在应用层,根据数据包传输的数据数据进行判断,安全性好,但是效率不高。

不同Linux内核版本的防火墙软件:

内核版本 使用的软件防火墙

Version2.0 ipfwadm

Version2.2 ipchains

Version2.4/2.6 iptables

Linux防火墙软件iptables利用的是数据包过滤机制,所以它会分析数据包的表头数据,根据表头数据与定义的规则来决定数据包是否进入主机。

下面根据这幅图来详细介绍利用iptables规则来进行数据包过滤匹配的流程:

1、首先可以看到:

1iptables4个表:rawmanglenatfilter

4个表的优先级由高到底依次是:

raw>mangle>nat>fileter

mangle表:主要与特殊的数据包标记有关

nat表:主要用于源地址与目标地址的IPPort转换。

filter表:是默认操作的表,主要用于过滤数据包,几乎所有的过滤都是在这里完成的。

2iptables5个链:PREROUTINGINPUTFORWARDOUTPTPOSTROUTING

表与链的对应关系:

mangle表:PREROUTINGINPUTFORWARDOUTPTPOSTROUTING

PREROUTING链:在数据包进入防火墙之后,路由判断之前改变数据包;

INPUT链:在数据包进入本机之后,应用程序接受之前改变数据包的;

FORWARD链:第一次路由判断后,最后一次路由判断之后改变数据包;

OUTPUT链:在确定数据包的目标地址之前改变数据包;

POSTROUTING链:最后一个路由判断之后即马上要离开防火墙时改变数据包。

    nat表:PREROUTINGOUTPTPOSTROUTING

PREROUTING链:在数据包刚到达防火墙时改变数据包的目标地址;

OUTPUT链:改变由本机产生的数据包的目标地址;

POSTROUTING链:在数据包就要离开防火墙时改变数据包的源地址。

filter表:INPUTFORWARDOUTPUT

INPUT链:过滤所有目标主机是本机的数据包;

FORWARD链:过滤所有路过本机的数据包,即需要本机转发的数据包;

OUTPUT链:过滤所有由本机产生的数据包。

注意:链名要大写,表名要小写。

(2)处理数据包的目标地址是本机时,数据包过滤匹配的流程:

1) 数据进入网络接口后,进入mangle表的PREROUTING链,在这里主要根据需要修改数据包头内容(比如数据包的TTL值);

2) 进入nat表的PREROUTING链,在这里可以根据需要做DNAT

3) 进行路由判断(进入本机还是转发);

4) 进入mangle表的INPUT链,修改数据包头内容;

5) 进入filter表的INPUT链,所有目标主机是本机的数据包都会经过这里,所以在此处写上iptables规则,对数据进行过滤;

6) 到达本机应用程序处理;

(3) 处理数据包的源地址是本机时, 数据包过滤匹配的流程:

1) 本地应用程序产生的数据包,经路由判断后,进入mangle表的OUTPUT链,在这里过根据需要修改数据包包头内容;

2) 进入nat表的OUTPUT链,根据需要做DNAT

3) 进入filter表的OUTPUT链,在这里可以根据需要设置过滤条件,对数据包进行过滤;

4) 进入mangle表的POSTROUTING链,对要离开本机的数据包根据需要做DNAT

5) 进入nat表的POSTROUTING链,对要离开的数据包做SNAT

6) 离开本机。

(4) 处理经过本机的转发的数据包时, 数据包过滤匹配的流程:

1) 数据包进入网络接口,首先进入manglePREROUTING链,根据需要修改数据包头的内容(如:TTL值);

2) 进入nat表的PREROUTING链,根据需要对数据包做DNAT转换;

3) 进入mangle表的FORWARD链,修改数据包头内容;

4) 进入filter表的FORWARD链,在这里可以设置一些对转发的数据包做过滤的规则,所有的转发数据包都会经过这里;

5) 进入manglePOSTROUTING链,修改数据包头内容;

6) 进入nat表的POSTROUTING链,根据需要对数据包对SNAT(还有地址伪装),最后离开网络接口。

防火墙是工作在内核中的,用户要想设置防火墙规则必须要使用iptables命令(类似于Raidmdadm)。

下面来详细介绍iptables命令的用法:

iptables是一个用于过滤和NAT的管理工具。

1iptables命令的用法格式:

1iptables [-t TABLE] -L [-n] [-v] [-x] [--line-number]

-t {mangle|nat|filter}  若不写,默认是filter

-L 列出目前的iptables规则

-n 以数据方式显示

-v 详细显示

-x 显示精确值(默认会做单位换算,在换算时会四舍五入)

--line-number 显示规则的行号

 
   
  1. //在不指定表时,默认显示的filter表iptables规则  
  2. [root@linli ~]# iptables -L -n -v --line-numbers  
  3. //显示nat表的iptables规则     
  4. [root@linli ~]# iptables -t nat -L -n -v --line-numbers 

(2)iptables [ -t TABLE] COMMAND CHAINS [条件] -j ACTION

-t {mangle|nat|filter}  若不写,默认是filter

COMMAND

1)规则管理类:

-A append,追加

-I insert,插入为第几条

-D delete,删除第几条

-R 替换

2)链管理类:

-F flush,清空链(可以指定链)

-N new,新建自定义链

-X delete,删除自定义链,而且只能删除自定义的空链

-E rename,给自己建的链重命名

3)定义默认策略:

-P policy,定义默认策略

把默认策略设为DROP

 
   
  1. [root@linli ~]# iptables -P INPUT DROP  
  2. [root@linli ~]# iptables -L -n  
  3. Chain INPUT (policy DROP)  
  4.  

4)清空计数器:

-Z zero,清空计数器

每条规则(包括默认策略)都有两个计数器:

一个是:被匹配到的所有数据包的个数

一个是:被匹配到的所有数据包的大小之和(即字节数)

 
   
  1. [root@linli ~]# iptables -L -n -v  
  2. Chain INPUT (policy DROP 1247 packets, 166K bytes)  
  3.  pkts bytes target     prot opt in     out     source               destination           
  4.    72  6057 ACCEPT     tcp  --  *      *       0.0.0.0/0            172.16.26.1         tcp dpt:22   
  5.  
  6. Chain FORWARD (policy DROP 0 packets, 0 bytes)  
  7.  pkts bytes target     prot opt in     out     source               destination           
  8.  
  9. Chain OUTPUT (policy DROP 786 packets, 51672 bytes)  
  10.  pkts bytes target     prot opt in     out     source               destination           
  11.    50  6228 ACCEPT     tcp  --  *      *       172.16.26.1          0.0.0.0/0           tcp spt:22   
  12. [root@linli ~]# iptables -Z INPUT  
  13. [root@linli ~]# iptables -L -n -v  
  14. Chain INPUT (policy DROP 1248 packets, 166K bytes)  
  15.  pkts bytes target     prot opt in     out     source               destination           
  16.     8   536 ACCEPT     tcp  --  *      *       0.0.0.0/0            172.16.26.1         tcp dpt:22   
  17.  
  18. Chain FORWARD (policy DROP 0 packets, 0 bytes)  
  19.  pkts bytes target     prot opt in     out     source               destination           
  20.  
  21. Chain OUTPUT (policy DROP 787 packets, 51732 bytes)  
  22.  pkts bytes target     prot opt in     out     source               destination           
  23.    84 10112 ACCEPT     tcp  --  *      *       172.16.26.1          0.0.0.0/0           tcp spt:22  

5)匹配条件

基本匹配

  -s SOURCE 匹配源地址是SOURCEIP/NETMASK)的进行规则处理

-d DISTINATION 匹配目标地址是DISTINATIONIP/NETMASK)的进行规则处理

   -p {tcp|udp|icmp} 匹配到指定协议的进行规则处理

   -i INTERFACE 匹配到进入端口是INTERFACE的进行规则处理

   -o INTERFACE 匹配到出去端口是INTERFACE的进行规则处理

练习:

阻止通过lo接口进来的数据包;

阻止通过lo接口出去的数据包;

 

扩展匹配(就是调用iptables的模块,以便扩展iptables匹配功能,使用-m选项)

 

隐含扩展(可以省略-m)

-p tcp

  --sport PORT

  --dport PORT

  --tcp-flags SYN = --syn  主动连接(这个比较常用)

-p udp

  --sport PORT

  --dport PORT

-p imcp

   --icmp-type

    8ping请求

       0ping回应

 

练习:  

允许本机的ssh服务能被192.168.0.0/24访问:

允许本机的web服务能被192.168.0.0/24访问:

设置filter表的INPUTOUTPUTFORWARD链默认策略为DROUP:

 

 
   
  1. //拒绝本机的端口号为1:1023的包出去  
  2. # iptables -A OUTPUT -o eth0 -p tcp --sport 1:1023 --syn -j DROP  

显示扩展(必须使用-m)

-m state  连接状态检测

   --state {NEW|ESTABLISHED|INVALID|RELATE}

   NEW:想要建立连接的数据包状态

   ESTABLISHED:已经建立连接的数据包状态

   INVALID:无效的数据包(如:数据破损的数据包状态)

   RELATE:表示数据包与我们主机发送出去的数据包有关(常用于FTP)

练习:仅允许本地主机上那些已建立的连接出去:

 

-m multiport  多端口匹配

   --source-ports

   --destination-ports

   --ports

 
   
  1. //允许刚建立的连接和已建立的连接访问172.16.26.1的多个端口服务,在数据包出去时只允许已建立的连接出去
  2. [root@linli ~]# iptables -A INPUT -d 172.16.26.1 -p tcp -m multiport --destination-ports 80,22,23,110,443 -m state --state NEW,ESTABLISHED -j ACCEPT  
  3. [root@linli ~]# iptables -A OUTPUT -s 172.16.26.1 -p tcp -m multiport --source-ports 80,22,23,110,443 -m state --state ESTABLISHED -j ACCEPT 

 

-m iprange  ip地址范围的匹配(可取反)

  [!] --src-range IP1-IP2

  [!]--dst-range IP1-IP2

 
   
  1. //允许对已新建立的和已建立的连接192.168.0.100-192.168.0.200访问172.16.26.1:80;对于出去的数据包只允许已建立的连接出去
  2. [root@linli ~]# iptables -A INPUT -d 172.16.26.1 -m iprange --src-range 192.168.0.100-192.168.0.200 -p tcp --dport 80 -m state --state NEW,ESTABLISHED -j ACCEPT  
  3. [root@linli ~]# iptables -A OUTPUT -s 172.16.26.1 -m iprange --dst-range 192.168.0.100-192.168.0.200 -p tcp --sport 80 -m state --state ESTABLISHED -j ACCEPT 

 

-m connlimit  限制某个地址发起的并发的连接个数

  [!] --connlimit-above n

  --connlimit-mask bits

 
   
  1. // 一个IP地址只允许远程连接2次  
  2. # iptables  -p  tcp  --syn  --dport  23  -m  connlimit --connlimit-above 2 -j REJECT  
  3. //或写成这种方式:  
  4. # iptables  -p  tcp  --syn  --dport  23  -m  connlimit  ! --connlimit-above 2 -j ACCEPT  
  5. // 注意:iptables v1.3.5不支持connlimit

 

-m limit 使用令牌桶限制数据包的发送速率

--limit rate (默认是3/hour)

--limit-burst n

 
   
  1. //访问172.16.26.1:80的数据包的发送速率限定在每秒1个,最大并发峰值2个
  2. [root@linli ~]# iptables -A INPUT -d 172.16.26.1 -p tcp --dport 80 -m limit --limit 1/second --limit-burst 2  -j ACCEPT  
  3. [root@linli ~]# iptables -A OUTPUT -s 172.16.26.1 -p tcp --sport 80 -m limit --limit 1/second --limit-burst 2  -j ACCEPT 
 
   
  1. //设置ping请求包的最大速率及峰值  
  2. [root@linli ~]# iptables -A INPUT -d 172.16.26.1 -p icmp --icmp-type 8 -m limit --limit 2/second --limit-burst 3 -j ACCEPT  
  3. [root@linli ~]# iptables -I OUTPUT 1 -s 172.16.26.1 -m state --state ESTABLISHED -j ACCEPT 

 

-m string  字符串匹配

  --algo {bm|kmp}  选择字符串匹配算法

  --string 

 
   
  1. //出现web的页面不能访问  
  2. [root@linli ~]# iptables -A OUTPUT -s 172.16.26.1 -p tcp --sport 80 -m string --algo kmp  --string "web" -j DROP 

 

-m time

  --timestart

  --timestop

  --days

  --datestart

  --datestop

注意:iptables v1.3.5不支持time模块。需要安装补丁才可以。

 

 注意:

从上面的多个小练习中,可以看到iptables规则的很多选项都是重复的,所以在写多条规则时,要注意合并和规则顺序。

 

用于数据包侵袭的:

# iptables -A INPUT -syn -p tcp -m state --state NEW -j DROP

# iptables -A INPUT -p tcp --tcp-flags ALL ALL -j DROP

# iptables -A INPUT -p tcp --tcp-flags ALL NONE -j DROP

用于拒绝扫描:

# iptables -A INPUT -p icmp -d 255.255.255.255 -j DROP

# iptables -A INPUT -p icmp -d 0.0.0.0 -j DROP