Linux防火墙

文章目录

  • 1 安全技术和防火墙
    • 1.1 安全技术
    • 1.2 防火墙的分类
    • 1.3 网络架构
  • 2 Linux防火墙的基本认识
    • 2.1 Netfilter
    • 2.2 防火墙工具介绍
      • 2.2.1 iptables
      • 2.2.2 firewalld
      • 2.2.3 nftables
    • 2.3 netfilter 中五个勾子函数和报文流向
    • 2.4 iptables的组成
    • 2.5 netfilter 完整流程
  • 3 iptables
    • 3.1 iptables 规则说明
      • 3.1.1 iptables 规则生成
      • 3.1.2 iptables 规则添加时考量点
      • 3.1.3 环境准备
    • 3.2 iptables 用法说明
    • 3.3 iptables 基本匹配条件
    • 3.4 iptables 扩展匹配条件
      • 3.4.1 隐式扩展
      • 3.4.2 显示扩展及相关模块
        • 3.4.2.2 iprange扩展
        • 3.4.2.3 mac扩展
        • 3.4.2.4 string扩展
        • 3.4.2.5 time扩展
        • 3.4.2.6 connlimit扩展
        • 3.4.2.7 limit扩展
        • 3.4.2.8 state扩展
    • 3.5 Target
    • 3.6 规则优化最佳实践
    • 3.7 iptables规则保存
    • 3.8 网络防火墙
      • 3.8.1 FORWARD 链实现内外网络的流量控制
      • 3.8.2 NAT表
      • 3.8.3 SNAT
      • 3.8.4 DNAT
      • 3.8.5 REDIRECT 转发
  • 4 firewalld服务
    • 4.1 firewalld 介绍
    • 4.2 firewall-cmd 命令
    • 4.3 其它规则
      • 4.3.1 管理rich规则
      • 4.3.2 rich规则实现
      • 4.3.3 伪装和端口转发
  • 5 nft
    • 5.1 nft介绍
    • 5.2 nft 相关概念
    • 5.3 nft 常见用法
      • 5.3.1 nft 命令格式
      • 5.3.2 查看
      • 5.3.3 增加
      • 5.3.4 删
      • 5.3.5 改
    • 5.4 nft 实战案例
      • 5.4.1 创建表和删除表
      • 5.4.2 创建链
      • 5.4.3 创建规则
        • 5.4.3.1 创建常规链规则
        • 5.4.3.2 创建基本链规则
      • 5.4.4 插入链的指定位置
        • 5.4.4.1 使用index 来指定规则的索引
        • 5.4.4.2 使用handle来指定规则的句柄
      • 5.4.5 删除规则
        • 5.4.5.1 删除单个规则
        • 5.4.5.2 删除所有规则
      • 5.4.6 列出规则
        • 5.4.6.1 列出所有规则
        • 5.4.6.2 列出指定表中的所有规则
        • 5.4.6.3 列出指定链中的所有规则
      • 5.4.7 备份还原
      • 5.4.8 迁移iptables规则到nft

1 安全技术和防火墙

1.1 安全技术

  • 入侵检测系统(Intrusion Detection Systems):特点是不阻断任何网络访问,量化、定位来自内外网络的威胁情况,主要以提供报告和事后监督为主,提供有针对性的指导措施和安全决策依据。一般采用旁路部署方式
  • 入侵防御系统(Intrusion Prevention System):以透明模式工作,分析数据包的内容如:溢出攻击、拒绝服务攻击、木马、蠕虫、系统漏洞等进行准确的分析判断,在判定为攻击行为后立即予以阻断,主动而有效的保护网络的安全,一般采用在线部署方式
  • 防火墙( FireWall ):隔离功能,工作在网络或主机边缘,对进出网络或主机的数据包基于一定的规则检查,并在匹配某规则时由规则定义的行为进行处理的一组功能的组件,基本上的实现都是默认情况下关闭所有的通过型访问,只开放允许访问的策略
    Linux防火墙_第1张图片

1.2 防火墙的分类

按网络协议划分:

  • 网络层防火墙:OSI模型下四层,又称为包过滤防火墙
  • 应用层防火墙/代理服务器:代理网关,OSI模型七层
    包过滤防火墙
    Linux防火墙_第2张图片
    网络层对数据包进行选择,选择的依据是系统内设置的过滤逻辑,被称为访问控制列表(ACL),通过检查数据流中每个数据的源地址,目的地址,所用端口号和协议状态等因素,或它们的组合来确定是否允许该数据包通过
    优点:对用户来说透明,处理数据快且易于维护
    缺点:无法检查应用层数据,如病毒等
    应用层防火墙
    Linux防火墙_第3张图片
    应用层防火墙/代理服务型防火墙,也称为代理服务器(Proxy Server)
    将所有跨越防火墙的网络通信链路分为两段
    内外用户的访问都是通过代理服务器上的”链接“来实现
    优点:在应用层对数据进行检查,比较安全
    缺点:增加防火墙的负载
    提示:现在生产环境中使用的防火墙一般都是二者结合体,即先检查网络数据,通过之后再送到应用层去检查

1.3 网络架构

Linux防火墙_第4张图片

2 Linux防火墙的基本认识

2.1 Netfilter

Linux防火墙_第5张图片
Linux防火墙是由Netfilter组件提供的,Netfilter工作在内核空间,集成在Linux内核中
Netfilter是Linux 2.4.x之后新一代的Linux防火墙机制,是Linux内核的一个子系统。Netfilter采用模块化设计,具有良好的可扩充性,提供扩展网络服务的结构化底层框架。Netfilter与IP协议栈是无缝契合,并允许对数据进行过滤、地址转换、处理等操作
Netfilter官网文档:https://netfilter.org/documentation/

2.2 防火墙工具介绍

2.2.1 iptables

由软件包iptables提供的命令行工具,工作在用户空间,用来编写规则,写好的规则被送往netfilter,告诉内核如何去处理信息包

2.2.2 firewalld

从CentOS 7 版开始引入了新的前端管理工具
软件包:

  • firewalld
  • firewalld-config
    管理工具:
  • firewall-cmd 命令行工具
  • firewall-config 图形工具

2.2.3 nftables

此软件是CentOS 8 新特性,它重用了netfilter框架的许多部分,例如连接跟踪和NAT功能。它还保留了命令法和基本iptables设计的几个部分,例如表,链和规则。就像iptables一样,表充当链的容器,并且链包含单独的规则,这些规则可以执行操作,例如丢弃数据包,移至下一个规则或跳至新链。
从用户的角度来看,nftables添加了一个名为nft的新工具,该工具替代了iptables,arptables和etables所有其它工具。从体系结构的角度来看,它还替换了内核中处理数据包过滤规则集运行时评估的那些部分。
CentOS 8 支持三种防火墙服务:iptables,firewalld,nftables

2.3 netfilter 中五个勾子函数和报文流向

Netfilter在内核中选取五个位置放了五个hook(勾子)function(INPUT、OUTPUT、FORWARD、PREROUTING、POSTROUTING),而这五个hook function向用户开放,用户可以通过一个命令工具(iptables)向其写入规则
由信息过滤表(table)组成,包含控制IP包处理的规则集(rules),规则被分组放在链(chain)上
Linux防火墙_第6张图片
提示:从Linux kernel 4.2版以后,Netfilter在prerouting前加了一个ingress勾子函数。可以使用这个新的入口挂钩来过滤来自第二层的流量,这个新挂钩比预路由要早,基本上是tc命令(流量控制工具)的替代品
三种报文流向

  • 流入本机:PREROUTING --> INPUT --> 用户空间进程
  • 流出本机:用户空间进程 --> OUTPUT --> POSTROUTING
  • 转发:PREROUTING --> FORWARD --> POSTROUTING

2.4 iptables的组成

iptables由五个表table和五个链chain以及一些规则组成
Linux防火墙_第7张图片
链 chain:

  • 内置链:每个内置链对应于一个勾子函数
  • 自定义链:用于对内置链进行扩展或补充,可实现更灵活的规则组织管理机制;只有Hook勾子调用自定义链时,才生效

五个内置链chain:
INPUT,OUTPUT,FORWARD,PREROUTING,POSTROUTING

五个表table: filter、nat、mangle、raw、security

  • filter表:过滤规则表,根据预定义的规则过滤符合条件的数据包,默认表
  • nat表:network address translation 地址转换规则表
  • mangle:修改数据标记位规则表
  • raw:关闭启用的连接追踪机制,加快封包穿越防火墙速度
  • security:用于强制访问控制(MAC)网络规则,由Linux安全模块(如SELinux)实现
    优先级由高到低的顺序为
    security --> raw --> mangle --> nat --> filter

表和链的对应关系
Linux防火墙_第8张图片
数据包过滤匹配流程
Linux防火墙_第9张图片
内核中数据包的传输过程

  • 当一个数据包进入网卡时,数据包首先进入PREROUTING链,内核根据数据包目的IP判断是否需要转送出去
  • 如果数据包是进入本机的,数据包就会沿着图向下移动,到达INPUT链。数据包到达INPUT链后,任何进程都会接收到它。本机上运行的程序可以发送数据包,这些数据包经过OUTPUT链,然后到达POSTROUTING链输出
  • 如果数据包是要转发出去的,且内核允许转发,数据包就会向右移动,经过FORWARD链,然后到达POSTROUTING链输出
    范例:
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         
[root@centos8 ~]#iptables -vnL -t nat
Chain PREROUTING (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain POSTROUTING (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         
[root@centos8 ~]#iptables -vnL -t mangle 
Chain PREROUTING (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain POSTROUTING (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         
[root@centos8 ~]#iptables -vnL -t raw
Chain PREROUTING (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         
[root@centos8 ~]#iptables -vnL -t security
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         

#CentOS 6 不支持INPUT链
[root@centos6 ~]# iptables -vnL -t nat
Chain PREROUTING (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain POSTROUTING (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         

2.5 netfilter 完整流程

Linux防火墙_第10张图片

3 iptables

3.1 iptables 规则说明

3.1.1 iptables 规则生成

规则rule:根据规则的匹配条件尝试匹配报文,对匹配成功的报文根据规则定义的处理动作作出处理,规则在链接上的次序即为其检查时的生效次序
匹配条件:默认为与条件,同时满足
基本匹配:IP,端口,TCP的Flags(SYN,ACK等)
扩展匹配:通过复高级功能匹配
处理动作:称为target,跳转目标

  • 内建处理动作:ACCPET,DROP,REJECT,SANT,DANT,MASQUERADE,MARK,LOG…
  • 自定义处理动作:自定义chain,利用分类管理复杂情形
    规则要添加在链上,才生效;添加在自定义链上不会自动生效

3.1.2 iptables 规则添加时考量点

  • 要实现哪种功能:判断添加在哪张表上
  • 报文流经的的路径:判断添加在哪个链上
  • 报文的流向,判断源和目的
  • 匹配规则:业务需要

3.1.3 环境准备

CentOS 7,8:
systemctl stop firewalld.service
systemctl disable firewalld.service

或者
systemctl disable --now firewalld.service

CentOS 6
service iptables stop
chkconfig iptables off

3.2 iptables 用法说明

帮助:man 8 iptables
格式:
iptables [-t table] {-A|-C|-D} chain rule-specification

   ip6tables [-t table] {-A|-C|-D} chain rule-specification

   iptables [-t table] -I chain [rulenum] rule-specification

   iptables [-t table] -R chain rulenum rule-specification

   iptables [-t table] -D chain rulenum

   iptables [-t table] -S [chain [rulenum]]

   iptables [-t table] {-F|-L|-Z} [chain [rulenum]] [options...]

   iptables [-t table] -N chain

   iptables [-t table] -X [chain]

   iptables [-t table] -P chain target

   iptables [-t table] -E old-chain-name new-chain-name

   rule-specification = [matches...] [target]

   match = -m matchname [per-match-options]

   target = -j targetname [per-target-options]

范例:filter表中的INPUT规则
Linux防火墙_第11张图片
iptables命令格式详解

iptables [-t table] SUBCOMMAND chain [-m matchname [per-match-options]]
-j targetname [per-target-options]

1、-t table:指定表
nat,mangle,raw,security,filter默认
2、SUBCOMMAND:子命令
链管理类:
-N:new,自定义一条新的规则链
-E:重命名自定义链;引用计数不为0的自定义链不能够被重命名,也不能被删除
-X:delete,删除自定义的空的规则链

-P:policy,设置默认策略;对filter表中的链而言,其默认策略由:ACCEPT:接受,DROP:丢弃

创建自定义链:
创建自定义链
添加链规则
将自定义链关联至对应的内置链

删除自定义链:
删除内置链中的自定义链
清空自定义链
删除自定义链

范例:

[root@centos8 ~]#iptables -N web_chain
[root@centos8 ~]#iptables -N web_chain -t nat
[root@centos8 ~]#iptables -X web_chain -t nat
[root@centos8 ~]#iptables -E web_chain WEB_CHAIN
[root@centos8 ~]#iptables -A WEB_CHAIN -s 10.0.0.6 -p tcp -m multiport --dports 80,443 -j REJECT
[root@centos8 ~]#iptables -R WEB_CHAIN 1 -s 10.0.0.6 -p tcp -m multiport --dports 80,443,8080 -j REJECT
[root@centos8 ~]#iptables -vnL WEB_CHAIN 
Chain WEB_CHAIN (0 references)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 REJECT     tcp  --  *      *       10.0.0.6             0.0.0.0/0            multiport dports 80,443,8080 reject-with icmp-port-unreachable
[root@centos8 ~]#iptables -A INPUT -j WEB_CHAIN     
[root@centos8 ~]#iptables -D INPUT 1
[root@centos8 ~]#iptables -D WEB_CHAIN 1
[root@centos8 ~]#iptables -X WEB_CHAIN 

范例:创建自定义链实现WEB的访问控制

[root@centos8 ~]#iptables -A INPUT -s 10.0.0.1 -j ACCEPT
[root@centos8 ~]#iptables -A INPUT -i lo -j ACCEPT
[root@centos8 ~]#iptables -A INPUT -j REJECT
[root@centos8 ~]#iptables -vnL 
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         
  250 14636 ACCEPT     all  --  *      *       10.0.0.1             0.0.0.0/0           
    0     0 ACCEPT     all  --  lo     *       0.0.0.0/0            0.0.0.0/0           
    1    76 REJECT     all  --  *      *       0.0.0.0/0            0.0.0.0/0            reject-with icmp-port-unreachable

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         
[root@centos8 ~]#iptables -N web_chain
[root@centos8 ~]#iptables -E web_chain WEB_CHAIN
[root@centos8 ~]#iptables -A WEB_CHAIN -p tcp -m multiport --dports 80,443,8080 -j ACCEPT
[root@centos8 ~]#iptables -I INPUT 3 -s 10.0.0.0/24 -j WEB_CHAIN
[root@centos8 ~]#iptables -A WEB_CHAIN -p icmp -j ACCEPT
[root@centos8 ~]#iptables -I WEB_CHAIN 2 -s 10.0.0.6 -j RETURN

[root@centos8 ~]#iptables -vnL --line-numbers
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
num   pkts bytes target     prot opt in     out     source               destination         
1     1281 84673 ACCEPT     all  --  *      *       10.0.0.1             0.0.0.0/0           
2        0     0 ACCEPT     all  --  lo     *       0.0.0.0/0            0.0.0.0/0           
3       41  3420 WEB_CHAIN  all  --  *      *       10.0.0.0/24          0.0.0.0/0           
4       39  3076 REJECT     all  --  *      *       0.0.0.0/0            0.0.0.0/0            reject-with icmp-port-unreachable

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
num   pkts bytes target     prot opt in     out     source               destination         

Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
num   pkts bytes target     prot opt in     out     source               destination         

Chain WEB_CHAIN (1 references)
num   pkts bytes target     prot opt in     out     source               destination         
1        0     0 ACCEPT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            multiport dports 80,443,8080
2       15  1252 RETURN     all  --  *      *       10.0.0.6             0.0.0.0/0           
3       24  2016 ACCEPT     icmp --  *      *       0.0.0.0/0            0.0.0.0/0           

[root@centos6 ~]#curl 10.0.0.8
centos8 website
[root@centos6 ~]# ping -c1 10.0.0.8
PING 10.0.0.8 (10.0.0.8) 56(84) bytes of data.
From 10.0.0.8 icmp_seq=1 Destination Port Unreachable

--- 10.0.0.8 ping statistics ---
1 packets transmitted, 0 received, +1 errors, 100% packet loss, time 0ms

范例:删除自定义链

#无法直接删除自定义链,删除自定义链和创建的顺序相反
[root@centos8 ~]#iptables -D INPUT 3
[root@centos8 ~]#iptables -F WEB_CHAIN 
[root@centos8 ~]#iptables -X WEB_CHAIN

[root@centos8 ~]#iptables -vnL --line-numbers
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
num   pkts bytes target     prot opt in     out     source               destination         
1     2209  137K ACCEPT     all  --  *      *       10.0.0.1             0.0.0.0/0           
2        0     0 ACCEPT     all  --  lo     *       0.0.0.0/0            0.0.0.0/0           
3      280 26444 REJECT     all  --  *      *       0.0.0.0/0            0.0.0.0/0            reject-with icmp-port-unreachable

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
num   pkts bytes target     prot opt in     out     source               destination         

Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
num   pkts bytes target     prot opt in     out     source               destination         

查看类:
-L:List,列出指定链上的所有规则,本选项须置后
-n:numberic,以数字格式显示地址和端口号
-v:verbose,详细信息
-vv:更详细
-x:exactly,显示计数器结果的精确值,而非单位转换后的易读值
–line-numbers:显示规则的序号
-S selected,以iptables-save 命令格式显示链上规则

常用组合:
-vnL
-vvnxL --line-numbers

规划管理类:
-A:append,追加
-I:insert,插入,要指明插入至的规则编号,默认为第一条
-D:delete,删除
(1)指明规则序号
(2)指明规则本身
-R:replace,替换指定链上的指定规则编号
-F:flush,清空指定的规则链
-Z:zero,置零
iptables的每条规则都有两个计数器
(1)匹配到的报文的个数
(2)匹配到的所有报文的大小之和
范例:
[root@centos8 ~]#iptables -F OUTPUT

3、chain:
PREROUTING,INPUT,OUTPUT,FORWARD,POSTROUTING

4、匹配条件

  • 基本:通用的,PARAMETERS
  • 扩展:需加载模块,MATCH EXTENTIONS

5、处理动作:
-j targetname [per-target-options]

简单动作:
ACCEPT
DROP

扩展动作:
REJECT:–reject-with:icmp-port-unreachable默认
RETURN:返回调用链
REDIRECT:端口重定向
LOG:记录日志,dmesg
MARK:做防火墙标记
DNAT:目标地址转换
SNAT:源地址转换
MASQUERADE:地址伪装
自定义链

3.3 iptables 基本匹配条件

基本匹配条件:无需加载模块,由iptables/netfilter自行提供

[!] -s, --source address[/mask][,...]:源IP地址或者不连续的IP地址
[!] -d, --destination address[/mask][,...]:目标IP地址或者不连续的IP地址
[!] -p, --protocol protocol:指定协议,可使用数字如0(all)
	protocol: tcp, udp, icmp, icmpv6, udplite,esp, ah, sctp, mh or“all“
	参看:/etc/protocols
[!] -i, --in-interface name:报文流入的接口;只能应用于数据报文流入环节,只应用于INPUT、FORWARD
、PREROUTING链
[!] -o, --out-interface name:报文流出的接口;只能应用于数据报文流出的环节,只应用于FORWARD、
OUTPUT、POSTROUTING链

范例:

[root@centos8 ~]#iptables -A INPUT -s 10.0.0.6,10.0.0.10 -j REJECT
[root@centos8 ~]#iptables -I INPUT -i lo -j ACCEPT
[root@centos8 ~]#curl 10.0.0.8
www.kobe.com on 10.0.0.8
[root@centos8 ~]#curl 127.0.0.1
www.kobe.com on 10.0.0.8

[root@centos6 ~]# ping -c1 10.0.0.8
PING 10.0.0.8 (10.0.0.8) 56(84) bytes of data.
64 bytes from 10.0.0.8: icmp_seq=1 ttl=64 time=0.769 ms

--- 10.0.0.8 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.769/0.769/0.769/0.000 ms
[root@centos6 ~]# curl 10.0.0.8
www.kobe.com on 10.0.0.8
[root@centos7 ~]# ping -c1 10.0.0.8
PING 10.0.0.8 (10.0.0.8) 56(84) bytes of data.
64 bytes from 10.0.0.8: icmp_seq=1 ttl=64 time=1.43 ms

--- 10.0.0.8 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 1.435/1.435/1.435/0.000 ms
[root@centos7 ~]# curl 10.0.0.8
www.kobe.com on 10.0.0.8

3.4 iptables 扩展匹配条件

扩展匹配条件:需要加载扩展模块(/usr/lib64/xtables/*.so),方可生效
扩展模块的查看帮助:man iptables-extensions
扩展匹配条件:

  • 隐式扩展
  • 显示扩展

3.4.1 隐式扩展

iptables 在使用-p选项指定了特定的协议时,无需再用-m选项指明扩展模的扩展机制,不需要手动加载扩展模块
tcp 协议的扩展选项

[!] --source-port, --sport port[:port]:匹配报文源端口,可为端口连续范围
[!] --destination-port,--dport port[:port]:匹配报文目标端口,可为连续范围
[!] --tcp-flags mask comp
	mask 需检查的标志位列表,用,分隔 , 例如 SYN,ACK,FIN,RST
	comp 在mask列表中必须为1的标志位列表,无指定则必须为0,用,分隔tcp协议的扩展选项

范例:

--tcp-flags	SYN,ACK,FIN,RST	 SYN	表示要检查的标志位为SYN,ACK,FIN,RST四个,其中SYN必须为1,余下的必须为0,第一次握手
--tcp-flags 	SYN,ACK,FIN,RST	 SYN,ACK 	第二次握手

#错误包
--tcp-flags	ALL	ALL
--tcp-flags	ALL	NONE

[!] --syn:用于匹配第一次握手,相当于:–tcp-flags SYN,ACK,FIN,RST SYN

范例:

[root@centos8 ~]#iptables -A INPUT -p tcp --tcp-flags SYN,ACK,FIN,RST SYN -j REJECT
等价于
[root@centos8 ~]#iptables -A INPUT -p tcp --syn -j REJECT

udp 协议的扩展选项

[!] --source-port, --sport port[:port]:匹配报文的源端口或端口范围
[!] --destination-port,--dport port[:port]:匹配报文的目标端口或端口范围

icmp 协议的扩展选项

[!] --icmp-type {type[/code]|typename}
	type/code
		0/0 echo-reply icmp应答
		8/0 echo-request icmp请求

范例:

[root@centos8 ~]#iptables -A INPUT -s 10.0.0.6 -p tcp --dport 21:23 -j REJECT

[root@centos8 ~]#iptables -A INPUT -s 10.0.0.6 -p icmp --icmp-type 8 -j REJECT
[root@centos6 ~]# ping 10.0.0.8 -c1
PING 10.0.0.8 (10.0.0.8) 56(84) bytes of data.
From 10.0.0.8 icmp_seq=1 Destination Port Unreachable

--- 10.0.0.8 ping statistics ---
1 packets transmitted, 0 received, +1 errors, 100% packet loss, time 1ms
[root@centos8 ~]#ping 10.0.0.6 -c1
PING 10.0.0.6 (10.0.0.6) 56(84) bytes of data.
64 bytes from 10.0.0.6: icmp_seq=1 ttl=64 time=0.500 ms

--- 10.0.0.6 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.500/0.500/0.500/0.000 ms

3.4.2 显示扩展及相关模块

显示扩展即必须使用-m选项指明要调用的扩展模块名称,需要手动加载扩展模块

[-m matchname [per-match-options] ]
**扩展模块的使用帮助:**
 * CentOS 7,8: man iptables-extensions
 * CentOS 6: man iptables

#### 3.4.2.1 multiport 扩展
以离散方式定义多端口匹配,最多指定15个端口
```sh
#指定多个源端口
[!] --source-ports,--sports port[,port|port:port]...

#指定多个目标端口
[!] --destination-ports,--dports port[,port|,port:port]...

#多个源或目标端
[!] --ports port[,port|,port:port]...

范例:

[root@centos8 ~]#iptables -A INPUT -s 172.16.0.0/16 -d 172.16.100.10 -p tcp -m multiport --dports 20:23,80 -j ACCEPT

[root@centos8 ~]#iptables -A INPUT -s 10.0.0.6 -p tcp -m multiport --dports 445,139 -j REJECT

3.4.2.2 iprange扩展

指明连续的(但一般不是整个网络)IP地址范围

[!] --src-range from[-to] 源IP地址范围
[!] --dst-range from[-to] 目标IP地址范围

范例:

[root@centos8 ~]#iptables -A INPUT -d 172.16.1.100 -p tcp --dport 80 -m iprange --src-range 172.16.1.5-172.16.1.10 -j DROP

3.4.2.3 mac扩展

mac模块可以指明源MAC地址,适用于:PREROUTING,FORWARD,INPUT chains

[!] --mac-source xx:xx:xx:xx:xx:xx

范例:

[root@centos8 ~]#iptables -A INPUT -s 10.0.0.6 -m mac --mac-source 00:0c:29:1a:fd:94 -j REJECT
[root@centos8 ~]#iptables -A INPUT -s 10.0.0.6 -j REJECT

3.4.2.4 string扩展

对报文中的应用层数据做字符串模式匹配检测

--algo {bm|kmp}	字符串匹配检测算法
--from offset		开始偏移
--to offset			结束偏移
[!]	--string	pattern		要检测的字符串模式
[!]	--hex-string	pattern	要检测的字符串模式,16进制格式

范例:

[root@centos8 ~]#iptables -A OUTPUT -p tcp --sport 80 -m string --algo bm --from 62 --string "kobe" -j REJECT
[root@centos6 ~]# curl 10.0.0.8
^C

3.4.2.5 time扩展

注意:CentOS 8 此模块有问题
根据将报文到达的时间与指定的时间范围进行匹配

--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...] 星期几,1 – 7 分别表示星期一到星期日
--kerneltz:内核时区(当地时间),不建议使用此选项,CentOS 7 系统默认为 UTC
注意: centos6 不支持kerneltz ,--localtz指定本地时区(默认)

范例:CentOS 8 的time模块有问题

[root@centos8 ~]#rpm -ql iptables|grep time
/usr/lib64/xtables/libxt_time.so
[root@centos8 ~]#iptables -A INPUT -m time --timestart 12:30 --timestop 13:30 -j ACCEPT 
iptables v1.8.2 (nf_tables): Couldn't load match `time':No such file or directory

Try `iptables -h' or 'iptables --help' for more information.

范例:每周的周六和周日的9点到18点禁止上网

[root@centos7 ~]# iptables -A INPUT -s 172.16.0.0/16 -d 10.0.0.8 -p tcp --dport 80 -m time --timestart 1:00 --timestop 10:00 --weekdays Sat,Sun -j REJECT

3.4.2.6 connlimit扩展

根据每客户端IP做并发连接数数量匹配
可防止Dos(Denial of service,拒绝服务)攻击

--connlimit-upto N	#连接的数量小于等于N时匹配
--connlimit-above N		#连接的数量大于N时匹配

范例:

[root@centos8 ~]#iptables -A INPUT -d 10.0.0.8 -p tcp --dport 22 -m connlimit --connlimit-above 2 -j REJECT

3.4.2.7 limit扩展

基于收发报文的速率做匹配,令牌桶过滤器

--limit-burst number		#前多少个包不限制
--limit	#[/second|/minute|/hour|/day]

范例:

[root@centos8 ~]#iptables -A INPUT -d 10.0.0.8 -p icmp --icmp-type 8 -m limit --limit 10/minute --limit-burst 5 -j ACCEPT 
[root@centos8 ~]#iptables -A INPUT -p icmp -j REJECT 

[root@centos8 ~]#iptables -A INPUT -p icmp -m limit --limit-burst 10 --limit 20/minute -j ACCEPT 
[root@centos8 ~]#iptables -A INPUT -p icmp -j REJECT
[root@centos6 ~]# ping 10.0.0.8
PING 10.0.0.8 (10.0.0.8) 56(84) bytes of data.
64 bytes from 10.0.0.8: icmp_seq=1 ttl=64 time=0.429 ms
64 bytes from 10.0.0.8: icmp_seq=2 ttl=64 time=1.26 ms
64 bytes from 10.0.0.8: icmp_seq=3 ttl=64 time=0.416 ms
64 bytes from 10.0.0.8: icmp_seq=4 ttl=64 time=0.453 ms
64 bytes from 10.0.0.8: icmp_seq=5 ttl=64 time=0.435 ms
64 bytes from 10.0.0.8: icmp_seq=6 ttl=64 time=0.487 ms
64 bytes from 10.0.0.8: icmp_seq=7 ttl=64 time=0.570 ms
64 bytes from 10.0.0.8: icmp_seq=8 ttl=64 time=0.684 ms
64 bytes from 10.0.0.8: icmp_seq=9 ttl=64 time=0.505 ms
64 bytes from 10.0.0.8: icmp_seq=10 ttl=64 time=0.883 ms
64 bytes from 10.0.0.8: icmp_seq=11 ttl=64 time=0.486 ms
64 bytes from 10.0.0.8: icmp_seq=12 ttl=64 time=0.734 ms
64 bytes from 10.0.0.8: icmp_seq=13 ttl=64 time=0.457 ms
64 bytes from 10.0.0.8: icmp_seq=14 ttl=64 time=0.778 ms
From 10.0.0.8 icmp_seq=15 Destination Port Unreachable
From 10.0.0.8 icmp_seq=16 Destination Port Unreachable
64 bytes from 10.0.0.8: icmp_seq=17 ttl=64 time=0.529 ms
From 10.0.0.8 icmp_seq=18 Destination Port Unreachable
From 10.0.0.8 icmp_seq=19 Destination Port Unreachable
From 10.0.0.8 icmp_seq=20 Destination Port Unreachable
64 bytes from 10.0.0.8: icmp_seq=21 ttl=64 time=0.700 ms
From 10.0.0.8 icmp_seq=22 Destination Port Unreachable
From 10.0.0.8 icmp_seq=23 Destination Port Unreachable
64 bytes from 10.0.0.8: icmp_seq=24 ttl=64 time=0.632 ms
From 10.0.0.8 icmp_seq=25 Destination Port Unreachable
From 10.0.0.8 icmp_seq=26 Destination Port Unreachable

3.4.2.8 state扩展

state 扩展模块,可以根据“连接追踪机制”去检查连接的状态,较耗资源
conntrack机制:追踪本机上的请求和响应之间的关系
状态类型:

  • NEW:新发出请求;连接追踪信息库中不存在此连接的相关信息条目,因此,将其识别为第一次发出的请求
  • ESTABLISHED:NEW状态之后,连接追踪信息库中为其建立的条目失效之前期间内所进行的通信状态
  • RELATED:新发起的但与已有连接相关联的连接,如:ftp协议中的数据连接与命令连接之间的关系
  • INVALID:无效的连接,如flag标记不正确
  • UNTRACKED:未进行追踪的连接,如:raw表中关闭追踪
    已经追踪到的并记录下来的连接信息库
[root@centos8 ~]#iptables -A INPUT -s 10.0.0.1 -j ACCEPT
[root@centos8 ~]#iptables -A INPUT -i lo -j ACCEPT
#下面两条规则是综合实现已经建立连接的可以保持连接,但新请求拒绝
[root@centos8 ~]#iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
[root@centos8 ~]#iptables -A INPUT -m state --state NEW -j REJECT

[root@centos6 ~]# ping 10.0.0.8
PING 10.0.0.8 (10.0.0.8) 56(84) bytes of data.
64 bytes from 10.0.0.8: icmp_seq=1 ttl=64 time=0.868 ms

[root@centos7 ~]# ping -c1 10.0.0.8
PING 10.0.0.8 (10.0.0.8) 56(84) bytes of data.
From 10.0.0.8 icmp_seq=1 Destination Port Unreachable

--- 10.0.0.8 ping statistics ---
1 packets transmitted, 0 received, +1 errors, 100% packet loss, time 0ms

[root@centos8 ~]#ping 10.0.0.6
PING 10.0.0.6 (10.0.0.6) 56(84) bytes of data.
64 bytes from 10.0.0.6: icmp_seq=1 ttl=64 time=0.319 ms
^C
--- 10.0.0.6 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.319/0.319/0.319/0.000 ms
[root@centos8 ~]#ping 10.0.0.7
PING 10.0.0.7 (10.0.0.7) 56(84) bytes of data.
64 bytes from 10.0.0.7: icmp_seq=1 ttl=64 time=0.813 ms
^C
--- 10.0.0.7 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.813/0.813/0.813/0.000 ms
[root@centos7 ~]# curl 10.0.0.8
curl: (7) Failed connect to 10.0.0.8:80; Connection refused

[root@centos8 ~]#cat /proc/net/nf_conntrack
ipv4     2 icmp     1 29 src=10.0.0.6 dst=10.0.0.8 type=8 code=0 id=62214 src=10.0.0.8 dst=10.0.0.6 type=0 code=0 id=62214 mark=0 zone=0 use=2
ipv4     2 tcp      6 299 ESTABLISHED src=10.0.0.1 dst=10.0.0.8 sport=4088 dport=22 src=10.0.0.8 dst=10.0.0.1 sport=22 dport=4088 [ASSURED] mark=0 zone=0 use=2
ipv4     2 tcp      6 431945 ESTABLISHED src=10.0.0.8 dst=10.0.0.1 sport=22 dport=10285 src=10.0.0.1 dst=10.0.0.8 sport=10285 dport=22 [ASSURED] mark=0 zone=0 use=2

调整连接追踪功能所能够容纳的最大连接数

[root@centos8 ~]#cat /proc/sys/net/netfilter/nf_conntrack_max 
26624
[root@centos8 ~]#cat /proc/sys/net/nf_conntrack_max 
26624

查看连接跟踪有多少条目

[root@centos8 ~]#cat /proc/sys/net/netfilter/nf_conntrack_count 
2

不同的协议的连接追踪时长

[root@centos8 ~]#ll /proc/sys/net/netfilter/
total 0
-rw-r--r-- 1 root root 0 Sep 16 20:47 nf_conntrack_acct
-rw-r--r-- 1 root root 0 Sep 16 20:47 nf_conntrack_buckets
-rw-r--r-- 1 root root 0 Sep 16 20:47 nf_conntrack_checksum
-r--r--r-- 1 root root 0 Sep 16 20:47 nf_conntrack_count
-rw-r--r-- 1 root root 0 Sep 16 20:47 nf_conntrack_dccp_loose
-rw-r--r-- 1 root root 0 Sep 16 20:47 nf_conntrack_dccp_timeout_closereq
-rw-r--r-- 1 root root 0 Sep 16 20:47 nf_conntrack_dccp_timeout_closing
-rw-r--r-- 1 root root 0 Sep 16 20:47 nf_conntrack_dccp_timeout_open
-rw-r--r-- 1 root root 0 Sep 16 20:47 nf_conntrack_dccp_timeout_partopen
-rw-r--r-- 1 root root 0 Sep 16 20:47 nf_conntrack_dccp_timeout_request
-rw-r--r-- 1 root root 0 Sep 16 20:47 nf_conntrack_dccp_timeout_respond
-rw-r--r-- 1 root root 0 Sep 16 20:47 nf_conntrack_dccp_timeout_timewait
-rw-r--r-- 1 root root 0 Sep 16 20:47 nf_conntrack_events
-rw-r--r-- 1 root root 0 Sep 16 20:47 nf_conntrack_expect_max
-rw-r--r-- 1 root root 0 Sep 16 20:47 nf_conntrack_generic_timeout
-rw-r--r-- 1 root root 0 Sep 16 20:47 nf_conntrack_helper
-rw-r--r-- 1 root root 0 Sep 16 20:47 nf_conntrack_icmp_timeout
-rw-r--r-- 1 root root 0 Sep 16 20:47 nf_conntrack_log_invalid
-rw-r--r-- 1 root root 0 Sep 16 20:47 nf_conntrack_max
-rw-r--r-- 1 root root 0 Sep 16 20:47 nf_conntrack_sctp_timeout_closed
-rw-r--r-- 1 root root 0 Sep 16 20:47 nf_conntrack_sctp_timeout_cookie_echoed
-rw-r--r-- 1 root root 0 Sep 16 20:47 nf_conntrack_sctp_timeout_cookie_wait
-rw-r--r-- 1 root root 0 Sep 16 20:47 nf_conntrack_sctp_timeout_established
-rw-r--r-- 1 root root 0 Sep 16 20:47 nf_conntrack_sctp_timeout_heartbeat_acked
-rw-r--r-- 1 root root 0 Sep 16 20:47 nf_conntrack_sctp_timeout_heartbeat_sent
-rw-r--r-- 1 root root 0 Sep 16 20:47 nf_conntrack_sctp_timeout_shutdown_ack_sent
-rw-r--r-- 1 root root 0 Sep 16 20:47 nf_conntrack_sctp_timeout_shutdown_recd
-rw-r--r-- 1 root root 0 Sep 16 20:47 nf_conntrack_sctp_timeout_shutdown_sent
-rw-r--r-- 1 root root 0 Sep 16 20:47 nf_conntrack_tcp_be_liberal
-rw-r--r-- 1 root root 0 Sep 16 20:47 nf_conntrack_tcp_loose
-rw-r--r-- 1 root root 0 Sep 16 20:47 nf_conntrack_tcp_max_retrans
-rw-r--r-- 1 root root 0 Sep 16 20:47 nf_conntrack_tcp_timeout_close
-rw-r--r-- 1 root root 0 Sep 16 20:47 nf_conntrack_tcp_timeout_close_wait
-rw-r--r-- 1 root root 0 Sep 16 20:47 nf_conntrack_tcp_timeout_established
-rw-r--r-- 1 root root 0 Sep 16 20:47 nf_conntrack_tcp_timeout_fin_wait
-rw-r--r-- 1 root root 0 Sep 16 20:47 nf_conntrack_tcp_timeout_last_ack
-rw-r--r-- 1 root root 0 Sep 16 20:47 nf_conntrack_tcp_timeout_max_retrans
-rw-r--r-- 1 root root 0 Sep 16 20:47 nf_conntrack_tcp_timeout_syn_recv
-rw-r--r-- 1 root root 0 Sep 16 20:47 nf_conntrack_tcp_timeout_syn_sent
-rw-r--r-- 1 root root 0 Sep 16 20:47 nf_conntrack_tcp_timeout_time_wait
-rw-r--r-- 1 root root 0 Sep 16 20:47 nf_conntrack_tcp_timeout_unacknowledged
-rw-r--r-- 1 root root 0 Sep 16 20:47 nf_conntrack_timestamp
-rw-r--r-- 1 root root 0 Sep 16 20:47 nf_conntrack_udp_timeout
-rw-r--r-- 1 root root 0 Sep 16 20:47 nf_conntrack_udp_timeout_stream
dr-xr-xr-x 1 root root 0 Sep 16 20:47 nf_log
-rw-r--r-- 1 root root 0 Sep 16 20:47 nf_log_all_netns

说明:

  • 连接追踪,需要加载模块:mdprobe nf_conntrack_ipv4(或者加一条关于state的规则)
  • 当服务器连接多于最大连接数时dmesg可以观察到:kernel:ip_conntrack:table full,dropping packet错误,并且导致建立TCP连接很慢
  • 各种状态的超时后,链接会从表中删除
    范例:
[root@centos8 ~]#echo 1 > /proc/sys/net/netfilter/nf_conntrack_max 
[root@centos8 ~]#tail -1 /var/log/messages
Sep 16 20:58:10 centos8 kernel: nf_conntrack: nf_conntrack: table full, dropping packet

连接过多的解决方法两个:
(1)加大nf_conntrack_max值

net.nf_conntrack_max = 393216
net.netfilter.nf_conntrack_max = 393216

(2)降低nf_conntrack timeout 时间

vim /etc/sysctl.conf
net.netfilter.nf_conntrack_tcp_timeout_established = 300
net.netfilter.nf_conntrack_tcp_timeout_time_wait = 120
net.netfilter.nf_conntrack_tcp_timeout_close_wait = 60
net.netfilter.nf_conntrack_tcp_timeout_fin_wait = 120
iptables -t nat -L -n

格式:

[!] --state state

范例:不允许10.0.0.7 访问本机,但本机可以访问10.0.0.7

[root@centos8 ~]#iptables -S
-P INPUT ACCEPT
-P FORWARD ACCEPT
-P OUTPUT ACCEPT
-A INPUT -s 10.0.0.1/32 -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT ! -s 10.0.0.7/32 -m state --state NEW -j ACCEPT
-A INPUT -m state --state ESTABLISHED -j ACCEPT
-A INPUT -j REJECT --reject-with icmp-port-unreachable
[root@centos8 ~]#

范例:

#实现其他主机可以访问本机的ssh和httpd服务
[root@centos8 ~]#iptables -A INPUT -d 10.0.0.8/32 -p tcp -m multiport --dports 22,80 -m state --state NEW,ESTABLISHED -j ACCEPT
[root@centos8 ~]#iptables -A OUTPUT -s 10.0.0.8/32 -p tcp -m multiport --sports 22,80 -m state --state ESTABLISHED -j ACCEPT

#实现其他主机不能访问本机的任何服务,本机可以访问其他的主机
[root@centos8 ~]#iptables -A INPUT -m state --state ESTABLISHED -j ACCEPT
[root@centos8 ~]#iptables -A INPUT -m state --state NEW -j REJECT

案例:开放被动模式的ftp服务
CentOS 8 此模块有bug
(1)装载ftp连接追踪的专用模块:
跟踪模块路径:/lib/modules/kernelversion/kernel/net/netfilter

vim /etc/sysconfig/iptables-config
IPTABLES_MODULES="nf_conntrack_ftp"
modprobe nf_conntrack_ftp

(2)放行请求报文:
命令连接:NEW,ESTABLISHED
数据连接:RELATED,ESTABLISHED

iptables -I INPUT -d LocalIP -p tcp -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -d LocalIP -p tcp --dport 21 -m state --state NEW -j ACCEPT

(3)放行响应报文:

iptables -I OUTPUT -s LocalIP -p tcp -m state --state ESTABLISHED -j ACCEPT

范例:开放被动模式的ftp服务示例

yum install vsftpd
systemctl start vsftpd
modprobe nf_conntrack_ftp
iptables -F
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -p tcp --dport 21 -m state --state NEW -j ACCEPT
iptables -A OUTPUT -m state --state ESTABLISHED -j ACCEPT
iptables -P INPUT DROP
iptables -P OUTPUT DROP
iptables -vnL

3.5 Target

target 包括以下类型:

自定义链:ACCEPT,DROP,REJECT,RETURN,LOG,SNAT,DNAT,REDIRECT,MASQUERADE
LOG:非中断target,本身不拒绝和允许,放在拒绝和允许规则前,并将日志记录在/var/log/messages系统日志中
--log-level level	级别:debug,info,notice,warning,error,crit,alert,emerg
--log-prefix prefix	日志前缀,用于区别不同的日志,最多29个字符

范例:

[root@centos8 ~]#iptables -A INPUT -s 10.0.0.0/24 -p tcp -m multiport --dports 80,21:23 -m state --state NEW -j LOG --log-prefix "New connection: "
[root@centos8 ~]#tail -f /var/log/messages
Sep 16 22:06:39 centos8 kernel: New connection: IN=eth0 OUT= MAC=00:0c:29:8d:3e:41:00:0c:29:94:f3:95:08:00 SRC=10.0.0.7 DST=10.0.0.8 LEN=60 TOS=0x00 PREC=0x00 TTL=64 ID=55621 DF PROTO=TCP SPT=55560 DPT=80 WINDOW=29200 RES=0x00 SYN URGP=0 
Sep 16 22:07:14 centos8 kernel: New connection: IN=eth0 OUT= MAC=00:0c:29:8d:3e:41:00:0c:29:1a:fd:94:08:00 SRC=10.0.0.6 DST=10.0.0.8 LEN=60 TOS=0x00 PREC=0x00 TTL=64 ID=679 DF PROTO=TCP SPT=50962 DPT=22 WINDOW=14600 RES=0x00 SYN URGP=0 
Sep 16 22:07:30 centos8 kernel: New connection: IN=eth0 OUT= MAC=00:0c:29:8d:3e:41:00:0c:29:1a:fd:94:08:00 SRC=10.0.0.6 DST=10.0.0.8 LEN=60 TOS=0x00 PREC=0x00 TTL=64 ID=47809 DF PROTO=TCP SPT=53598 DPT=80 WINDOW=14600 RES=0x00 SYN URGP=0 
Sep 16 22:07:34 centos8 kernel: New connection: IN=eth0 OUT= MAC=00:0c:29:8d:3e:41:00:0c:29:1a:fd:94:08:00 SRC=10.0.0.6 DST=10.0.0.8 LEN=60 TOS=0x00 PREC=0x00 TTL=64 ID=53331 DF PROTO=TCP SPT=53600 DPT=80 WINDOW=14600 RES=0x00 SYN URGP=0

范例:

[root@centos8 ~]#iptables -R INPUT 2 -p tcp --dport 21 -m state --state NEW -j
LOG --log-prefix "ftp new link: "
[root@centos8 ~]#tail -f /var/log/messages
Dec 21 10:02:31 centos8 kernel: ftp new link: IN=eth0 OUT=
MAC=00:0c:29:f9:8d:90:00:0c:29:10:8a:b1:08:00 SRC=192.168.39.6 DST=192.168.39.8
LEN=60 TOS=0x00 PREC=0x00 TTL=64 ID=15556 DF PROTO=TCP SPT=53706 DPT=21
WINDOW=14600 RES=0x00 SYN URGP=0

3.6 规则优化最佳实践

1.安全放行所有入站和出站的状态为ESTABLISHED状态连接,建议放在第一条,效率更高
2.谨慎放行入站的请求
3.有特殊目的限制访问功能,要在放行规则之前加以拒绝
4.同类规则(访问同一应用,比如:http),匹配范围小的放在前面,用于特殊处理
5.不同类的规则(访问不同应用,一个是http,另一个是mysql),匹配范围大的放在前面,效率更高

-s 10.0.0.6 -p tcp --dport 3306 -j REJECT
-s 172.16.0.0/16 -p tcp --dport 80 -j REJECT

6.应该将那些可由一条规则能够描述的多个规则合并为一条,减少规则数量,提高检查效率
7.设置默认策略,建议白名单(只放行特定连接)

  • iptables -P,不建议,容易出现“自杀现象”
  • 规则的最后定义规则作为默认策略,推荐使用,放在最后一条

3.7 iptables规则保存

使用iptables命令定义的规则,手动删除之前,其生效期限为kernel存活期限
持久保存规则:
CentOS 7,8

iptables-save > /PATH/TO/SOME_RULES_FILE

CentOS 6

#将规则覆盖保存至/etc/sysconfig/iptables文件中
service iptables save

加载规则
CentOS 7,8 重新载入预存规则文件中规则:

iptables-restore < /PATH/FROM/SOME_RULES_FILE

iptables-restore选项

-n,--noflush:不清除原有规则
-t,--test:仅分析生成规则集,但不提交

CentOS 6:

#会自动从/etc/sysconfig/iptables 重新载入规则
service iptables restart

开机自动重载规则

  • 用脚本保存各iptables命令;让此脚本开机后自动运行
    /etc/rc.d/rc.local文件中添加脚本路径/PATH/TO/SOME_SCRIPT_FILE
  • 用规则文件保存各规则,开机时自动载入此规则文件中的规则
    在/etc/rc.d/rc.local文件添加
iptables-restore < /PATH/FROM/IPTABLES_RULES_FILE
定义Unit File,CentOS 7,8 可以安装iptables-services 实现iptables.service
范例:CentOS 7,8 使用iptables-services
[root@centos8 ~]#yum -y install iptables-services
[root@centos8 ~]#cp /etc/sysconfig/iptables{,.bak}

#保存现在的规则到文件中方法1
[root@centos8 ~]#/usr/libexec/iptables/iptables.init save

#保存现在的规则到文件中方法2
[root@centos8 ~]#iptables-save > /etc/sysconfig/iptables

#开机启动
[root@centos8 ~]#systemctl enable iptables.service
[root@centos8 ~]#systemctl mask firewalld.service nftables.service		

3.8 网络防火墙

iptables/netfilter 利用filter表的FORWARD链,可以充当网络防火墙
注意的问题:
(1)请求-响应报文均会经由FORWARD链,要注意规则的方向性
(2)如果要启用conntrack机制,建议将双方向的状态为ESTABLISHED的报文直接放行

3.8.1 FORWARD 链实现内外网络的流量控制

范例:实现内网可以访问外网,反之禁止
Linux防火墙_第12张图片

#环境准备
[root@internet ~]#hostname -I
192.168.0.6
[root@internet ~]#route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
192.168.0.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0
169.254.0.0 0.0.0.0 255.255.0.0 U 1002 0 0 eth0
0.0.0.0 192.168.0.8 0.0.0.0 UG 0 0 0 eth0

[root@firewall ~]#hostname -I
10.0.0.8 192.168.0.8
[root@firewall ~]#vim /etc/sysctl.conf
net.ipv4.ip_forward=1
[root@firewall ~]#sysctl -p

[root@lanserver1 ~]#hostname -I
10.0.0.7
[root@lanserver1 ~]#route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 10.0.0.8 0.0.0.0 UG 100 0 0 eth0
10.0.0.0 0.0.0.0 255.255.255.0 U 100 0 0 eth0

[root@lanserver2 ~]#hostname -I
10.0.0.17
[root@lanserver2 ~]#route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 10.0.0.8 0.0.0.0 UG 100 0 0 eth0
10.0.0.0 0.0.0.0 255.255.255.0 U 100 0 0 eth0

#方法1 通过标准模块实现内网访问外网,反之禁止
[root@firewall ~]#iptables -AFORWARD -j REJECT
[root@firewall ~]#iptables -IFORWARD -s 10.0.0.0/24 -p tcp --dport 80 -j
ACCEPT
[root@firewall ~]#iptables -IFORWARD -d 10.0.0.0/24 -p tcp --sport 80 -j
ACCEPT
[root@firewall ~]#iptables -I FORWARD -s 10.0.0.0/24 -p icmp --icmp-type 8 -j
ACCEPT
[root@firewall ~]#iptables -I FORWARD -d 10.0.0.0/24 -p icmp --icmp-type 0 -j
ACCEPT

[root@firewall ~]#iptables -vnL --line-numbers

#方法2 利用state模块实现内网访问可以访问外网,反之禁止
[root@firewall ~]#iptables -DFORWARD 1
[root@firewall ~]#iptables -DFORWARD 2
[root@firewall ~]#iptables -vnL --line-numbers


[root@firewall ~]#iptables -IFORWARD -m state --state RELATED,ESTABLISHED -j
ACCEPT
[root@firewall ~]#iptables -vnL --line-numbers

[root@lanserver1 ~]#ping 192.168.0.6 -c1
PING 192.168.0.6 (192.168.0.6) 56(84) bytes of data.
64 bytes from 192.168.0.6: icmp_seq=1 ttl=63 time=2.20 ms
[root@lanserver2 ~]#curl 192.168.0.6
internet
[root@internet ~]#ping 10.0.0.7 -c1
PING 10.0.0.7 (10.0.0.7) 56(84) bytes of data.
From 192.168.0.8 icmp_seq=1 Destination Port Unreachable
[root@internet ~]#curl 10.0.0.7
curl: (7) couldn't connect to host
#利用state模块实现允许内网可以访问外网所有资源
[root@firewall ~]#iptables -DFORWARD 2
[root@firewall ~]#iptables -DFORWARD 2
[root@firewall ~]#iptables -IFORWARD 2 -s 10.0.0.0/24 -m state --state NEW -j
ACCEPT
[root@firewall ~]#iptables -vnL --line-numbers

[root@lanserver1 ~]#ping 192.168.0.6 -c1
PING 192.168.0.6 (192.168.0.6) 56(84) bytes of data.
64 bytes from 192.168.0.6: icmp_seq=1 ttl=63 time=2.26 ms

[root@lanserver2 ~]#curl 192.168.0.6
internet
[root@lanserver2 ~]#ssh 192.168.0.6
The authenticity of host '192.168.0.6 (192.168.0.6)' can't be established.
RSA key fingerprint is SHA256:ldHMw3UFehPuE3bgtMHIX5IxRRTM7fwC4iZ0Qqglcys.
RSA key fingerprint is MD5:8c:44:d9:3d:22:54:62:d8:27:77:d5:06:09:58:76:92.
Are you sure you want to continue connecting (yes/no)?

[root@internet ~]#curl 10.0.0.7
curl: (7) couldn't connect to host
[root@internet ~]#ping 10.0.0.7 -c1
PING 10.0.0.7 (10.0.0.7) 56(84) bytes of data.
From 192.168.0.8 icmp_seq=1 Destination Port Unreachable

[root@internet ~]#ssh 10.0.0.7
ssh: connect to host 10.0.0.7 port 22: Connection refused

#允许内网指定主机被外网访问
[root@firewall ~]#iptables -IFORWARD 3 -d 10.0.0.7 -p tcp --dport 80 -j ACCEPT
[root@firewall ~]#iptables -vnL --line-numbers

[root@internet ~]#curl 10.0.0.7
lanserver1
[root@internet ~]#ping 10.0.0.7 -c1
PING 10.0.0.7 (10.0.0.7) 56(84) bytes of data.
From 192.168.0.8 icmp_seq=1 Destination Port Unreachable

[root@internet ~]#curl 10.0.0.17
curl: (7) couldn't connect to host

范例:内部可以访问外部,外部禁止访问内部

[root@internet-host ~]#hostname -I
10.0.0.6
[root@internet-host ~]#route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
10.0.0.0 0.0.0.0 255.255.255.0 U 1 0 0 eth0
0.0.0.0 10.0.0.8 0.0.0.0 UG 0 0 0 eth0

[root@firewall-host ~]#hostname -I
10.0.0.8 192.168.100.8

[root@lan-host ~]#hostname -I
192.168.100.7
[root@lan-host ~]#route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 192.168.100.8 0.0.0.0 UG 100 0 0 eth0
192.168.100.0 0.0.0.0 255.255.255.0 U 100 0 0 eth0

[root@firewall-host ~]#vim /etc/sysctl.conf
net.ipv4.ip_forward=1
[root@firewall-host ~]#sysctl -p
[root@firewall-host ~]#iptables -A FORWARD -d 192.168.100.0/24 -m state --state
NEW -j REJECT

范例:针对内部的特定服务可以允许外部访问,其它服务禁止访问

[root@firewall-host ~]#iptables -I FORWARD -d 192.168.100.0/24 -p tcp --dport 80
-j ACCEPT
[root@firewall-host ~]#iptables -vnL FORWARD --line-numbers

3.8.2 NAT表

Linux防火墙_第13张图片
NAT: network address translation,支持PREROUTING,INPUT,OUTPUT,POSTROUTING四个链

请求报文:修改源/目标IP,由定义如何修改
响应报文:修改源/目标IP,根据跟踪机制自动实现
NAT的实现分为下面类型:

  • SNAT:source NAT ,支持POSTROUTING, INPUT,让本地网络中的主机通过某一特定地址访问外部网络,实现地址伪装,请求报文:修改源IP
  • DNAT:destination NAT 支持PREROUTING , OUTPUT,把本地网络中的主机上的某服务开放给外部网络访问(发布服务和端口映射),但隐藏真实IP,请求报文:修改目标IP
  • PNAT: port nat,端口和IP都进行修改

3.8.3 SNAT

SNAT:基于nat表的target,适用于固定的公网IP
SNAT选项:

  • –to-source [ipaddr[-ipaddr]][:port[-port]]
  • –random
iptables -t nat -A POSTROUTING -s LocalNET ! -d LocalNET -j SNAT --to-source ExtIP

注意:需要开启ip_forward
范例:

iptables -t nat -A POSTROUTING -s 10.0.0.0/24 ! -d 10.0.0.0/24 -j SNAT --to-source 172.18.1.6-172.18.1.9

MASQUERADE:基于nat表的target,适用于动态的公网IP,如:拨号网络
MASQUERADE选项:

  • –to-ports port[-port]
  • –random
iptables -t nat -A POSTROUTING -s LocalNET ! -d LocalNET -j MASQUERADE

范例:

iptables -t nat -A POSTROUTING -s 10.0.0.0/24 ! -d 10.0.0.0/24 -j MASQUERADE

范例:查看本地主机访问公网时使用的IP

[root@centos8 ~]#curl http://ip.sb
39.164.140.134

[root@centos8 ~]#curl http://ipinfo.io/ip/
39.164.140.134

[root@centos8 ~]#curl http://ifconfig.me
39.164.140.134

[root@centos8 ~]#curl -L http://tool.lu/ip
当前IP: 39.164.140.134
归属地: 中国 河南 郑州

[root@centos8 ~]#curl -sS --connect-timeout 10 -m 60 https://www.bt.cn/Api/getIpAddress
39.164.140.134[root@centos8 ~]#

[root@centos8 ~]#curl cip.cc
IP	: 39.164.140.134
地址	: 中国  河南  鹤壁
运营商	: 移动

数据二	: 河南省郑州市 | 移动

数据三	: 

URL	: http://www.cip.cc/39.164.140.134

范例:SNAT
Linux防火墙_第14张图片

#启用路由转发
[root@firewall ~]#vim /etc/sysctl.conf
net.ipv4.ip_forward=1
[root@firewall ~]#sysctl -p

#针对专线静态公共IP
[root@firewall ~]#iptables -t nat -A POSTROUTING -s 10.0.0.0/24 -j SNAT --tosource
192.168.0.8

#针对拨号网络和专线静态公共IP
[root@firewall ~]#iptables -t nat -A POSTROUTING -s 10.0.0.0/24 -j MASQUERADE

#查看监听端口
[root@firewall ~]#ss -ntl

#内网可以访问外网
[root@lanserver1 ~]#curl 192.168.0.6
internet

#外网不可以访问内网
[root@internet ~]#curl 10.0.0.7
curl: (7) Failed to connect to 10.0.0.7: Network is unreachable

#在外网服务器查看到是firewalld的地址在访问
[root@internet ~]#tail -f /var/log/httpd/access_log
192.168.0.8 - - [08/Jul/2020:17:36:54 +0800] "GET / HTTP/1.1" 200 9 "-"
"curl/7.29.0"

#查看转换状态信息
[root@firewall ~]#cat /proc/net/nf_conntrack
ipv4 2 tcp 6 112 TIME_WAIT src=10.0.0.7 dst=192.168.0.6 sport=58384
dport=80 src=192.168.0.6 dst=192.168.0.8 sport=80 dport=58384 [ASSURED] mark=0
zone=0 use=2

范例:实现SNAT

[root@internet-host ~]#hostname -I
10.0.0.6
[root@internet-host ~]#route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
10.0.0.0 0.0.0.0 255.255.255.0 U 1 0 0 eth0

#启用路由转发
[root@firewall ~]#vim /etc/sysctl.conf
net.ipv4.ip_forward=1
[root@firewall ~]#sysctl -p

[root@firewall-host ~]#hostname -I
10.0.0.8 192.168.100.8
[root@firewall-host ~]#sysctl -a |grep net.ipv4.ip_forward
net.ipv4.ip_forward = 1

[root@lan-host ~]#hostname -I
192.168.100.7
[root@lan-host ~]#route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 192.168.100.8 0.0.0.0 UG 100 0 0 eth0
192.168.100.0 0.0.0.0 255.255.255.0 U 100 0 0 eth0

[root@firewall-host ~]#iptables -t nat -A POSTROUTING -s 192.168.100.0/24 -j
SNAT --to-source 10.0.0.8
[root@firewall-host ~]#iptables -vnL -t nat

[root@lan-host ~]#curl 10.0.0.6
internet Server
[root@internet-host ~]#curl 192.168.100.7
curl: (7) Failed to connect to 192.168.100.7: Network is unreachable

[root@internet-host ~]#tail /var/log/httpd/access_log
10.0.0.8 - - [21/Mar/2020:16:31:35 +0800] "GET / HTTP/1.1" 200 16 "-"
"curl/7.29.0"

[root@lan-host ~]#ping 10.0.0.6
PING 10.0.0.6 (10.0.0.6) 56(84) bytes of data.
64 bytes from 10.0.0.6: icmp_seq=1 ttl=63 time=0.989 ms
64 bytes from 10.0.0.6: icmp_seq=2 ttl=63 time=0.544 ms

[root@internet-host ~]#tcpdump -i eth0 -nn icmp
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes
16:34:30.171222 IP 10.0.0.8 > 10.0.0.6: ICMP echo request, id 24718, seq 120,
length 64
16:34:30.171255 IP 10.0.0.6 > 10.0.0.8: ICMP echo reply, id 24718, seq 120,
length 64

[root@firewall-host ~]#iptables -t nat -R POSTROUTING 1 -s 192.168.100.0/24 -j
MASQUERADE

[root@firewall-host ~]#iptables -t nat -nvL

[root@firewall-host ~]#cat /proc/net/nf_conntrack
ipv4 2 tcp 6 32 TIME_WAIT src=192.168.100.7 dst=10.0.0.6 sport=39430
dport=80 src=10.0.0.6 dst=10.0.0.8 sport=80 dport=39430 [ASSURED] mark=0 zone=0
use=2

3.8.4 DNAT

DNTA:nat表的target,适用于端口映射,即可重定向到本机,也可以支持重定向至不同主机的不同端口,但不支持多目标,即不支持负载均衡功能

DNAT选项:

  • –to-destination [ipaddr[-ipaddr]][:port[-port]]
    DNAT格式:
iptables -t nat -A PREROUTING -d ExtIP -p tcp|udp --dport PORT -j DNAT --todestination
InterSeverIP[:PORT]

注意:需要开启ip_forward
范例:DNAT
Linux防火墙_第15张图片

#启用路由转发
[root@firewall ~]#vim /etc/sysctl.conf
net.ipv4.ip_forward=1
[root@firewall ~]#sysctl -p

[root@firewall ~]#iptables -t nat -A PREROUTING -d 192.168.0.8 -p tcp --dport 80
-j DNAT --to-destination 10.0.0.7:8080

[root@internet ~]#curl 192.168.0.8
lanserver1
[root@lanserver1 ~]#tail /var/log/httpd/access_log
192.168.0.6 - - [08/Jul/2020:18:10:37 +0800] "GET / HTTP/1.1" 200 11 "-"
"curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.27.1 zlib/1.2.3
libidn/1.18 libssh2/1.4.2"

[root@firewall ~]#cat /proc/net/nf_conntrack
ipv4 2 tcp 6 117 TIME_WAIT src=192.168.0.6 dst=192.168.0.8 sport=58170
dport=80 src=10.0.0.7 dst=192.168.0.6 sport=8080 dport=58170 [ASSURED] mark=0
zone=0 use=2

范例:

iptables -t nat -A PREROUTING -d 172.16.100.6 -p tcp --dport 22 -j DNAT --to-destination 10.0.1.22
iptables -t nat -A PREROUTING -d 172.16.100.6 -p tcp --dport 80 -j DNAT --to-destination 10.0.1.22:8080

范例:

[root@firewall-host ~]#iptables -t nat -A PREROUTING -d 10.0.0.8 -p tcp --dport
80 -j DNAT --to-destination 192.168.100.7

[root@internet-host ~]#curl 10.0.0.8
lan server
[root@internet-host ~]#telnet 10.0.0.8
Trying 10.0.0.8...
telnet: connect to address 10.0.0.8: Connection refused

[root@lan-host ~]#tail -f /var/log/httpd/access_log
10.0.0.6 - - [21/Mar/2020:17:32:37 +0800] "GET / HTTP/1.1" 200 11 "-"
"curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.27.1 zlib/1.2.3
libidn/1.18 libssh2/1.4.2"

[root@lan-host ~]#tail -f /var/log/httpd/access_log
10.0.0.6 - - [21/Mar/2020:17:32:37 +0800] "GET / HTTP/1.1" 200 11 "-"
"curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.27.1 zlib/1.2.3
libidn/1.18 libssh2/1.4.2"

[root@lan-host ~]#vim /etc/httpd/conf/httpd.conf
listen 8000
[root@lan-host ~]#systemctl restart httpd

[root@firewall-host ~]#iptables -t nat -R PREROUTING 1 -d 10.0.0.8 -p tcp --
dport 80 -j DNAT --to-destination 192.168.100.7:8000

综合案例:两个私网的互通
Linux防火墙_第16张图片

3.8.5 REDIRECT 转发

REDIRECT,是NAT表的target,通过改变目标IP和端口,将接受的包转发至同一个主机的不同端口,可用于PREROUTING OUTPUT链
REDIRECT选项:

  • –to-ports port[-port]
    注意:无需开启 ip_forward
    示例:
iptables -t nat -A PREROUTING -d 172.16.100.10 -p tcp --dport 80 -j REDIRECT --to-ports 8080

范例:

[root@centos8 ~]#iptables -t nat -A PREROUTING -t tcp --dport 8000 -j REDIRECT --to-ports 80

4 firewalld服务

4.1 firewalld 介绍

firewalld 是CentOS 7.0新推出的管理netfilter的用户空间软件工具
firewalld是配置和监控防火墙规则的系统守护进程。可以实现iptables,ip6tables,etables功能
firewalld服务由firewalld包提供
firewalld支持划分区域zone,每个zone可以设置独立的防火墙规则
归入zone顺序:

  • 先根据数据包中源地址,将其纳为某个zone
  • 纳为网络接口所属zone
  • 纳入默认zone,默认为public zone,管理员可以改为其它zone
  • 网卡默认属于public zone,lo网络接口属于trusted zone
    firewalld zone 分类
    Linux防火墙_第17张图片
    预定义服务
    Linux防火墙_第18张图片
    firewalld预定义服务配置
  • firewall-cmd --get-services 查看预定义服务列表
  • /usr/lib/firewalld/services/*.xml预定义服务的配置
    firewalld三种配置方法
  • firewall-config 图形工具:需安装firewall-config包
  • firewall-cmd 命令行工具:firewalld包,默认安装
  • /etc/firewalld/配置文件,一般不建议,如:/etc/firewalld/zones/public.xml

4.2 firewall-cmd 命令

firewall-cmd格式

Usage: firewall-cmd [OPTIONS...]

常见选项

--get-zones 列出所有可用区域
--get-default-zone 查询默认区域
--set-default-zone= 设置默认区域
--get-active-zones 列出当前正使用的区域
--add-source=[--zone=] 添加源地址的流量到指定区域,如果无--zone= 选项,使
用默认区域
--remove-source= [--zone=] 从指定区域删除源地址的流量,如无--zone= 选项,
使用默认区域
--add-interface=[--zone=] 添加来自于指定接口的流量到特定区域,如果无-
-zone= 选项,使用默认区域
--change-interface=[--zone=] 改变指定接口至新的区域,如果无--zone=
选项,使用默认区域
--add-service= [--zone=] 允许服务的流量通过,如果无--zone= 选项,使用默
认区域
--add-port=[--zone=] 允许指定端口和协议的流量,如果无--zone= 选
项,使用默认区域
--remove-service= [--zone=] 从区域中删除指定服务,禁止该服务流量,如果
无--zone= 选项,使用默认区域
--remove-port=[--zone=] 从区域中删除指定端口和协议,禁止该端口
的流量,如果无--zone= 选项,使用默认区域
--reload 删除当前运行时配置,应用加载永久配置
--list-services 查看开放的服务
--list-ports 查看开放的端口
--list-all [--zone=] 列出指定区域的所有配置信息,包括接口,源地址,端口,服务等,
如果无--zone= 选项,使用默认区域

范例:

#查看默认zone
firewall-cmd --get-default-zone
#默认zone设为dmz
firewall-cmd --set-default-zone=dmz
#在internal zone 中增加源地址192.168.0.0/24的永久规则
firewall-cmd --permanent --zone=internal --add-source=192.168.0.0/24
#在internal zone中增加协议mysql的永久规则
firewall-cmd --permanent --zone=internal --add-service=mysql
#加载新规则以生效
firewall-cmd --reload

范例:配置firewalld

systemctl mask iptables
systemctl mask ip6tables
systemctl status firewalld
systemctl enable firewalld
systemctl start firewalld
firewall-cmd --get-default-zone
firewall-cmd --set-default-zone=public
firewall-cmd --permanent --zone=public --list-all
firewall-cmd --permanent --zone=public --add-port 8080/tcp
firewall-cmd ---reload

4.3 其它规则

当基本firewalld语法规则不能满足要求时,可以使用以下更复杂的规则

  • rich-rules 富规则,功能强,表达性语言
  • Direct configuration rules直接规则,灵活性差,帮助:man 5 firewalld.direct

4.3.1 管理rich规则

rich规则比基本的firewalld语法实现更强的功能,不仅实现允许/拒绝,还可以实现日志syslog和auditd,也可以实现端口转发,伪装和限制速率
规则实现顺序:

  • 该区域的端口转发,伪装规则
  • 该区域的日志规则
  • 该区域的允许规则
  • 该区域的拒绝规则
    每个匹配的规则生效,所有规则都不匹配,该区域默认规则生效
    rich语法:
rule
[source]
[destination]
service|port|protocol|icmp-block|masquerade|forward-port
[log]
[audit]
[accept|reject|drop]

帮助:man 5 firewalld.richlanguage
rich规选项*
Linux防火墙_第19张图片

4.3.2 rich规则实现

拒绝从192.168.0.100的所有流量,当address 选项使用source 或 destination时,必须用family= ipv4|ipv6

firewall-cmd --permanent --zone=public --add-rich-rule='rule family=ipv4 source address=192.168.0.100/32 reject'

限制每分钟只有两个连接到ftp服务

firewall-cmd --add-rich-rule='rule service name=ftp limit value=2/m accept'

抛弃esp(IPsec体系中的一种主要协议)协议的所有数据包

firewall-cmd --permanent --add-rich-rule='rule protocol value=esp drop'

接受所有192.68.1.0/24子网端口5900-5905范围的TCP流量

firewall-cmd --permanent --zone=vnc --add-rich-rule='rule family=ipv4 source
address=192.168.1.0/24 port port=5900-5905 protocol=tcp accept'

rich日志规则

log [prefix="" [level=] [limit value=""]

 可以是emerg,alert, crit, error, warning, notice, info, debug.
 s:秒, m:分钟, h:小时, d:天
audit [limit value=""]

范例:

#接受ssh新连接,记录日志到syslog的notice级别,每分钟最多三条信息
firewall-cmd --permanent --zone=work --add-rich-rule='rule service name="ssh"
log prefix="ssh " level="notice" limit value="3/m" accept

#从2001:db8::/64子网的DNS连接在5分钟内被拒绝,并记录到日志到audit,每小时最大记录一条信息
firewall-cmd --add-rich-rule='rule family=ipv6 source address="2001:db8::/64"
service name="dns" audit limit value="1/h" reject' --timeout=300

firewall-cmd --permanent --add-rich-rule='rule family=ipv4 source
address=172.25.X.10/32 service name="http" log level=notice prefix="NEW HTTP "
limit value="3/s" accept'
firewall-cmd --reload
tail -f /var/log/messages
curl http://serverX.example.com

4.3.3 伪装和端口转发

NAT网络地址转换,firewalld支持伪装和端口转发两种NAT方式
伪装NAT

firewall-cmd --permanent --zone= --add-masquerade
firewall-cmd --query-masquerade #检查是否允许伪装
firewall-cmd --add-masquerade #允许防火墙伪装IP
firewall-cmd --remove-masquerade #禁止防火墙伪装IP

范例:

firewall-cmd --add-rich-rule='rule family=ipv4 source address=192.168.0.0/24
masquerade'

端口转发
端口转发:将发往本机的特定端口的流量转发到本机或不同机器的另一个端口。通常要配合地址伪装才能实现

firewall-cmd --permanent --zone= --add-forward-port=port=
:proto=[:toport=][:toaddr=]

说明:toport= 和toaddr= 至少要指定一个
范例:

#转发传入的连接9527/TCP,到防火墙的80/TCP到public zone 的192.168.0.254
firewall-cmd --add-masquerade 启用伪装
firewall-cmd --zone=public --add-forwardport=
port=9527:proto=tcp:toport=80:toaddr=192.168.0.254

rich规则的port转发语法:

forward-port port= protocol=tcp|udp [to-port=] [to-addr=
]

范例:

#转发从192.168.0.0/24来的,发往80/TCP的流量到防火墙的端口8080/TCP
firewall-cmd --zone=work --add-rich-rule='rule family=ipv4 source
address=192.168.0.0/24 forward-port port=80 protocol=tcp to-port=8080'

firewall-cmd --permanent --add-rich-rule 'rule family=ipv4 source
address=172.25.X.10/32 forward-port port=443 protocol=tcp to-port=22'
firewall-cmd --reload
ssh -p 443 serverX.example.com

范例:限制ssh服务非标准端口访问

cp /usr/lib/firewalld/services/ssh.xml /etc/firewalld/services/ssh.xml
vim /etc/firewalld/services/ssh.xml

systemctl restart sshd.service
systemctl status -l sshd.service
sealert -a /var/log/audit/audit.log
semanage port -a -t ssh_port_t -p tcp 999
systemctl restart sshd.service
ss -tulpn | grep sshd
firewall-cmd --permanent --zone=work --add-source=172.25.X.0/24
firewall-cmd --permanent --zone=work --add-port=999/tcp
firewall-cmd --reload

5 nft

5.1 nft介绍

nftables是一个netfilter项目,旨在替换现有的{ip,ip6,arp,eb}tables 框架,为 {ip,ip6}tables 提供一个新的包过滤框架、一个新的用户空间实用程序(nft)和一个兼容层。它使用现有的钩子、链接跟踪系统、用户空间排队组件和 netfilter 日志子系统。
nftables主要由三个组件组成:内核实现、libnl netlink 通信和nftables 用户空间。其中内核提供了一个netlink 配置接口以及运行时规则集评估,libnl包含了与内核通信的基本函数,用户空间可以通过nft和用户进行交互。
在 Linux 内核版本高于 3.13 时可用。提供一个新的命令行工具 nft 语法与 iptables 不同。
官方Wiki:https://wiki.nftables.org
官方文档:https://www.netfilter.org/projects/nftables/manpage.html
参考文档:https://www.mankier.com/8/nft

5.2 nft 相关概念

nftables 和 iptables 一样,由表(table)、链(chain)和规则(rule)组成,其中表包含链,链包含规则,规则是真正的 action,规则由地址,接口,端口或包含当前处理数据包中的其他数据等表达式以及诸如drop, queue, continue等声明组成。
与 iptables 相比,nftables 主要有以下几个变化:

  • iptables 规则的布局是基于连续的大块内存的,即数组式布局;而 nftables 的规则采用链式布局,即数组和链表的区别
  • iptables 大部分工作在内核态完成,如果要添加新功能,只能重新编译内核;而 nftables 的大部分工作是在用户态完成的,添加新功能更加容易,不需要改内核
  • nftables不包含任何内置表和链
  • 拥有使用额外脚本的能力, 拥有一些高级的类似编程语言的能力,例如定义变量和包含外部文件
  • iptables 有内置的链,即使只需要一条链,其他的链也会跟着注册;而 nftables 不存在内置的链,可以按需注册。由于 iptables 内置了一个数据包计数器,所以即使这些内置的链是空的,也会带来性能损耗
  • 简化了 IPv4/IPv6 双栈管理
  • 原生支持集合、字典和映射

nftables 的每个表只有一个地址簇,并且只适用于该簇的数据包。表可以指定五个簇中的一个:
Linux防火墙_第20张图片
inet 同时适用于 IPv4 和 IPv6 的数据包,即统一了 ip 和 ip6 簇,可以更容易地定义规则,注:当
没有指定地址簇时,默认为ip

链是用来保存规则的,和表一样,链也需要被显示创建,因为 nftables 没有内置的链。链有以下两种类
型:

  • 基本链 : 数据包的入口点,需要指定钩子类型和优先级,相当于内置链
  • 常规链 : 不需要指定钩子类型和优先级,可以用来做跳转,从逻辑上对规则进行分类,类似于自定义链
    范例:CentOS 8.0 nftables 包
[root@centos8 ~]#rpm -qi nftables
Name        : nftables
Epoch       : 1
Version     : 0.9.0
Release     : 8.el8
Architecture: x86_64
Install Date: Wed 19 Aug 2020 06:31:07 AM CST
Group       : Unspecified
Size        : 758622
License     : GPLv2
Signature   : RSA/SHA256, Tue 02 Jul 2019 08:19:09 AM CST, Key ID 05b555b38483c65d
Source RPM  : nftables-0.9.0-8.el8.src.rpm
Build Date  : Sat 11 May 2019 11:06:46 PM CST
Build Host  : x86-01.mbox.centos.org
Relocations : (not relocatable)
Packager    : CentOS Buildsys 
Vendor      : CentOS
URL         : http://netfilter.org/projects/nftables/
Summary     : Netfilter Tables userspace utillites
Description :
Netfilter Tables userspace utilities.

[root@centos8 ~]#rpm -ql nftables
/etc/nftables
/etc/nftables/all-in-one.nft
/etc/nftables/arp-filter.nft
/etc/nftables/bridge-filter.nft
/etc/nftables/inet-filter.nft
/etc/nftables/ipv4-filter.nft
/etc/nftables/ipv4-mangle.nft
/etc/nftables/ipv4-nat.nft
/etc/nftables/ipv4-raw.nft
/etc/nftables/ipv6-filter.nft
/etc/nftables/ipv6-mangle.nft
/etc/nftables/ipv6-nat.nft
/etc/nftables/ipv6-raw.nft
/etc/sysconfig/nftables.conf
/usr/lib/.build-id
/usr/lib/.build-id/3a
/usr/lib/.build-id/3a/fa4045dde41ce6154a86f17bcc091fba562b50
/usr/lib/.build-id/6f
/usr/lib/.build-id/6f/e11fbe352ba378822d3e856ecbb2ba0fe8b8d8
/usr/lib/systemd/system/nftables.service
/usr/lib64/libnftables.so.0
/usr/lib64/libnftables.so.0.0.0
/usr/sbin/nft
/usr/share/licenses/nftables
/usr/share/licenses/nftables/COPYING
/usr/share/man/man8/nft.8.gz

[root@centos8 ~]#cat /etc/sysconfig/nftables.conf 
#
# This this will contain your nftables rules and
# is read by the systemd service when restarting
#
# These provide an iptables like set of filters
# (uncomment to include)
# include "/etc/nftables/bridge-filter.nft"
# include "/etc/nftables/inet-filter.nft"
# include "/etc/nftables/ipv4-filter.nft"
# include "/etc/nftables/ipv4-mangle.nft"
# include "/etc/nftables/ipv4-nat.nft"
# include "/etc/nftables/ipv6-filter.nft"
# include "/etc/nftables/ipv6-mangle.nft"
# include "/etc/nftables/ipv6-nat.nft"

5.3 nft 常见用法

5.3.1 nft 命令格式

Usage: nft [ options ] [ cmds... ]

Options:
  -h, --help			显示帮助
  -v, --version			显示版本信息
  -c, --check			检查命令的有效性,而不实际应用更改
  -f, --file 		包含文件内容
  -i, --interactive		从命令行读取输入
  -j, --json			以JSON格式化输出
  -n, --numeric	指定一次后,以数字方式显示网络地址(默认行为)。指定两次以数字方式显示Internet
服务(端口号)。指定三次以数字方式显示协议,用户ID和组ID。		
  -s, --stateless	省略规则集的状态信息
  -N			将IP地址转换为名称
  -a, --handle		显示规则句柄handle
  -e, --echo			Echo what has been added, inserted or replaced.
  -I, --includepath 	添加目录到包含文件的搜索路径中。默认为: /etc
  --debug 	添加调试,在level处(scanner, parser, eval, netlink,
mnl, proto-ctx, segtree, all)

nft 命令基本格式
nft 操作符 操作目标 操作内容

1 操作符:增,删,改,查,清除,插入,创建
表操作:add,delete,list,flush
链操作:add,delete,rename,list,flush,create
规则:add,delete,insert

2 操作目标:链,表,链,规则
链类型:filter,route,nat
链勾子:hook

3 操作内容:...

规则选项
Linux防火墙_第21张图片

5.3.2 查看

nft list ruleset #列出所有规则
nft list tables #列出所有表
nft list table filter #列出ip簇的filter表
nft list table inet filter #列出inet簇的filter表
nft list chain filter INPUT #列出filter表input链
以上命令后面也可以加 -nn 用于不解析IP地址和端口
加 -a 用于显示 handles

范例:

[root@centos8 ~]#nft list tables
[root@centos8 ~]#vim /etc/sysconfig/nftables.conf
#删除此行前的注释
include "/etc/nftables/inet-filter.nft"

[root@centos8 ~]#systemctl restart nftables.service 
[root@centos8 ~]#nft list tables
table inet filter

#默认为ip簇,无规则
[root@centos8 ~]#nft list table filter
Error: Could not process rule: No such file or directory
list table filter
           ^^^^^^

#指定inet簇才有规则
[root@centos8 ~]#nft list table inet filter
table inet filter {
	chain input {
		type filter hook input priority 0; policy accept;
	}

	chain forward {
		type filter hook forward priority 0; policy accept;
	}

	chain output {
		type filter hook output priority 0; policy accept;
	}
}
[root@centos8 ~]#nft list ruleset
table inet filter {
	chain input {
		type filter hook input priority 0; policy accept;
	}

	chain forward {
		type filter hook forward priority 0; policy accept;
	}

	chain output {
		type filter hook output priority 0; policy accept;
	}
}

5.3.3 增加

增加表:nft add table filter
增加链:nft add chain filter input { type filter hook input priority 0 ; } #要和hook(勾子)相关链
增加规则:nft add rule filter input tcp dport 22 accept

5.3.4 删

只需要把上面的 add 改为 delete 即可

5.3.5 改

更改链名用rename
更改规则用replace

5.4 nft 实战案例

5.4.1 创建表和删除表

[root@centos8 ~]#nft add table inet test_table
[root@centos8 ~]#nft list tables
table inet filter
table inet test_table
[root@centos8 ~]#nft delete table inet test_table
[root@centos8 ~]#nft list tables
table inet filter
[root@centos8 ~]#nft add table inet test_table

列出所有的规则

[root@centos8 ~]#nft list ruleset
table inet filter {
	chain input {
		type filter hook input priority 0; policy accept;
	}

	chain forward {
		type filter hook forward priority 0; policy accept;
	}

	chain output {
		type filter hook output priority 0; policy accept;
	}
}
table inet test_table {
}

5.4.2 创建链

现在表中还没有任何规则,需要创建一个链来保存规则
创建基本链:

[root@centos8 ~]#nft add chain inet test_table test_filter_input_chain { type filter hook input priority 0 \; }
  • 反斜线()用来转义,这样shell就不会将分号解释为美丽的结尾
  • priority 采用整数值,可以是负数,值较小的链优先处理
    创建常规链:
[root@centos8 ~]#nft add chain inet test_table test_chain

列出链:

[root@centos8 ~]#nft list table inet test_table
table inet test_table {
	chain test_filter_input_chain {
		type filter hook input priority 0; policy accept;
	}

	chain test_chain {
	}
}
[root@centos8 ~]#nft list chain inet test_table test_chain
table inet test_table {
	chain test_chain {
	}
}
[root@centos8 ~]#nft list ruleset
table inet filter {
	chain input {
		type filter hook input priority 0; policy accept;
	}

	chain forward {
		type filter hook forward priority 0; policy accept;
	}

	chain output {
		type filter hook output priority 0; policy accept;
	}
}
table inet test_table {
	chain test_filter_input_chain {
		type filter hook input priority 0; policy accept;
	}

	chain test_chain {
	}
}

5.4.3 创建规则

5.4.3.1 创建常规链规则

有了表和链之后,就可以创建规则了,规则由语句或表达式构成,包含在链中

#创建常规链的规则
[root@centos8 ~]#nft add rule inet test_table test_chain tcp dport http reject 
[root@centos8 ~]#nft list chain inet test_table test_chain
table inet test_table {
	chain test_chain {
		tcp dport http reject
	}
}

#常规链规则默认不生效
[root@centos7 ~]#curl 10.0.0.8
rft Http Server

add 表示将规则添加到链的末尾,如果想将规则添加到链的开头,可以使用 insert

[root@centos8 ~]#nft insert rule inet test_table test_chain tcp dport mysql reject

列出规则:

[root@centos8 ~]#nft list chain inet test_table test_chain
table inet test_table {
	chain test_chain {
		tcp dport mysql reject
		tcp dport http reject
	}
}
[root@centos8 ~]#nft list table inet test_table
table inet test_table {
	chain test_filter_input_chain {
		type filter hook input priority 0; policy accept;
	}

	chain test_chain {
		tcp dport mysql reject
		tcp dport http reject
	}
}

5.4.3.2 创建基本链规则

[root@centos8 ~]#nft add rule inet test_table test_filter_input_chain tcp dport http reject
[root@centos8 ~]#nft add rule inet test_table test_filter_input_chain ip saddr 10.0.0.6 reject
[root@centos8 ~]#nft list chain inet test_table test_filter_input_chain
table inet test_table {
	chain test_filter_input_chain {
		type filter hook input priority 0; policy accept;
		tcp dport http reject
		ip saddr 10.0.0.6 reject
	}
}
[root@centos7 ~]#curl 10.0.0.8
curl: (7) Failed to connect to 10.0.0.8 port 80: Connection refused

5.4.4 插入链的指定位置

将规则插入到链的指定位置,有两种方法:

5.4.4.1 使用index 来指定规则的索引

index 类似于 iptables 的-I 选项,index的值是从0 开始的
index必须指定向一个存在的规则,比如nft insert rule … index 0 就是非法的
add 表示新规则添加在索引位置的规则后面
insert表示新规则添加在索引位置的规则前面

[root@centos8 ~]#nft insert rule inet test_table test_filter_input_chain index 0 tcp dport mysql reject

[root@centos8 ~]#nft list chain inet test_table test_filter_input_chain 
table inet test_table {
	chain test_filter_input_chain {
		type filter hook input priority 0; policy accept;
		tcp dport mysql reject
		tcp dport http reject
		ip saddr 10.0.0.6 reject
	}
}
[root@centos8 ~]#nft insert rule inet test_table test_filter_input_chain index 1 udp dport 123 accept
[root@centos8 ~]#nft list chain inet test_table test_filter_input_chain 
table inet test_table {
	chain test_filter_input_chain {
		type filter hook input priority 0; policy accept;
		tcp dport mysql reject
		udp dport ntp accept
		tcp dport http reject
		ip saddr 10.0.0.6 reject
	}
}

5.4.4.2 使用handle来指定规则的句柄

在 nftables 中,句柄值是固定不变的,除非规则被删除,这就为规则提供了稳定的索引。而 index 的值是可变的,只要有新规则插入,就有可能发生变化。一般建议使用 handle 来插入新规则。
add 表示新规则添加在索引位置的规则后面, insert 表示新规则添加在索引位置的规则前面。
handle 的值可以通过参数 --handle 或者 -a 获取

[root@centos8 ~]#nft -a list chain inet test_table test_filter_input_chain 
table inet test_table {
	chain test_filter_input_chain { # handle 1
		type filter hook input priority 0; policy accept;
		tcp dport mysql reject # handle 8
		udp dport ntp accept # handle 9
		tcp dport http reject # handle 6
		ip saddr 10.0.0.6 reject # handle 7
	}
}

[root@centos8 ~]#nft add rule inet test_table test_filter_input_chain handle 7 tcp dport ftp reject
[root@centos8 ~]#nft -a list chain inet test_table test_filter_input_chain 
table inet test_table {
	chain test_filter_input_chain { # handle 1
		type filter hook input priority 0; policy accept;
		tcp dport mysql reject # handle 8
		udp dport ntp accept # handle 9
		tcp dport http reject # handle 6
		ip saddr 10.0.0.6 reject # handle 7
		tcp dport ftp reject # handle 10
	}
}

[root@centos8 ~]#nft insert rule inet test_table test_filter_input_chain handle 8 udp dport 8080 reject[root@centos8 ~]#nft -a -nn list ruleset
table inet filter { # handle 1
	chain input { # handle 1
		type filter hook input priority 0; policy accept;
	}

	chain forward { # handle 2
		type filter hook forward priority 0; policy accept;
	}

	chain output { # handle 3
		type filter hook output priority 0; policy accept;
	}
}
table inet test_table { # handle 3
	chain test_filter_input_chain { # handle 1
		type filter hook input priority 0; policy accept;
		udp dport 8080 reject # handle 11
		tcp dport 3306 reject # handle 8
		udp dport 123 accept # handle 9
		tcp dport 80 reject # handle 6
		ip saddr 10.0.0.6 reject # handle 7
		tcp dport 21 reject # handle 10
	}

	chain test_chain { # handle 2
		tcp dport 3306 reject # handle 5
		tcp dport 80 reject # handle 4
	}
}

可以在创建规则时就获取到规则的句柄值,在创建规则时同时加上参数 --echo或者-e和–handle

[root@centos8 ~]#nft -a -e add rule inet test_table test_filter_input_chain tcp dport 6379 reject
add rule inet test_table test_filter_input_chain tcp dport 6379 reject # handle 12
[root@centos8 ~]#nft -a list chain inet test_table test_filter_input_chain 
table inet test_table {
	chain test_filter_input_chain { # handle 1
		type filter hook input priority 0; policy accept;
		udp dport http-alt reject # handle 11
		tcp dport mysql reject # handle 8
		udp dport ntp accept # handle 9
		tcp dport http reject # handle 6
		ip saddr 10.0.0.6 reject # handle 7
		tcp dport ftp reject # handle 10
		tcp dport 6379 reject # handle 12
	}
}

5.4.5 删除规则

5.4.5.1 删除单个规则

单个规则只能通过其句柄删除,首先需要找到想要删除的规则句柄

[root@centos8 ~]#nft --handle list ruleset
table inet filter { # handle 1
	chain input { # handle 1
		type filter hook input priority 0; policy accept;
	}

	chain forward { # handle 2
		type filter hook forward priority 0; policy accept;
	}

	chain output { # handle 3
		type filter hook output priority 0; policy accept;
	}
}
table inet test_table { # handle 3
	chain test_filter_input_chain { # handle 1
		type filter hook input priority 0; policy accept;
		udp dport http-alt reject # handle 11
		tcp dport mysql reject # handle 8
		udp dport ntp accept # handle 9
		tcp dport http reject # handle 6
		ip saddr 10.0.0.6 reject # handle 7
		tcp dport ftp reject # handle 10
		tcp dport 6379 reject # handle 12
	}

	chain test_chain { # handle 2
		tcp dport mysql reject # handle 5
		tcp dport http reject # handle 4
	}
}

然后使用句柄值来删除该规则:

[root@centos8 ~]#nft delete rule inet test_table test_filter_input_chain handle 8
[root@centos8 ~]#nft -a list chain inet test_table test_filter_input_chain 
table inet test_table {
	chain test_filter_input_chain { # handle 1
		type filter hook input priority 0; policy accept;
		udp dport http-alt reject # handle 11
		udp dport ntp accept # handle 9
		tcp dport http reject # handle 6
		ip saddr 10.0.0.6 reject # handle 7
		tcp dport ftp reject # handle 10
		tcp dport 6379 reject # handle 12
	}
}

5.4.5.2 删除所有规则

[root@centos8 ~]#nft flush ruleset
[root@centos8 ~]#nft list ruleset

5.4.6 列出规则

可以列出所有规则,也可以列出规则的一部分

5.4.6.1 列出所有规则

[root@centos8 ~]#nft list ruleset
table inet test_table {
	chain test_filter_input_chain {
		type filter hook input priority 0; policy accept;
		ip saddr 10.0.0.6 reject
		tcp dport 6379 reject
		udp dport http-alt reject
		tcp dport 6379 reject
		ip saddr 10.0.0.6 reject
	}
}

5.4.6.2 列出指定表中的所有规则

[root@centos8 ~]#nft list table inet test_table
table inet test_table {
	chain test_filter_input_chain {
		type filter hook input priority 0; policy accept;
		ip saddr 10.0.0.6 reject
		tcp dport 6379 reject
		udp dport http-alt reject
		tcp dport 6379 reject
		ip saddr 10.0.0.6 reject
	}
}

5.4.6.3 列出指定链中的所有规则

[root@centos8 ~]#nft list chain inet test_table test_filter_input_chain 
table inet test_table {
	chain test_filter_input_chain {
		type filter hook input priority 0; policy accept;
		ip saddr 10.0.0.6 reject
		tcp dport 6379 reject
		udp dport http-alt reject
		tcp dport 6379 reject
		ip saddr 10.0.0.6 reject
	}
}

5.4.7 备份还原

规则都是临时的,要想永久生效,可以将规则备份,重启后自动加载恢复
查看service文件

[root@centos8 ~]#cat /lib/systemd/system/nftables.service 
[Unit]
Description=Netfilter Tables
Documentation=man:nft(8)
Wants=network-pre.target
Before=network-pre.target

[Service]
Type=oneshot
ProtectSystem=full
ProtectHome=true
ExecStart=/sbin/nft -f /etc/sysconfig/nftables.conf
ExecReload=/sbin/nft 'flush ruleset; include "/etc/sysconfig/nftables.conf";'
ExecStop=/sbin/nft flush ruleset
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target

备份配置并还原

[root@centos8 ~]#nft list ruleset
table inet test_table {
	chain test_filter_input_chain {
		type filter hook input priority 0; policy accept;
		ip saddr 10.0.0.6 reject
		tcp dport 6379 reject
		udp dport http-alt reject
		tcp dport 6379 reject
		ip saddr 10.0.0.6 reject
	}
}

[root@centos8 ~]#nft list ruleset > /etc/sysconfig/nftables.conf

#删除所有规则
[root@centos8 ~]#nft flush ruleset
[root@centos8 ~]#nft list ruleset

#重新启动后全部还原
[root@centos8 ~]#systemctl restart nftables.service
[root@centos8 ~]#nft list ruleset 
table inet test_table {
	chain test_filter_input_chain {
		type filter hook input priority 0; policy accept;
		ip saddr 10.0.0.6 reject
		tcp dport 6379 reject
		udp dport http-alt reject
		tcp dport 6379 reject
		ip saddr 10.0.0.6 reject
	}
}

启用指定的配置文件

[root@centos8 ~]#cat nftables2.conf
table inet test2_table {
	chain test2_filter_input_chain {
		type filter hook input priority 0; policy accept;
		ip saddr { 10.0.0.1, 10.0.0.10 } accept
		tcp dport { http, nfs,ssh } reject
	}
}

#-f 指定规则配置文件,如果已经有规则,是追加至现有规则后
[root@centos8 ~]#nft -f nftables2.conf
[root@centos8 ~]#nft list ruleset
table inet test2_table {
	chain test2_filter_input_chain {
		type filter hook input priority 0; policy accept;
		ip saddr { 10.0.0.1, 10.0.0.10 } accept
		tcp dport { ssh, http, nfs } reject
	}
}

5.4.8 迁移iptables规则到nft

  1. To save the existing rules to a file, run below command:
# iptables-save > rules.iptables
  1. Move the step1 file to CentOS/RHEL 8 Server via scp or ftp. You can use vi editor as well to copy the content from CentOS/RHEL 6 or 7 machine.
  2. Run the below command to generate the nft rules file on CentOS/RHEL 8 with iptables rules file.
# iptables-restore-translate -f rules.iptables > rules.nft
  1. Load the rules in CentOS/RHEL 8 machine, make sure nftables service is running on the
    system.
# nft -f rules.nft  ### load the rule via nft to nftables.
  1. To Display rule in CentOS/RHEL 8 Server .
# nft list ruleset

You can see the rules have been migrated from CentOS/RHEL 6 or 7 to CentOS/RHEL 8 server now and can test them as well

你可能感兴趣的:(Linux运维,linux)