iptables防火墙

iptables防火墙

iptables 基本介绍

  • iptables 内置了rawfilternatmangle四张表。所有规则配置后立即生效,不需要重新启动服务。
    • raw: 优先级最高,一般情况下用不到
    • filter: 负责过滤数据包,包括的规则链: INPUTOUTPUTFORWARD
    • nat: 涉及到网络地址转换,包括的规则链: PREROUTINGPOSTROUTINGOUTPUT
    • mangle: 主要应用在修改数据包内容上,用来做流量整形的,给数据包打个标识,默认的规则链: INPUTOUTPUTFORWARDPOSTROUTINGPREROUTING
  • 五个链
    • INPUT: 匹配目标IP是本机的数据包
    • OUTPUT: 向外流出的数据包
    • FORWARD: 匹配流经本机的数据包
    • PREROUTING: 用来修改目的地址来做DNAT。如: 把内网的80端口映射到路由器外网端口上
    • POSTROUTING: 用来修改源地址来做SNAT。如: 内网通过路由器NAT转换功能实现通过一个公网IP地址上网

iptables的使用方法

  • iptables 命令语法格式
  • 注意
    • 不指定表名时,默认表示filter表
    • 不指定链名时,默认表示该表内所有链
    • 除非设置规则链的缺省策略,否则需要指定匹配条件
  • iptables [-t 要操作的表] <操作命令> [要操作的链] [规则号码] [匹配条件] [-j 匹配到以后的动作]

操作命令(-A、-I、-D、-P、-F、-L)

  • -A<链名> APPEND,追加一条规则(放到最后)

    # 拒绝所有人访问服务器
    iptables -t filter -A INPUT -j DROP
    
  • -I<链名> [规则num]: 增加一条规则,原来在该位置上的规则向后移动

    # 在filter表INPUT链上的第一个位置增加一条规则
    iptables -I INPUT 1 -j ACCEPT
    # 在filter表INPUT链上的第二个位置增加一条规则
    iptables -I INPUT 2 -j ACCEPT
    
  • -D: 删除一条规则

    • 若规则列表中有多条相同的规则时,按内容匹配只删除序号最小的一条
    • 按号码匹配删除时,确保规则号码<=已有规则数,否则报错
    • 按内容匹配删除时,确保规则存在,否则报错

      # 删除filter表INPUT链中的第一条规则
      iptables -D INPUT 1
      
  • -P <链名><动作>: POLICY 设置某个链的默认规则,默认规则是ACCEPT

    [[email protected] ~]# iptables -L
    Chain INPUT (policy ACCEPT)
    target     prot opt source               destination
    
    # 修改默认规则
    [[email protected] ~]# iptables -P INPUT DROP
    [[email protected] ~]# iptables -L
    Chain INPUT (policy DROP)
    target     prot opt source               destination
    
  • -F <链名>,flush 清空规则

    # 清空filter表中所有链上的规则
    iptables -F
    # 清空filter表中INPUT链上的规则
    iptables -F INPUT
    # 清空nat表中所有的规则
    iptables -t nat -F
    
  • -L <链名>,list 列出规则

    • v: 显示详细信息,包括每条规则的匹配包数量和匹配字节数
    • x: 在v的基础上,禁止自动单位转换(K, M)
    • n: 只显示IP地址和端口号码,不显示域名和服务名称

      # 如果组合写的话vnx必须写在L前面
      iptables -vnxL
      # ||
      iptables -L -n 
      # 列出nat表中所有链的规则
      iptables -t nat -L 
      

匹配条件

  • 流入、流出接口(-i、-o)
  • 按网络接口匹配

    • -i <匹配数据进入的网络接口> 此参数主要应用于nat表,例如目标地址转换

      # 匹配是否从网络接口eth0进来
      -i eth0
      
    • -o <匹配数据流出的网络接口>

      -o eth0
      
  • 来源、目的地址(-s、-d)
  • 按来源目的匹配

    • -s <匹配来源地址>,可以是IP、NET、DOMAIN,也可为空(任何地址)

      # 匹配来自192.168.0.1的数据包
      -s 192.168.1.0 
      # 匹配来自192.168.1.0/24的网络数据包
      -s 192.168.1.0/24
      # 匹配来自192.168.0.0/16的网络数据包
      -s 192.168.0.0/16
      
    • -d <匹配目的地址>,可以是IP、NET、DOMAIN,也可为空(任何地址)

      # 匹配去往14.215.177.39的数据包
      -d 14.215.177.39
      # 匹配去往14.215.177.39/16的网路数据包
      -d 14.215.177.39/16
      # 匹配去往域名www.baidu.com的数据包
      -d www.baidu.com
      
  • 协议类型(-p)
  • 按协议类型匹配

    • -p <匹配协议类型>,可以是TCP、UDP、ICMP等,也可为空

      -p tcp
      -p udp
      # -p icmp --icmp-type 类型(ping: type 8 pong: type 0)
      # 别人ping我主机的请求被丢弃
      iptables -A INPUT -p icmp --icmp-type 8 -j DROP
      
  • 来源、目的端口(–sport、–dport),–sport和–dport必须配合-p参数使用
  • 按来源目的端口匹配

    • –sport <匹配源端口>,可以是单个端口,可以是端口范围

      # 匹配源端口是1000的数据包
      --sport 1000 
      # 匹配源端口是1000-3000的数据包(含1000、3000)
      --sport 1000:3000
      # 匹配源端口是3000以下的数据包(含3000)
      --sport :3000
      # 匹配源端口是1000以上的数据包(含1000)
      --sport 1000:
      
    • –dport <匹配目的端口>,可以是单个端口,可以是端口范围

      # 匹配目的端口是80的数据包
      --dport 80
      # 匹配目的端口是6000-8000的数据包(含6000、8000)
      --dport 6000:8000
      # 匹配目的端口是8000以下的数据包(含8000)
      --dport :8000
      # 匹配目的端口是6000以上的数据包(含6000)
      --dport 6000:
      

动作(-j)

  • ACCEPT(同意,允许数据包通过本链而不拦截)
  • DROP(丢弃,直接丢弃数据,没有任何回应)
  • REJECT(拒绝,会返回一个拒绝的数据包)
  • SNAT(源地址转换)(nat表的POSTROUTING链)

    • -j SNAT –to IP[-IP][:端口-端口]
    • SNAT支持转换为单IP,也支持转换到IP地址池(一组连续的IP地址)
    • 将内网192.168.0.0/24的源地址修改为公网IP地址1.1.1.1

      iptables -t nat -A POSTROUTING -s 192.168.0.0/24 -j SNAT --to 1.1.1.1
      
  • DNAT(目的地址转换)(nat表的PREROUTING链)

    • -j DNAT –to IP[-IP][:端口-端口]
    • DNAT支持转换为单IP,也支持转换到IP地址池(一组连续的IP地址)
    • 把从eth0进来的要访问TCP/80的数据包目的地址修改为192.168.0.1

      iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j DNAT --to 192.168.0.1
      
  • MASQUERADE(动态源地址转换,动态IP下使用。伪装一个公网IP地址)

    • 将源地址是192.168.0.0/24的数据包进行地址伪装,转换为eth0上的IP地址。eth0为路由器外网出口IP地址

      iptables -t nat -A POSTROUTING -s 192.168.0.0/24 -o eth0 -j MASQUERADE
      

附加模块

  • 按包状态匹配(state)

    • -m state --state 状态
    • 状态:NEW、RELATED、ESTABLISHED、INVALID
    • NEW: 刚建立状态
    • RELATED: 衍生态
    • ESTABLISHED: 已经建立连接
    • INVALID: 不能被识别属于哪个链接或没有任何状态
    • 例:

      iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
      
  • 按来源MAC匹配(mac)

    • -m mac --mac-source MAC
    • 匹配某个MAC地址
    • 例:

      # 阻断来自某MAC地址的数据包通过本机
      # 注意: 报文经过路由后,数据包中原有的mac信息会被替换,所以在路由后的iptables中使用mac模块无效
      iptables -A FORWARD -m mac --mac-source 00:50:56:20:2D:A1 -j DROP
      
  • 按包速率匹配(limit)

    • -m limit --limit 匹配速率 [--burst 缓冲数量]
    • 例:

      # 一秒中转发50个数据包到192.168.0.1
      iptables -A FORWARD -d 192.168.0.1 -m limit --limit 50/s -j ACCEPT
      # 50个数据包转发完后阻断
      iptables -A FORWARD -d 192.168.0.1 -j DROP
      
  • 多端口匹配(multiport)

    • -m multiport <--sports|--dports|--ports> 端口1[,端口2,....端口N]
    • 一次性匹配多个端口,可以区分源端口,目的端口或不指定端口
    • 注意: 必须与-p参数一起使用
    • 例:

      # 允许所有客户端访问服务器的21,22,25,80端口上的服务
      iptables -A INPUT -p tcp -m multiport --dports 21,22,25,80 -j ACCEPT
      

实战

使用iptables保护WEB服务器

# 放行环回口所有数据
iptables -A INPUT -i lo -j ACCEPT
# 放行22和80端口
iptables -A INPUT -p tcp -m multiport --dports 22,80 -j ACCEPT
# ||
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
iptables -A INPUT -p tcp --dport 80 -j ACCEPT

# 允许已经建立TCP连接的包以及该连接相关的包通过。状态防火墙能识别TCP或者UDP会话。非状态防火墙只能根据端口识别,不能识别会话
iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
# 修改默认规则
iptables -P INPUT DROP

搭建路由器使内网机器能上网

  • 使170服务器可以通过150服务器上网
  • 配置150服务器

    • 添加两个网卡,配置eth0为桥接,eth1为vmnet4模式

      [[email protected] ~]# cat /etc/sysconfig/network-scripts/ifcfg-eth1
      # Please read /usr/share/doc/initscripts-*/sysconfig.txt
      # for the documentation of these parameters.
      DEVICE=eth1
      BOOTPROTO=none
      NETMASK=255.255.255.0
      TYPE=Ethernet
      HWADDR=00:0c:29:25:5f:ab
      IPADDR=192.168.2.1
      
    • 重启网络

      service network restart
      
    • 启动内核路由转发功能

      vim /etc/sysctl.conf
      # 修改net.ipv4.ip_forward = 0为
      net.ipv4.ip_forward = 1
      sysctl -p
      
    • 配置SNAT路由转发

      # 添加nat表中路由后把192.168.2.0/24的所有请求转发到192.168.1.150公网IP
      iptables -t nat -A POSTROUTING -s 192.168.2.0/24 -j SNAT --to 192.168.1.150
      
  • 配置170服务器

    • 配置网卡eth0为vmnet4模式,并修改ip地址为192.168.2.2

      [[email protected] ~]# cat /etc/sysconfig/network-scripts/ifcfg-eth0
      DEVICE=eth0
      TYPE=Ethernet
      ONBOOT=yes
      NM_CONTROLLED=yes
      BOOTPROTO=none
      PREFIX=24
      DEFROUTE=yes
      IPV4_FAILURE_FATAL=yes
      IPV6INIT=no
      NAME="System eth0"
      HWADDR=00:50:56:2a:92:c8
      USERCTL=no
      IPADDR=192.168.2.2
      NETMASK=255.255.255.0
      GATEWAY=192.168.2.1 # 配置网关为2.1
      DNS1=192.168.1.1
      
    • 重启网络

      service network restart
      

拒绝访问服务器本身和拒绝通过服务器访问别的机器

  • 基于搭建路由器使内网机器能上网环境
  • 禁止170服务器通过150服务器访问192.168.2.1,即不允许访问服务器本身

    iptables -A INPUT -s 192.168.2.2 -j DROP
    
  • 禁止170服务器通过150服务器上网

    iptables -A FORWARD -s 192.168.2.2 -j DROP
    

使用DNAT功能,把内网web服务器端口映射到路由器外网

  • 基于搭建路由器使内网机器能上网环境
  • 访问192.168.1.150的80端口转发到170服务器的192.168.2.2:80

    iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j DNAT --to 192.168.2.2:80
    # ||
    iptables -t nat -A PREROUTING -d 192.168.1.150 -p tcp --dport 80 -j DNAT --to 192.168.2.2:80