Iptables配置实践

Iptables

Posted by BlueFat on Wednesday, November 13, 2019

Netfilter 与 iptables 的关系

Linux 系统在内核中提供了对报文数据包过滤和修改的官方项目名为 Netfilter,它指的是 Linux 内核中的一个框架,它可以用于在不同阶段将某些钩子函数(hook)作用域网络协议栈。Netfilter 本身并不对数据包进行过滤,它只是允许可以过滤数据包或修改数据包的函数挂接到内核网络协议栈中的适当位置。这些函数是可以自定义的。

iptables 是用户层的工具,它提供命令行接口,能够向 Netfilter 中添加规则策略,从而实现报文过滤,修改等功能。Linux 系统中并不止有 iptables 能够生成防火墙规则,其他的工具如 firewalld 等也能实现类似的功能。

使用 iptables 进行包过滤

iptables 策略是由一组有序的规则建立的,它告诉内核应该如何处理某些类别的数据包。每一个 iptables 规则应用于一个表中的一个链。一个 iptables 链就是一个规则集,这些规则按序与包含某种特征的数据包进行比较匹配。

iptables 默认有 4 个表

  1. nat 表(地址转换表)
  2. filter 表(数据过滤表)
  3. raw 表(状态跟踪表)
  4. mangle 表(包标记表)

每个表都有一组内置链,用户还可以添加自定义的链。最重要的内置链是 filter 表中的 INPUT、OUTPUT 和 FORWARD 链。

  1. INPUT 链(入站规则)
  2. OUTPUT 链(出站规则)
  3. FORWARD 链(转发规则)
  4. PREROUTING 链(路有前规则)
  5. POSTROUTING 链(路由后规则)

下图展现了一个数据包是如何通过内核中的 net 和 filter 表的:

11

iptables的4表5链

iptables --> 四表五链 
    添加规则是的考量点:
        (1)要实现那种功能:判断添加在那张表上
        (2)报文流经的路径:判断添加在那个链上

 链 -->> 练上规则的次序,即为检查的次序,因此隐含一定的法则 
        (1)同类规则(访问同一应用):匹配范围小的放上面
        (2)不同类规则(访问不同应用):匹配到报文平率较大的放上面
        (3)将可以由条规则描述的多个规则合并为一个
        (4)设置默认策略:

 功能的优先级次序:raw --> mangle --> nat --> filter

规则:
    组成部分:报文的匹配条件,匹配到后处理动作 
    匹配条件:根据协议报文特征指定匹配条件
            基本匹配条件:源 IP,目标 IP,源端口,目标端口
                        扩展匹配条件:IP 追踪
    处理动作:
                        内建处理机制
                        自定义处理机制
 注意:

报文不会经过自定义链,只能在内置链上通过规则引用后生效
        iptables 的规则管理工具
                添加、修改、删除、显示等功能
        规则和链有计数器:
                pkgs:有规则或链所匹配到的报文的个数
                bytes: 由规则或链匹配到的所有报文大小之和

匹配

每个 iptables 规则都包含一组匹配和一个目标动作,后者定义了复合规则的数据包应该采取什么处理行为。iptables 匹配指定是数据包必须匹配的条件,只有当数据包满足所有的匹配条件时,iptables 才能根据规则的目标所指定的动作来处理该数据包。

每个匹配都在 iptables 的命令行中指定。下面是一些常用的基本匹配:

参数 作用
-P 设置默认策略
-F 清空规则链
-L 查看规则链
-A 在规则链的末尾加入新规则
-I num 在规则链的头部加入新规则
-D num 删除某一条规则
-s 匹配来源地址 IP/MASK,加叹号 “!” 表示除这个 IP 外
-d 匹配目标地址
-i 网卡名称 匹配从这块网卡流入的数据
-o 网卡名称 匹配从这块网卡流出的数据
-p 匹配协议,如 TCP、UDP、ICMP
–dport num 匹配目标端口号
–sport num 匹配来源端口号

防火墙的匹配规则

  • 匹配即可停止
  • 匹配有先后顺序
  • 默认规则的优先级最低

基础语法

表名作用:

  • raw:高级功能,如:网址过滤。
  • mangle:数据包修改(QOS),用于实现服务质量。
  • net:地址转换,用于网关路由器。
  • filter:包过滤,用于防火墙规则。

规则链作用:

  • INPUT 链:处理输入数据包。
  • OUTPUT 链:处理输出数据包。
  • PORWARD 链:处理转发数据包。
  • PREROUTING 链:用于目标地址转换(DNAT)。
  • POSTOUTING 链:用于源地址转换(SNAT)。

动作作用:

  • ACCEPT:接收数据包。
  • DROP:丢弃数据包。
  • REJECT :拒绝数据包
  • REDIRECT:重定向、映射、透明代理。
  • SNAT:源地址转换。
  • DNAT:目标地址转换。
  • MASQUERADE:IP 伪装(NAT),用于 ADSL。
  • LOG:日志记录。
# 规则的观察与清除 

	 iptables [-t tables] [-L] [-nv]

 选项与参数:
-t :后面接 table ,例如 nat 或 filter ,若省略此项目,则使用默认的 filter
-L :列出目前的 table 的规则 
-n :不进行 IP 与 HOSTNAME 的反查,显示讯息的速度会快很多!
-v :列出更多的信息,包括通过该规则的封包总位数、相关的网络接口等

     iptables [-t tables] [-FXZ]

 选项与参数:
-F :清除所有的已订定的规则;
-X :杀掉所有使用者 "自定义" 的 chain (应该说的是 tables )啰;
-Z :将所有的 chain 的计数与流量统计都归零 


# 封包的基础比对:IP, 网域及接口装置

    iptables [-AI 链名] [-io 网络接口] [-p 协议] [-s 来源 IP / 网域] [-d 目标 IP / 网域] -j [ACCEPT|DROP|REJECT|LOG]

 选项与参数:
-AI 链名:针对某的链进行规则的 "插入""累加"
    -A :新增加一条规则,该规则增加在原本规则的最后面。例如原本已经有四条规则,
         使用 -A 就可以加上第五条规则!
    -I :插入一条规则。如果没有指定此规则的顺序,默认是插入变成第一条规则。
         例如原本有四条规则,使用 -I 则该规则变成第一条,而原本四条变成 2~5 号 
    链 :有 INPUT, OUTPUT, FORWARD 等,此链名称又与 -io 有关,请看底下。

-io 网络接口:设定封包进出的接口规范
    -i :封包所进入的那个网络接口,例如 eth0, lo 等接口。需与 INPUT 链配合;
    -o :封包所传出的那个网络接口,需与 OUTPUT 链配合;

-p 协定:设定此规则适用于哪种封包格式
   主要的封包格式有: tcp, udp, icmp 及 all 。

-s 来源 IP / 网域:设定此规则之封包的来源项目,可指定单纯的 IP 或包括网域,例如:
   IP  :192.168.0.100
   网域:192.168.0.0/24, 192.168.0.0/255.255.255.0 均可。
   若规范为『不许』时,则加上 ! 即可,例如:
   -s ! 192.168.100.0/24 表示不许 192.168.100.0/24 之封包来源;

-d 目标 IP / 网域:同 -s ,只不过这里指的是目标的 IP 或网域。

-j :后面接动作,主要的动作有接受(ACCEPT)、丢弃(DROP)、拒绝(REJECT) 及记录 (LOG)

#TCP, UDP 的规则比对:针对端口设定

    iptables [-AI 链] [-io 网络接口] [-p tcp,udp] [-s 来源 IP / 网域] [--sport 埠口范围] [-d 目标 IP / 网域] [--dport 端口范围] -j [ACCEPT|DROP|REJECT]

 选项与参数:
--sport 埠口范围:限制来源的端口号码,端口号码可以是连续的,例如 1024:65535
--dport 埠口范围:限制目标的端口号码。

#iptables 外挂模块:mac 与 state

    iptables -A INPUT [-m state] [--state 状态]

选项与参数:
-m :一些 iptables 的外挂模块,主要常见的有:
     state :状态模块 
     mac   :网络卡硬件地址 (hardware address)
--state :一些封包的状态,主要有:
     INVALID    :无效的封包,例如数据破损的封包状态
     ESTABLISHED:已经联机成功的联机状态;
     NEW        :想要新建立联机的封包状态;
     RELATED    :这个最常用!表示这个封包是与我们主机发送出去的封包有关


#ICMP 封包规则的比对:针对是否响应 ping 来设计

    iptables -A INPUT [-p icmp] [--icmp-type 类型] -j ACCEPT

 选项与参数:
--icmp-type :后面必须要接 ICMP 的封包类型,也可以使用代号,
              例如 8  代表 echo request 的意思。

注意事项与规律

  • 可以不指定表,默认为 filter 表
  • 可以不指定链,默认为对应表的所有链
  • 除非设置默认策略,否则必须指定匹配条件
  • 选项 / 链名 / 目标操作用大写字母,其余都小写

管理类命令

管理规则

-A:             附加一条规则,添加在链的尾部
-I CHAIN [n]:   插入一条规则,插入对应 CHAIN 上的第 n 条,默认插到第一条
-D CHAIN [n]:   删除指定链中的第 n 条规则
-R CHAIN [num]: 替换指定的规则

管理链

-F [CHAIN]:     清空指定规则链,如果省略 CHAIN,则清空对应表中的所有链
-P CHAIN TARGE: 设定指定链的默认策略
-N:             自定义一个新的空链
-X:             删除一个自定义的空链

查看规则:

-L:             显式指定表中的规则
-n:             以数字格式显式主机地址和端口号
-v:             显式链及规则的详细信息
--line-numbers: 显式规则号码

匹配

每个 iptables 规则都包含一组匹配和一个目标动作,后者定义了复合规则的数据包应该采取什么处理行为。iptables 匹配指定是数据包必须匹配的条件,只有当数据包满足所有的匹配条件时,iptables 才能根据规则的目标所指定的动作来处理该数据包。

常用的基本匹配

-s                  匹配源 IP 地址或网络
-d                  匹配目标 IP 地址或网络
-p                  匹配协议类型(如 tcp,udp,icmp)
-i                  流入接口(如 eth0)
-o                  流出接口

在使用 -p {tcp|udp|icmp} 进行匹配时,还可以使用隐含的扩展匹配,这些功能是由 iptables 的模块提供的,但是这里可以省去指明模块:

-p tcp
    --sport [!] port[:port]     匹配源端口
    --dport [!] port[:port]     匹配目标端口
    --tcp-flags [!] mask comp
        检查 TCP 标志位,各标志以逗号分隔,comp 中指定的标记必须为 1,comp 中没出现,而 mask 中出现的,必须为 0

-p icmp
    --icmp-type [!] TYPENAME    匹配 ICMP 类型

-p udp
    --sport [!] port[:port]     匹配源端口
    --dport [!] port[:port]     匹配目标端口

使用扩展模块进行匹配

使用模块扩展进行匹配时,必须使用 -m 指明由哪个模块进行的扩展

多端口匹配

-m multiport
    --sports [!] port[,port[,port:port...]] 匹配多个源端口
    --dports [!] port[,port[,port:port...]] 匹配多个目标端口
    --ports 匹配多个端口(无论源还是目标端口)

范围 IP 地址匹配

-m iprange
    [!] --src-range IPADDR-IPADDR   匹配一个范围的源 IP 地址
    [!] --dst-range IPADDR-IPADDR   匹配一个范围的目标 IP 地址

连接数限制

-m connlimit
    [!] --connlimit-above N     限制同时连接数量

连接速率限制

-m limit
    --limit RATE        单位时间连接控制,使用 '/second''/minute''/hour''/day' 等单位为后缀,默认是 3/hour
    --limit-burst N     同一时间的连接的并发连接控制,默认为 5

报文内容字符串匹配

-m string
    --algo {bm|kmp}     字符串匹配算法,可以选择 bm 或 kmp
    --string "STRING"   匹配的字符串
    --hex-string "STRING"   十六进制格式的字符串

基于时间的控制

-m time
    --datestart YYYY[-MM[[-DD[Thh[:mm[:ss]]]]]
    --datestop YYYY[-MM[-DD[Thh[:mm[:ss]]]]]
        匹配起始时间与结束时间

    --timestart hh:mm[:ss]
    --timestop hh:mm[:ss]
        [!] --monthdays day[,day...]
        [!] --weekdays day[,day...]
    根据时间和星期几来匹配

目标动作

iptables 对匹配的数据包执行一个目标动作,目标动作由 -j 来指定

# -j ACCEPT
ACCEPT:     放行
DROP:       丢弃报文
REJECT:     发送一个 ICMP 报文拒绝
DNAT:       目标地址转换(即修改报文的目标地址)
    --to-destination ipaddr[:port]  
    指定修改的目标地址和端口
SNAT:       源地址转换(修改报文的源地址)
    --to-source ipaddr[-ipaddr][:port-port]
    指定修改的源地址和端口
REDIRECT:   端口重定向
MASQUERADE: 地址伪装
LOG:        记录日志
    --log-prefix "STRING"
    记录日志的前缀

范例

0. 配置默认规则
iptables -P INPUT DROP
iptables -P OUTPUT ACCEPT
iptables -P FORWARD DROP

1. 设置 filter 表 INPUT 链的默认策略为 DROP
iptables -P INPUT DROP

2. 允许源地址为 172.16.0.0/16 网段的主机连接本机 SSH
iptables -A INPUT -s 172.16.0.0/16 -p tcp --dport 22 -j ACCEPT

3. 允许 ICMP 请求报文
iptables -A INPUT -p icmp --icmp-type 8

4. 允许 80443 端口的访问(使用离散端口扩展模块)
iptables -A INPUT -p tcp -m multiport --dports 80,443 -j ACCEPT

5. 允许 Telnet 的 23 端口访问,并限制同时只能有 5 个连接
iptables -A INPUT -p tcp --dport 23 -m connlimit --connlimit-above 5 -j REJECT

6. 拒绝本地端口 80 发出的,含有 “communist” 关键字的响应报文的发出
iptables -A OUTPUT -p tcp --sport 80 -m string --algo kmp --string "communist" -j DROP

7. 仅允许工作日的工作时间访问本机 UDP 53 端口
iptables -A INPUT -p udp --dport 53 -m time --timestart 08:00 --timestop 18:00 --weekdays Mon,Tue,Wen,Thu,Fri -j ACCEPT

8. 允许 172.16.0.1 ~ 172.16.0.100 的主机访问本机 TCP 3306 端口
iptables -A INPUT -p tcp --dport 3306 -m iprange --src-range 172.16.0.1-172.16.0.100 -j ACCEPT

9. 目的地址转换,映射内部地址
iptables -t nat -A PREROUTING -i ppp0 -p tcp --dprot 81 -j DNAT --to 192.168.0.2:80
iptables -t nat -A PREROUTING -i ppp0 -p tcp --dprot 81 -j DNAT --to 192.168.0.1-192.168.0.10

10. 源地址转换,隐藏内部地址
iptables -t nat -A POSTROUTING -s 192.168.0.0/24 -j SNAT --to 1.1.1.1
iptables -t nat -A POSTROUTING -s 192.168.0.0/24 -j SNAT --to 1.1.1.1-1.1.1.10

11. 地址伪装,动态ip的NAT
iptables -t nat -A POSTROUTING -s 192.168.0.0/24 -o eth0 -j MASQUERADE

让其他私有IP的服务器连接公网,masquerade和snat的主要区别在于,snat是把源地址转换为固定的IP地址或者是地址池,而masquerade会根据网卡的IP变化而变化

12. 开启转发功能
iptables -A FORWARD -i eth1 -o eth0 -j ACCEPT #允许对外转发

13. 过滤某个MAC
iptables -A FORWARD -m mac --mac -source MAC地址 -j DROP

报文经过路由后,数据包中原有的MAC信息会被替换,所以在路由后的iptables中使用mac匹配没有意义。

14. 数据包限流
iptables -A FORWARD -d 192.168.0.1 -m limit --limit 50/s -j ACCEPT
iptables -A FORWARD -d 192.168.0.1 -j DROP

15. 多端口匹配
iptables -A INPUT -p tcp -m muliport --dport s 21,22,25,80,110 -j ACCEPT

16. 丢弃非法连接
iptables -A INPUT -m state --state INVALID -j DROP
iptables -A OUTPUT -m state --state INVALID -j DROP
iptables -A FORWARD -m state --state INVALID -j DROP

Nginx iptables优化

iptables -A INPUT -m state --state ESTABLISHED,RELATED,UNTRACKED -j ACCEPT
iptables -t raw -A PREROUTING -p tcp -m tcp -m multiport --dports 80,81,443 -j NOTRACK
iptables -t raw -A OUTPUT -p tcp -m tcp -m multiport --sports 80,81,443 -j NOTRACK

iptables 的状态追踪

iptables中连接追踪的功能叫做 ip_conntrackip_conntrack 是个内核模块,能够实时记录当前主机上客户端和服务器端彼此正在建立的连接关系, 并且能够追踪到连接所处的状态和连接之间的关系

查看状态追踪模块是否启用:

# lsmod | grep "ip_conntrack"

ip_conntrack是根据ip报文实现的追踪,能够根据客户端来源随时追踪连接会话处于什么过程。

/proc/net/ip_conntrack 保存了当前系统上每一个客户端和当前主机建立的tcp和udp连接关系,一个条目记录一个连接的两个会话通道以及 连接的状态

/proc/sys/net/ipv4/ip_conntrack_max 记录了最多可以记录的连接条目数,一旦超出后续的连接将会被丢弃。 在非常繁忙的服务器上,尽量不要启用ip_conntrack模块

显式当前系统的所有连接

# ipstate -t 

ip_conntrack 模块被 iptable_nat 和 ip_nat 模块所依赖,ip_nat 和 iptable_nat 是被 nat 表所使用的,因此即使停止 iptables 服务, 一旦查看了 nat 表,就会自动激活 ip_conntrack 模块

使用状态扩展模块进行匹配:

-m state
    --state STATE       根据连接状态进行匹配
        NEW:            新连接请求
        ESTABLISHED:    已建立的连接
        INVALID:        非法连接报文
        RELATED:        向关联的裂解(如 FTP 的命令连接和数据连接), 当一个连接和某个已处于 ESTABLISHED 状态的连接有关系时,
        就被认为是 RELATED 的了。换句话说,一个连接要想 是RELATED的,首先要有一个 ESTABLISHED 的连接。

例子

允许本机的 TCP 21 端口被访问,且允许任何 RELATED 和 ESTABLISHED 的报文访问本机

iptables -A INPUT -p tcp --dport 21 -j ACCEPT
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

保存规则

可以使用 iptables 服务保存规则

# service iptables save
    规则将被保存至  /etc/sysconfig/iptables
使用 iptables-save 和 iptables-restore 来保存规则和还原规则

# iptables-save > /etc/sysconfig/iptables.20150520
# iptables-restore < /etc/sysconfig/iptables.20150520

iptables 的错误恢复

定制 iptables 规则是非常危险的,尤其是在服务器位于异地的情况下,iptables 规则写入的失误就可能造成服务器无法访问,因此在定制iptables规则之前,先做好测试,并使用 at 启动计划任务,在错误情况下恢复iptables 规则。

# 1. 在修改iptables规则之前,备份原有的规则
$ iptables-save > /etc/sysconfig/iptables.bak

# 2. 将要修改的规则写入脚本文件
$ vim ~/iptables.sh

# 3. 添加计划任务,防止 iptables 的错误规则导致服务器无法访问
$ at now + 2 minite
at> /sbin/iptables-restore < /etc/sysconfig/iptables.bak          
at> <EOT>

# 4. 使用预定义的脚本修改防火墙规则
$ sh ~/iptables.sh

# 5. 如果规则没问题,则取消掉定时任务
$ atrm N(N表示at队列号)

配置 iptables 白名单机制

配置 iptables 白名单是相对简单有效的管理手段

# 清除所有规则(慎用)
iptables -F
iptables -X
iptables -Z

# 查看 iptable 和行号
iptables -nL --line-number

# 保存当前防火墙配置
service iptables save

# 手动编辑防火墙策略
vi /etc/sysconfig/iptables

*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
# 开放本地和 Ping
-A INPUT -i lo -j ACCEPT  
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT 
-A INPUT -p icmp -j ACCEPT
# 配置内网白名单
-A INPUT -s 10.0.0.0/8 -j ACCEPT
-A INPUT -s 172.16.0.0/12 -j ACCEPT
-A INPUT -s 192.168.0.0/16 -j ACCEPT
# 配置外网白名单
-A INPUT -s 180.168.36.198 -j ACCEPT 
-A INPUT -s 180.168.34.218 -j ACCEPT 
-A INPUT -s 222.73.202.251 -j ACCEPT 
# 控制端口
-A INPUT -p tcp --dport 80 -j ACCEPT 
-A INPUT -p tcp --dport 22 -j ACCEPT
# 拒绝其它
-A INPUT -j DROP 
-A FORWARD -j DROP 
# 开放出口
-A OUTPUT -j ACCEPT 
COMMIT

# 重启生效
service iptables restart

# 复查结果

iptables -nL --line-number

Chain INPUT (policy ACCEPT)
num  target     prot opt source               destination         
1    ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0           
2    ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0           state RELATED,ESTABLISHED 
3    ACCEPT     icmp --  0.0.0.0/0            0.0.0.0/0           
4    ACCEPT     all  --  10.0.0.0/8           0.0.0.0/0           
5    ACCEPT     all  --  172.16.0.0/12        0.0.0.0/0           
6    ACCEPT     all  --  192.168.0.0/16       0.0.0.0/0           
7    ACCEPT     all  --  180.168.36.198       0.0.0.0/0           
8    ACCEPT     all  --  180.168.34.218       0.0.0.0/0           
9    ACCEPT     all  --  222.73.202.251       0.0.0.0/0           
10   ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0           tcp dpt:80 
11   ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0           tcp dpt:22 
12   DROP       all  --  0.0.0.0/0            0.0.0.0/0           

Chain FORWARD (policy ACCEPT)
num  target     prot opt source               destination         
1    DROP       all  --  0.0.0.0/0            0.0.0.0/0           

Chain OUTPUT (policy ACCEPT)
num  target     prot opt source               destination         
1    ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0

设置 crontab 脚本

便于运维集中化管理扩展

vim /root/start_iptables.sh

#!/bin/bash
#0 0 * * * /root/start_iptables.sh

# 清除配置
/sbin/iptables -P INPUT ACCEPT
/sbin/iptables -F
/sbin/iptables -X
# 开放本地和 Ping
/sbin/iptables -A INPUT -i lo -j ACCEPT  
/sbin/iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT 
/sbin/iptables -A INPUT -p icmp -j ACCEPT
# 配置内网白名单
/sbin/iptables -A INPUT -s 10.0.0.0/8 -j ACCEPT
/sbin/iptables -A INPUT -s 172.16.0.0/12 -j ACCEPT
/sbin/iptables -A INPUT -s 192.168.0.0/16 -j ACCEPT
# 配置外网白名单
/sbin/iptables -A INPUT -s 180.168.36.198 -j ACCEPT 
/sbin/iptables -A INPUT -s 180.168.34.218 -j ACCEPT 
/sbin/iptables -A INPUT -s 222.73.202.251 -j ACCEPT 
# 控制端口
/sbin/iptables -A INPUT -p tcp --dport 80 -j ACCEPT 
/sbin/iptables -A INPUT -p tcp --dport 22 -j ACCEPT
# 拒绝其它
/sbin/iptables -A INPUT -j DROP 
/sbin/iptables -A FORWARD -j DROP 
# 开放出口
/sbin/iptables -A OUTPUT -j ACCEPT 


chmod 755 /root/start_iptables.sh
crontab -e
0 0 * * * /root/start_iptables.sh

CentOS7 配置 iptables

# 配置好 yum 源以后安装 iptables-service
yum install -y iptables-services
# 停止 firewalld
systemctl stop firewalld
# 禁止 firewalld 自动启动
systemctl disable firewalld
# 启动 iptables
systemctl start iptables
# 将 iptables 设置为开机自动启动,以后即可通过 iptables-service 控制 iptables 服务
systemctl enable iptables

开启 Linux 路由转发

# 关闭路由转发
echo 0 > /proc/sys/net/ipv4/ip_forward            
# 开启路由转发
echo 1 > /proc/sys/net/ipv4/ip_forward            
# 注意以上操作仅当前有效,计算机重启后无效,修改 / etc/sysctl.conf 配置文件,可以实现永久有效规则
echo 'net.ipv4.ip_forward=1' >> /etc/sysctl.conf

配置 NAT Tunnel

俗称跳板机

# 配置 iptables
vi /etc/sysconfig/iptables
*nat
:PREROUTING ACCEPT [6:504]
:INPUT ACCEPT [0:0]
:OUTPUT ACCEPT [1:52]
:POSTROUTING ACCEPT [1:52]

-A POSTROUTING -j MASQUERADE
COMMIT

*filter
:INPUT DROP [1029028:53321694]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [44723822:21524638399]

#zabbix
-A INPUT -s 10.65.200.90 -p tcp -m tcp --dport 10050 -j ACCEPT

-A INPUT -p tcp --dport 22 -j ACCEPT

# For keepalived:
# allow vrrp
-A INPUT -p vrrp -j ACCEPT
-A INPUT -p igmp -j ACCEPT
# allow multicast
-A INPUT -d 224.0.0.18 -j ACCEPT

# Drop packets from spoofed networks
-A INPUT -s 169.254.0.0/16   -j DROP
#-A INPUT -s 10.0.0.0/8       -j DROP
#-A INPUT -s 127.0.0.0/8      -j DROP
-A INPUT -s 224.0.0.0/4      -j DROP
-A INPUT -d 224.0.0.0/4      -j DROP
-A INPUT -s 240.0.0.0/5      -j DROP
-A INPUT -d 240.0.0.0/5      -j DROP
-A INPUT -s 0.0.0.0/8        -j DROP
-A INPUT -d 0.0.0.0/8        -j DROP
-A INPUT -d 239.255.255.0/24 -j DROP
-A INPUT -d 255.255.255.255  -j DROP

# Drop Invalid packets
-A INPUT   -m state --state INVALID -j DROP
#-A FORWARD -m state --state INVALID -j DROP
-A OUTPUT  -m state --state INVALID -j DROP

# Drop Bogus TCP packets
-A INPUT -p tcp --tcp-flags SYN,FIN SYN,FIN -j DROP
-A INPUT -p tcp --tcp-flags SYN,RST SYN,RST -j DROP

-A INPUT -p icmp --icmp-type echo-reply -j ACCEPT
-A INPUT -p icmp --icmp-type destination-unreachable -j ACCEPT
-A INPUT -p icmp --icmp-type redirect -j ACCEPT
-A INPUT -p icmp --icmp-type echo-request -j ACCEPT
-A INPUT -p icmp --icmp-type time-exceeded -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
COMMIT

# 重启生效并检查
service iptables restart
iptables -nvL

常用的 iptables 配置文件

# dnat
-A PREROUTING -s 1.1.1.1/30,2.2.2.2 -p tcp --dport 10000 -j DNAT --to-destination 10.71.12.89:80
# snat
-A POSTROUTING -d 1.1.1.1 -j SNAT --to-source 2.2.2.2
-A POSTROUTING -o bond1 -j SNAT --to-source 3.3.3.3
-A POSTROUTING -j MASQUERADE
# multiport
-A INPUT -s 10.65.200.90 -p tcp -m multiport --dports 10050,10051 -j ACCEPT
-A INPUT -s 10.65.200.90 -p tcp -m multiport --dports 10050:10060 -j ACCEPT

Ansible 管理 iptables

核心先规范好 iptables 模板格式,然后利用 ansible blockinfile 中的 marker 批量修改

*filter
:INPUT DROP [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]

# lvs-tun
-A INPUT -p ipv4 -j ACCEPT

# keepalived vrrp
-A INPUT -p vrrp -j ACCEPT
-A INPUT -p igmp -j ACCEPT
-A INPUT -d 224.0.0.18 -j ACCEPT

# http/https
-A INPUT -p tcp --dport 80 -j ACCEPT
-A INPUT -p tcp --dport 443 -j ACCEPT

# BEGIN ANSIBLE MANAGED BLOCK iptables
-A INPUT -s xxx -p tcp --dport 22 -j ACCEPT
-A INPUT -s xxx -p tcp --dport 22 -j ACCEPT
-A INPUT -s xxx -p tcp --dport 22 -j ACCEPT
# END ANSIBLE MANAGED BLOCK iptables

# BEGIN ANSIBLE MANAGED BLOCK jumphost
-A INPUT -s 10.10.8.151/32     -p tcp --dport 22 -j ACCEPT
-A INPUT -s 10.10.70.149 -p tcp -m tcp --dport 38422 -j ACCEPT
# END ANSIBLE MANAGED BLOCK jumphost

# BEGIN ANSIBLE MANAGED BLOCK userdefined
# END ANSIBLE MANAGED BLOCK userdefined

# Drop packets from spoofed networks
-A INPUT -s 169.254.0.0/16   -j DROP
-A INPUT -s 224.0.0.0/4      -j DROP
-A INPUT -d 224.0.0.0/4      -j DROP
-A INPUT -s 240.0.0.0/5      -j DROP
-A INPUT -d 240.0.0.0/5      -j DROP
-A INPUT -s 0.0.0.0/8        -j DROP
-A INPUT -d 0.0.0.0/8        -j DROP
-A INPUT -d 239.255.255.0/24 -j DROP
-A INPUT -d 255.255.255.255  -j DROP

# Drop Invalid packets
-A INPUT   -m state --state INVALID -j DROP
#-A FORWARD -m state --state INVALID -j DROP
-A OUTPUT  -m state --state INVALID -j DROP

# Drop Bogus TCP packets
-A INPUT -p tcp --tcp-flags SYN,FIN SYN,FIN -j DROP
-A INPUT -p tcp --tcp-flags SYN,RST SYN,RST -j DROP

-A INPUT -p icmp --icmp-type echo-reply -j ACCEPT
-A INPUT -p icmp --icmp-type destination-unreachable -j ACCEPT
-A INPUT -p icmp --icmp-type redirect -j ACCEPT
-A INPUT -p icmp --icmp-type echo-request -j ACCEPT
-A INPUT -p icmp --icmp-type time-exceeded -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
COMMIT
---
- hosts: all
  become: yes
  gather_facts: no

  tasks:
    - name: backup iptables
      copy:
        src: /etc/sysconfig/iptables
        dest: /etc/sysconfig/iptables.bak
        remote_src: yes

    - name: add iptables line for internal logic service
      blockinfile:
        path: /etc/sysconfig/iptables
        insertafter: '^:OUTPUT ACCEPT'
        marker: "# {mark} iptables whitelist only for internal logic service"
        block: |
          -A INPUT -s 10.0.0.0/8 -j ACCEPT

    - name: reload service
      service: name=iptables state=reloaded
      tags:
        - reload

转载:
iptables 配置实践
iptables/netfilter详解中文手册
Linux的iptables常用配置范例
iptables 配置实践
企业防火墙之iptables