Linux防火墙之iptables

iptables是Linux防火墙的管理工具,位于/sbin/iptables。真正实现防火墙功能的是位于内核空间的netfilter,它是Linux内核中实现包过滤的内部结构。

过滤 IPv4 数据包的代码已经内置于内核中,并且按照不同的目的被组织成的集合。
由一组预先定义的组成,包含遍历顺序规则。
每一条规则包含一个谓词的潜在匹配和相应的动作(称为目标),如果谓词为真,该动作会被执行。也就是说条件匹配。
iptables 是用户工具,允许用户使用规则

iptables命令简介

iptables [-t 表名: filter/nat/mangle/raw] 命令选项 [链名: PREROUTING/INPUT/OUTPUT/FORWARD/POSTROUTING] [条件匹配] [-j 目标动作或跳转: ACCEPT/DROP/REJECT/LOG/REDIRECT/SNAT/DNAT]

  • 常用的命令选项

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    -t:指定要操纵的表(四个表);
    -A:向规则链中添加条目;
    -D:从规则链中删除条目;
    -i:向规则链中插入条目;
    -R:替换规则链中的条目;
    -L:显示规则链中已有的条目;
    -F:清楚规则链中已有的条目;
    -Z:清空规则链中的数据包计算器和字节计数器;
    -N:创建新的用户自定义规则链;
    -P:定义规则链中的默认目标;
    -h:显示帮助信息;
    -p:指定要匹配的数据包协议类型;
    -s:指定要匹配的数据包源;

    -i -in-interface 进入的网络接口
    -o --out-interface 输出的网络接口
    -m state 当与连接跟踪结合使用时,允许访问包的连接跟踪状态。
    --state state state是一个逗号分割的匹配连接状态列表。
    INVALID 表示包是未知连接,
    ESTABLISHED 表示是双向传送的连接,
    NEW 表示包 为新的连接,否则是非双向传送的,
    RELATED 表示包由新连接开始,但是和一个已存在的连接在一起,如FTP数据传送,或者一个ICMP错误。
  • 常用的条件匹配:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    1、状态匹配:-m state --state 连接状态
    NEW:与任何连接无关的
    ESTABLISHED:响应请求或已建立连接的
    RELATED:与已有连接有相关性的,如FTP数据连接

    2、MAC地址匹配:-m mac --mac-source MAC地址
    eg:iptables -A INPUT -m mac --mac-source f0:1b:12:12:22:4f -j DROP

    3、IP范围匹配:-m iprange --src-range IP范围
    eg:iptables -A FORWARD -p tcp -m iprange --src-range 192.168.0.1-192.168.0.10 -j ACCEPT

    4、多端口匹配:-m multiport --sports 源端口列表 和 -m multiport --sports 目的端口列表
    eg:iptables -A INPUT -p tcp -m multiport --dport 11,29,116,121 -j ACCEPT

iptables基础操作

以下内容基于centos6系统环境。

  • 服务安装

    1
    yum -y install iptables
  • 保存iptables到文件

    1
    2
    3
    4
    iptables-save > ~/iptables.rules

    /etc/rc.d/init.d/iptables save 默认将规则写入/etc/sysconfig/iptables
    重启service iptables restart生效
  • 从文件中还原iptables规则

    1
    iptables-restore < ~/iptables.rules
  • 监控iptables

    • 查看规则命中的次数

      1
      iptables -L -v -n --line-numbers
    • 删除不必要的规则

      1
      iptables -nvL | grep -v "0     0"
    • 监控iptables活动

      1
      watch --interval=5 'iptables -nvL | grep -v "0     0"'
    • 使用FWLogwatch分析iptables日志生成报告

  • 清空所有默认规则

    1
    iptables -F
  • 清空所有自定义规则

    1
    iptables -X
  • 所有计数器归0

    1
    iptables -Z

iptables应用实例

基本规则

  • 预设规则(默认为ACCEPT)

    1
    2
    3
    iptables -P INPUT DROP
    iptables -P OUTPUT ACCEPT
    iptables -P FORWARD DROP
  • 查看当前规则:

    1
    iptables -nvL --line-number
  • 追加规则

    1
    iptables -A INPUT -s 10.1.1.1 -j DROP
  • 插入规则

    1
    iptables -I INPUT 3 -s 10.1.1.2 -j DROP
  • 删除规则

    1
    2
    3
    iptables -D INPUT -s 10.1.1.1 -j DROP
    按行号删
    iptables -D INPUT 1
  • 修改规则

    1
    2
    将第2条规则改为ACCEPT
    iptables -R INPUT 3 -j ACCEPT
  • 清空规则

    1
    iptables -F

规则案例

ACCEPT

  • 放行ping

    1
    2
    iptables -A INPUT -p icmp -j ACCEPT
    iptables -A OUTPUT -p icmp -j ACCEPT
  • 允许lookback

    1
    2
    3
    4
    5
    iptables -A INPUT -i lo -p all -j ACCEPT
    iptables -A OUTPUT -o lo -p all -j ACCEPT

    iptables -A INPUT -i lo -j ACCEPT
    iptables -A OUTPUT -o lo -j ACCEPT
  • 放行80端口

    1
    2
    iptables -A INPUT -p tcp --dport 80 -j ACCEPT
    iptables -A OUTPUT -p tcp --sport 80 -j ACCEPT //如果设置了iptables -P OUTPUT DROP,需要添加该条,否则远程无法连接
  • 允许防火墙转发除ICMP协议以外的所有数据包

    1
    2
    3
    4
    5
    iptables -A FORWARD -p ! icmp -j ACCEPT
    ````
    - 注:"!" 条件取反

    - 允许某个特定网络 rsync 进入本机

    iptables -A INPUT -i eth0 -p tcp -s 192.168.1.0/24 –dport 873 -m state –state NEW,ESTABLISHED -j ACCEPT
    iptables -A OUTPUT -o eth0 -p tcp –sport 873 -m state –state ESTABLISHED -j ACCEPT

    1
    2
    3


    - 仅允许来自指定网络的ssh连接请求

    iptables -A INPUT -i eth0 -p tcp -s 192.168.1.0/24 –dport 22 -m state –state NEW,ESTABLISHED -j ACCEPT
    iptables -A OUTPUT -o eth0 -p tcp –sport 22 -m state –state ESTABLISHED -j ACCEPT

    1
    2

    - 仅允许从本地发起到指定网络的SSH连接请求

    iptables -A OUTPUT -o eth0 -p tcp -d 192.168.1.0/24 –dport 22 -m state –state NEW,ESTABLISHED -j ACCEPT
    iptables -A INPUT -i eth0 -p tcp –sport 22 -m state –state ESTABLISHED -j ACCEPT

    1
    2

    - 允许转发来自192.168.1.0/24局域网段的DNS解析请求数据包。

    iptables -A FORWARD -s 192.168.1.0/24 -p udp –dport 53 -j ACCEPT
    iptables -A FORWARD -d 192.168.1.0/24 -p udp –sport 53 -j ACCEPT

    1
    2

    - 允许本机开放从TCP端口1000-1024提供的应用服务。

    iptables -A INPUT -p tcp –dport 1000:1024 -j ACCEPT
    iptables -A OUTPUT -p tcp –sport 1000:1024 -j ACCEPT

    1
    2

    - 使用Multiport放行多个端口

    iptables -A INPUT -p tcp -m multiport –dports 22,80,443 -j ACCEPT
    iptables -A OUTPUT -p tcp -m multiport –sports 22,80,443 -j ACCEPT

    1
    2

    - 允许防火墙本机对外开放TCP端口20、21、25、110以及被动模式FTP端口1250-1280

    iptables -A INPUT -p tcp -m multiport –dport 20,21,25,110,1250:1280 -j ACCEPT

    1
    2
    3
      - 注意:这里用“-m multiport --dport”来指定多个目的端口

    - 针对端口访问的过滤。下面表示除了192.168.1.1-192.168.1.10之间的ip能访问192.168.0.1机器的80端口以外,其他ip都不可以访问!

    iptables -A INPUT -d 192.168.0.1 -p tcp –dport 80 -m iprange –src-range 192.168.1.1-192.168.1.10 -j ACCEPT

    1
    2

    - 只允许管理员从192.168.1.0/24网段使用SSH远程登录防火墙主机。

    iptables -A INPUT -p tcp –dport 22 -s 202.13.0.0/16 -j ACCEPT
    iptables -A INPUT -p tcp –dport 22 -j DROP

    1
    2

    - 允许192.168.1.0网段的服务器访问(-t filter表配置可以省略,默认就是这种表的配置)

    iptables -A INPUT -s 192.168.1.0/24 -p tcp -m state –state NEW -m tcp –dport 22 -j ACCEPT
    或者
    iptables -t filter -A INPUT -s 192.168.1.0/24 -p tcp -m state –state NEW -m tcp –dport 22 -j ACCEPT

    1
    2

    - 如果本地主机有两块网卡,一块连接内网(eth0),一块连接外网(eth1),那么可以使用下面的规则将eth0的数据路由到eht1:

    iptables -A FORWARD -i eth0 -o eth1 -j ACCEPT

    1
    2

    - 允许所有本机向外的访问

    iptables -A OUTPUT -j ACCEPT

    1
    2
    3
    4
    5


    ### DROP

    - 屏蔽环回(loopback)访问

    iptables -A INPUT -i lo -j DROP
    iptables -A OUTPUT -o lo -j DROP

    1
    2

    - 屏蔽 ping

    iptables -A INPUT -p icmp -i eth0 -j DROP

    1
    2

    - 屏蔽来自外部的ping,即禁止外部机器ping本机

    iptables -A INPUT -p icmp –icmp-type echo-request -j DROP
    iptables -A OUTPUT -p icmp –icmp-type echo-reply -j DROP

    1
    2

    - 屏蔽从本机ping外部主机,禁止本机ping外部机器

    iptables -A OUTPUT -p icmp –icmp-type echo-request -j DROP
    iptables -A INPUT -p icmp –icmp-type echo-reply -j DROP

    1
    2
    3
      - --icmp-type 8 同样表示 Echo request(Ping回显请求)

    - 允许本机 ping 别的主机;但不开放别的主机 ping 本机;

    iptables -I INPUT -p icmp –icmp-type echo-request -j DROP
    iptables -I INPUT -p icmp –icmp-type echo-reply -j ACCEPT
    iptables -I INPUT -p icmp –icmp-type destination-Unreachable -j ACCEPT
    或者下面禁ping操作:
    echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_all

    1
    2

    - 屏蔽指定mac地址

    iptables -A INPUT -m mac –mac-source 00:00:00:00:00:00 -j DROP

    1
    2

    - 屏蔽某个IP

    iptables -A INPUT -s xxx.xxx.xxx.xxx -j DROP

    1
    2

    - 拒绝转发来自192.168.0.1主机的数据

    iptables -A FORWARD -s 192.168.0.1 -j REJECT

    1
    2

    - 屏蔽从192.168.0.1到192.168.0.254

    iptables -I INPUT -s 192.168.0.0/24 -j DROP

    1
    2

    - 过滤源地址段:

    iptables -A INPUT -m iprange –src-range 192.168.1.1-192.168.1.10 -j DROP

    1
    2

    - 过滤目标地址段:

    iptables -A INPUT -m iprange –dst-range 192.168.1.11-192.168.1.20 -j DROP

    1
    2

    - 丢弃无效的数据包

    iptables -A INPUT -m conntrack –ctstate INVALID -j DROP

    1
    2

    - 拒绝转发来自192.168.1.1主机的数据,允许转发来自192.168.0.0/24网段的数据

    iptables -A FORWARD -s 192.168.1.1 -j REJECT
    iptables -A FORWARD -s 192.168.0.0/24 -j ACCEPT

    1
    2
    3
      - 说明:注意一定要把拒绝的放在前面不然就不起作用了!

    - 丢弃从外网接口(eth1)进入防火墙本机的源地址为私网地址的数据包

    iptables -A INPUT -i eth1 -s 192.168.0.0/16 -j DROP
    iptables -A INPUT -i eth1 -s 172.16.0.0/12 -j DROP
    iptables -A INPUT -i eth1 -s 10.0.0.0/8 -j DROP

    1
    2

    - 拒绝 TCP 标志位全部为 1 及全部为 0 的报文访问本机

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

    1
    2

    - 禁止转发来自MAC地址为`aa:aa:aa:45:75:d0`的和主机的数据包

    iptables -A FORWARD -m mac –mac-source aa:aa:aa:45:75:d0 -j DROP

    1
    2
    3
      - iptables中使用“-m 模块关键字”的形式调用显示匹配。咱们这里用“-m mac –mac-source”来表示数据包的源MAC地址

    - 禁止转发源IP地址为192.168.1.1-192.168.1.100的TCP数据包

    iptables -A FORWARD -p tcp -m iprange –src-range 192.168.1.1-192.168.1.100 -j DROP

    1
    2
    3
      - 此处用“-m iprange --src-range”指定IP范围

    - 禁止转发与正常TCP连接无关的非--syn请求数据包

    iptables -A FORWARD -m state –state NEW -p tcp ! –syn -j DROP

    1
    2
    3
      - “-m state”表示数据包的连接状态,“NEW”表示与任何连接无关的

    - 拒绝访问防火墙的新数据包,但允许响应连接或与已有连接相关的数据包

    iptables -A INPUT -p tcp -m state –state NEW -j DROP
    iptables -A INPUT -p tcp -m state –state ESTABLISHED,RELATED -j ACCEPT

    1
    2
    3
      - “ESTABLISHED”表示已经响应请求或者已经建立连接的数据包,“RELATED”表示与已建立的连接有相关性的,比如FTP数据连接等

    - 为某个端口访问设置白名单

    iptables -A INPUT -s -p tcp -m tcp –dport 22 -j ACCEPT
    iptables -D INPUT -p tcp -m tcp –dport 22 -j DROP
    eg:
    iptables -A INPUT -p tcp –dport 21 -s 113.128.0.0/16 -j ACCEPT;
    iptables -A INPUT -p tcp –dport 21 -s 120.0.0.0/8 -j ACCEPT;
    iptables -A INPUT -p tcp –dport 21 -j DROP

    1
    2
    3
    4
    5


    ### LIMIT

    - 防止DoS攻击

    iptables -A INPUT -p tcp –dport 80 -m limit –limit 25/minute –limit-burst 100 -j ACCEPT

    1
    2
    3
    4
    5
      - -m limit: 启用limit扩展,限制速度。
    - --limit 25/minute: 允许最多每分钟25个连接
    - --limit-burst 100: 当达到100个连接后,才启用上述25/minute限制(连接上限)

    - 限制并发连接数

    iptables -A INPUT -p tcp –syn –dport 22 -m connlimit –connlimit-above 3 -j REJECT //限制每客户端不超过 3 个连接
    iptables -A INPUT -p tcp –syn -m multiport –dport http,https –m connlimit –connlimit-above 20 -j REJECT –reject-with-tcp-reset

    1
    2

    - 开放本机的ssh服务给192.168.1.1-192.168.1.100 中的主机;新请求建立的速率一分钟不得超过5个;仅允许响应报文通过其服务端口离开本机;

    iptables -A INPUT -p tcp –dport 22 -m iprange –src-rang 192.168.1.1-192.168.1.100 -m limit –limit 5/m -j ACCEPT
    iptables -A OUTPUT -p tcp –sport 22 -m iprange –dst-rang 192.168.1.1-192.168.1.100 -m state –state ESTABLISHED -j ACCEPT

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12


    ### PREROUTING

    IPtables中可以灵活的做各种网络地址转换(NAT)。

    - 网络地址转换主要有两种:SNAT和DNAT
    - SNAT是source network address translation的缩写,即源地址目标转换。
    - MASQUERADE,地址伪装,在iptables中有着和SNAT相近的效果,但也有一些区别:使用SNAT的时候,出口ip的地址范围可以是一个,也可以是多个。
    - DNAT是destination network address translation的缩写,即目标网络地址转换。

    - 把所有10.0.0.0网段的数据包SNAT成192.168.1.1的ip然后发出去

    iptables -t nat -A POSTROUTING -s 10.0.0.0/255.255.255.0 -o eth0 -j SNAT –to-source 192.168.1.1

    1
    2

    - 把所有10.0.0.0网段的数据包SNAT成192.168.1.1/192.168.1.2/192.168.1.3等几个ip然后发出去

    iptables -t nat -A POSTROUTING -s 10.0.0.0/255.255.255.0 -o eth0 -j SNAT –to-source 192.168.1.1-192.168.1.3

    1
    2
    3
      - 对于SNAT,不管是几个地址,必须明确的指定要SNAT的IP

    - 动态SNAT地址转换,不管现在eth0的出口获得了怎样的动态ip,MASQUERADE会自动读取eth0现在的ip地址然后做SNAT出去

    iptables -t nat -A POSTROUTING -s 10.0.0.0/255.255.255.0 -o eth0 -j MASQUERADE

    1
    2
    3
      - MASQUERADE的作用是,从服务器的网卡上,自动获取当前ip地址来做NAT

    - 8022映射22端口

    iptables -t nat -A PREROUTING -p tcp -d 192.168.1.1 –dport 8022 -j DNAT –to-destination 192.168.1.1:22

    1
    2

    - 将所有到达eth0网卡80端口的流量重定向转发到8080端口

    iptables -t nat -A PREROUTING -i eth0 -p tcp –dport 89 -j REDIRECT –to-port 8080

    1
    2

    - 设置 8080 端口转发到 80 端口

    iptables -t nat -A PREROUTING -p tcp -d 10.1.1.1 –dport 8080 -j DNAT –to 10.1.1.1:80
    iptables -A INPUT -i eth0 -p tcp –dport 8080 -m state –state NEW,ESTABLISHED -j ACCEPT
    iptables -A OUTPUT -o eth0 -p tcp –sport 8080 -m state –state ESTABLISHED -j ACCEPT

    1
    2
    3
    4
    5


    ## 实践场景

    - 按时段限制(需要模块支持)

    iptables –A OUTPUT -p tcp -m multiport –dport http,https -i eth0 -o eth1 -m time –timestart 12:00 –timestop 13:00 –d 10.0.0.0/8 -j ACCEPT
    iptables -A INPUT -p tcp -m time –timestart 02:00 –timestop 03:00 -j DROP
    iptables -A INPUT -p udp -m time –timestart 02:00 –timestop 03:00 -j DROP

    1
    2

    - 限制本机的web服务器在周一不允许访问;新请求的速率不能超过100个每秒;web服务器包含了admin字符串的页面不允许访问:

    web服务器仅允许响应报文离开本机;周一不允许访问

    iptables -A INPUT -p tcp –dport 80 -m time ! –weekdays Mon -j ACCEPT
    iptables -A OUTPUT -p tcp –dport 80 -m state –state ESTABLISHED -j ACCEPT

新请求速率不能超过100个每秒

iptables -A INPUT -p tcp –dport 80 -m limit –limit 100/s -j ACCEPT

web包含admin字符串的页面不允许访问,源端口:dport

iptables -A INPUT -p tcp –dport 80 -m string –algo bm –string ‘admin’ -j REJECT

web服务器仅允许响应报文离开主机,放行端口(目标端口):sport

iptables -A OUTPUT -p tcp –dport 80 -m state –state ESTABLISHED -j ACCEPT

1
2

- 在工作时间,即周一到周五的8:30-18:00,开放本机的ftp服务给 192.168.1.0网络中的主机访问;数据下载请求的次数每分钟不得超过5个;

iptables -A INPUT -p tcp –dport 21 -s 192.168.1.0/24 -m time ! –weekdays 6,7 -m time –timestart 8:30 –timestop 18:00 -m connlimit –connlimit-above 5 -j ACCET

1
2

- 屏蔽ssh和rsync端口,只允许白名单机器访问

cat << EOF
#!/bin/bash
/etc/init.d/iptables stop
iptables -A INPUT -s 10.0.0.1 -p tcp –dport 22 -j ACCEPT # 中控白名单
iptables -A OUTPUT -d 10.0.0.1 -p tcp –sport 22 -j ACCEPT
iptables -A INPUT -s 10.0.0.2 -p tcp –dport 22 -m state –state NEW,ESTABLISHED -j ACCEPT # 监控探针通过22端口连通性监控机器存活,开白名单。
iptables -A INPUT -p tcp -m multiport –dports 22,873 -j DROP
iptables -A OUTPUT -p tcp -m multiport –dports 22,873 -j DROP
iptables -L -v -n –line-numbers
EOF | bash

```

参考文档