防火墙的有关知识
一.Firewall理论知识
  1.防火墙是有软件或硬件组成的组件,工作在网络边缘(主机的边缘),对进出本网络的数据包基于一定的规则进行检查,并在匹配某规则时由规则定义的处理机制进行处理的
  2.网络防火墙是不妨家贼的,防火墙主要有主机防火墙和网络防火墙
  3.防火墙的类型。这是根据工作层次的不同来分类的
    1)网络防火墙,(工作在第三层):主要根据数据包的源地址,目标地址,源端口,目标端口,tcp/ip的首部特征及mac地址等规则来进行检查的。
    2)应用防火墙或者叫代理服务器/代理网关(工作在第七层)
  4.(三层防火墙)当一台主机要访问服务器时,数据通过防火墙时,防火墙的检查机制
   1)先拆物理层头和数据链路层头,才能检查网络层的信息,
   2)检查通过后,从新封装物理层和数据链路层数据,再转发数据包,这些都在网络层实现的
  5.(七层防火墙)当数据伪装了,绕过三层防火墙时,要通过七层防火墙机制
    1)代理防火墙增加了服务器的负载
    2)通过检查数据来验证是否通过,防止了×××等,
    3)应放在内核中,tcp/ip协议上
   
  6.防火墙防止位置
    1)在tcp/ip协议栈设置5个点,放5个钩子函数(hook function)
        tcp/ip协议栈有一个路由子系统
    2)有一块网卡连接内网的,一块连接外网的
      信息通过路由表来选择从哪一块网卡上走的
    3)5个点的放置位置
      第一个:如果数据是到本机内的,即(firefox),就会在入口网卡和本机间建一个点
      第二个:数据不到主机内部的,即(从一个网卡进来然后 另外的网卡上去的),这里会有一个点
      第三个:从主机内部出去的,即(访问别人的数据),有一个点
      第四个:在网卡之外,在刚刚进入网卡时,再没进入tcp/ip协议之前放一个点
      第五个:在数据将要离开,马上就要送到网线上去的时候,设立一个点
  7.上面设立的5个口,放置5个hook function,设定一定的规则,就叫框架
     一个这样的框架就叫Netfilter(网络过滤器),这时还不是防火墙,想要成为防火墙,需要规则,
     定义规则需要工具iptable
 
  8.iptable 是工作在用户的工具,它将用户定义的规则传递给Netfilter,因此我们写规则是在客户端,然后发送到服务器端
  9.定义规则时,要说明要将这个规则放在哪个门(即哪个hook function点)
 
  10.根据规则的机制,将数据在不同的点处理
  11.处理的几种机制
     1)过滤
     2)NAT
     3)MANglo  对数据做一些改变,(打扮一下)
     4)RAW
   这4中机制都需要规则

  12.一个点可以放多个规则
       这些规则组成一个链
       多个链组成表
  13.我们放置hook function的5个点的名称:
     PREROUTING 数据刚刚进入本机网卡,还没进入tcp/ip协议栈进行处理时的
     INPUT 数据到本机内部的
     OUTPUT 本机内部出去的
     FORWARD 转发链,一个网卡进来,从另一个网卡出去的
     POSTROUTING 数据将要离开网卡时,将要到网线上时

   这叫5个点都可以放置很多的规则,所以这叫5个内置的链,系统内置的链

  14.一个链个放多个表的规则,几个表的名字叫
    filter:过滤表-->在INPUT,OUTPUT,FOWARD三个点上做
    nat :地址转换表-->在PREROUTING,POSTROUTING,OUTPUT
    mangle :重新打扮一下的表-->在五个地方都可以,
    raw  -->PREROUTING,OUTPUT
   当我们写一条规则的时候,系统会根据这四条规则至上而下匹配,知道匹配到规则为止,如果没有找到匹配规则,就会按照默认规则来匹配,因此我们还要写默认匹配规则;

    每一个口上(即hook function)可以放多条规则,这些规则串起来就是一个链;同理每一个口上有多条链,这些链又组成了表(iptable);
  
    因为每个点可能根据功能分成多个不同的表,因此根据功能我们可以将每个口上分成不同的表,即上面的表:filter、net、mangle、raw这几个表;

  
  15.做规则要考虑的步骤:
     功能-->做在个表上-->在那个链上做


二.写iptable规则  (RH253的91页)
   1.一条规则有多个匹配条件
   2.iptables [-t table] command CHAIN [NUM] criteria -j TARGET
              表名       命令     链    链号 匹配条件  处理方式
     -t table
      filter
      nat
      mangle
      raw
     command:
      CHAIN: 对链操作的命令
       -N:new-->用户新建自定义的链,自己新定义的链不在那5个点上,所以必须5个点调用,才会生效,通常      与-j匹配
       -X:->删处用户自定义的一条空链
       -F:flush-->清空,如果没有跟链号,它会清空所有的链
       -Z:zero-->清空计数器的,
       -P:policy-->定义一个链的默认处理策略,就是指定哪一个连
       -E:重命名一条链

      RULE:对链规则操作的命令
      -A:append-->在链的最后面加一条规则
      -I:insert-->插入,eg:-I CHAIN num 表示插入第几条,如果不指num,表示插入第一条
      -R:replace-->替换,一般表示替换第几条,eg:-R CHAIN mum
      -D:delete-->删除,一般表示删除规则中的第几条规则,eg:-D CHAIN NUM
    Llist:
     -L:list
        -n,numerlic-->以数字形式显示地址,
        -v,verbose-->显示详细信息
        -x,-->不要作单位换算
        --line-numbers -->显示规则的行号
      
   3.匹配规则:Match Creteria
     基本匹配
       -s,--src,--source 匹配数据包的源地址
       -d,--dst,--destination匹配数据包的目标地址
       -i,指定数据的流入接口,即(从哪个网卡进来的)
       -o,指定数据包的流出接口,即(从哪个网卡出去的)
       -p,portocol协议匹配,(tcp|udp|icmp)
 
     扩展匹配(两类):指的就是对某一种功能的扩展
        隐含扩展-->对协议的扩展
         -p tcp
            --sport 指定源端口
            --dport 指定目标端口
            --tcp-flags,(SYN,ACK,PSH,URG,RST,ALL,NONE)指定tcp的标志位,
            --syn
         -p udp
           --sport
           --dport
         -p imcp
             --icmp-type 叫icmp的类型
              ping别人时或者别人ping我的时候,echo-request,相应代码是8;响应别人时,echo-reply,响应代码是0;
        显示扩展
         -m state -->必须用-m指定显示扩展
           四种状态(state)
             NEW, 就是发起一个新连接,也就是一个请求
             ESTABLISHED, 别人发一个请求,你给一个回应,就叫ESTABLISED,被人确认也是ESTABLISED
             RELATED,控制链接和数据连接都建立的时候,就是RELATED
             INVALID,无法识别的状态
         -m multiport 指定多端口
            --sports 22,80,443 指定多源端的端口(可以是非连续的端口)
            --dports   指定多目的端的端口(可以是非连续的端口)
            --ports   指定多个端口(可以是非连续的端口)
         -m connlimit  做并发连接数目限定的
            --connlimit-above 5
         -m string 字符串匹配
           --algo bm|kmp  这是指定匹配字符串的算法
           --string  指定要匹配的字符串
           eg:iptables -A INPUT -d 192.168.0.5 -p tcp --dport 80 -m string -- algo kmp --string 'test' -j REJECT
         -m time
            --timestart value 跟的时间格式:HH:MM
            --timestop
      
      -j TARGET 处理
         ACCEPT
         DROP  悄悄的丢弃
         REJECT 拒绝回应
         SNAT 源地址转换
         DNAT 目标地址转换
         REDIRECT端口重定向
         LOG  只记录,不接受,也不拒绝

三.写规则,
   1.我本机上有ssh服务,工作在tcp协议上的22号端口,凡是来自192.168.0.0/24,目标地址是本机,都允许通过
    eg:iptables -t filter -A INPUT -s 192.168.0.0/24 -d 192.168.0.2 -p tcp --dport 22 -j ACCEPT
      iptables -t filter -A OUTPUT -s 192.168.0.2 -d 192.168.0.0/24 -p tcp --sport 22 -j ACCEPT
      策略:
       “通”-->它的默认策略是堵
       “堵”-->它的默认策略是通
   2.查看策略
     iptables -L -n  默认查看的是filter表
   3.这两条规则是让自己进去和出去的,因为自己用的是ssh远程登录的
    iptables -A INPUT -s 192.168.0.0/24 -d 192.168.0.5 -p tcp --dport 22 -j ACCEPT
    iptables -A OUTPUT -s 192.168.0.5 -d 192.168.0.0/24 -p tcp --sport 22 -j ACCEPT
   4.写默认规则(这里采用的是通)
     iptables -t filter -P(大写) INPUT DROP
     iptables -t filter -P(大写) OUTPUT DROP
  
   5.上面的只是放行ssh,而没有允许ping,下面定义放行本机的数据包
      iptables  -I INPUT -s 127.0.0.0/8 -d 127.0.0.0/8 -j ACCEPT    
      iptables  -I OUTPUT -s 127.0.0.0/8 -d 127.0.0.0/8 -j ACCEPT
      或者:
      iptables -I INPUT -s 127.0.0.0/8 -d 127.0.0.0/8 -j ACCEPT
      iptables -I OUTPUT -s 127.0.0.0/8 -d 127.0.0.0/8 -j ACCEPT
  

   6.eg:允许本机ping任何主机
    iptabels -t filter -A OUTPUT -s 192.168.0.5 -icmp --icmp-type 8 -j ACCEPT  -->目标地址不用写了
    iptabels -t filter -A INTPUT -d 192.168.0.5 -icmp --icmp-type 0 -j ACCEPT  -->源地址不用写了
  
   7.eg:允许别人ping本机
    iptabels -t filter -A OUTPUT -d 192.168.0.5 -icmp --icmp-type 0 -j ACCEPT
    iptabels -t filter -A INTPUT -s 192.168.0.5 -icmp --icmp-type 8 -j ACCEPT
  

四. iptables的几条重要规则
   1.iptables -F INPUT 清空filter表的INPUT链,
   2.iptables -L -n -v 显示匹配的信息,如数据包,字节等
     iptables -L -n --line-numbers 对规则编号显示,(有助于删除时用到编号)
     iptables -D OUTPUT 2  删除OUTPUT链的第二条规则

   3.iptables -N attach-input 在filter表上添加一条新链,(这条新链不会生效,要想它生效,让它与INPUT链关联起来)
    关联的方法:写好规则后,在后面的-j后面写上attach-input,就会关联到attach-input链上

    eg:我们先建立好一个web服务,然后建立好一个网页,在我们自己添加的链上做防火墙配置,看是否生效
      # iptables -A attach-input -s 192.168.0.0/24 -d 192.168.0.79 -p tcp --dport 80 -j DROP   -->这是添加的规则
      # iptables -A INPUT -s 192.168.0.0/24 -j attach-input  -->这一步就是将attach-input链与INPUT链关联起来,让源端口为192.168.0.0/24的地址经过INPUT链的限制规则都给attach-input链来处理;这时候我们上面的一条规则就生效了,我们再访问web服务就会被拒绝了;
      # iptables -F INPUT     -->我们清空INPUT链的规则后,就又可以访问了

   4.iptables -X attach-input  删除用户自定义的链,必须是空的,所以我们应该先清空我们在自定义的链上的规则
   5.iptables -F attach-input 清空链的规则

   6.我们可以用!来取反
     eg:-s '!' 192.168.0.0/24   -->表示出了源地址是192.168.0.0/24以外的地址,这里的''是强引用,不让ssh修改
    
     我们这时候可以看出我们可以在很多地方用到!来取反;

五.1.我们的显示扩展
     -m state    -->所有的显示扩展必须使用-m来指定;state是netfilter的模块,这个模块可以实现对数据包的状态功能的检测的;但是我们要注意了,我们的状态检测扩展支持以下状态;(RH253的99页)
       state的类型如下:
          NEW:表示建立一个新的连接,即,syn=1,但是ACK,PSH,URG,RST,ALL,NONE都为0的连接
          ESTABLISHED:建立连接,(即,reply packet:表示响应请求);就是出了第一次建立的连接之后的所有连接;
          RELATED:用ftp说明,像ftp服务需要用到两个端口的时候,一个完整的控制连接和数据连接组合起来才称为RELATED
          INVALID:(无效的),就是一些错误
    
   2.eg:对web服务器,用到扩展访问列表做状态检测,(注意:一定要用到-m)
        首先我们关闭所有的数据出入
        # iptables -P INPUT DROP
        # iptables -P OUTPUT DROP
        # iptables -P FORWARD DROP
        下面允许http服务的数据进来和出去
        # iptables -A INPUT -d 192.168.0.79 -p tcp --dport 80 -j ACCEPT
        # iptables -A OUTPUT -s 192.168.0.79 -p tcp --sport 80 -j ACCEPT
        上面的规则是不能防范反弹式木马的,要想放置反弹式木马需要下面的配置
        # iptables -I INPUT 1 -d 192.168.0.79 -p tcp --dport 80 -m state --state NEW,ESTABLISHED -j ACCEPT
        # iptables -I OUTPUT 1 -s 192.168.0.79 -p tcp --sport 80 -m state --state ESTABLISHED -j ACCEPT

   3.# iptables -L -n --line-numbers     -->可以显示iptables的行号
     # iptables -D INPUT 2          --->删除INPUT链的第2条  
             
  
六.对ftp的iptables配置:看iptables怎样放行ftp的数据包的
   1.iptables -A INPUT -d 192.168.0.5 -p tcp --dport 21 -j ACCEPT
     iptables -A INPUT -d 192.168.0.5 -p tcp --dport 20 -j ACCEPT
     iptables -A OUTPUT -s 192.168.0.5 -p tcp --sprot 21 -j ACCEPT
     iptables -A OUTPUT -s 192.168.0.5 -p tcp --sport 20 -j ACCEPT
     我们定义了这些规则之后会发现还不可以访问ftp,要想访问ftp服务,就需要开放大于1024的所有端口;
     我们还有下面的方法来配置ftp的防火墙;

七.上面的有太多缺点,需要手动开放端口,开放的端口太少,所以用下面的方法,添加ftp模块,让其自动的开放端口(100页)
   1.lsmod | grep ftp 查看是否加载了ftp的模块
      需要加载的ftp模块有:ip_conntrack_ftp, ip_conntrack_tftp, ip_nat_ftp, ip_nat_tftp;

     我们这里只需要加载下面两个就行了
     modprobe ip_conntrack_ftp --->这是加载的ftp的第一个模块
     modprobe ip_nat_ftp  --->这是加载ftp的第二个模块

  2.要想开机自动加载这两个模块,需要配置这个文件vim /etc/sysconfig/iptables-config 
    将IPTABLES_MODULES=""改为IPTABLES_MODULES="ip_nat_ftp ip_conntrack_ftp",就好了

  3.仍然要开放21号端口,因为这是命令行端口,必须指定开放
    iptables -A INPUT -d 192.168.0.79 -p tcp --dport 21 -j ACCEPT
    iptables -A OUTPUT -m state --state ESTABLISHED -j ACCEPT  -->-m state是利用显示扩展功能的模块

  4.开始配置随机端口
    iptables -A INPUT -d 192.168.0.79 -p tcp -m state --state NEW ESTABLISHED RELATED -j ACCEPT -->这个命令理论上是对的,但是,实际不能写入;下面我们将这个命令分开写入:如下
    # iptables -t filter -A INPUT -d 192.168.0.79 -p tcp -m state --state RELATED -j ACCEPT
    # iptables -R INPUT 3 -d 192.168.0.79 -p tcp -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT

    # iptables -A OUTPUT -m state --state ESTABLISHED RELATED -j ACCEPT  -->这个命令理论上也是对的,但是,实际上是错误的,也需要分开来写:如下
    # iptables -A OUTPUT -m state --state ESTABLISHED -j ACCEPT
    # iptables -R OUTPUT 1 -m state --state ESTABLISHED,RELATED -j ACCEPT

  5.我们想要指定连续的端口时,需要用到显示扩展
     -m multiport
         --sports   指定几个可以是非连续的源端口
         --dports   指定几个可以是非连续的目标端口
         --ports    指定几个可以使非连续的端口

  6.-m connlimit   这是一个做并发连接数限定的显示扩展
      --connlimit-above 5   -->表示指定一个用户最多可以有5个并发连接,可以用!来取反
     
  7.-m string     这是匹配字符串的显示扩展,如:限制qq的时候常用的
      --algo bm|kmp   这个选项是指定字符串算法,通常有bm和kmp,不能少
    eg:# iptables -A INPUT -d 192.168.0.79 -p tcp --dport 80 -m string --algo kmp --string 'test' -j ACCEPT

  8.-m time    根据时间来做匹配的
      --timestart value  表示起始时间
      --timestop value   表示结束时间
      --days
    这里我们需要注意的是,我们用时间限定的时候,结束时间不能小于起始时间;
    eg:--timestart 07:10 --timestop 23:59:59

八.地址转化:
   1.源地址转换-->永远在POSTROUTING上面做
         源地址转换的作用是:让私有地址能够上网
     目标地址转换-->永远在PREROUTING上面上做
         目标地址转换的作用是:让公有地址能够访问是有地址主机的资源
   2.iptables -t net -L -n 查看net表上的信息
  

   3.实验条件:这是通过路由的方法来访问www服务器的
     1)要两块网卡,一块是桥接的,能给外网相连即(192.168.0.254),一块是私有的,和内网相连
     2)想让私有地址的主机与公网地址的网关通信,需要将防火墙上路由功能打开,即:/proc/sys/net/ipv4/ip_forward的参数控制路由功能的,将默认参数设置为1
     3)route -n 查看路由表
     4)一定要给内部主机添加网关:rout add default gw 192.168.10.5
     5)给www服务器建一路由:route add -net 192.168.10.0/24 gw 192.168.10.1
     6)/var/log/httpd/access_log 放的是日志,可以看到是谁访问过自己

   4.要通过地址转换(是源地址转换)
     1)打开路由功能
     2)地址转换:iptables -t nat -A POSTROUTING -s 192.168.10.0/24 -d 192.168.0.0/24 -j SNAT --to-source 192.168.0.25  --->这是在net服务气上做的;是源地址转换,将192.168.10.0/24访问192.168.0.0/24 网段的地址时,将其转到192.168.0.25(网关)上
     3)route del -net 192.168.10.0/24 删除上面的路由表,证明地址转换实现了上网
    

   5.目标地址转换
     1)当公网的地址访问私有地址时,需要目标地址转换,同时还需要在WWW服务器上配置路由表:# route add -net 192.168.10.0/24 gw 192.168.0.68
     2)iptables -t nat -A PREROUTING -s 192.168.10.0/24 -d 192.168.10.1 -p tcp --dport 80 -j DNAT --to-dcstination 192.168.0.254  -->这是在nat服务器上做的目标地址转换
     3)打开防火墙上的路由功能


九.让iptables做七层过滤的做法
   1.编辑内核,将内核编辑成Layer7,Layer7是源代码包
   2.重装iptables模块
  
   3.将源代码包转换成二进制的过程就是编译的过程
   4.编译源代码包的一般过程
     1) 解压缩下载的源代码包,然后再切换到包里面去,执行下面的命令
     2) ./configure是用来检测你的安装平台的目标特征的。比如它会检测你是不是有CC或GCC,并不是需要CC或GCC,它是个shell脚本 -->检查编译环境的预编译环境的 (configure,这一步一般用来生成 Makefile,为下一步的编译做准备)
      ./configure的几个常用选项:
        --prefix  -->用来指定软件包安装的前缀
        --syscondir  -->用于指定配置文件的安装位置
       
     3) make是用来编译的,它从Makefile中读取指令,然后编译
     4)make modulls_install
     5)make install是用来安装的,它也从Makefile中读取指令,安装到指定的位置

   5.一个软件包的组成部分:二进制文件 ,库文件,配置文件,帮助文件
     1)make 之后,就会生成,二进制文件,库文件,配置文件给的有样例,帮助文件自带的有
     2)make install 就是让生成的二进制文件,库文件,配置文件,帮助文件放在该放的位置
     3)如果不指定路劲的话,第三方软件一般都安装在/var/local/目录下,
   6.二进制文件:/usr/local/tutils/bin,/usr/local/tutils/sbin,/usr/local/tutils/libexec
     库文件:/usr/local/tutils/lib
     配置文件:/usr/local/tutils/etc
     帮助文件:/usr/local/tutils/share
     上面的是自己指定的路径
  
十.1.系统默认寻找库文件路径:/lib,/usr/lib/,/usr/local/lib

     假如我们安装软件的路径不是默认路径,而是安装在tutils目录中,那么我们必须添加环境变量,让命令可以执行:
     我们可以修改默认路径:# export PATH=$PATH:/usr/local/tutils/bin:/usr/local/tutils/sbin

    2.定义库文件的查找路径的两种方法
       第一种:直接在这个文件里定义/etc/ld.so.conf  这个文件可以定义那些非标准路径下的库文件查找路径,
       第二种:/etc/ld.so.conf.d/*.conf  为了便于安装多个源代码包路径的管理,就定义凡是安装在该目录下,以.conf结尾的文件定义的路径都是库文件要搜索的路径,这里的文件是自定义的;

       我们用这两种方法假如我们自定义的路径之后,并不会马上生效,因为我们需要的命令在开机的时候默认就会独到内存中去,并哈希一下;这就需要用到下面的一个命令;

 
     3.#idconfig -v 表示告诉内存重新读取一下我定义的库文件,-v 显示过程
     
     4.帮助文件
       当我们man的时候,它会自动到/usr/share/man/目录内找相应的文件
        /etc/man.config 定义我们man的时候的找文件的路径
        在文件内MANPATH 是定义man查找文件的路径的(可以查证一下)
    
      下面的就是重要的地方了:
          我们要想让内核读我们自定义路径的man文档,就需要在/etc/man.config 文件里自己写MANPATH路径
    5.加完路劲之后,它任然不会自动生效,需要source一下这个文件
      # . /etc/man.config

      如果我们没有假如到man配置文件中去,我们又想查看这个man内的命令,可以如下:
      # man MANPATH /usr/local/tutils/share/man queryperf(这是命令)

十一.怎样让非标准路径的头文件变成标准路径的头文件
 
     1.头文件就是告诉你怎么去调用一个库
       /usr/include/ 或者/usr/local/include  --->这里放置的都是系统头文件

     2.我们安装的软件也有头文件
       因此:我们要制定路径
       我们安装的头文件放在/usr/local/tutils/include,

     3.用连接让非标准路径变成标准路径:我们一般用软连接,如下
        eg:ln -sv /usr/local/tutils/include  /usr/include/tutils  -->这里我们将目录include连接到/usr/include/中并且重新命名为tutils目录;
    
十二.上面的一般都解决了源代码安装的问题了
     我们通常源码安装的步骤
     make
     make modules_install
     make install