Linux防火墙---iptables
防火墙iptables
1. 安全技术
-
入侵检测与管理系统IDS(Intrusion Detection Systems)
特点是不阻断任何网络访问,量化、定位来自内外网络的威胁情况,主要以提供报告和事后监督为主,提供有针对性的指导措施和安全决策依据。一般采用旁路部署方式
-
入侵防御系统IPS(Intrusion Prevention System)
以透明模式工作,分析数据包的内容如:溢出攻击、拒绝服务攻击、木马、蠕虫、系统漏洞等进行准确的分析判断,在判定为攻击行为后立即予以阻断,主动而有效的保护网络的安全,一般采用在线部署方式
-
防火墙( FireWall )
隔离功能,工作在网络或主机边缘,对进出网络或主机的数据包基于一定的规则检查,并在匹配某规则时由规则定义的行为进行处理的一组功能的组件,基本上的实现都是默认情况下关闭所有的通过型访问,只开放允许访问的策略
1. 1 防火墙的分类
- 主机防火墙:服务范围为当前主机
- 网络防火墙:服务范围为防火墙一侧的局域网
- 硬件防火墙:在专用硬件级别实现部分功能的防火墙;另一个部分功能基于软件实现,如:天融信,Checkpoint,NetScreen
- 软件防火墙:运行于通用硬件平台之上的防火墙的应用软件
- 网络层防火墙:OSI模型下四层
- 应用层防火墙/代理服务器:代理网关,OSI模型七层
1.2 网络型防火墙
1.2.1 包过滤防火墙
网络层对数据包进行选择,选择的依据是系统内设置的过滤逻辑,被称为访问控制列表(ACL),通过检查数据流中每个数据的源地址,目的地址,所用端口号和协议状态等因素,或他们的组合来确定是否允许该数据包通过
优点:对用户来说透明,处理速度快且易于维护
缺点:无法检查应用层数据,如病毒等
1.3 应用层防火墙
应用层防火墙/代理服务型防火墙(Proxy Service)
将所有跨越防火墙的网络通信链路分为两段
内外网用户的访问都是通过代理服务器上的“链接”来实现
优点:在应用层对数据进行检查,比较安全
缺点:增加防火墙的负载
现实生产环境中所使用的防火墙一般都是二者结合,即先检查网络数据,通过之后再送到应用层去检查
2 Linux 防火墙的基本认识
2.1 Netfilter
Linux防火墙是由Netfilter组件提供的,Netfilter工作在内核空间,集成在linux内核中
Netfilter 是Linux2.4.x之后新一代的Linux防火墙机制,是linux内核的一个子系统。Netfilter采用模块化设计,具有良好的可扩充性,提供扩展各种网络服务的结构化底层框架。Netfilter与IP协议栈是无缝契合,并允许对数据报进行过滤、地址转换、处理等操作
Netfilter官网文档:https://netfilter.org/documentation/
2.2 防火墙工具介绍
2.2.1 iptables
由软件包iptables提供的命令行工具,工作在用户空间,用来编写规则,写好的规则被送往netfilter,告诉内核如何去处理信息包
[root@centos8 ~]#rpm -qi iptables
Name : iptables
Version : 1.8.2
Release : 9.el8
Architecture: x86_64
Install Date: Wed 25 Sep 2019 09:29:06 PM CST
Group : Unspecified
Size : 2050086
License : GPLv2 and Artistic 2.0 and ISC
Signature : RSA/SHA256, Tue 02 Jul 2019 06:50:00 AM CST, Key ID 05b555b38483c65d
Source RPM : iptables-1.8.2-9.el8.src.rpm
Build Date : Sat 11 May 2019 10:21:57 PM CST
Build Host : x86-01.mbox.centos.org
Relocations : (not relocatable)
Packager : CentOS Buildsys <bugs@centos.org>
Vendor : CentOS
URL : http://www.netfilter.org/
Summary : Tools for managing Linux kernel packet filtering capabilities
Description :
The iptables utility controls the network packet filtering code in the
Linux kernel. If you need to set up firewalls and/or IP masquerading,
you should either install nftables or this package.
Note: This package contains the nftables-based variants of iptables and
ip6tables, which are drop-in replacements of the legacy tools.
[root@centos8 ~]# iptables --version
iptables v1.8.2 (nf_tables)
[root@centos8 ~]#ll /usr/sbin/iptables
lrwxrwxrwx. 1 root root 17 May 11 2019 /usr/sbin/iptables -> xtables-nft-multi
[root@centos7 ~]#ll /usr/sbin/iptables
lrwxrwxrwx. 1 root root 13 Dec 9 2018 /usr/sbin/iptables -> xtables-multi
[root@centos7 ~]# iptables --version
iptables v1.4.21
[root@centos6 ~]#iptables --version
iptables v1.4.7
[root@centos6 ~]#ll /sbin/iptables
lrwxrwxrwx. 1 root root 33 Dec 12 2018 /sbin/iptables -> /etc/alternatives/iptables.x86_64
[root@centos6 ~]#ll /etc/alternatives/iptables.x86_64
lrwxrwxrwx. 1 root root 20 Dec 12 2018 /etc/alternatives/iptables.x86_64 -> /sbin/iptables-1.4.7
范例:安装iptables的service包
[root@centos8 ~]#dnf -y install iptables-services
[root@centos8 ~]#rpm -ql iptables-services
/etc/sysconfig/ip6tables
/etc/sysconfig/iptables
/usr/lib/systemd/system/ip6tables.service
/usr/lib/systemd/system/iptables.service
/usr/libexec/initscripts/legacy-actions/ip6tables
/usr/libexec/initscripts/legacy-actions/ip6tables/panic
/usr/libexec/initscripts/legacy-actions/ip6tables/save
/usr/libexec/initscripts/legacy-actions/iptables
/usr/libexec/initscripts/legacy-actions/iptables/panic
/usr/libexec/initscripts/legacy-actions/iptables/save
/usr/libexec/iptables
/usr/libexec/iptables/ip6tables.init
/usr/libexec/iptables/iptables.init
2.2.2 firewalld
从CentOS 7 版开始引入了新的前端管理工具
软件包:
- firewalld
- firewalld-config
管理工具:
- firewall-cmd 命令行工具
- firewall-config 图形工作
2.2.3 nftables
此软件是CentOS 8 新特性,Nftables最初在法国巴黎的Netfilter Workshop 2008上发表,然后由长期的netfilter核心团队成员和项目负责人Patrick McHardy于2009年3月发布。它在2013年末合并到Linux内核中,自2014年以来已在内核3.13中可用。
它重用了netfilter框架的许多部分,例如连接跟踪和NAT功能。它还保留了命名法和基本iptables设计的几个部分,例如表,链和规则。就像iptables一样,表充当链的容器,并且链包含单独的规则,这些规则可以执行操作,例如丢弃数据包,移至下一个规则或跳至新链。
从用户的角度来看,nftables添加了一个名为nft的新工具,该工具替代了iptables,arptables和ebtables中的所有其他工具。从体系结构的角度来看,它还替换了内核中处理数据包过滤规则集运行时评估的那些部分。
范例:查看软件包
[root@centos8 ~]#rpm -qi nftables
Name : nftables
Epoch : 1
Version : 0.9.0
Release : 8.el8
Architecture: x86_64
Install Date: Wed 25 Sep 2019 09:29:06 PM 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 <bugs@centos.org>
Vendor : CentOS
URL : http://netfilter.org/projects/nftables/
Summary : Netfilter Tables userspace utillites
Description :
Netfilter Tables userspace utilities.
范例:CentOS 8 支持三种防火墙工具
[root@centos8 ~]#systemctl status iptables.service
● iptables.service - IPv4 firewall with iptables
Loaded: loaded (/usr/lib/systemd/system/iptables.service; disabled; vendor preset: disabled)
Active: inactive (dead)
[root@centos8 ~]#systemctl status firewalld.service
● firewalld.service - firewalld - dynamic firewall daemon
Loaded: loaded (/usr/lib/systemd/system/firewalld.service; disabled; vendor preset: enabled)
Active: inactive (dead)
Docs: man:firewalld(1)
[root@centos8 ~]#systemctl status nftables.service
● nftables.service - Netfilter Tables
Loaded: loaded (/usr/lib/systemd/system/nftables.service; disabled; vendor preset: disabled)
Active: inactive (dead)
Docs: man:nft(8)
2.3 netfilter 中五个勾子函数和报文流向
Netfilter在内核中选取五个位置放了五个hook(勾子) function(INPUT、OUTPUT、FORWARD、PREROUTING、POSTROUTING),而这五个hook function向用户开放,用户可以通过一个命令工具(iptables)向其写入规则
由信息过滤表(table)组成,包含控制IP包处理的规则集(rules),规则被分组放在链(chain)上
提示:从 Linux kernel 4.2 版以后,Netfilter 在prerouting 前加了一个 ingress 勾子函数。可以使用这个新的入口挂钩来过滤来自第2层的流量,这个新挂钩比预路由要早,基本上是 tc 命令(流量控制工具)的替代品
三种报文流向:
流入本机:PREROUTING --> INPUT–>用户空间进程
流出本机:用户空间进程 -->OUTPUT–> POSTROUTING
转发:PREROUTING --> FORWARD --> POSTROUTING
2.4 iptables的组成
iptables由五个表table和五个链chain以及一些规则组成
五个表table:filter、nat、mangle、raw、security
filter表:过滤规则表,根据预定义的规则过滤符合条件的数据包
nat表:network address translation 地址转换规则表
mangle:修改数据标记位规则表
raw:关闭启用的连接跟踪机制,加快封包穿越防火墙速度
security:用于强制访问控制(MAC)网络规则,由Linux安全模块(如SELinux)实现
优先级由高到低的顺序为:
security -->raw-->mangle-->nat-->filter
五个内置链chain:
INPUT,OUTPUT,FORWARD,PREROUTING,POSTROUTING
链 chain:
- 内置链:每个内置链对应于一个钩子函数
- 自定义链:用于对内置链进行扩展或补充,可实现更灵活的规则组织管理机制;只有Hook钩子调用自定义链时,才生效
五链chain | 说明 |
---|---|
INPUT |
通过路由表后目的地为本机 |
OUTPUT |
由本机产生,向外转发 |
FORWARD |
通过路由表后,目的地不为本机 |
PREROUTING |
数据包进入路由表之前 |
POSTROUTING |
发送到网卡接口之前 |
表和链对应关系
数据包过滤匹配流程
内核中数据包的传输过程
- 当一个数据包进入网卡时,数据包首先进入PREROUTING链,内核根据数据包目的IP判断是否需要转送出去
- 如果数据包是进入本机的,数据包就会沿着图向下移动,到达INPUT链。数据包到达INPUT链后,任何进程都会收到它。本机上运行的程序可以发送数据包,这些数据包经过OUTPUT链,然后到达POSTROUTING链输出
- 如果数据包是要转发出去的,且内核允许转发,数据包就会向右移动,经过FORWARD链,然后到达POSTROUTING链输出
查看表支持的链
root@centos8 ~]#iptables -vnL -t filter
[root@centos8 ~]#iptables -vnL -t nat
[root@centos8 ~]#iptables -vnL -t mangle
[root@centos8 ~]#iptables -vnL -t raw
[root@centos8 ~]#iptables -vnL -t security
#CentOS 6 nat表不支持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
3. iptables 规则说明
3.1 iptables 规则组成
规则rule:根据规则的匹配条件尝试匹配报文,对匹配成功的报文根据规则定义的处理动作作出处理,规则在链表上的次序即为其检查时的生效次序
匹配条件:默认为与条件,同时满足
基本匹配:IP,端口,TCP的Flags(SYN,ACK等)
扩展匹配:通过复杂高级功能匹配
处理动作:称为target,跳转目标
内建处理动作:ACCEPT,DROP,REJECT,SNAT,DNAT,MASQUERADE,MARK,LOG…
自定义处理动作:自定义chain,利用分类管理复杂情形
规则要添加在链上,才生效;添加在自定义链上不会自动生效
3.1.2 iptables规则添加时考量点
- 要实现哪种功能:判断添加在哪张表上
- 报文流经的路径:判断添加在哪个链上
- 报文的流向:判断源和目的
- 匹配规则:业务需要
3.1.3 环境准备
Centos 7,8:
systemctl stop firewalld.service
systemctl disable firewalld. service
Centos6:
service iptables stop
chkconfig iptables off
3.1.4 iptables命令格式详解:
iptables [-t table] SUBCOMMAND chain [-m matchname [per-match-options]] -j targetname [per-target-options]
iptables -t filter -A INPUT -s 10.0.0.129 -j DROP
iptables -t filter -A INPUT -s 10.0.0.129 -j REJECT
1、-t table:指定表
raw, mangle, nat, [filter]默认
2、SUBCOMMAND:子命令
3.1.5 链管理类:
-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 (1 references)
pkts bytes target prot opt in out source destination
1 60 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 #让自己定义链加到INPUT
[root@centos8 ~]#iptables -X WEB_CHAIN
iptables v1.8.2 (nf_tables): CHAIN_USER_DEL failed (Device or resource busy): chain WEB_CHAIN
[root@centos8 ~]#iptables -F WEB_CHAIN
[root@centos8 ~]#iptables -X WEB_CHAIN
iptables v1.8.2 (nf_tables): CHAIN_USER_DEL failed (Device or resource busy): chain WEB_CHAIN
[root@centos8 ~]#iptables -D INPUT 1
[root@centos8 ~]#iptables -X WEB_CHAIN
3.1.6 查看类:
-L:list, 列出指定鏈上的所有规则,本选项须置后
-n:numberic,以数字格式显示地址和端口号
-v:verbose,详细信息
-vv 更详细
-x:exactly,显示计数器结果的精确值,而非单位转换后的易读值
--line-numbers:显示规则的序号
-S selected,以iptables-save 命令格式显示链上规则
3.1.7 常用组合:
-vnL
-vvnxL –-line-numbers
查看iptables规则
iptables -vnL
查看iptables规则编号
iptables -vnL --line-numbers
[root@web1 ~]# iptables -nL --line-numbers
Chain INPUT (policy ACCEPT)
num target prot opt source destination
1 REJECT icmp -- 10.0.0.129 0.0.0.0/0 reject-with icmp-port-unreachable
2 ACCEPT tcp -- 10.0.0.129 0.0.0.0/0 tcp dpt:80
3 DROP all -- 10.0.0.129 0.0.0.0/0
4 ACCEPT tcp -- 10.0.0.1 0.0.0.0/0 tcp dpt:22
5 REJECT tcp -- 10.0.0.0/24 0.0.0.0/0 tcp dpt:22 reject-with icmp-port-unreachable
3.1.8 规则管理类:
-A:append,追加
-I:insert, 插入,要指明插入至的规则编号,默认为第一条
-D:delete,删除
(1) 指明规则序号
(2) 指明规则本身
-R:replace,替换指定链上的指定规则编号
-F:flush,清空指定的规则链
-Z:zero,置零
iptables的每条规则都有两个计数器
(1) 匹配到的报文的个数
(2) 匹配到的所有报文的大小之和
范例:
增加一条规则
iptables -A INPUT 2 -s 10.0.0.129 -j DROP
插入一条规则
iptables -I INPUT 2 -s 10.0.0.1 -j ACCEPT #在插入一行到编号2
删除规则
iptables -D INPUT 2 #把编号为2规则删除,编号查看使用--line-numbers
iptables -D INPUT -s 10.0.0.1 -j ACCEPT
替换指定规则:
iptables -R INPUT 3 -s 10.0.0.1 -j ACCEPT #把编号为3规则替换
清空指定链的规则,
iptalbes -F
iptables -F OUTPUT #指定清除OUTPUT链
更改INPUT链默认规则
iptables -P INPUT DROP
3.1.9 chain:
PREROUTING,INPUT,FORWARD,OUTPUT,POSTROUTING
处理动作:
-j targetname [per-target-options]
简单:ACCEPT(接受),DROP(丢弃)
扩展:
REJECT:–reject-with:icmp-port-unreachable默认
RETURN:返回调用链
REDIRECT:端口重定向
LOG:记录日志,dmesg
MARK:做防火墙标记
DNAT:目标地址转换
SNAT:源地址转换
MASQUERADE:地址伪装
自定义链
3.2 iptables 基本匹配条件
3.2.1 匹配条件
- 基本:通用的,PARAMETERS
- 扩展:需加载模块,MATCH EXTENTIONS
基本匹配条件:无需加载模块,由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
--sport 源端口,--dport 目标端口 基本匹配时只能写一个端口
[!] -i, --in-interface name:报文流入的接口;只能应用于数据报文流入环节,只应用于INPUT、FORWARD、PREROUTING链
[!] -o, --out-interface name:报文流出的接口;只能应用于数据报文流出的环节,只应用于FORWARD、OUTPUT、POSTROUTING链
3.2.2 iptables 扩展匹配条件
扩展匹配条件:需要加载扩展模块(/usr/lib64/xtables/*.so),方可生效
扩展模块的查看帮助 :man iptables-extensions
扩展匹配条件:
- 隐式扩展
- 显式扩展
3.2.2.1 隐式扩展
iptables 在使用-p选项指明了特定的协议时,无需再用-m选项指明扩展模块的扩展机制,不需要手动加载扩展模块
tcp协议的扩展选项
- tcp协议的扩展选项
选项 | 说明 |
---|---|
[!] --sport port[:port] |
匹配报文源端口,可为端口范围 |
[!] --dport port[:port] |
匹配报文目标端口,可为范围 |
[!] --tcp-flags mask comp |
mask 需检查的标志位列表,用,分隔 例如 SYN,ACK,FIN,RST comp 在mask列表中必须为1的标志位列表,无指定则必须为0,用,分隔 |
[!] --syn |
用于匹配第一次握手 相当于:–tcp-flags SYN,ACK,FIN,RST SYN |
示例:
# 只让129主机访问 80端口(web服务)
[root@web1 ~]# iptables -A INPUT -s 10.0.0.129 -p tcp --dport 80 -j ACCEPT
[root@web1 ~]# iptables -A INPUT -s 10.0.0.129 -j REJECT
#源是130的不充许访问本机的22至80端口(22,23,24......80)
[root@web1 ~]#iptables -t filter -A INPUT -s 10.0.0.130 -p tcp --dport 22:80 -j DROP
#130主机只允许131主机远程连接(22端口)
[root@web1 ~]# iptables -A INPUT -d 10.0.0.130 ! -s 10.0.0.131 -p tcp --dport 22 -j REJECT
- udp协议的扩展选项
选项 | 说明 |
---|---|
[!] --sport port[:port] |
匹配报文的源端口或端口范围 |
[!] --dport port[:port] |
匹配报文的目标端口或端口范围 |
- icmp协议的扩展选项
选项 | 说明 |
---|---|
`[!] --icmp-type {type[/code] | typename}` |
示例:
--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
#在本机禁止ping的时候,别人来ping本主机是拒绝的,但本机ping别的台主机可以,
iptables -A INPUT -p icmp --icmp-type 0 -j ACCPET
iptables -A INPUT -d 10.0.0.130 -p ICMP -j REJECT
3.2.2.显式扩展
必须显式地指明使用的扩展模块进行的扩展
显式扩展:必须使用-m选项指明要调用的扩展模块的扩展机制,要手动加载扩展模块
[-m matchname [per-match-options]]
- multiport扩展
#以离散方式定义多端口匹配,最多指定15个端口
[!] --sports port[,port|,port:port]...
#指定多个源端口
[!] --dports port[,port|,port:port]...
#指定多个目标端口
[!] --ports port[,port|,port:port]...多个源或目标端口
示例:
#只允许10.0.0.128访问10.0.0.130的20,21,22,80端口。
iptables -A INPUT -s 10.0.0.128 -d 10.0.0.130 -p tcp -m multiport --dports 20:22,80 -j ACCEPT
iptables -A INPUT -d 10.0.0.130 -j REJECT
- iprange扩展
指明连续的(但一般不是整个网络)ip地址范围 | |
---|---|
[!] --src-range from[-to] |
源IP地址范围 |
[!] --dst-range from[-to] |
目标IP地址范围 |
示例:
#172.16.1.5-172.16.1.10无法访问172.16.1.100的80端口
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
#10.0.0.140-10.0.0.150 无法访问10.0.0.130的22,23端口
iptables -R INPUT 3 -d 10.0.0.130 -p tcp -m multiport --dport 22,23 -m iprange --src-range 10.0.0.140-10.0.0.150 -j REJECT
- mac扩展
指明源MAC地址, 适用于:PREROUTING, FORWARD,INPUT chains
[!] --mac-source XX:XX:XX:XX:XX:XX
示例:
iptables -A INPUT -s 10.0.0.129 -m mac --mac-source 00:50:56:12:34:56 -j ACCEPT
iptables -A INPUT -s 10.0.0.129 -j REJECT
#只能IP是 10.0.0.129 并且MAC是:00:50:56:12:34:56的才允许
- string扩展
对报文中的应用层数据做字符串模式匹配检测
选项 | 说明 |
---|---|
`--algo {bm | kmp}` |
–from offset | 开始偏移 |
–to offset | 结束偏移 |
[!] --string pattern | 要检测的字符串模式 |
[!] --hex-string pattern | 要检测字符串模式,16进制格式 |
示例:
#禁止访问百度
iptables -A OUTPUT -s 10.0.0.130 -p tcp -m multiport --dport 80,443 -m string --algo bm --string "baidu" -j REJECT
3.3 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指定本地时区(默认)
范例:
[root@centos7 ~]#iptables -A INPUT -s 10.0.0.129 -d 10.0.0.130 -p tcp --dport 80 -m time --timestart 10:00 --timestop 10:05 --weekdays Sat,Sun --kerneltz -j DROP
3.4 connlimit扩展
根据每个客户端IP做并发连接数数量匹配
可防止Dos(Denial of Service,拒绝服务)攻击
选项 | 说明 |
---|---|
–-connlimit-upto # | 连接的数量小于等于#时匹配 |
-–connlimit-above # | 连接,的数量大于#时匹配 |
通常分别与默认的拒绝或允许策略配合使用,限制同一个IP的连接数
示例:
#同一个IP远程连接10.0.0.133连接数不能超过2个,一定要写目标IP
iptables -A INPUT -d 10.0.0.133 -p tcp --dport 22 -m connlimit --connlimit-above 2 -j REJECT
3.5 limit扩展
基于收发报文的速率做匹配, 令牌桶过滤器
--limit-burst # | 初始值,#个后开始限制
--limit #[/second|/minute|/hour|/day] | 限制#个每秒/分/时/日
示例:
#前5个ping正常响应,超过5个后每分钟响应10个
iptables -A INPUT -d 10.0.0.130 -p icmp --icmp-type 8 -m limit --limit-burst 5 --limit 10/minute -j ACCEPT
iptables -A INPUT -p icmp -j REJECT
结果:
[root@zabbixagent2 html]# ping 10.0.0.130
PING 10.0.0.130 (10.0.0.130) 56(84) bytes of data.
64 bytes from 10.0.0.130: icmp_seq=1 ttl=64 time=0.597 ms
64 bytes from 10.0.0.130: icmp_seq=2 ttl=64 time=1.33 ms
64 bytes from 10.0.0.130: icmp_seq=3 ttl=64 time=1.23 ms
64 bytes from 10.0.0.130: icmp_seq=4 ttl=64 time=1.24 ms
64 bytes from 10.0.0.130: icmp_seq=5 ttl=64 time=0.893 ms
From 10.0.0.130 icmp_seq=6 Destination Port Unreachable
64 bytes from 10.0.0.130: icmp_seq=7 ttl=64 time=1.01 ms
From 10.0.0.130 icmp_seq=8 Destination Port Unreachable
From 10.0.0.130 icmp_seq=9 Destination Port Unreachable
From 10.0.0.130 icmp_seq=10 Destination Port Unreachable
From 10.0.0.130 icmp_seq=11 Destination Port Unreachable
From 10.0.0.130 icmp_seq=12 Destination Port Unreachable
64 bytes from 10.0.0.130: icmp_seq=13 ttl=64 time=0.621 ms
From 10.0.0.130 icmp_seq=14 Destination Port Unreachable
3.6 state扩展
[!] --state state
根据连接追踪机制
去检查连接的状态,较耗资源
conntrack机制:追踪本机上的请求和响应之间的关系
状态有如下几种:
NEW
:新发出请求;连接追踪信息库中不存在此连接的相关信息条目,因此,将其识别为第一次发出的请求
ESTABLISHED
:NEW状态之后,连接追踪信息库中为其建立的条目失效之前期间内所进行的通信状态
RELATED
:新发起的但与已有连接相关联的连接,如:ftp协议中的数据连接与命令连接之间的关系
INVALID
:无效的连接,如flag标记不正确
UNTRACKED
:未进行追踪的连接,如raw表中关闭追踪
示例:
iptables -A INPUT -d 172.16.1.10 -p tcp -m multiport --dports 22,80 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -s 172.16.1.10 -p tcp -m multiport --sports 22,80 -m state --state ESTABLISHED -j ACCEPT
已经追踪到的并记录下来的连接信息库
/proc/net/nf_conntrack
调整连接追踪功能所能够容纳的最大连接数量
/proc/sys/net/nf_conntrack_max
不同的协议的连接追踪时长
/proc/sys/net/netfilter/
注意:CentOS7 需要加载模块: modprobe nf_conntrack_ipv4
iptables的链接跟踪表最大容量为/proc/sys/net/nf_conntrack_max,各种状态的超时链接会从表中删除;当模块满载时,后续连接可能会超时,各种状态的超时后,链接会从表中删除
解决方法两个:
(1) 加大nf_conntrack_max 值
vi /etc/sysctl.conf
net.nf_conntrack_max = 393216
net.netfilter.nf_conntrack_max = 393216
(2) 降低 nf_conntrack timeout时间
vi /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
3.6.1 开放被动模式的ftp服务
CentOS 8 此模块有bug
(1) 装载ftp连接追踪的专用模块:
跟踪模块路径:/lib/modules/kernelversion/kernel/net/netfilter
查看是加载了ftp追踪模块
lsmod |grep nf_conntrack_ftp
如果没有加载则手动加载:
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
示例
yum install vsftpd
systemctl start vsftpd
modprobe nf_conntrack_ftp
iptables -F
iptables -A INPUT -s 10.0.0.1 -j ACCEPT
iptables -A INPUT -s 10.0.0.0/24 -j REJECT
iptables -I INPUT 2 -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -I INPUT 3 -p tcp --dport 21 -m state --state NEW -j ACCEPT
iptables -A OUTPUT -m state --state ESTABLISHED -j ACCEPT
iptables -vnL
3.7 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个字符 |
示例:
iptables -A INPUT -s 10.0.0.0/24 -p tcp -m multiport --dports 80,21,22,23 -m state --state NEW -j LOG --log-prefix "new connections: "
[root@centos8 ~]#tail -f /var/log/messages
Jan 19 11:51:34 web1 kernel: new connections: IN=ens33 OUT= MAC=00:0c:29:bc:77:74:00:0c:29:1b:9a:31:08:00 SRC=10.0.0.167 DST=10.0.0.130 LEN=60 TOS=0x00 PREC=0x00 TTL=64 ID=13272 DF PROTO=TCP SPT=42052 DPT=22 WINDOW=29200 RES=0x00 SYN URGP=0
4. 规则优化最佳实践
-
安全放行所有入站和出站的状态为ESTABLISHED状态连接,建议放在第一条,效率更高
-
谨慎放行入站的新请求
-
有特殊目的限制访问功能,要在放行规则之前加以拒绝
-
同类规则(访问同一应用,比如:http ),匹配范围小的放在前面,用于特殊处理
-
不同类的规则(访问不同应用,一个是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
-
应该将那些可由一条规则能够描述的多个规则合并为一条
-
设置默认策略,建议白名单(只放行特定连接) iptables -P DROP,不建议,容易出现“自杀现象”
-
规则的最后定义规则做为默认策略,推荐使用,放在最后一条
4.1 iptables规则保存
使用iptables命令定义的规则,手动删除之前,其生效期限为kernel存活期限
4.1.1 持久保存规则:
CentOS 7,8
iptables-save > /PATH/TO/SOME_RULES_FILE
CentOS 6
#将规则覆盖保存至/etc/sysconfig/iptables文件中
service iptables save
4.1.2 加载规则
CentOS 7 重新载入预存规则文件中规则:
iptables-restore < /PATH/FROM/SOME_RULES_FILE
选项:
-n, –noflush:不清除原有规则
-t, –test:仅分析生成规则集,但不提交
CentOS 6:
#会自动从/etc/sysconfig/iptables 重新载入规则
service iptables restart
4.1.3 开机自动重载规则
-用脚本保存各iptables命令;让此脚本开机后自动运行
/etc/rc.d/rc.local文件中添加脚本路径 /PATH/TO/SOME_SCRIPT_FILE
-用规则文件保存各规则,开机时自动载入此规则文件中的规则
在/etc/rc.d/rc.local文件添加(/etc/rc.d/rc.local必须要有执行权限,即有X权限)
iptables-restore < /PATH/FROM/IPTABLES_RULES_FILE
定义Unit File, CentOS 7,8 可以安装 iptables-services 实现iptables.service
yum install iptables-services
cp /etc/sysconfig/iptables{,.bak}
iptables-save > /etc/sysconfig/iptables
systemctl enable iptables.service
5. 网络防火墙
iptables/netfilter 利用filter表的FORWARD链,可以充当网络防火墙:
注意的问题:
(1) 请求-响应报文均会经由FORWARD链,要注意规则的方向性
(2) 如果要启用conntrack机制,建议将双方向的状态为ESTABLISHED的报文直接放行
5.1 FORWARD 链实现内外网络的流量控制
范例:内部10.0.0.130可以访问外部192.168.11.128,外部禁止访问内部
前提:要搭建好网络环境,130的网关要指向129,11.128的网关要指向11.129
[root@firewall-host ~]#vim /etc/sysctl.conf
net.ipv4.ip_forward=1
[root@firewall-host ~]#sysctl -p
[root@firewall-host ~]#iptables -A FORWARD -d 10.0.0.0/24 -m state --state NEW -j REJECT
#外网访问
[root@localhost128 ~]# ping 10.0.0.130
PING 10.0.0.130 (10.0.0.130) 56(84) bytes of data.
From 192.168.11.128 icmp_seq=1 Destination Port Unreachable
From 192.168.11.128 icmp_seq=2 Destination Port Unreachable
#内网访问:
[root@rout1 ~]# ping 192.168.11.128
PING 192.168.11.128 (192.168.11.128) 56(84) bytes of data.
64 bytes from 192.168.11.128: icmp_seq=1 ttl=64 time=0.230 ms
64 bytes from 192.168.11.128: icmp_seq=2 ttl=64 time=0.316 ms
范例:针对内部的特定服务可以允许外部访问,其它服务禁止访问
[root@firewall-host ~]#iptables -I FORWARD -s 192.168.11.0/24 -p tcp --dport 80 -j ACCEPT
[root@firewall-host ~]#iptables -vnL FORWARD --line-numbers
Chain INPUT (policy ACCEPT 3930 packets, 553K bytes)
pkts bytes target prot opt in out source destination
Chain FORWARD (policy ACCEPT 190 packets, 21752 bytes)
pkts bytes target prot opt in out source destination
6 394 ACCEPT tcp -- * * 192.168.11.0/24 0.0.0.0/0 tcp dpt:80
2 168 REJECT all -- * * 0.0.0.0/0 10.0.0.0/24 state NEW reject-with icmp-port-unreachable
Chain OUTPUT (policy ACCEPT 2514 packets, 432K bytes)
pkts bytes target prot opt in out source destination
#外网访问内网130:
[root@localhost ~]# curl 10.0.0.130 #只有访问web可以
web1
[root@localhost ~]# ssh 10.0.0.130
ssh: connect to host 10.0.0.130 port 22: Connection refused
[root@localhost ~]# ping 10.0.0.130
PING 10.0.0.130 (10.0.0.130) 56(84) bytes of data.
From 192.168.11.128 icmp_seq=1 Destination Port Unreachable
From 192.168.11.128 icmp_seq=2 Destination Port Unreachable
^C
--- 10.0.0.130 ping statistics ---
2 packets transmitted, 0 received, +2 errors, 100% packet loss, time 1000ms
#内网访问外网11.128:
[root@rout1 ~]# ping 192.168.11.128 #ping可以
PING 192.168.11.128 (192.168.11.128) 56(84) bytes of data.
64 bytes from 192.168.11.128: icmp_seq=1 ttl=63 time=0.783 ms
64 bytes from 192.168.11.128: icmp_seq=2 ttl=63 time=0.695 ms
^C
--- 192.168.11.128 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 3ms
rtt min/avg/max/mdev = 0.695/0.739/0.783/0.044 ms
[root@rout1 ~]# ssh 192.168.11.128 #ssh连接也可以
The authenticity of host '192.168.11.128 (192.168.11.128)' can't be established.
ECDSA key fingerprint is SHA256:xUJux9liPkV4D1K6o3Nh2jyLXVUtdG5Ep3Qd/QoKdVg.
Are you sure you want to continue connecting (yes/no/[fingerprint])? ^C
5.2 NAT 表
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都进行修改
范例:查看本地主机访问公网时使用的IP
[root@centos8 ~]#curl http://ipinfo.io/ip/
111.199.191.204
[root@centos8 ~]#curl http://ifconfig.me
111.199.191.204
[root@centos8 ~]#curl -L http://tool.lu/ip
当前IP: 111.199.191.204
归属地: 中国 北京 北京
5.2.1 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
#LocalNET 本地网络
#ExtIP 出口的外网IP
范例:
iptables -t nat -A POSTROUTING -s 10.0.0.0/24 ! -d 10.0.0.0/24 -j SNAT --to-source 192.168.11.129
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.1.0/24 ! –d 10.0.1.0/24 -j MASQUERADE
内网IP 10.0.0. 130通过 iptable SNAT 显示访问外网192.168.11.128
范例:实现SNAT
192.168.11.128操作:
启动http服务,并且不设置指向192.168.11.129的路由
10.0.0. 130操作:
把路由指向10.0.0.129
中间iptables主机:
转发是否开启:
[root@firewall-host ~]#sysctl -a |grep net.ipv4.ip_forward
net.ipv4.ip_forward = 1
`必须要开启`
[root@firewall-host ~]#iptables -t nat -A POSTROUTING -s 10.0.0.0/24 -j SNAT --to-source 192.168.11.129
[root@firewall-host ~]#iptables -vnL -t nat
Chain PREROUTING (policy ACCEPT)
target prot opt source destination
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain POSTROUTING (policy ACCEPT)
target prot opt source destination
SNAT all -- 10.0.0.0/24 !10.0.0.0/24
pkts bytes target prot opt in out source destination
5.2.2 DNAT
DNAT:nat表的target,适用于端口映射,即可重定向到本机,也可以支持重定向至不同主机的不同端口,但不支持多目标,即不支持负载均衡功能
DNAT选项:
- –to-destination [ipaddr[-ipaddr]][:port[-port]]
[root@firewall-host ~]#man iptables-extensions
--to-destination [ipaddr[-ipaddr]][:port[-port]]
which can specify a single new destination IP address, an inclusive range of IP addresses. Optionally a port range, if the rule also specifies one of the following protocols: tcp, udp, dccp or sctp. If no port range is specified, then the destination port will never be modi‐fied. If no IP address is specified then only the destination port will be modified. In Ker‐nels up to 2.6.10 you can add several --to-destination options. For those kernels, if you specify more than one destination address, either via an address range or multiple --to-des‐tination options, a simple round-robin (one after another in cycle) load balancing takes place between these addresses. Later Kernels (>= 2.6.11-rc1) don't have the ability to NAT to multiple ranges anymore.
iptables -t nat -A PREROUTING -d ExtIP -p tcp|udp --dport PORT -j DNAT --to-destination InterSeverIP[:PORT]
范例:
iptables -t nat -A PREROUTING -s 0/0 -d 172.18.100.6 -p tcp --dport 22 -j DNAT --to-destination 10.0.1.22
iptables -t nat -A PREROUTING -s 0/0 -d 172.18.100.6 -p tcp --dport 80 -j DNAT --to-destination 10.0.1.22:8080
内网10.0.0.130提供web服务,利用iptables DNAT实现外网主机192.168.11.128可以访问
范例:
内网主机10.0.0.130操作:
1。把默认路由指向10.0.0.129
2。启动web服务
中间iptables主机:
[root@firewall-host ~]#iptables -t nat -A PREROUTING -s 0/0 -d 192.168.11.129 -p tcp --dport 80 -j DNAT --to-destination 10.0.0.130:80
[root@firewall-host ~]#iptables -t nat -vnL PREROUTING
Chain PREROUTING (policy ACCEPT)
num target prot opt source destination
1 DNAT tcp -- 0.0.0.0/0 192.168.11.129 tcp dpt:80 to:10.0.0.130:80
外网主机192.168.11.128操作:
#访问测试
[root@zabbixagent2 ~]# curl 192.168.11.129
RS1
如果内网主机10.0.0.130提供web服务使用的8000端口,iptables主机配置:
iptables -t nat -A PREROUTING -s 0/0 -d 192.168.11.129 -p tcp --dport 80 -j DNAT --to-destination 10.0.0.130:8000
5.2.3 REDIRECT 转发
REDIRECT,是NAT表的 target,通过改变目标IP和端口,将接受的包转发至同一个主机的不同端口,可用于PREROUTING OUTPUT链
REDIRECT选项:
—to-ports port[-port]
范例:
iptables -t nat -A PREROUTING -d 10.0.0.130 -p tcp --dport 80 -j REDIRECT --to-ports 8000
范例:
在DNAT的基础上操作。
内网主机10.0.0.130端口发生了改变,由原来的80变成了8000.在不修改防火墙主机规则的前提下,内网主机自己定制规则
10.0.0.130操作:
iptables -t nat -A PREROUTING -d 10.0.0.130 -p tcp --dport 80 -j REDIRECT --to-ports 8000
root@web1 ~]# iptables -t nat -nL
Chain PREROUTING (policy ACCEPT)
target prot opt source destination
REDIRECT tcp -- 0.0.0.0/0 10.0.0.130 tcp dpt:80 redir ports 8000
外网主机192.168.11.128操作:
#访问测试
[root@zabbixagent2 ~]# curl 192.168.11.129
RS1
5.3 使用NPS工具实现远程主机可以访问内网主机
需求:任何可上网设置都可以远程连接到内网主机10.0.0.130。
必备条件:有一台上面有公网IP的云主机。
工具:nps
https://github.com/ehang-io/nps
示例:
5.3.1.云主机安装服务端:
云主机操作:
在云主机上面下载nps的服务端:
mkdir nps
cd nps
wget https://github.com/ehang-io/nps/releases/download/v0.26.9/linux_amd64_server.tar.gz
tar -xvf linux_amd64_server.tar.gz
./nps install
nps start
[root@hecs-centos-8 ~]# ps -ef|grep nps
root 475408 1 0 11:22 ? 00:00:00 /usr/bin/nps service
[root@hecs-centos-8 ~]# netstat -an|grep 8080
tcp6 0 0 :::8080 :::* LISTEN
`
nps默认配置文件使用了80,443,8080,8024端口
80与443端口为域名解析模式默认端口
8080为web管理访问端口
8024为网桥端口,用于客户端与服务器通信
`
打开浏览器访问
`http://云主机的公网IP:8080`
5.3.2 在web界面配置客户端
新增客户端
5.3.3 内网主机配置
内网主机操作:
下载nps的客户端:
mkdir npsClient
cd npsClient
wget https://github.com/ehang-io/nps/releases/download/v0.26.9/linux_amd64_client.tar.gz
tar -xvf linux_amd64_client.tar.gz
连接服务端:
./npc -server=139.x.x.x:8024 -vkey=zaa3otvipfwp4h5f -type=tcp #可以放后台运行
5.3.4 测试
6. firewalld服务
6.1 firewalld 介绍
firewalld是CentOS 7.0新推出的管理netfilter的用户空间软件工具
firewalld是配置和监控防火墙规则的系统守护进程。可以实现iptables,ip6tables,ebtables的功能
firewalld服务由firewalld包提供
firewalld支持划分区域zone,每个zone可以设置独立的防火墙规则
归入zone顺序:
- 先根据数据包中源地址,将其纳为某个zone
- 纳为网络接口所属zone
- 纳入默认zone,默认为public zone,管理员可以改为其它zone
网卡默认属于public zone,lo网络接口属于trusted zone
firewalld zone分类
zone名称 | 默认配置 |
---|---|
trusted | 允许所有流量 |
home | 拒绝除和传出流量相关的,以及ssh,mdsn,ipp-client,samba-client,dhcpv6-client预定义服务之外其它所有传入流量 |
internal | 和home相同 |
work | 拒绝除和传出流量相关的,以及ssh,ipp-client,dhcpv6-client预定义服务之外的其它所有传入流量 |
public | 拒绝除和传出流量相关的,以及ssh,dhcpv6-client预定义服务之外的其它所有传入流量,新加的网卡默认属于public zone |
external | 拒绝除和传出流量相关的,以及ssh预定义服务之外的其它所有传入流量,属于external zone的传出ipv4流量的源地址将被伪装为传出网卡的地址。 |
dmz | 拒绝除和传出流量相关的,以及ssh预定义服务之外的其它所有传入流量 |
block | 拒绝除和传出流量相关的所有传入流量 |
drop | 拒绝除和传出流量相关的所有传入流量(甚至不以ICMP错误进行回应) |
预定义服务
服务名称 | 配置 |
---|---|
ssh | Local SSH server. Traffic to 22/tcp |
dhcpv6-client | Local DHCPv6 client. Traffic to 546/udp on the fe80::/64 IPv6 network |
ipp-client | Local IPP printing. Traffic to 631/udp. |
samba-client | Local Windows file and print sharing client. Traffic to 137/udp and 138/udp. |
mdns | Multicast DNS (mDNS) local-link name resolution. Traffic to 5353/udp to the 224.0.0.251 (IPv4) or ff02::fb (IPv6) multicast addresses. |
firewalld预定义服务配置
- firewall-cmd –get-services 查看预定义服务列表
- /usr/lib/firewalld/services/*.xml预定义服务的配置
firewalld 三种配置方法
- firewall-config (firewall-config包)图形工具
- firewall-cmd (firewalld包)命令行工具
- /etc/firewalld 配置文件,一般不建议
6.2 firewall-cmd 命令
firewall-cmd 格式
Usage: firewall-cmd [OPTIONS...]
常见选项
--get-zones 列出所有可用区域
--get-default-zone 查询默认区域
--set-default-zone=<ZONE> 设置默认区域
--get-active-zones 列出当前正使用的区域
--add-source=<CIDR>[--zone=<ZONE>] 添加源地址的流量到指定区域,如果无--zone= 选项,使用默认区域
--remove-source=<CIDR> [--zone=<ZONE>] 从指定区域删除源地址的流量,如无--zone= 选项,使用默认区域
--add-interface=<INTERFACE>[--zone=<ZONE>] 添加来自于指定接口的流量到特定区域,如果无--zone= 选项,使用默认区域
--change-interface=<INTERFACE>[--zone=<ZONE>] 改变指定接口至新的区域,如果无--zone= 选项,使用默认区域
--add-service=<SERVICE> [--zone=<ZONE>] 允许服务的流量通过,如果无--zone= 选项,使用默认区域
--add-port=<PORT/PROTOCOL>[--zone=<ZONE>] 允许指定端口和协议的流量,如果无--zone= 选项,使用默认区域
--remove-service=<SERVICE> [--zone=<ZONE>] 从区域中删除指定服务,禁止该服务流量,如果无--zone= 选项,使用默认区域
--remove-port=<PORT/PROTOCOL>[--zone=<ZONE>] 从区域中删除指定端口和协议,禁止该端口的流量,如果无--zone= 选项,使用默认区域
--reload 删除当前运行时配置,应用加载永久配置
--list-services 查看开放的服务
--list-ports 查看开放的端口
--list-all [--zone=<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
6.3 其它规则
当基本firewalld语法规则不能满足要求时,可以使用以下更复杂的规则
- rich-rules 富规则,功能强,表达性语言
- Direct configuration rules 直接规则,灵活性差, 帮助:man 5 firewalld.direct
6.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规则选项
选项 | 描述 |
---|---|
–add-rich-rule=’‘ | Add to the specified zone, or the default zone if no zone is specified. |
–remove-rich-rule=’‘ | Remove to the specified zone, or the default zone if no zone is specified. |
–query-rich-rule=’‘ | Query if has been added to the specified zone, or the default zone if no zone is specified. Returns 0 if the rule is present, otherwise 1. |
–list-rich-rules | Outputs all rich rules for the specified zone, or the default zone if no zone is specified. |
6.3.2 rich规则实现
拒绝从192.168.0.11的所有流量,当address 选项使用source 或 destination时,必须用family= ipv4 |ipv6
firewall-cmd --permanent --zone=public --add-rich-rule='rule family=ipv4 source address=192.168.0.11/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.168.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="<PREFIX TEXT>" [level=<LOGLEVEL>] [limit value="<RATE/DURATION>"]
<LOGLEVEL> 可以是emerg,alert, crit, error, warning, notice, info, debug.
<DURATION> s:秒, m:分钟, h:小时, d:天
audit [limit value="<RATE/DURATION>"]
范例
#接受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
6.3.3 伪装和端口转发
NAT网络地址转换,firewalld支持伪装和端口转发两种NAT方式
伪装NAT
firewall-cmd --permanent --zone=<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=<ZONE> --add-forward-port=port=<PORTNUMBER>:proto=<PROTOCOL>[:toport=<PORTNUMBER>][:toaddr=]
说明:toport= 和toaddr= 至少要指定一个
范例:
#转发传入的连接9527/TCP,到防火墙的80/TCP到public zone 的192.168.0.254
firewall-cmd --add-masquerade 启用伪装
firewall-cmd --zone=public --add-forward-port=port=9527:proto=tcp:toport=80:toaddr=192.168.0.254
rich规则的port转发语法:
forward-port port=<PORTNUM> protocol=tcp|udp [to-port=<PORTNUM>] [to-addr=<ADDRESS>]
范例:
#转发从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
#转发从10.0.0.130来的发住防火墙192.168.100.27 80/TCP的流量,通过防火墙192.168.100.27访问192.168.100.4上的web服务
网络拓扑图见iptables的SNAT
# firewall-cmd --permanent --add-masquerade #先打开转发
# firewall-cmd --permanent --add-forward-port=port=80:proto=tcp:toaddr=192.168.100.4:toport=80
# firewall-cmd --reload
测试:
在10.0.0.130上
curl 192.168.100.4
hello
范例:限制ssh服务非标准端口访问
cp /usr/lib/firewalld/services/ssh.xml /etc/firewalld/services/ssh.xml
vim /etc/firewalld/services/ssh.xml
<port protocol="tcp" port="999"/>
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
7. nft
7.1 nft 介绍
nftables 是新的数据包分类框架,新的linux防火墙管理程序,旨在替代现存的 {ip,ip6,arp,eb}_tables,在 Linux 内核版本高于 >=3.13 时可用。提供一个新的命令行工具 nft,语法与 iptables 不同。
官方Wiki:https://wiki.nftables.org
官方文档:https://www.netfilter.org/projects/nftables/manpage.html
参考文档:https://www.mankier.com/8/nft
7.2 nft 相关概念
nftables 和 iptables 一样,由表(table)、链(chain)和规则(rule)组成,其中表包含链,链包含规则,规则是真正的 action,规则由地址,接口,端口或包含当前处理数据包中的其他数据等表达式以及诸如drop, queue, continue等声明组成。
与 iptables 相比,nftables 主要有以下几个变化:
- iptables 规则的布局是基于连续的大块内存的,即数组式布局;而 nftables 的规则采用链式布局,即数组和链表的区别
- iptables 大部分工作在内核态完成,如果要添加新功能,只能重新编译内核;而 nftables 的大部分工作是在用户态完成的,添加新功能更加容易,不需要改内核
- nftables不包含任何内置表和链
- 拥有使用额外脚本的能力, 拥有一些高级的类似编程语言的能力,例如定义变量和包含外部文件
- iptables 有内置的链,即使只需要一条链,其他的链也会跟着注册;而 nftables 不存在内置的链,可以按需注册。由于 iptables 内置了一个数据包计数器,所以即使这些内置的链是空的,也会带来性能损耗
- 简化了 IPv4/IPv6 双栈管理
- 原生支持集合、字典和映射
nftables 的每个表只有一个地址簇,并且只适用于该簇的数据包。表可以指定五个簇中的一个:
nftables簇 | iptables命令行工具 |
---|---|
ip IPv4 地址 | iptables |
ip6 IPv6 地址 | ip6tables |
inet IPv4 和 IPv6 地址 | iptables和ip6tables |
arp 地址解析协议(ARP)地址 | arptables |
bridge 处理桥接数据包 | ebtables |
inet
同时适用于 IPv4 和 IPv6 的数据包,即统一了ip
和ip6
簇,可以更容易地定义规则,注:当没有指定地址簇时,默认为ip
IPv4/IPv6/Inet address family hooks
┌────────────┬──────────────────────────────────────┐
│Hook │ Description │
├────────────┼──────────────────────────────────────┤
│prerouting │ All packets entering the system are │
│ │ processed by the prerouting hook. It │
│ │ is invoked before the routing │
│ │ process and is used for early fil‐ │
│ │ tering or changing packet attributes │
│ │ that affect routing. │
├────────────┼──────────────────────────────────────┤
│input │ Packets delivered to the local sys‐ │
│ │ tem are processed by the input hook. │
├────────────┼──────────────────────────────────────┤
│forward │ Packets forwarded to a different │
│ │ host are processed by the forward │
│ │ hook. │
├────────────┼──────────────────────────────────────┤
│output │ Packets sent by local processes are │
│ │ processed by the output hook. │
├────────────┼──────────────────────────────────────┤
│postrouting │ All packets leaving the system are │
│ │ processed by the postrouting hook.
链是用来保存规则的,和表一样,链也需要被显示创建,因为 nftables 没有内置的链。链有以下两种类型:
- 基本链 : 数据包的入口点,需要指定钩子类型和优先级,相当于内置链
- 常规链 : 不需要指定钩子类型和优先级,可以用来做跳转,从逻辑上对规则进行分类,类似于自定义链
范例:
[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/nftables/netdev-ingress.nft
/etc/sysconfig/nftables.conf
/usr/lib/.build-id
/usr/lib/.build-id/68
/usr/lib/.build-id/68/8ad5e5fdc5ba8d10bf227ba50d77fd99040c1c
/usr/lib/.build-id/cc
/usr/lib/.build-id/cc/43827ec42d27875c99ce6bd0f0537614e0129a
/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
[root@centos8 ~]#systemctl start nftables
7.3 nft 常见用法
7.3.1 nft 命令格式
[root@centos8 ~]#nft --help
Usage: nft [ options ] [ cmds... ]
选项说明
-h, --help 显示帮助
-v, --version 显示版本信息
-c, --check 检查命令的有效性,而不实际应用更改。
-f, --file <filename> 包含文件内容<filename>
-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 <directory> 添加<directory>目录到包含文件的搜索路径中。默认为: /etc
--debug <level [,level...]> 添加调试,在level处(scanner, parser, eval, netlink, mnl, proto-ctx, segtree, all)
nft 命令基本格式
nft 操作符 操作目标 操作内容
操作符: 增,删,改,查,清除,插入,创建
操作目标: 表,链,规则
表操作:add,delete,list,flush
链操作:add,delete,rename,list,flush,create
链类型:filter,route,nat
链钩子:hook
规则:add,delete,insert
操作内容:...
规则选项
1 | accept | 接受 | 接受 包 | 停止处理 |
---|---|---|---|---|
2 | drop | 丢弃 | 丢弃 包 | 停止处理 |
3 | reject | 拒绝 | 驳回 包 | 停止处理 |
4 | queue | 队列 | 发送包 到用户空间程序 | 停止处理 |
5 | continue | 继续 | 继续处理包 | |
6 | return | 返回 | 发送到调用的规则链进行处理 | |
7 | jump | 跳跃 | 发送到指定的规则链进行处理 | 当完成时或执行了返回的声明,返回到调用的规则链 |
8 | goto | 转到 | 发送到指定的规则链进行处理 | 不返回到调用的规则链 |
9 | limit | limit | 达到接收包的匹配限制, | 则根据规则处理包 |
10 | log | log | 日志记录 包 | 继续处理 |
7.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
^^^^^^
[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;
}
}
7.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
7.3.4 删
只需要把上面的 add 改为 delete 即可
7.3.5 改
更改链名用rename
更改规则用replace
示例:
让全部主机不能访问137的80端口
#nft add rule filter INPUT tcp dport 80 drop
#nft list table filter
#table ip filter {
chain INPUT {
type filter hook input priority filter; policy accept;
tcp dport 80 drop
}
}
#删除rules:
#nft -n -a list table filter
table ip filter { # handle 22
chain INPUT { # handle 1
type filter hook input priority 0; policy accept;
tcp dport 80 drop # handle 2
}
}
#nft delete rule filter INPUT handle 2
让130不能访问访问137的80端口
#nft add rule filter INPUT ip saddr 10.0.0.130 tcp dport 80 drop
#nft list table filter
table ip filter {
chain INPUT {
type filter hook input priority filter; policy accept;
ip saddr 10.0.0.130 tcp dport 80 drop
}
}
7.3.6 备份还原
规则都是临时的,要想永久生效,可以将规则备份,重启后自动加载恢复
查看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 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_chain {
tcp dport mysql reject
tcp dport http reject
}
chain test_filter_input_chain {
type filter hook input priority 0; policy accept;
tcp dport mysql reject
tcp dport ftp reject
udp dport http-alt reject
tcp dport http reject
tcp dport 6379 reject
}
}
[root@centos8 ~]#nft list ruleset > /etc/sysconfig/nftables.conf
#删除所有规则
[root@centos8 ~]#nft flush ruleset
[root@centos8 ~]#nft list ruleset
#删除某一条规则:
#nft -n -a list table filter
table ip filter { # handle 22
chain INPUT { # handle 1
type filter hook input priority 0; policy accept;
tcp dport 22 accept # handle 2
tcp dport 80 drop # handle 3
}
}
#nft delete rule filter INPUT handle 3 #把tcp dport 80 drop删除
#重新启动后全部还原
[root@centos8 ~]#systemctl restart nftables.service
[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_chain {
tcp dport mysql reject
tcp dport http reject
}
chain test_filter_input_chain {
type filter hook input priority 0; policy accept;
tcp dport mysql reject
tcp dport ftp reject
udp dport http-alt reject
tcp dport http reject
tcp dport 6379 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
}
}
7.3.7 迁移iptables规则到nft
- To save the existing rules to a file, run below command:
# iptables-save > rules.iptables
- 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.
- 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
- 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.
- 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