一、防火墙基础原理
1
、防火墙是什么?隔离本地网络与外界网络之间的一道防御系统
通俗的说,防火墙就是防火的墙,主要目的就是隔离火并建立安全区域,所以防火墙对于互联网或计算机而言 可能是工作在主机或网络的边缘(计算机的边缘可能是一块网卡,而网络边缘可能是路由),对于进出数据的报文事先定义好的规则中的标准进行检查、监控,一旦符合标准的话,我们就采取由这个规则定义的处理动作,我们称为主机防火墙或网络防火墙
linux:网络防火墙,有两组框架,实现防火功能的主要是netfilter
      netfilter:是内核中的过滤框架,是网络过滤器
      iptables:是一个生产防火墙规则的并且能够将其附加在netfilter上,真正实现
数据报文过滤的工具,当然这只是其中的一种功能,NAT、mangle等规则生成的工具。而它本身并不能防火,真正起到防火墙功能的是规则,规则只有放到netfilter上才能生效。规则包括处理标准和处理办法防火墙可以是硬件也可以是软件,无论硬件还是软件需要定义规则之后,让其生效,才能真正工作起来
注意:防火墙不防家贼

2、如何定义防火墙中的规则办法?
2.1、首先规则中一个有一个默认规则,而这个默认规则有两种处理方法:
开发:符合规则的放行,不符合的堵住,即堵住非法分子
关闭:默认情况下门是关着的只有拿到通行证的才能进入
防火墙要想实现是靠规来实现的,而规则包括匹配标准和处理方法
2.2、匹配标准
根据IP匹配
:源IP,目标IP
根据TCP匹配
:源端口(SPORT),目标端口(DPORT)定义标志位规则限定哪个可以通过
SYN=1,FIN=0,RST=0,ACK=0--》第一次握手;SYN=1,FIN=0,RST=0,ACK=1--》第二次握手:
SYN=0,FIN=0,RST=0,ACK=1--》第三次握手
根据UDP匹配:源端口(SPORT),目标端口(DPORT)
根据ICMP匹配:icmp-type报文类型
2.3、数据报文过滤(防火墙):
在内核的TCP/IP协议栈上,选几个开放的位置,而这几个位置必须是数据报文经过的地方。只对用户空间的某个命令进行开放使用,用户空间中有一个应用程序,这个应用程序帮我们生成防火墙规则,把生成的规则放在对应的位置上,因为只开放给某个命令,这个命令写得规则会立即送给内核空间中对应的位置上。内核不是不能和应用程序打交道,只是在某种特定的情况下需要调用系统调用。这组组件在linux2.4上叫iptables/netfilter,不同的内核版本上实现的功能也不同,在早期的内核版本上是没有防火墙功能的,而是参考OpenBSO机制移植过来的。netfilter工作在内核空间(可以放规则的位置),iptables工作在用户空间,可以写规则,通过系统调用将规则放置在与它对应的位置上,只有生效以后这个应用程序就没有用处了。
2.4、IP报文的流向:三种,而规则就放在了这三种流向中的某一个当中
从外部到本机内部--》流入
本机内部来报文到外面的--》流出
报文转发
注:只要有报文经过,它必须要从其中的一个位置经过,而路由表中的目标IP可以判定它应该走哪条路这叫路由决策,路由决策发生在一个报文被本机的网卡接收进来以后,送到TCP/IP协议栈上的那一刻就要做出路由决策。上面三种流向是工作在TCP/IP协议栈上的三个钩子函数,任何一个报文经过其中的任何一个流向时都会被检查一遍如果被其中的某条规则匹配到,就会执行其中的处理方法
hook:钩子函数,自上而下逐个检查。五个规则:
    prerouting:路由之前
    input:本地进来
    output:本地出去
    forward:转发
    postrouting:路由之后

而这每个规则组合起来就是一个链,叫规则链,每一个钩子对应的函数都应该有一个链
五个规则链:
PREROUTING
INPUT
FORWARD
OUTPUT
POSTROUTING

2.5、各个功能在哪些链上来实现?
iptables表
filter(过滤):表
    INPUT
    OUTPUT
    FORWARD

nat:表,网络地址转换,将内部私有IP地址转换成公网IP地址
    PREROUTING    
    POSTROUTING

mangel(拆开、修改、封装):表
    PREROUTING
    INPUT
    FORWARD
    OUTPUT
    POSTROUTING

raw(原始格式):表
    PREROUTING
    OUTPUT

注:可以使用自定义的链,但只能在被调用时才能发挥作用,而且如果没有被自定义链中的任何 规则匹配,还应该有返回机制;用户可以删除自定义的空链,默认链无法删除。每一条规则 都有两个内置的计数器,一个记录被匹配的报文个数,另一个记录被匹配的报文大小之和    
3、如何写规则?(一般系统自带的iptables包是安装过的)
写规则格式:使用iptables命令
iptables [-t TABLE] COMMAND CHAIN [num]匹配标准 -j 处理办法:TABLE默认是”filter“
     -j:跳转(accept:放行,drop:丢弃,reject:拒绝,LOG:日志(--log-prefix))
#iptables -t filter -A INPUT -s 172.16.0.0/16 -j DROP   只要是来自这个网段的来访问我的主机都拒绝
3.1、常用的匹配标准:
a:通用匹配:自己可以完成的检查
    -s(--src):指定源地址
    -d(--dst):目标地址
    -p:{tcp|udp|icmp}指定协议
    -i:指定数据报文流入的接口
    可用PREROUTING,INPUT,FORWARD
    -o:指定数据报文流出的接口
    可用 POSTROUTING,OUTPUT,FORWARD
b:扩展匹配:依赖模块完成的检查
隐含扩展:不用特别指明由哪个模块进行的扩展,因为此时使用-p{tcp|udp|icmp}
    -p tcp
        --sport PORT[-PORT]:源端口
        --dport PORT[-PORT]:目标端口
        --tcp-flags mask comp:tcp的标志位,只检查mask指定的标志位,是逗号分隔的标志位列表:
        comp:此表中出现的标志位必须为1,comp中没出现,而mask中出现的,必须为0
        --tcp-flags SYN,FIN,ACK,RST SYN =--syn(SYN=1,其他为0,这是三次握手中的第一次)
        --tcp-flags SYN,FIN,ACK,RST SYN,ACK (SYN=1,ACK=1,FIN=0,RST=0)
    -p udp
        --sport
        --dport
    -p icmp:
        --icmp-type:报文协议的类型
自己ping别人:出去的是8,回来的是0
别人ping自己:进来的是8,出去的是0

        0:echo-replay回显应答(ping应答)
        8:echo-request回显请求(ping请求)ping出去的是8
显式扩展:必须指明由哪个模块进行的扩展,在iptables中使用-m选项可完成此功能
    -m EXTESTION --spe-opt使用额外的匹配机制
        state:状态扩展,结合ip_conntrack追踪会话的状态,ip状态有四种
        NEW:新连接请求
        ESTABLISHED:已建立的连接
        INVALID:非法连接
        RELATED:相关联的
    -m state --state NEW -j ACCEPT 状态为NEW的放行
    -m state --state NEW,ESTABLISHED -j ACCEPT 状态为NEW、ESTABLISHED的都放行
离散多端口匹配扩展(最多使用15个):multiport
        --source-ports
        --destination-ports
        --ports
    -m iprange指定IP地址段(指定地址池),也可以取反“!”
             --src-range
             --dst-range
    -m connlimit:连接数限定
            !--connmilit-above n:指定上限为n
     -m limit
        --limit:RATE控制单位时间内的流量上限
        --limit-burst:一批可以同时涌进多少个请求
    -m string 限定用户访问的字符串
        --algo:字符算法{bm|kmp}
        --string:匹配哪个字符串
3.2、常用的命令:
管理规则的命令: 
    -A:附加一条规则,添加在链的尾部    
    -I CHAIN [num]:插入一条规则,插入为对应的CHAIN上的第num条
    -D CHAIN [num]:删除指定链中的第num条规则
    -R CHAIN [num]:替换指定的规则
管理链命令:
    -F [CHAIN] :flush,清空指定规则链,若省略CHAIN,则可以实现删除对应表中的所有链
    -P CHAIN :设定指定链的默认策略
    -N:自定义一条新的空链
    -X:删除一个自定义的空链
    -Z:置零指定链中所有规则的计数器
    -E:重命名自定义的链
查看类的命令
    -L:显示指定表中的规则
        -n:以数字形式显示主机地址和端口号
#iptables -L -n == iptables -t filter -L -n 显示的内容是一样的
也可以查看nat表,mangle表,只要把filter改成nat、mangle就可以查看
        -x:显示精确值
#iptables -L -n -v -x
        -v:显示链及规则的详细信息
        -vv:显示更详细的信息
#iptables -L -n -v
        --line-numbers:显示规则号码
动作:(target)
-j ACCEPT:放行
   DROP:丢弃
   REJECT:拒绝
   DANT:目标地址转换
   SNAT:源地址转换
   REDIRECT:端口重定向
   MASQUERADE:地址伪装
   LOG:只记录日志,不表示拒绝和允许
     --log-prefix:日志前缀
   MASK:打标记    
二、命令解析:
1、放行192.168.0.0网段对本主机的访问
#iptables -t filter -A INPUT -s 192.168.0.0/16 -d 172.16.50.10 -p tcp --dport 22 -j ACCEPT
#iptables -t filter -A OUTPUT -s 172.16.50.10/16 -d 192.168.0.0 -p tcp --sport 22 -j ACCEPT
2、修改默认策略:首先需要先把自己的物理主机的Ip地址定义出来, 否则设定默认策略为DROP后自己也不能远程登录
[root@localhost ~]# iptables -P INPUT DROP
[root@localhost ~]# iptables -P OUTPUT DROP
[root@localhost ~]# iptables -P FORWARD DROP
3、允许所有人访问web服务(源IP可以省略,I插入的规则默认放在第一条)
[root@localhost ~]# iptables -I INPUT -d 172.16.50.5 -p tcp --dport 80 -j ACCEPT
[root@localhost ~]# iptables -I OUTPUT -s 172.16.50.5 -p tcp --sport 80 -j ACCEPT
4、自己ping自己
[root@localhost ~]# iptables -A INPUT -s 127.0.0.1 -d 127.0.0.1 -i lo -j ACCEPT
[root@localhost ~]# iptables -A OUTPUT -s 127.0.0.1 -d 127.0.0.1 -o lo -j ACCEPT
5、自己可以ping别人,别人不能ping我们
[root@localhost ~]# iptables -A OUTPUT -s 172.16.50.5 -p icmp --icmp-type 8 -j ACCEPT
[root@localhost ~]# iptables -A INPUT -d 172.16.50.5 -p icmp --icmp-type 0 -j ACCEPT
6、让别人也能ping我们,并且只放行已建立的链接
iptables -A INPUT -d 172.16.50.5 -p icmp --icmp-type 8 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -s 172.16.50.5 -p icmp --icmp-type 0 -m state --state ESTABLISHED -j ACCEPT
6
7、只放行已建立的链接,新请求不放行
# iptables -A INPUT -d 172.16.50.5 -p tcp --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
# iptables -A OUTPUT -s 172.16.50.5 -p tcp --sport 22 -m state --state ESTABLISHED -j ACCEPT
8、修改默认策略为DROP
[root@localhost ~]# iptables -P INPUT DROP
[root@localhost ~]# iptables -P OUTPUT DROP
[root@localhost ~]# iptables -L -n
2

9、放行web条目,放行已建立的链接,新请求不放行
# iptables -A INPUT -d 172.16.50.5 -p tcp --dport 80 -m state --state NEW,ESTABLISHED -j ACCEPT
# iptables -A OUTPUT -s 172.16.50.5 -p tcp --sport 80 -m state --state ESTABLISHED -j ACCEPT
3
10、查看建立的条目及行号
[root@localhost ~]# iptables -L -n --line-numbers  
7
# iptables -I OUTPUT -s 172.16.50.5 -m state --state ESTABLISHED -j ACCEPT
此时就可以把上面的三个条目给删了,默认匹配第一条的。
11、放行ftp(21号端口)
# iptables -A INPUT -d 172.16.50.5 -p tcp --dport 21 -m state --state  NEW,ESTABLISHED -j ACCEPT
[root@localhost ~]# iptables -A INPUT -i lo -j ACCEPT
[root@localhost ~]# iptables -A OUTPUT -o lo -j ACCEPT
[root@localhost ~]# service vsftpd restart  启动ftp服务
注意:装载模块(不需要手动装载,只需要修改配置文件)
[root@localhost ~]# vim /etc/sysconfig/iptables-config
IPTABLES_MODULES="ip_nat_ftp ip_conntrack_ftp"   #添加要加载的模块,如果有多个模块,用空格隔开
# iptables -A INPUT -d 172.16.50.5 -p tcp -m state --state ESTABLISHED,RELATED -j ACCEPT
# iptables -R OUTPUT 1 -s 172.16.50.5 -m state --state RELATED,ESTABLISHED -j ACCEPT
[root@localhost ~]# service iptables save   保存原来的配置条目
[root@localhost ~]# service iptables restart   重启iptables服务
使用远程登录ftp
8
条目中几乎都有ESTABLISHED,可以使用一个命令完成,提高工作效率
# iptables -I INPUT -d 172.16.50.5 -p tcp -m state --state ESTABLISHED,RELATED -j ACCEPT
可以添加多个条目为NEW
#iptables -I INPUT 2 -d 172.16.50.5 -p tcp -m multiport --destination-ports 21,22,80 -m state --state NEW -j ACCEPT
上面所添加的条目都可以使用一条命令完成,可以很好的提高工作效率
12、放行指定Ip地址池之内的和放行指定IP地址池之外的
# iptables -A INPUT -p tcp -m iprange --src-range 172.16.50.1-172.16.50.100 --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
# iptables -A INPUT -p tcp -m iprange ! --src-range 172.16.50.1-172.16.50.100 --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
13、设定某个特定IP最多能发起几个连接数、控制单位时间内的流量上限、限定用户访问的字符串
# iptables -A INPUT -d 172.16.50.10 -p tcp --dport 80 -m connlimit ! --connlimit-above 2 -j ACCEPT(低于2个放行)
# iptables -R OUTPUT -s 172.16.50.10 -p tcp --dport 22 -m limit --limit 3/minute --limit-burst 3 -j ACCEPT
# iptables -I OUTPUT -s 172.16.50.10 -m string --algo kmp --string "拒绝的字符串" -j REJECT
14、限定当前主机的ping请求,记录ping成功的请求的信息
上面我们已经添加了icmp的条目,如果再添加一个条目在之前条目的下面是不会生效的,需要添加在原来条目的上面才能匹配到
iptables -I INPUT 8 -d 172.16.50.5 -p icmp --icmp-type 8 -j LOG --log-prefix "--firewall log for icmp--"
如果此时有其他主机ping我们的主机,可以查看日志
[root@localhost ~]# tail /var/log/messages
9
15、iptables不是服务,但有脚本;服务脚本的主要作用在于管理保存的规则.我们所写的规则是直接保存在内核空间中的内存上,关机后就没有了。装载及移除iptables/netfilter相关的内核模块:
iptables_nat,iptables_filter,iptables_mangle,iptables_raw,ip_nat,ip_conntrack,一启动服务,这些模块就会被装载进来,此前所保存的规则也会生效起来的

[root@localhost ~]#lsmod这个命令时检查iptables的模块是否装在进来    
ip_conntrack:实时记录这当前主机上、客户端、服务器端彼此正在建立的连接的连接关系,并且能够
追踪到哪一个连接和另外连接正处于什么状态,拥有什么样的关系

[root@localhost ~]#cat /proc/net/ip_conntrack    查看iptables的状态,追踪表
5
[root@localhost ~]#iptstate:此命令可以追踪当前主机上每个请求
切记:/proc/sys/net/ipv4/ip_conntrack_max:定义ip_conntrack最多同时追踪多少个链接,如果超出一个数目,那些链接会因为超时被丢弃在某些非常繁忙的服务器上,不要触发这个模块
修改max值:
4 
不会永久有效,需要写在配置文件中
[root@localhost ~]# vim /etc/sysctl.conf
[root@localhost ~]#iptables -t nat -L 此命令可以自动激活ip_conntrack及它所依赖的库,在服务器非常繁忙的系统上是非常危险的,重启iptables,会清空原有所设置的表及表中的每一个链所设置的规则需要保存的,保存规则:
[root@localhost ~]# service iptables save  保存在/etc/sysconfig/iptables,重启服务后也不会丢弃
[root@localhost ~]#iptables-save > /etc/sysconfig/iptables.2013041801  使用输出重定向也可以保存,但不会生效
[root@localhost ~]#iptables-restore < /etc/sysconfig/iptables.2013041801  使用输入重定向可以让其生效
1
16、自己也可以定义一个规则链
# iptables -N clean_in  新建规则链
# iptables -A clean_in -d 255.255.255.255 -p icmp -j DROP
# iptables -A clean_in -d 172.16.255.255 -p icmp -j DROP
检查tcp的标志位
# iptables -A clean_in -p tcp ! --syn -m state --state NEW -j DROP
# iptables -A clean_in -p tcp --tcp-flags ALL ALL -j DROP
# iptables -A clean_in -p tcp --tcp-flags ALL NONE -j DROP
# iptables -A clean_in -d 172.16.50.5 -j RETURN
# iptables -I INPUT -j clean_in (被主链调用,先由clean_in处理,没有问题就交由主链)
# iptables -A INPUT  -i eth0 -m multiport -p tcp --dports 53,113,135,137,139,445 -j DROP
# iptables -A INPUT  -i eth0 -m multiport -p udp --dports 53,113,135,137,139,445 -j DROP
# iptables -A INPUT  -i eth0 -p udp --dport 1026 -j DROP
# iptables -A INPUT  -i eth0 -m multiport -p tcp --dports 1433,4899 -j DROP
# iptables -A INPUT  -p icmp -m limit --limit 10/second -j ACCEPT
17、利用iptables的recent模块来抵御DOS(拒绝服务)***
ssh: 远程连接
# iptables -I INPUT 2 -d 172.16.50.5 -p tcp --dport 22 -m connlimit --connlimit-above 6 -j DROP
利用connlimit模块将单IP的并发设置为6;会误杀使用NAT上网的用户,可以根据实际情况增大该值;
# iptables -I INPUT 3 -d 172.16.50.5 -p tcp --dport 22 -m state --state NEW -m recent --set --name SSH
记录访问tcp 22端口的新连接,记录名称为SSH,--set 记录数据包的来源IP,如果IP已经存在将更新已经存在的条目
# iptables -I INPUT 4 -d 172.16.50.5 -p tcp --dport 22 -m state --state NEW -m recent --update --seconds 300 --hitcount 3 --name SSH -j DROP
利用recent和state模块限制单IP在300s内只能与本机建立3个新连接。被限制五分钟后即可恢复访问。
指SSH记录中的IP,300s内发起超过3次连接则拒绝此IP的连接。
--update 是指每次建立连接都更新列表;
--seconds必须与--rcheck或者--update同时使用
--hitcount必须与--rcheck或者--update同时使用

iptables的记录:/proc/net/ipt_recent/SSH,也可以使用下面的这句记录日志:
# iptables -A INPUT -d 172.16.50.5-p tcp --dport 22 -m state --state NEW -m recent --update --name SSH --second 300 --hitcount 3 -j LOG --log-prefix "SSH Attack"
 知识不断更新中,等待大家的关注