网络安全技术基础
目前主流的网络安全产品(技术)包括以下几类
入侵检测系统 IDS
IDS:Intrusion Detection Systems (入侵检测系统)
其特点是不阻断任何网络访问,而是依照一定的安全策略,通过软,硬件,对网络,系统的运行状况进 行监控,尽可能发现各种攻击企图,攻击行为或攻击结果,以保证网络系统资源的机密性,完整性和可用性。
本质上,IDS 是监听设备(系统),不用直接接入网络链路,网络流量也不用经过IDS。所以IDS一般以 旁路部署的形入接入系统,然后在网络上收集它所关心的报文即可。对于收集到的报文数据,IDS会进行 清洗统计,并与内置的规则进行比对和分析,从而得出哪些网络数据是入侵和攻击。
根据模型和部署方式不同,IDS 可分为基于主机的IDS,基于网络的IDS,以及新一代的分布式IDS。
基于主机的IDS
在每个要保护的主机上运行一个代理程序,一般只能检测该主机上发生的入侵。主要部署在重要的系统服务器,工作站上。IDS代理程序监控操作系统或系统事件级别的可疑活动(如尝试登录等)。在使用时 需要清楚的定义哪些是不合法的活动,然后根据这些定义的规则来做检测。
基于网络的IDS
该类系统一般被动地在网络上监听整个网段上的信息流,通过捕获网络数据包,进行分析,能够检测该 网络段上发生的网络入侵。
分布式IDS
一般由多个部件组成,分布在网络的各个部分,每个部件完成相应功能,分别进行数据采集、数据分析 等。通过中心的控制部件,进行数据汇总、分析、产生入侵警报等。在这种 "分布式IDS(入侵检测系统)” 的结构下,不仅可以检测到针对单独主机的入侵,同时也可以检测到针对该网段上的主机的入侵。
入侵防御系统 IPS
IPS: Intrusion Prevention System (入侵防御系统)
IPS 以串行的方式接入系统,IPS系统可以深度感知并检测经流的数据报文,可以根据预先设定的安全策 略,对流经的每个报文进行深度检测(包括协议分析跟踪、特征匹配、流量统计分析、事件关联分析等),如果发现藏匿于其中的网络攻击,可以根据该攻击的威胁级别立即采取措施,这些措施包括中断 连接,丢弃报文,隔离文件,向管理员告警等。
IPS可以分为 主机入侵防御系统,网络入侵防御系统,无线入侵防御系统等几类。
主机 IPS
主机IPS部署在终端主机节点上,主要用来保护单台主机,主机IPS与网络IPS结合使用效果更佳,对于能 够规避网络IPS的威胁,主机IPS可以看是防御系统的最后一道防线。
网络 IPS
网络IPS一般部署在系统的战略位置上,所有进出的流量和报文,都要经由网络IPS,其作用在整个网络 上。
无线 IPS
此类的入侵防御系统可以扫描无线网络,进行寻找未经授权的访问,并可以将未授权的设备移出网络。
防火墙 FW
FW:Firewal
防火墙系统是在内部网络和外部网络之间,专用网络与公共网络之间,可信网络和不可信网络之间建立 屏障。它是一种隔离技术,是在两个网络通讯时执行的一种访问控制尺度,它能允许经你 “同意”的个人 和数据进入你的网络,同时将你 “不同意” 的个人和数据拒之门外,最大限度的阻止非法的流量和数据进 入系统或网络。同时防火墙也可以根据规则禁止本地网络向外发送数据报文,以及根据规则转发网络流 量等。
防火墙以串行的方式接入系统,所有流入流出的网络报文都要经由防火墙。
根据工作模式不同,防火墙可以分为 网络层防火墙,应用层防火墙等。
防水墙 WW
WW:Waterwall
与防火墙相对,防水墙是一种防止内部信息泄漏的安全产品。它利用透明加解密,身份认证,访问控制 和审计跟踪等技术手段,对涉密信息,重要业务数据和技术专利等敏感信息的存储,传播和处理过程, 实施安全保护;最大限度地防止敏感信息泄漏、被破坏和违规外传,并完整记录涉及敏感信息的操作日志,以便日后审计。
防火墙的分类
按照保护范围来划分
可以分为主机防火墙和网络防火墙。
主机防火墙
主机防火墙对单个主机进行防护,运行在终端主机上,主机防火墙可以阻止未授权的程序和数据出入计 算机,Windows和Linux 系统都有自带的主机防火墙。
网络防火墙
网络防火墙部署在整个系统的主线网路上,对整个系统的出入数据进行过滤。
按实现方式划分
可以分为硬件防火墙和软件防火墙
硬件防火墙
硬件防火墙以独立硬件设备的形式提供服务,独立供电,独立部署,其软件是单独运行在硬件里面的, 所有硬件资源都只给防火墙这一个程序使用。
常见的硬件防火墙生产厂商有 华为,天融信,启明星辰,绿盟,深信服等。
软件防火墙
没有独立硬件,一般以应用程序的形式提供,运行于通用硬件平台,寄生于操作系统中,是通过纯软件 的方式提供服务
按网络协议划分
可以分为网络层防火墙和应用层防火墙
网络层防火墙工作在OSI七层模型中的网络层,又称包过滤防火墙。
应用层防火墙工作在OSI七层模型中的应用层,又称网关防火墙或代理服务器防火墙。
网络层防火墙
网络层防火墙对流经的数据包中的源地址,目标地址,端口号及协议等内容做出分析,依据事先设定好 的过滤规则,对数据包作出不同的处理(包括拒绝,丢弃,放行,转发等)。这些过滤规则,被称为访问控制列表(ACL)。
网络层防火墙只能根据数据包头部的协议端口号等进行过滤,无法过滤应用层的具体数据
应用层防火墙
应用层网只针对特别的网络应用服务协议来确定数据过滤逻辑。应用层网关防火墙是内部网和外部网的隔离点,它部署在主链路上,将系统分为两部份,起到内外部网络通讯时的中间转接作用
Linux 防火墙基础知识
netfilter 基础
netfilter/iptables 项目由 Rusty Russe 创建于1998年,并于 1999 年建立了 Netfilter Core team,并在 此后负责维护此项目,同时也于2000年3月合并进了 linux 2.3.x 版本的 linux 内核
从 Linux 2.4.x 版本的内核开始,netfilter 就正式成为了新一代的 Linux 防火墙机制,是Linux内核的一 个子系统。Netfilter采用模块化设计,具有良好的可扩充性,提供扩展网络服务的结构化底层框架。 Netfilter与IP协议栈是无缝契合,并允许对数据包进行过滤、地址转换、处理等操作
netfilter/iptables 有三部分组成,分别是netfilter 框架/iptables(内核空间)/iptables 命令行工具(用户空间)。
内核中netfilter相关的模块
[root@ubuntu24 ~]# grep -i netfilter /boot/config-6.8.0-45-generic
CONFIG_NETFILTER=y
CONFIG_NETFILTER_ADVANCED=y
CONFIG_BRIDGE_NETFILTER=m
# Core Netfilter Configuration
CONFIG_NETFILTER_INGRESS=y
CONFIG_NETFILTER_EGRESS=y
CONFIG_NETFILTER_SKIP_EGRESS=y
CONFIG_NETFILTER_NETLINK=m
CONFIG_NETFILTER_FAMILY_BRIDGE=y
CONFIG_NETFILTER_FAMILY_ARP=y
CONFIG_NETFILTER_BPF_LINK=y
CONFIG_NETFILTER_NETLINK_HOOK=m
CONFIG_NETFILTER_NETLINK_ACCT=m
CONFIG_NETFILTER_NETLINK_QUEUE=m
CONFIG_NETFILTER_NETLINK_LOG=m
CONFIG_NETFILTER_NETLINK_OSF=m
CONFIG_NETFILTER_CONNCOUNT=m
CONFIG_NETFILTER_NETLINK_GLUE_CT=y
....
防火墙工具
对于防火墙工具,建议只用一个,多个工具共存可能会有冲突
iptables
由软件包iptables提供的命令行工具,工作在用户空间,用来编写规则,写好的规则被送往netfilter,告 诉内核如何去处理信息包。
firewalld
redhat 系列的发行版中,从CentOS 7 版本开始,引入了新的前端管理工具。
nftables
此软件是 CentOS 8的新特性,Nftables 最初在法国巴黎的 Netfilter Workshop 2008 上发表,后由 netfilter核心团队成员和项目负责人Patrick McHardy 于2009年3月发布。并于2013年末合并到Linux内 核中,自2014年开始,己经在 3.13版本以以后的版本的内核中可用。
它重用了 netfilter框架的许多部份,例如连接跟踪和NAT功能。它还保留了命名法和基本iptables设计的 几个部份,例如表,链和规则。就像iptables一样,充当链的容器,并且链包含单独的规则,这些规则 可以执行操作,例如丢弃数据包,移至下一个规则或跳至新链
从用户角度来看,nftables添加了名为 nft 的新工具,该工具是iptables及其衍生指令 (ip6tables, arptables,ebtables)的超集,替代了iptables 及其衍生指令的中的所有工具。从体系结构的角度来看, 它还替换了内核中处理数据包过滤规则集运行时评估的那些部分
netfilter 工作原理
netfilter 在内核中某些位置放置了五个勾子函数(hook function),分别是 INPUT,OUTPUT, FORWARD,PREROUTING,POSTROUTING,管理员可以通过配置工具配置规则,让这五个函数按照自 定义的规则进行工作,达到防火墙的功能。
特别说明
从 Linux kernel 4.2 版以后,netfilter 在prerouting 前加了一个 ingress 勾子函数。可以使用这个新的 入口挂钩来过滤来自第2层的流量,这个新挂钩比预路由要早,基本上是 tc 命令(流量控制工具)的替 代品
三种报文流向
数据走向 | 具体过程 |
---|---|
流入本机 | PREROUTING --> INPUT --> 用户空间进程 |
流出本机 | 用户空间进程 --> OUTPUT --> POSTROUTING |
从本机转发 | PREROUTING --> FORWARD --> POSTROUTING |
iptables 的组成
netfilter 在内核中设置了五个勾子函数,管理员在用户空间,通过程序设置过滤规则,内核中的勾子函数根据预设的规则进行工作,达到对流经的数据包进行过滤,拒绝,转发等功能
iptables中有五个链(chain)对应内核中的五个勾子函数。除此之外,iptables中还有五个表 (table),一起来配合工作
iptables 中的链
类型 | 备注 |
---|---|
内置链 | 对应内核中的每一个勾子函数 (INPUT,OUTPUT,FORWARD,PREROUTING, POSTROUTING) |
自定义链 | 用于对内置链进行扩展或补充,可实现更灵活的规则组织管理机制;只有Hook钩子调用自定义链时,才会生效 |
iptables 中的表
表名 | 备注 |
---|---|
filter | 过滤规则表,根据预定义的规则过滤符合条件的数据包,默认表 |
nat | network address translation 地址转换规则表 |
mangle | 修改数据标记位规则表 |
raw | 关闭启用的连接跟踪机制,加快封包穿越防火墙速度 |
security | 用于强制访问控制(MAC)网络规则,由Linux安全模块(如SELinux)实现,很少使用 |
表的优先级(从高到低)
security --> raw --> mangle --> nat --> filter
链和表的对应关系(不是每个链都能支持五个表)
表 | 可支持的链 |
---|---|
raw | PREROUTING,OUTPUT |
mangle | PREROUTING,POSTROUTING,INPUT,OUTPUT,FORWARD |
nat | PREROUTING,POSTROUTING,INPUT,OUTPUT |
filter | INPUT,FORWARD,OUTPUT |
数据包过滤匹配流程
-
当一个数据包进入网卡时,数据包首先进入PREROUTING链,内核根据数据包目的IP判断是否需要传送出去;
-
如果数据包是进入本机的,则会进入INPUT链,然后交由本机的应用程序处理;
-
如果数据包是要转发的,且内核允许转发,则数据包在PREROUTING链之后到达FORWARD链,再经由POSTROUTING链输出
-
本机的应用程序往外发送数据包,会先进入OUTPUT链,然后到达POSTROUTING链输出
-
数据流入:PREROUTING --> INPUT
-
数据流出:OUTPUT --> POSTROUTING
-
数据转发:PREROUTING --> FORWARD --> POSTROUTING
iptables
前置工作
在 ubuntu 中,在用iptables命令设置防火墙之前,先关闭自带的 ufw 服务,因为 ufw 服务中也有一套 自定义的规则,如果在开启 ufw 服务的情况下再用 iptables 设置或删除规则,容易发生冲突。
在 redhat 系中要先停用 firewalld 服务
#ubuntu中
[root@ubuntu24 ~]# systemctl disable --now ufw
Synchronizing state of ufw.service with SysV service script with /usr/lib/systemd/systemd-sysv-install.
Executing: /usr/lib/systemd/systemd-sysv-install disable ufw
Removed "/etc/systemd/system/multi-user.target.wants/ufw.service".
#Rocky 中
[root@Rocky-9 ~]# systemctl disable --now firewalld.service
Removed "/etc/systemd/system/multi-user.target.wants/firewalld.service".
Removed "/etc/systemd/system/dbus-org.fedoraproject.FirewallD1.service".
iptables 命令组成
iptables 完整命令由四部份组成
iptables Table Chain Rule
#通过 iptables 命令,在某个表,某个链上设置一个过滤规则
字段说明
字段 | 说明 |
---|---|
iptables | 命令 |
Table | 具体要操作的表,用 -t 指定,raw|mangle|nat|filter,默认filter |
Chain | 具体要操作的链,PREROUTING|INPUT|FORWARD|OUTPUT|POSTROUTING |
Rule | 具体规则,由匹配条件和目标组成,如果满足条件,就执行目标中的规则,目标用 -j 指定 |
完整格式示例
iptables -t filter -A INPUT -s 192.168.0.1 -j DROP
iptables 命令格式
iptables [-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]
#指定表
-t|--table table #指定表raw|mangle|nat|filter,如果不显式指定,默认是filter
#操作链
-N|--new-chain chain #添加自定义新链
-X|--delete-chain [chain] #删除自定义链(要求链中没有规则)
-P|--policy chain target #设置默认策略,对filter表中的链而言,其默认策略有ACCEPT|DROP
-E|--rename-chain old-chain new-chain #重命名自定义链,引用计数不为0的自定义链不能被重命名
-L|--list [chain] #列出链上的所有规则
-S|--list-rules [chain] #列出链上的的有规则
-F|--flush [chain] #清空链上的所有规则,默认是所有链
-Z|--zero [chain [rulenum]] #置0,清空计数器,默认操作所有链上的所有规则
#操作具体规则
-A|--append chain rule-specification #往链上追加规则
-I|--insert chain [rulenum] rule-specification #往链上插入规则,可以指定编号,默认插入到最前面(第一条)
-C|--check chain rule-specification #检查链上的规则是否正确
-D|--delete chain rule-specification #删除链上的规则
-D|--delete chain rulenum #根据编号删除链上的规则
-R|--replace chain rulenum rule-specification #根据链上的规则编号,使用新的规则替换原有规则
#其它选项
-h|--help #显示帮助
-V|--version #显示版本
-v|--verbose #显示详细信息
-n|--numeric #以数字形式显示IP和端口,默认显示主机名和协议名
--line-numbers #显示每条规则编号
示例
#查看规则
#默认filter表
[root@ubuntu24 ~]# iptables -S
-P INPUT ACCEPT
-P FORWARD ACCEPT
-P OUTPUT ACCEPT
#指定filter表
[root@ubuntu24 ~]# iptables -t filter -vS
-P INPUT ACCEPT -c 0 0
-P FORWARD ACCEPT -c 0 0
-P OUTPUT ACCEPT -c 0 0
#指定filter表,INPUT链
[root@ubuntu24 ~]# iptables -t filter -vS INPUT
-P INPUT ACCEPT -c 0 0
#新增规则
#在INPUT 链的 filter 表上设置过滤规则,将来自 10.0.0.152 的数据包丢弃掉
[root@ubuntu24 ~]# iptables -t filter -A INPUT -s 10.0.0.152 -j DROP
[root@ubuntu24 ~]# iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
DROP all -- 10.0.0.152 anywhere
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
#查看详细信息
[root@ubuntu24 ~]# iptables -vL
Chain INPUT (policy ACCEPT 28 packets, 1668 bytes)
pkts bytes target prot opt in out source destination
0 0 DROP all -- any any 10.0.0.152 anywhere
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@ubuntu24 ~]# iptables -vnL
Chain INPUT (policy ACCEPT 41 packets, 5870 bytes)
pkts bytes target prot opt in out source destination
0 0 DROP 0 -- * * 10.0.0.152 0.0.0.0/0
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
#在最前面插入一条放行物理机IP的规则
[root@ubuntu24 ~]# iptables -t filter -I INPUT -s 10.0.0.1 -j ACCEPT
#删除 iptables 规则
#查看规则编号
[root@ubuntu24 ~]# iptables -t filter -vnL INPUT --line-numbers
Chain INPUT (policy ACCEPT 191 packets, 28455 bytes)
num pkts bytes target prot opt in out source destination
1 114 9992 ACCEPT 0 -- * * 10.0.0.1 0.0.0.0/0
2 0 0 DROP 0 -- * * 10.0.0.152 0.0.0.0/0
#删除第2条规则,根据规则编号删除
[root@ubuntu24 ~]# iptables -t filter -D INPUT 2
#删除第一条,根据命令来删除
[root@ubuntu24 ~]# iptables -t filter -D INPUT -s 10.0.0.1 -j ACCEPT
#规则替换
[root@ubuntu24 ~]# iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
REJECT all -- 10.0.0.151 anywhere reject-with icmp-port-unreachable
#将10.0.0.151 更改为 10.0.0.0/24 整个网段
[root@ubuntu24 ~]# iptables -t filter -R INPUT 1 -s 10.0.0.0/24 -j REJECT
#由于物理机IP也被拒绝自己也会掉线
#需要插入一条规则去放行物理机IP,要用-I
#这种情况下,ACCEPT规则一定要写在前面,如果放在REJECT 就不会匹配到ACCEPT
#清空统计数据
# 查看
[root@ubuntu24 ~]# iptables -vnL INPUT
Chain INPUT (policy ACCEPT 575 packets, 80374 bytes)
pkts bytes target prot opt in out source destination
134 27116 ACCEPT 0 -- * * 10.0.0.1 0.0.0.0/0
69 4065 REJECT 0 -- * * 10.0.0.0/24 0.0.0.0/0 reject-with icmp-port-unreachable
#清空INPUT链上的第一条规则统计数据
[root@ubuntu24 ~]# iptables -t filter -Z INPUT 1
[root@ubuntu24 ~]# iptables -vnL INPUT
Chain INPUT (policy ACCEPT 575 packets, 80374 bytes)
pkts bytes target prot opt in out source destination
7 405 ACCEPT 0 -- * * 10.0.0.1 0.0.0.0/0
69 4065 REJECT 0 -- * * 10.0.0.0/24 0.0.0.0/0 reject-with icmp-port-unreachable
#每个表中都有默认规则
#修改默认规则
[root@ubuntu24 ~]# iptables -P FORWARD DROP
输出内容说明
字段 | 说明 |
---|---|
pkts | 在当前规则中,被命中的数据包数量 |
bytes | 在当前规则中,被命中的总流量大小 |
target | 动作,目标,DROP 表示丢弃 |
prot | 具体协议 |
opt | 选项 |
in | 数据从哪个网络设备进来 |
out | 数据从哪个网络设备上出去 |
source | 源,可以是主机IP,网段,anywhere 表示不受限 |
destination | 目标,可以是主机IP,网段,anywherer 表示不受限 |
iptables 防火墙中的规则,在生效时会按照顺序,从上往下生效,当前一条规则命中后,不再继续往下 匹配
如果多条规则里面,匹配条件中有交集,或者有包含关系,则这些规则,要注意前后顺序,范围小的, 需要精确匹配的,要往前放,范围大的,往后放,负责兜底的,放在最后。
如果多条规则里面,匹配条件没有交集,彼此不会互相影响,则无所谓前后顺序,但是从效率上来讲, 更容易命中的要放在前面。
iptables 匹配条件
iptables 中的匹配条件分为基本匹配和扩展匹配两种,当一条 iptables 规则中有多个匹配条件时,默认 是 “与” ,即要同时满足
匹配条件-基本匹配
[!] -s|--source address[/mask][,...] #匹配源IP地址或网段
[!] -d|--destination address[/mask][,...] #匹配目标IP地址或网段
[!] -p|--protocol protocol #匹配具体协议,可以使用协议号或协议名,具体见 /etc/protocols
[!] -i|--in-interface name #匹配报文流入接口,只用于数据流入
[!] -o|--out-interface name #匹配报文流出接口,只用于数据流出
#示例
#规则取反
[root@ubuntu24 ~]# iptables -vnL
Chain INPUT (policy ACCEPT 17 packets, 1484 bytes)
pkts bytes target prot opt in out source destination
1315 81273 ACCEPT 0 -- * * 10.0.0.1 0.0.0.0/0
3 252 REJECT 0 -- * * 10.0.0.157 0.0.0.0/0 reject-with icmp-port-unreachable
#从 10.0.0.157 来的数据包被拒绝
[root@ubuntu24 ~]# ping 10.0.0.161
PING 10.0.0.161 (10.0.0.161) 56(84) bytes of data.
From 10.0.0.161 icmp_seq=1 Destination Port Unreachable
From 10.0.0.161 icmp_seq=2 Destination Port Unreachable
From 10.0.0.161 icmp_seq=3 Destination Port Unreachable
#设置取反规则,除了 10.0.0.150 来的数据,其它都拒绝
[root@ubuntu24 ~]# iptables -t filter -R INPUT 2 ! -s 10.0.0.157 -j REJECT
[root@ubuntu24 ~]# ping 10.0.0.161
PING 10.0.0.161 (10.0.0.161) 56(84) bytes of data.
64 bytes from 10.0.0.161: icmp_seq=1 ttl=64 time=0.610 ms
64 bytes from 10.0.0.161: icmp_seq=2 ttl=64 time=0.434 ms
64 bytes from 10.0.0.161: icmp_seq=3 ttl=64 time=0.811 ms
#根据协议过滤
#拒绝来自157IP上的ICMP协议
[root@ubuntu24 ~]# iptables -t filter -A INPUT -s 10.0.0.157 -p icmp -j REJECT
[root@ubuntu24 ~]# iptables -vnL
Chain INPUT (policy ACCEPT 558 packets, 49035 bytes)
pkts bytes target prot opt in out source destination
25 1468 ACCEPT 0 -- * * 10.0.0.1 0.0.0.0/0
2 168 REJECT 1 -- * * 10.0.0.157 0.0.0.0/0 reject-with icmp-port-unreachable
[root@ubuntu24 ~]# ping 10.0.0.161
PING 10.0.0.161 (10.0.0.161) 56(84) bytes of data.
From 10.0.0.161 icmp_seq=1 Destination Port Unreachable
#扔掉目标为161的IP上的ICMP协议
[root@ubuntu24 ~]# iptables -t filter -A INPUT -d 10.0.0.161 -p icmp -j DROP
[root@ubuntu24 ~]# iptables -vnL
Chain INPUT (policy ACCEPT 558 packets, 49035 bytes)
pkts bytes target prot opt in out source destination
500 29893 ACCEPT 0 -- * * 10.0.0.1 0.0.0.0/0
3 252 DROP 1 -- * * 0.0.0.0/0 10.0.0.161
[root@ubuntu24 ~]# ping 10.0.0.161
PING 10.0.0.161 (10.0.0.161) 56(84) bytes of data.
#没有任何回应
匹配条件-扩展匹配
扩展匹配条件需要加载扩展模块才能使用
查看扩展模块
[root@ubuntu24 ~]# dpkg -L iptables | grep libxt_.*.so
/usr/lib/x86_64-linux-gnu/xtables/libxt_AUDIT.so
/usr/lib/x86_64-linux-gnu/xtables/libxt_CHECKSUM.so
/usr/lib/x86_64-linux-gnu/xtables/libxt_CLASSIFY.so
/usr/lib/x86_64-linux-gnu/xtables/libxt_CONNMARK.so
/usr/lib/x86_64-linux-gnu/xtables/libxt_CONNSECMARK.so
/usr/lib/x86_64-linux-gnu/xtables/libxt_CT.so
/usr/lib/x86_64-linux-gnu/xtables/libxt_DSCP.so
/usr/lib/x86_64-linux-gnu/xtables/libxt_HMARK.so
/usr/lib/x86_64-linux-gnu/xtables/libxt_IDLETIMER.so
/usr/lib/x86_64-linux-gnu/xtables/libxt_LED.so
/usr/lib/x86_64-linux-gnu/xtables/libxt_LOG.so
/usr/lib/x86_64-linux-gnu/xtables/libxt_MARK.so
/usr/lib/x86_64-linux-gnu/xtables/libxt_NAT.so
/usr/lib/x86_64-linux-gnu/xtables/libxt_NFLOG.so
/usr/lib/x86_64-linux-gnu/xtables/libxt_NFQUEUE.so
....
扩展匹配条件分为隐式扩展和显示扩展两种
隐式扩展
iptables 在使用 -p 选项指明了特定的协议时,无需再用 -m 选项指明扩展模块的扩展机制,不需要手动 加载扩展模块,不需要用 -m 显式指定的扩展,即隐式扩展。
tcp,upd,icmp 这三个协议是可以用 -m 指定的模块,但同时,也可以在基本匹配里面用 -p 来指定这 几个协议
[root@ubuntu24 ~]# dpkg -L iptables | grep tcp.so
/usr/lib/x86_64-linux-gnu/xtables/libxt_tcp.so
[root@ubuntu24 ~]# dpkg -L iptables | grep udp.so
/usr/lib/x86_64-linux-gnu/xtables/libxt_udp.so
[root@ubuntu24 ~]# dpkg -L iptables | grep icmp.so
/usr/lib/x86_64-linux-gnu/xtables/libipt_icmp.so
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 #第二次握手
[!] --syn #第一次握手的简单写法
#用tcp 协议和目标端口拒绝ssh服务
#拒绝来自于157的,其目标IP是161,目标端口是 21 到 23 的数据
[root@ubuntu24 ~]# iptables -t filter -A INPUT -s 10.0.0.157 -d 10.0.0.161 -p tcp --dport 21:23 -j REJECT
[root@ubuntu24 ~]# iptables -vnL
Chain INPUT (policy ACCEPT 559 packets, 49111 bytes)
pkts bytes target prot opt in out source destination
1512 91031 ACCEPT 0 -- * * 10.0.0.1 0.0.0.0/0
0 0 REJECT 6 -- * * 10.0.0.157 10.0.0.161 tcp dpts:21:23 reject-with icmp-port-unreachable
upd 协议的扩展选项
[!] --source-port|--sport port[:port] #匹配报文的源端口或端口范围
[!] --destination-port|--dport port[:port] #匹配报文的目标端口或端口范围
icmp 协议的扩展选项
[!] --icmp-type {type[/code]|typename}
0/0|echo-reply #icmp应答
8/0|echo-request #icmp请求
显式扩展及相关模块
显示扩展即必须使用 -m 选项指明要调用的扩展模块名称,需要手动加载扩展模块
-m matchname [per-match-options]
multiport 扩展
以离散方式定义多端口匹配,最多指定15个端口
[!] --source-ports|--sports port[,port|,port:port]... #指定多个源端口
[!] --destination-ports|--dports port[,port|,port:port]... #指定多个目标端口
[!] --ports port[,port|,port:port]... #多个源或目标端口
#在一条规则中指定两个端口
[root@ubuntu24 ~]# iptables -t filter -A INPUT -s 10.0.0.157 -d 10.0.0.161 -p tcp -m multiport --dports 22,80 -j REJECT
[root@ubuntu24 ~]# iptables -vnL
Chain INPUT (policy ACCEPT 559 packets, 49111 bytes)
pkts bytes target prot opt in out source destination
1822 109K ACCEPT 0 -- * * 10.0.0.1 0.0.0.0/0
0 0 REJECT 6 -- * * 10.0.0.157 10.0.0.161 multiport dports 22,80 reject-with icmp-port-unreachable
iprange 扩展
指明连续的(但一般不是整个网络)ip地址范围
[!] --src-range from[-to] #源IP地址范围
[!] --dst-range from[-to] #目标IP地址范围
#拒绝 10.0.0.9-10.0.0.99 这91个IP #libxt_iprange.so用于实现IP地址范围的匹配功能
[root@ubuntu24 ~]# iptables -t filter -A INPUT -m iprange --src-range 10.0.0.9-10.0.0.99 -j DROP
[root@ubuntu24 ~]# iptables -nvL
Chain INPUT (policy ACCEPT 561 packets, 49289 bytes)
pkts bytes target prot opt in out source destination
2082 124K ACCEPT 0 -- * * 10.0.0.1 0.0.0.0/0
0 0 DROP 0 -- * * 0.0.0.0/0 0.0.0.0/0 source IP range 10.0.0.9-10.0.0.99
mac 扩展
mac 模块可以指明源MAC地址,适用于:PREROUTING, FORWARD,INPUT chains
[!] --mac-source XX:XX:XX:XX:XX:XX
#拒绝 mac 地址为 00:0c:29:f3:44:9a 的主机
[root@ubuntu24 ~]# iptables -t filter -A IvnL
Chain INPUT (policy ACCEPT 561 packets, 49289 bytes)
pkts bytes target prot opt in out source destination
2391 143K ACCEPT 0 -- * * 10.0.0.1 0.0.0.0/0
3 252 REJECT 0 -- * * 0.0.0.0/0 10.0.0.161 MAC 00:0c:29:1e:65:08 reject-with icmp-port-unreachable
[root@ubuntu24 ~]# ping 10.0.0.161
PING 10.0.0.161 (10.0.0.161) 56(84) bytes of data.
From 10.0.0.161 icmp_seq=1 Destination Port Unreachable
From 10.0.0.161 icmp_seq=2 Destination Port Unreachable
string 扩展
对报文中的应用层数据做字符串模式匹配检测
--algo {bm|kmp} #过滤算法 Boyer-Moore|Knuth-Pratt-Morris,在Rocky8.6中bm算法配合nginx有问题
--from offset #开始偏移量,一般用来跳过包头,只检查具体内容,这样能提高效率
--to offset #结束偏移量
[!] --string pattern #具体要匹配的字符串
[!] --hex-string pattern #具体要匹配的字符串,16进制格式
#示例
[root@ubuntu24 html]# curl 10.0.0.161/bd.html
baidu
[root@ubuntu24 html]# curl 10.0.0.161/gg.html
google
#设置出口规则,在返回的数据包中,跳过前62字节的报文头,如果内容中出现 google,则拒绝返回
[root@ubuntu ~]# iptables -t filter -A OUTPUT -m string --algo kmp --from 62 --string "google" -j REJECT
[root@ubuntu24 html]# iptables -vnL OUTPUT
Chain OUTPUT (policy ACCEPT 26 packets, 2760 bytes)
pkts bytes target prot opt in out source destination
0 0 REJECT 0 -- * * 0.0.0.0/0 0.0.0.0/0 STRING match "google" ALGO name kmp FROM 62 reject-with icmp-port-unreachable
#再次测试
[root@ubuntu24 ~]# curl 10.0.0.161/bd.html
baidu
#google 无法返回
[root@ubuntu24 ~]# curl 10.0.0.161/gg.html
^C
#区分大小写,大写不会被命中
[root@ubuntu24 ~]# curl 10.0.0.161/GG.html
GOOgle
time 扩展
根据将报文到达的时间与指定的时间范围进行匹配,此扩展中默认使用UTC时间,所以使用时,要根据当前时区进行计算。
此扩展在CentOS8中有问题
--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...] #指定几号,1-31
[!] --weekdays day[,day...] #指定星期几,可以写Mon|Tue|Wed|Thu|Fri|Sat|Sun,也可以写1|2|3|4|5|6|7
--contiguous
--kerneltz #内核时区,此选项不建议使用,CentOS7版本以上系统默认UTC
#示例
#Rocky8.6配置报错
[root@rocky ~]# iptables -t filter -A INPUT -m time --timestart 01:00 --timestop
14:00 -s 10.0.0.150 -j REJECT
Warning: Extension time revision 0 not supported, missing kernel module?
iptables v1.8.4 (nf_tables): RULE_APPEND failed (No such file or directory):
rule in chain INPUT
#在ubuntu中设置
[root@ubuntu24 html]# iptables -t filter -A INPUT -m time --timestart 1:00 --timestop 14:00 -s 10.0.0.157 -j REJECT
[root@ubuntu24 html]# iptables -vnL
Chain INPUT (policy ACCEPT 739 packets, 88669 bytes)
pkts bytes target prot opt in out source destination
4418 263K ACCEPT 0 -- * * 10.0.0.1 0.0.0.0/0
31 2604 REJECT 0 -- * * 10.0.0.157 0.0.0.0/0 TIME from 01:00:00 to 14:00:00 UTC reject-with icmp-port-unreachable
[root@ubuntu24 ~]# ping 10.0.0.161
PING 10.0.0.161 (10.0.0.161) 56(84) bytes of data.
From 10.0.0.161 icmp_seq=1 Destination Port Unreachable
From 10.0.0.161 icmp_seq=2 Destination Port Unreachable
From 10.0.0.161 icmp_seq=3 Destination Port Unreachable
From 10.0.0.161 icmp_seq=4 Destination Port Unreachable
From 10.0.0.161 icmp_seq=5 Destination Port Unreachable
#先暂停掉ntp服务
[root@ubuntu24 html]# timedatectl set-ntp 0
[root@ubuntu24 html]# date -s "+20 hour"
[root@ubuntu24 ~]# ping 10.0.0.161
From 10.0.0.161 icmp_seq=11 Destination Port Unreachable
From 10.0.0.161 icmp_seq=12 Destination Port Unreachable
From 10.0.0.161 icmp_seq=13 Destination Port Unreachable
64 bytes from 10.0.0.161: icmp_seq=14 ttl=64 time=0.399 ms
64 bytes from 10.0.0.161: icmp_seq=15 ttl=64 time=0.389 ms
64 bytes from 10.0.0.161: icmp_seq=16 ttl=64 time=0.363 ms
connlimit 扩展
根据每客户端IP做并发连接数数量匹配,可防止 Dos(Denial of Service,拒绝服务)攻击
--connlimit-upto N #连接的数量小于等于N时匹配
--connlimit-above N #连接的数量大于N时匹配
#示例
#在另一台机上安装压测工具
[root@ubuntu24 ~]# apt install apache2-utils
[root@ubuntu24 ~]# ab -n 100000 -c 1000 http://10.0.0.161/
-n N #总共发起多少个请求,默认一个
-c N #每次请求并发数,默认一个
#在161主机上查看连接
[root@ubuntu24 ~]# ss -nt
#如果并发连接数超过10个,则拒绝连接
[root@ubuntu24 ~]# iptables -t filter -A INPUT -m connlimit --connlimit-above 10 -j REJECT
#已经没有办法发起连接
[root@ubuntu24 ~]# ab -n 100000 -c 1000 http://10.0.0.161/
This is ApacheBench, Version 2.3 <$Revision: 1903618 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking 10.0.0.161 (be patient)
apr_socket_recv: Connection refused (111)
Total of 1 requests completed
limit 扩展
基于收发报文的速率做匹配 , 令牌桶过滤器。
connlimit 扩展是限制单个客户端对服务器的并发连接数,limit 扩展是限制服务器上所有的连接数。
--limit-burst number #前多少个包不限制
--limit [/second|/minute|/hour|/day] #在一个时间区间内能接收的连接数
#示例
#添加 icmp 放行规则,前10个不处理,后面每分钟放行20个
[root@ubuntu24 ~]# iptables -t filter -A INPUT -p icmp --icmp-type 8 -m limit --limit 20/minute --limit-burst 10 -j ACCEPT
#兜底的拒绝规则
[root@ubuntu24 ~]# iptables -t filter -A INPUT -p icmp -j REJECT
[root@ubuntu24 ~]# iptables -vnL
Chain INPUT (policy ACCEPT 652 packets, 39685 bytes)
pkts bytes target prot opt in out source destination
0 0 ACCEPT 1 -- * * 0.0.0.0/0 0.0.0.0/0 icmptype 8 limit: avg 20/min burst 10
0 0 REJECT 1 -- * * 0.0.0.0/0 0.0.0.0/0 reject-with icmp-port-unreachable
state 扩展
state 扩展,可以根据 "连接追踪机制" 去检查连接的状态,比较耗费资源
[!] --state state
state 扩展的状态
状态类型 | 说明 |
---|---|
NEW | 新发出请求;连接追踪信息库中不存在此连接的相关信息条目,因此,将其识别 为第一次发出的请求 |
ESTABLISHED | NEW状态之后,连接追踪信息库中为其建立的条目失效之前期间内所进行的通 信状态 |
RELATED | 新发起的但与已有连接相关联的连接,如:ftp协议中的数据连接与命令连接之 间的关系 |
INVALID | 无效的连接,如flag标记不正确 |
UNTRACKED | 未进行追踪的连接,如:raw表中关闭追踪 |
连接追踪机制需要内核选项支持,rocky中开启了此功能,所以此处我们在 rocky 中进行测试
[root@Rocky-9 ~]# cat /usr/lib/modules/5.14.0-427.28.1.el9_4.x86_64/config | grep CONFIG_NF_CONNTRACK_PROCFS
CONFIG_NF_CONNTRACK_PROCFS=y
#当前还没有启用
[root@Rocky-9 ~]# lsmod | grep nf_conntrack
#启用连接跟踪机制后,会自动生成此文件
[root@Rocky-9 ~]# cat /proc/net/nf_conntrack
cat: /proc/net/nf_conntrack: No such file or directory
#只要系统中某处要使用到连接追踪机制,连接追踪机制相关模块会自动加载
#示例
#拒绝新连接
#先建立连接,再设置防火墙规则
64 bytes from 10.0.0.153: icmp_seq=4 ttl=64 time=0.405 ms
64 bytes from 10.0.0.153: icmp_seq=5 ttl=64 time=0.296 ms
64 bytes from 10.0.0.153: icmp_seq=6 ttl=64 time=0.671 ms
64 bytes from 10.0.0.153: icmp_seq=7 ttl=64 time=0.911 ms
64 bytes from 10.0.0.153: icmp_seq=8 ttl=64 time=1.16 ms
64 bytes from 10.0.0.153: icmp_seq=9 ttl=64 time=0.822 ms
[root@Rocky-9 ~]# iptables -t filter -A INPUT -m state --state ESTABLISHED -j ACCEPT
[root@Rocky-9 ~]# iptables -t filter -A INPUT -m state --state NEW -j REJECT
#己连接的客户端可以继续通信
#新的客户端拒绝连接
[root@ubuntu24 ~]# ping 10.0.0.153
PING 10.0.0.153 (10.0.0.153) 56(84) bytes of data.
From 10.0.0.153 icmp_seq=1 Destination Port Unreachable
From 10.0.0.153 icmp_seq=2 Destination Port Unreachable
#启用连接跟踪机制之后,连接状态是记录在文件中的
[root@Rocky-9 ~]# cat /proc/net/nf_conntrack
ipv4 2 tcp 6 299 ESTABLISHED src=10.0.0.153 dst=10.0.0.1 sport=22 dport=2587 src=10.0.0.1 dst=10.0.0.153 sport=2587 dport=22 [ASSURED] mark=0 zone=0 use=2
ipv4 2 icmp 1 29 src=10.0.0.157 dst=10.0.0.153 type=8 code=0 id=14954 src=10.0.0.153 dst=10.0.0.157 type=0 code=0 id=14954 mark=0 zone=0 use=2
#nf_conntrack 文件内容说明
ipv4 #第一列 网络层协议名称
2 #第二列 网络层协议号
icmp #第三列 传输层协议名称
1 #第四列 传输层协议号
29 #第五列 无后续包进入时无效的秒数,即老化时间
ESTABLISHED #第六列 该连接的连接状态,不是所有协议都有此列值
#后续都是k=v 格式的连接参数和选项
#nf_conntrack文件中能记录多少内容,取决于配置
[root@Rocky-9 ~]# cat /proc/sys/net/netfilter/nf_conntrack_max
65536
相关内核参数
参数 | 说明 |
---|---|
/proc/sys/net/netfilter/nf_conntrack_max | 连接追踪功能所能够容纳的最大连接数量,修改 此处,下一项也会改变 |
/proc/sys/net/nf_conntrack_max | 连接追踪功能所能够容纳的最大连接数量,修改 此处,上一项也会改变 |
/proc/sys/net/netfilter/nf_conntrack_count | 己追踪的连接数量 |
/proc/sys/net/netfilter/time | 不同协议超时时长,单位为秒,超时后会踢出己 监控的队列 |
target
-j targetname [per-target-options]
target | 说明 |
---|---|
ACCEPT | 允许通过,命中此规则后,不再对比当前链的其它规则,进入下一个链 |
DROP | 丢弃,命中此规则后,该连接直接中断,发送方收不到任何回应 |
REJECT | 拒绝,命中此规则后,该连接直接中断,发送方能收到拒绝回应 |
RETURN | 返回,在当前链中不再继续匹配,返回到主链,一般用于自定义规则链中 |
LOG | 记录日志,将被命中的数据记录在日志中 |
SNAT | 源IP地址转换 |
DNAT | 目标IP地址转换 |
REDIRECT | 本机端口转换 |
MASQUERADE | 源IP地址动态转换 |
自定义 |
--log-level level #日志级别
debug|info|notice|warning|error|crit|alert|emerg
--log-prefix prefix #日志前缀,用于区别不同的日志,最多29个字符
规则优化最佳实践
-
安全放行所有入站和出站的状态为ESTABLISHED状态连接,建议放在第一条,效率更高
-
谨慎放行入站的新请求
-
有特殊目的限制访问功能,要在放行规则之前加以拒绝
-
同类规则(访问同一应用,比如:http ),匹配范围小的放在前面,用于特殊处理
-
不同类的规则(访问不同应用,一个是http,另一个是mysql ),匹配范围大的放在前面,效率更高
-
应该将那些可由一条规则能够描述的多个规则合并为一条,减少规则数量,提高检查效率
-
设置默认策略,建议白名单(只放行特定连接)
-
默认规则(iptables -P)是 ACCEPT,不建议修改,容易出现 “自杀” 现象
-
规则的最后定义规则做为默认策略,推荐使用,放在最后一条
iptables 规则保存
使用iptables 命令定义的规则,手动删除之前,其生效期限为 kernel 存活期限,当系统重启之后,定义的规则会消失。
持久化保存规则
[root@Rocky-9 ~]# iptables -vnL
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
28 1684 ACCEPT 0 -- * * 0.0.0.0/0 0.0.0.0/0 state ESTABLISHED
0 0 REJECT 0 -- * * 0.0.0.0/0 0.0.0.0/0 state NEW reject-with icmp-port-unreachable
#在标准输出中显示
[root@Rocky-9 ~]# iptables-save
# Generated by iptables-save v1.8.10 (nf_tables) on Thu Sep 26 10:46:33 2024
*filter
:INPUT ACCEPT [4:336]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A INPUT -m state --state ESTABLISHED -j ACCEPT
-A INPUT -m state --state NEW -j REJECT --reject-with icmp-port-unreachable
COMMIT
# Completed on Thu Sep 26 10:46:33 2024
#导出到文件
[root@Rocky-9 ~]# iptables-save > iptables.rule
#清空规则
[root@Rocky-9 ~]# iptables -F
#导入
#加载保存的规则
[root@Rocky-9 ~]# iptables-restore < ./iptables.rule
[root@Rocky-9 ~]# iptables -vnL
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
28 1684 ACCEPT 0 -- * * 0.0.0.0/0 0.0.0.0/0 state ESTABLISHED
0 0 REJECT 0 -- * * 0.0.0.0/0 0.0.0.0/0 state NEW reject-with icmp-port-unreachable
iptables-restore 命令
iptables-restore命令是将保存在文件中的防火墙规则导入到系统中
iptables-restore [option] [file]
#常用选项
-h #显示帮助
-t #测试
-n #保留原有规则
开机自动加载规则
[root@rocky ~]# vim /etc/rc.d/rc.local
#增加如下行
iptables-restore < /root/iptables.rule
#保存后给文件增加执行权限
[root@rocky ~]# chmod a+x /etc/rc.d/rc.local
网络防火墙
NAT 网络转换原理
NAT
NAT:(Network Address Translation) 网络地址转换
局域网中的主机都是分配的私有IP地址,这些IP地址在互联网上是不可达的,局域网中的主机,在与互 联网通讯时,要经过网络地址转换,去到互联网时,变成公网IP地址对外发送数据。服务器返回数据 时,也是返回到这个公网地址,再经由网络地址转换返回给局域网中的主机。
一个局域网中的主机,想要访问互联网,在出口处,应该有一个公网可达的IP地址,应该能将局域网中 的IP地址通过NAT转换成公网IP。
NAT的分类
NAT | 说明 | 备注 |
---|---|---|
SNAT | Source NAT | 源地址转换,修改请求报文中的源IP地址 |
DNAT | Destination NAT | 目标地址转换,修改响应报文中的目标IP地址 |
PNAT | Port NAT | 端口转换,IP地址和端口都进行转换 |
iptables 中的 NAT
在 iptables 中的基于 nat 表来实现 SNAT 和 DNAT
左边 10.0.0.0/24 网段的主机用来模拟内网环境,需要配置路由指向
192.168.10.0/24 网段不需要配置路由,右边用来模拟互联网环境,让其与防火墙主机之间没有路由表
#修改10.0.0.150 主机的网关,指向 10.0.0.123
[root@ubuntu24 ~]# route add default gw 10.0.0.123 dev eth0
[root@ubuntu24 ~]# route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 10.0.0.123 0.0.0.0 UG 0 0 0 eth0
10.0.0.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0
#防火墙主机只保留同网段的网关
[root@ubuntu24 sites-enabled]# 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 0 0 0 eth0
192.168.10.0 0.0.0.0 255.255.255.0 U 0 0 0 eth1
#确认开启 ip_forward功能
[root@ubuntu24 sites-enabled]# sysctl -a | grep ip_forward
net.ipv4.ip_forward = 1
...
#如果没有开启的话
[root@ubuntu24 sites-enabled]# echo 1 > /proc/sys/net/ipv4/ip_forward
#192.168.10.150主机
#关闭防火墙
[root@ubuntu ~]# systemctl disable --now ufw.service
Synchronizing state of ufw.service with SysV service script with
/lib/systemd/systemd-sysv-install.
Executing: /lib/systemd/systemd-sysv-install disable ufw
Removed /etc/systemd/system/multi-user.target.wants/ufw.service.
#开启nginx 服务
[root@ubuntu22:~]# systemctl status nginx.service
● nginx.service - A high performance web server and a reverse proxy server
Loaded: loaded (/lib/systemd/system/nginx.service; enabled; vendor preset: enabled)
Active: active (running) since Thu 2024-09-26 05:35:03 UTC; 1h 15min ago
Docs: man:nginx(8)
Main PID: 1012 (nginx)
Tasks: 3 (limit: 2176)
Memory: 9.1M
CPU: 71ms
CGroup: /system.slice/nginx.service
├─1012 "nginx: master process /usr/sbin/nginx -g daemon on; master_process on;"
├─1014 "nginx: worker process" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" ""
└─1015 "nginx: worker process" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" ""
#在本机测试web服务
[root@ubuntu22:~]# curl 192.168.10.150
<h2>this page from 192.168.10.150<h2>
#在防火墙主机测试web服务
[root@ubuntu24 sites-enabled]# curl 192.168.10.150
<h2>this page from 192.168.10.150<h2>
#查看日志信息
[root@ubuntu22:~]# tail /var/log/nginx/access.log
192.168.10.150 - - [26/Sep/2024:06:51:34 +0000] "GET / HTTP/1.1" 200 38 "-" "curl/7.81.0"
192.168.10.123 - - [26/Sep/2024:06:52:10 +0000] "GET / HTTP/1.1" 200 38 "-" "curl/8.5.0"
#在10.0.0.150主机上测试
#可以ping通防火墙
[root@ubuntu24 ~]# ping 10.0.0.123
PING 10.0.0.123 (10.0.0.123) 56(84) bytes of data.
64 bytes from 10.0.0.123: icmp_seq=1 ttl=64 time=0.746 ms
[root@ubuntu24 ~]# ping 192.168.10.123
PING 192.168.10.123 (192.168.10.123) 56(84) bytes of data.
64 bytes from 192.168.10.123: icmp_seq=1 ttl=64 time=0.962 ms
#但ping 不同目标机器
[root@ubuntu24 ~]# ping 192.168.10.150
PING 192.168.10.150 (192.168.10.150) 56(84) bytes of data.
^C
--- 192.168.10.150 ping statistics ---
2 packets transmitted, 0 received, 100% packet loss, time 1023ms
SNAT 实现源IP地址转换
SNAT:Source NAT,源地址转换,基于nat表,工作在 POSTROUTING 链上。
具体是指将经过当前主机转发的请求报文的源IP地址转换成根据防火墙规则指定的IP地址。
iptables -t nat -A POSTROUTING -s LocalNet ! -d LocalNet -j SNAT --to-source
ExtIP [--random]
--to-source [ipaddr[-ipaddr]][:port[-port]] #转换成指定IP,或指定范围内的IP,端口可选
--random #端口映射基于hash算法随机化
#在防火墙主机上添加规则,如果源IP是 10.0.0.0/24网段的IP,则出去的时候,替换成192.168.10.123
[root@ubuntu24 sites-enabled]# iptables -t nat -A POSTROUTING -s 10.0.0.0/24 ! -d 10.0.0.0/24 -j SNAT --to-source 192.168.10.123
[root@ubuntu24 sites-enabled]# iptables -t nat -L POSTROUTING
Chain POSTROUTING (policy ACCEPT)
target prot opt source destination
SNAT all -- 10.0.0.0/24 !10.0.0.0/24 to:192.168.10.123
#测试,10.0.0.150 主机可以到达 192.168.10.150
[root@ubuntu24 ~]# ping 192.168.10.150
PING 192.168.10.150 (192.168.10.150) 56(84) bytes of data.
64 bytes from 192.168.10.150: icmp_seq=1 ttl=63 time=2.08 ms
64 bytes from 192.168.10.150: icmp_seq=2 ttl=63 time=1.22 ms
64 bytes from 192.168.10.150: icmp_seq=3 ttl=63 time=0.590 ms
#在 192.168.10.150主机上抓PING包
#所有的PING包都来自于 192.168.10.123,而并非是 10.0.0.150
[root@ubuntu22:~]# tcpdump icmp
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on ens33, link-type EN10MB (Ethernet), snapshot length 262144 bytes
07:05:40.371030 IP 192.168.10.123 > 192.168.10.150: ICMP echo request, id 15740, seq 1, length 64
07:05:40.371055 IP 192.168.10.150 > 192.168.10.123: ICMP echo reply, id 15740, seq 1, length 64
07:05:41.372536 IP 192.168.10.123 > 192.168.10.150: ICMP echo request, id 15740, seq 2, length 64
07:05:41.372574 IP 192.168.10.150 > 192.168.10.123: ICMP echo reply, id 15740, seq 2, length 64
#web服务测试
[root@ubuntu24 ~]# curl 192.168.10.150
<h2>this page from 192.168.10.150<h2>
#查看192.168.10.150的日志
[root@ubuntu22:~]# tail -f /var/log/nginx/access.log
192.168.10.150 - - [26/Sep/2024:06:51:34 +0000] "GET / HTTP/1.1" 200 38 "-" "curl/7.81.0"
192.168.10.123 - - [26/Sep/2024:06:52:55 +0000] "GET / HTTP/1.1" 200 38 "-" "curl/8.5.0"
192.168.10.123 - - [26/Sep/2024:07:07:24 +0000] "GET / HTTP/1.1" 200 38 "-" "curl/8.5.0"
MASQUERADE 实现源IP地址转换
如果我们内网的出口设备上有固定IP,则直接指定 --to-source IP 没有任何问题,但是如果是使用拨号上 网,出口网络设备上的IP地址会发生变化,这种情况下,我们的出口IP不能写成固定的
这种场景下,我们需要使用 MASQUERADE 进行地址转换,MASOUERADE 可以从主机网卡上自动获取 IP地址当作出口IP地址
iptables -t nat -A POSTROUTING -s LocalNET ! -d LocalNet -j MASQUERADE [--toports port[-port]] [--random]
--to-ports port[-port] #指定端口
--random #端口映射基于hash算法随机化
#清空防火墙主机规则
#用 MASQUERADE 设置SNAT转发
[root@ubuntu24 sites-enabled]# iptables -t nat -A POSTROUTING -s 10.0.0.0/24 ! -d 10.0.0.0/24 -j MASQUERADE
[root@ubuntu24 sites-enabled]# iptables -t nat -vnL POSTROUTING
Chain POSTROUTING (policy ACCEPT 1 packets, 132 bytes)
pkts bytes target prot opt in out source destination
0 0 MASQUERADE 0 -- * * 10.0.0.0/24 !10.0.0.0/24
#测试,10.0.0.150 主机可以到达 192.168.10.150
[root@ubuntu24 ~]# ping 192.168.10.150
PING 192.168.10.150 (192.168.10.150) 56(84) bytes of data.
64 bytes from 192.168.10.150: icmp_seq=1 ttl=63 time=2.78 ms
64 bytes from 192.168.10.150: icmp_seq=2 ttl=63 time=0.902 ms
#在 192.168.10.150主机上抓PING包
#所有的PING包都来自于 192.168.10.123
[root@ubuntu22:~]# tcpdump icmp
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on ens33, link-type EN10MB (Ethernet), snapshot length 262144 bytes
07:13:36.690200 IP 192.168.10.123 > 192.168.10.150: ICMP echo request, id 15745, seq 5, length 64
07:13:36.690225 IP 192.168.10.150 > 192.168.10.123: ICMP echo reply, id 15745, seq 5, length 64
#防火墙主机IP发生变化,192.168.10.123 > 192.168.10.150,192.168.10.123也会发生变化
DNAT 实现目标IP地址转换
在内网环境中,使用私有IP地址的设备要与互联网进行通讯时,需要借助出口设备将原内网IP地址转换 成公网可达的IP地址再进行通讯。
在内网环境中,只有在出口设备上才有一个(或数个)公网可达的IP,所以在互联网上,是不能路由至内网 主机的。如果要让内网主机上的服务在公网上可见,我们需要使用 DNT 实现目标IP地址转换。
DNAT:Destination NAT,目标地址转换,基于nat表,工作在 PREROUTING 链上
iptables -t nat -A PREROUTING -d ExtIP -p tcp|udp|icmp --dport PORT -j DNAT --todestination InterSeverIP[:PORT]
-d ExtIP #指公网可达的IP地址,必须是固定IP
--to-destination [ipaddr[-ipaddr]][:port[-port]] #转换成指定IP,或指定范围内的IP,端口可选
#在 192.168.10.150上查看
[root@ubuntu22:~]# route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
192.168.10.0 0.0.0.0 255.255.255.0 U 0 0 0 ens33
#清空防火墙主机规则
#在防火墙主机上设置DNAT转发规则,在使 192.168.10.150 访问 192.168.10.123 的 web 服务时,服务时将请求转发到 10.0.0.150上
[root@ubuntu24 sites-enabled]# iptables -t nat -A PREROUTING -d 192.168.10.123 -p tcp --dport 80 -j DNAT --to-destination 10.0.0.150:80
[root@ubuntu24 sites-enabled]# iptables -t nat -vnL
Chain PREROUTING (policy ACCEPT 14 packets, 1632 bytes)
pkts bytes target prot opt in out source destination
0 0 DNAT 6 -- * * 0.0.0.0/0 192.168.10.123 tcp dpt:80 to:10.0.0.150:80
#测试
[root@ubuntu22:html]# curl 192.168.10.123
<h2>this page from 10.0.0.150<h2>
DNAT 只能将一条请求规则重定向到一台后端主机,无法实现负载均衡功能
早期 iptables 中有一条规则重定向到多台后端主机的功能,后来被 lvs 取代
防火墙主机上看不到80和8080的端口监听,因为这里看到的是应用程序在监听的端口,而防火墙是在内核中实现的
REDIRECT 实现本机端口转换
REDIRECT:重定向,通过定义规则,将收到的数据包转发至同一主机的不同端口
REDIRECT 功能无需开启内核 ip_forward 转发
iptables -t nat -A PREROUTING -d ExtIP -p tcp|udp --dport PORT -j REDIRECT --to-ports PORT
--to-ports #新的端口
#修改nginx配置,监听81端口
[root@ubuntu24 ~]# vim /etc/nginx/sites-enabled/default
include /etc/nginx/conf.d/*.conf;
server {
listen 81 default_server;
listen [::]:81 default_server;
#重启服务
[root@ubuntu24 ~]# systemctl restart nginx
#测试, 在10.0.0.123 上访问 10.0.0.150 的 web服务
[root@ubuntu24 ~]# curl 10.0.0.150
curl: (7) Failed to connect to 10.0.0.150 port 80 after 1 ms: Connection refused
#在10.0.0.150上添加REDIRECT规则,将80端口的请求转发到81端口
[root@ubuntu24 html]# iptables -t nat -A PREROUTING -d 10.0.0.150 -p tcp --dport 80 -j REDIRECT --to-ports 81
[root@ubuntu24 html]# iptables -t nat -vnL
Chain PREROUTING (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
0 0 REDIRECT 6 -- * * 0.0.0.0/0 10.0.0.150 tcp dpt:80 redir ports 81
[root@ubuntu24 sites-enabled]# curl 10.0.0.150
<h2>this page from 10.0.0.150<h2>
iptables 中的自定义链
iptables 中除了系统自带的五个链之外,还可以自定义链,来实现将规则进行分组,重复调用的目的。
自定义链添加规则之后,要作为系统链的 target 与之关联,才能起到作用
#添加自定义链
[root@ubuntu ~]# iptables -t filter -N web_chain
#查看
[root@ubuntu ~]# iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain FORWARD (policy DROP)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
Chain web_chain (0 references)
target prot opt source destination
#修改
[root@ubuntu ~]# iptables -t filter -E web_chain WEB_CHAIN
#向自定链中添加规则
[root@ubuntu ~]# iptables -t filter -A WEB_CHAIN -p tcp -m multiport --dports 80,443 -j ACCEPT
#查看
[root@ubuntu24 sites-enabled]# iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
Chain WEB_CHAIN (0 references)
target prot opt source destination
ACCEPT tcp -- anywhere anywhere multiport dports http,https
#自定义链必须关联到系统链上才能使用
[root@ubuntu ~]# iptables -t filter -A INPUT -s 10.0.0.1 -j WEB_CHAIN
#再次查看
[root@ubuntu24 sites-enabled]# iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
WEB_CHAIN all -- 10.0.0.1 anywhere
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
Chain WEB_CHAIN (1 references)
target prot opt source destination
ACCEPT tcp -- anywhere anywhere multiport dports http,https
在使用单独的自定义链的情况下,如果需要修改,则只需要修改链上的具体规则,而不用修改自定义链 与系统链的关联关系
自定义链中的规则进行复用
清空规则,并不会删除自定义链
[root@ubuntu24 sites-enabled]# iptables -t filter -F
[root@ubuntu24 sites-enabled]# iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
Chain WEB_CHAIN (0 references)
target prot opt source destination
#删除自定义链
[root@ubuntu ~]# iptables -t filter -X WEB_CHAIN
firewalld
firewalld 介绍
firewalld 是 CentOS 7.0 新推出的管理 netfilter 的用户空间软件工具,也被 ubuntu18.04 版以上所支 持 (apt install firewalld)
firewalld 是配置和监控防火墙规则的系统守护进程,可以实现 iptables,ip6tables,ebtables 的功 能。
firewalld 服务由 firewalld 包提供。
firewalld 中有多个系统自带的 Zone,每个zone都对应不同的防火墙规则,使用不同的 Zone,就表示 使用不同的防火墙规则,每个Zone的具体规则可以进行修改,也可以自定义Zone。
firewalld 中自带的 Zone
Zone | 说明 |
---|---|
block | 拒绝所有 |
dmz | 拒绝除和传出流量相关的,以及ssh预定义服务之外的其它所有传入流量 |
drop | 拒绝除和传出流量相关的所有传入流量(甚至不以ICMP错误进行回应) |
external | 拒绝除和传出流量相关的,以及ssh预定义服务之外的其它所有传入流量,属于 external zone的传出ipv4流量的源地址将被伪装为传出网卡的地址 |
home | 拒绝除和传出流量相关的,以及ssh,mdsn,ipp-client,samba-client,dhcpv6-client预 定义服务之外其它所有传入流量 |
internal | 和home相同 |
public | 拒绝除和传出流量相关的,以及ssh,dhcpv6-client预定义服务之外的其它所有传入 流量,新加的网卡默认属于public zone |
trusted | 允许所有流量 |
work | 拒绝除和传出流量相关的,以及ssh,ipp-client,dhcpv6-client预定义服务之外的其它 所有传入流量 |
firewalld 三种配置方法
-
firewall-config 图形工具:需要安装 firewall-config 包
-
firewall-cmd 命令行工具:来自于 firewalld 包,默认己安装
-
/etc/firewalld/* 配置文件:一般不直接修改配置文件来管理firewalld
#安装
[root@c7 ~]# yum install -y firewall-config
#要依赖本地主机的图形化软件
[root@c7 ~]# firewall-config
firewall-cmd 工具
firewall-cmd 是 firewalld 服务的命令行编辑工具
firewall-cmd [OPTIONS...]
#常用选项
--state #查看服务运行状态
--reload #重载,修改后只是在当前运行环境下生效,如果想还原回去之前的配置,可以使用此选项
--complete-reload #完全重载
--runtime-to-permanent #将当前运行状态的配置永久保存
--check-config #检查规则配置是否出错
--get-log-denied #显示日记记录规则
--set-log-denied= #设置日志记录规则 all|unicast|broadcast|multicast|off
--permanent #设置永久生效规则时加上此项,如果没有此项,则更改的都是临时生效规则
--get-default-zone #显示默认使用的 zone
--set-default-zone= #设置默认zone
--get-active-zones #显示当前使用中的 zone及对应的设备
--get-zones #显示可用的 zone
--get-services #显示所有己定义的 services,每一个 services 对应一个或多个端口规则,多个 service 组成 zone
--get-icmptypes #显示icmp协议类型
--get-zone-of-interface= #显示指定设备的 zone
--list-all-zones #列出每个zone中的所有规则
--new-zone= #添加一个新的zone
--new-zone-from-file= #从指定文件中读取规则,添加新zone
--delete-zone= #删除指定zone
--zone= #指定zone,配合其它选项
--info-zone= #查看指定zone运行情况
--new-service= #添加一个新的 service
--new-service-from-file= #从文件中添加一个新的 serivce
--list-services #显示所有 service
--delete-service= #删除 service
--info-service= #输出 info 相关信息
--change-interface= #指定要修改的设备,与其它项一起配合使用
#查看默认Zone中的所有内容
[root@rocky86 ~]# firewall-cmd --list-all
block (active)
target: %%REJECT%% #目标
icmp-block-inversion: no #决定 icmp-blocks
interfaces: eth0 eth1 #生效的网络设备
sources: #来源,IP或MAC
services: http ssh #放行的服务
ports: #允许的目标端口,即本地开放的端口
protocols: #允许通过的协议
forward: no #允许转发的端口
masquerade: no #是否允许伪装(yes/no),可改写来源IP地址及mac地址
forward-ports: #允许转发的端口
source-ports: #允许的源端口
icmp-blocks: #ICMP类型,配合 icmp-block-inversion=no/yes一起使用
rich rules: #富规则