Linux 防火墙

防火墙

1.Linux 防火墙的两种主流工具:iptables 与 firewalld

Linux 内核本身集成了 "netfilter" 防火墙框架(内核态),而 iptablesfirewalld用户态工具,用于配置 netfilter 的规则。两者关系如下:

  • netfilter:内核中的数据包处理模块(真正执行过滤逻辑),是 "底层引擎"。
  • iptables:传统的命令行工具,直接操作 netfilter 规则,属于 "静态防火墙"(规则变更需重启服务或手动刷新)。
  • firewalld:CentOS 8+ 引入的动态防火墙管理工具,基于 netfilter,通过 "区域" 和 "服务" 简化规则配置,支持动态更新(无需重启服务)。

一句话总结:netfilter 是内核 "引擎",iptables 和 firewalld 是操作引擎的 "遥控器",只是遥控器的操作逻辑不同。

2.iptables

2.1四表五链

1. 外界访问本机 (入站流量)

场景:用户访问服务器上的网站、SSH 连接服务器。

  • 路径 : 外界PREROUTING路由判断(是给我的)INPUT本机进程

  • 关键点

    :

    • PREROUTING: 最先接触数据包,适合做端口映射 (DNAT)。
    • INPUT: 只有目标 IP 是本机的包才会走到这里,是做主机防火墙(允许/拒绝访问)的核心位置。
2. 本机访问外界 (出站流量)

场景: 服务器主动下载更新、服务器代码调用外部 API。

  • 路径 : 本机进程OUTPUT路由判断POSTROUTING外界

  • 关键点

    :

    • OUTPUT: 控制本机程序能访问哪些外部资源。
    • POSTROUTING: 数据包离开前的最后一步,适合做源地址转换 (SNAT/Masquerade),让内网服务器能以上网关身份上网。
3. 本机作为网关转发 (转发流量)

场景: 服务器作为路由器、Docker 宿主机转发容器流量、K8s Node 转发 Pod 流量。

  • 路径 : 外界PREROUTING路由判断(不是给我的)FORWARDPOSTROUTING外界(另一侧)

  • 关键点

    :

    • 不经过 INPUT/OUTPUT : 转发的流量不会进入本机应用层,也不会经过 OUTPUT 链。
    • FORWARD: 专门用于控制是否允许数据包"穿墙而过"。
链名 位置 作用 形象比喻
PREROUTING 刚进门 修改目标 (DNAT) 前台登记:不管找谁,先在这改目的地
INPUT 进屋内 过滤入站 保安查岗:想进屋见我?先检查证件
FORWARD 穿堂过 过滤转发 过道安检:不住这?只是路过?检查放行
OUTPUT 出屋前 过滤出站 出门审批:我要出去办事?先看看允不允许
POSTROUTING 出门后 修改来源 (SNAT) 门卫换装:出去时把发件人改成网关地址
表名称 核心功能 包含的链(规则可配置在哪些关卡) 最常用场景
filter 过滤数据包(允许 / 拒绝),默认表 INPUTFORWARDOUTPUT 日常访问控制(如禁止特定 IP 访问)
nat 网络地址转换(修改数据包的源 / 目的 IP / 端口) PREROUTINGINPUTOUTPUTPOSTROUTING 端口映射(如公网 IP:80 → 内网 IP:8080)、共享上网
mangle 修改数据包标记(如 TOS、TTL),用于高级路由 所有五链 流量整形、QoS 服务质量控制
raw 关闭数据包的连接跟踪(提升性能) PREROUTINGOUTPUT 高并发场景(如 Web 服务器)优化

2.2基本命令

bash 复制代码
1.查看表的规则
[root@test ~]# iptables -nL ----默认是filter表
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


[root@test ~]# iptables -nL -t nat
Chain PREROUTING (policy ACCEPT)
target     prot opt source               destination

Chain INPUT (policy ACCEPT)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

Chain POSTROUTING (policy ACCEPT)
target     prot opt source               destination


2.修改默认规则
[root@test ~]# iptables -P INPUT DROP
默认是filter表,指定表-t
[root@test ~]# iptables  -t mangle -P INPUT DROP 
注意:每个表之间的相同链的规则设定为一样但是互不干涉,filter表的默认INPUT链改成DROP与mangle表的默认INPUT链的改成DROP一样,比如说前者修改之后不能ssh登录了,当把前者改回来之后,后者也设置了相同的操作也不能ssh登录

3.一般命令格式
一般匹配:
-t 指定表
-A 规则末尾添加
-p 指定协议一般是tcp udp icmp
--dport 目标端口
--sport 源端口
-D 删除表规则
-F 清除表所有规则
-i 入站网卡
-o 出站网卡
-R 替换指定序号的规则
-s 源ip地址/掩码

扩展匹配:
多端口:`-m multiport --dports 80,443`(匹配 80 或 443 端口)。
IP 范围:`-m iprange --src-range 192.168.1.10-192.168.1.20`(匹配源 IP 范围)
状态匹配:`-m state --state NEW,ESTABLISHED`(匹配连接状态,如新建连接、已建立连接)

基本搭配:
iptables -t 表名 -A 链名 -p 协议 ----dport 端口 -j 动作    
iptables -t 表名 -I 链名 -p 协议 ----sport 端口 -j 动作
iptables -t 表名 -D 链名 序号(排在规则表的序号从上到下1开始)
iptables -t 表名 -F 

iptbales 规则匹配原则:
1、从上往下依次匹配
2、匹配到规则后不再往下匹配
3、默认策略是ACCEPT接受

2.3实验操作

bash 复制代码
实验1:禁止172.25.254.0/24网段的地址进行ping
[root@test ~]# iptables -A INPUT -p icmp  -s 172.25.254.0/24 -j DROP
测试:
[root@test ~]# ping 172.25.254.100
PING 172.25.254.100 (172.25.254.100) 56(84) 比特的数据。
^C
--- 172.25.254.100 ping 统计 ---
已发送 4 个包, 已接收 0 个包, 100% packet loss, time 3095ms
[root@test ~]# ip a
    inet 172.25.254.100/24 brd 172.25.254.255 scope global noprefixroute eth0
  
实验2:配置火墙,禁止172.25.254.10使用ssh进行远程登录
[root@test ~]# iptables -A INPUT -p tcp --dport 22 -s 172.25.254.10 -j DROP
测试:
10主机
[root@web ~]# ssh root@172.25.254.100

[root@web ~]#

20主机
[root@docker-node2 ~]#  ssh root@172.25.254.100

The authenticity of host '172.25.254.100 (172.25.254.100)' can't be established.
ED25519 key fingerprint is SHA256:PLjrNVbTybbdPZYp3PTIri8RrApcPIPfSSdayjz3LZk.
This host key is known by the following other names/addresses:
    ~/.ssh/known_hosts:1: 172.25.254.10
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes

3.firewalld

firewalld 是为简化防火墙管理设计的动态工具,核心是 "区域(zone)" 和 "服务(service)",需讲清其与 iptables 的设计理念差异。

3.1区域与服务

(1)区域(zone):按 "信任级别" 分组的规则集合

firewalld 将网络环境按 "信任程度" 分为多个区域,每个区域包含预设的规则(允许哪些服务 / 端口),主机的网卡可绑定到某个区域,流量按区域规则处理。常用区域(从高信任到低信任)

区域名称 信任等级 核心特点 适用场景 默认开放服务
trusted 最高 允许所有传入、传出流量,无任何限制(完全信任) 封闭测试环境、绝对安全的内部网络 所有端口 / 服务
home 允许家庭网络常用服务,限制外部非必要流量 家庭 WiFi、家用局域网 ssh、mdns、samba-client、dhcpv6-client
internal 中高 与 home 区规则一致,语义上区分 "内部网络" 企业内网、办公室内部网络 ssh、mdns、samba-client、dhcpv6-client
work 仅开放办公基础服务,关闭非工作类服务(比 home/internal 限制更严) 办公工位网络、企业工作网络 ssh、dhcpv6-client
public 中低 仅开放最基础无风险服务,严格限制其他流量(firewalld 默认区域) 咖啡馆 WiFi、酒店网络、服务器公网接口 ssh、dhcpv6-client
external 启用 NAT 转发,仅允许 ssh 传入,拒绝其他外部主动连接 外网网关接口、路由器外网口 ssh(默认启用 masquerade 伪装)
dmz 较低 仅开放指定公网服务,隔离外网与内网核心设备 Web 服务器、邮件服务器等公开服务部署 无(需手动开放 http/https 等特定服务)
block 最低 拒绝所有传入流量,返回 ICMP 不可达响应;允许所有传出流量 高安全需求的内部网络 无(仅允许内部主动向外通信)
drop 最低 丢弃所有传入流量,不做任何回应;仅允许所有传出流量(最严格) 核心数据库、敏感业务服务器 无(仅允许内部主动向外通信)

firewalld 默认提供的九个 zone 配置文件都保存在 "/usr/lib/firewalld/zones/" 目录下,分别为:block.xml drop.xml home.xml public.xml work.xml dmz.xml external.xml internal.xml trusted.xml

在 RHEL7 中,firewall 服务是默认的防火墙配置管理工具,他拥有基于 CLI(命令行界面)和基于 GUI(图形用户界面)的两种管理方式。firewall-config 和 firewall-cmd 是直接编辑 xml 文件,其中 firewall-config 是图形化工具,firewall-cmd 是命令行工具。

(2)服务(service):预定义的 "端口 + 协议" 集合

firewalld 将常用服务(如 HTTP、SSH)的 "端口 + 协议" 封装为 "服务",避免用户手动输入端口,简化配置。例如:

  • ssh 服务:对应 tcp/22 端口。
  • http 服务:对应 tcp/80 端口。
  • 自定义服务:可通过配置文件定义(/usr/lib/firewalld/services//etc/firewalld/services/)。

(3)动态更新机制:规则变更无需重启服务

firewalld 通过 firewalld 服务进程管理规则,修改规则后执行 firewall-cmd --reload 即可生效(不中断现有连接),这是与 iptables(修改后需重启或手动刷新)的核心区别。

3.2基本命令

注意:

永久/运行时模式

runtime模式:运行时模式,立即生效,重启失效

permanent模式:永久模式,重启生效

  • --permanent 参数需配合 firewall-cmd --reload 生效`
  • 紧急阻断流量:firewall-cmd --panic-on
  • 将当前运行时配置保存为永久配置firewall-cmd --runtime-to-permanent
3.2.1.服务管理与状态查看
命令 说明
systemctl start firewalld 启动防火墙服务
systemctl stop firewalld 停止防火墙服务
systemctl restart firewalld 重启防火墙服务(注意:这会中断现有连接,通常建议使用 --reload
systemctl enable firewalld 设置开机自启
firewall-cmd --state 查看防火墙运行状态(running/not running)
firewall-cmd --version 查看 firewalld 版本
3.2.2区域状态
命令 说明
firewall-cmd --get-default-zone 查看默认区域
firewall-cmd --set-default-zone=public 设置默认区域为 public (永久生效)
firewall-cmd --get-zones 列出所有可用的区域
firewall-cmd --get-active-zones 查看当前活跃的区域及其绑定的网卡
firewall-cmd --zone=public --get-target 查看指定区域的默认目标行为
3.2.3. 规则配置:端口与服务

1.开放/关闭服务 (推荐)

bash 复制代码
# 查看当前区域开放的服务
firewall-cmd --zone=public --list-services

# 临时开放 http 服务 (重启后失效)
firewall-cmd --zone=public --add-service=http

# 永久开放 http 服务
firewall-cmd --zone=public --add-service=http --permanent

# 永久关闭 http 服务
firewall-cmd --zone=public --remove-service=http --permanent

# 重载配置使永久规则生效
firewall-cmd --reload

2.开放关闭端口

bash 复制代码
# 查看当前区域开放的端口
firewall-cmd --zone=public --list-ports

# 临时开放 8080/tcp 端口
firewall-cmd --zone=public --add-port=8080/tcp

# 永久开放 8080/tcp 端口
firewall-cmd --zone=public --add-port=8080/tcp --permanent

# 永久关闭端口
firewall-cmd --zone=public --remove-port=8080/tcp --permanent

# 开放端口范围 (例如 6000-6010)
firewall-cmd --zone=public --add-port=6000-6010/tcp --permanent

3.高级配置:富规则

bash 复制代码
# 语法结构:rule [family="ipv4|ipv6"] source address="IP" [port port="X" protocol="tcp"] [accept|reject|drop] [log]

# 1. 允许特定 IP (192.168.1.100) 访问 SSH (22端口)
firewall-cmd --permanent --zone=public --add-rich-rule='rule family="ipv4" source address="192.168.1.100" port port="22" protocol="tcp" accept'

# 2. 拒绝特定网段 (10.0.0.0/24) 的所有访问
firewall-cmd --permanent --zone=public --add-rich-rule='rule family="ipv4" source address="10.0.0.0/24" reject'

# 3. 允许所有 IP 访问 80 端口,但记录日志 (前缀为 "HTTP-LOG")
firewall-cmd --permanent --zone=public --add-rich-rule='rule family="ipv4" port port="80" protocol="tcp" log prefix="HTTP-LOG" level="info" accept'

# 4. 限制 SSH 连接速率 (每秒最多 3 个新连接,超过则拒绝)
firewall-cmd --permanent --zone=public --add-rich-rule='rule family="ipv4" port port="22" protocol="tcp" limit value="3/s" reject'

# 应用更改
firewall-cmd --reload

# 查看富规则
firewall-cmd --zone=public --list-rich-rules

# 删除富规则
firewall-cmd --zone=public --remove-rich-rules='rule family="ipv4" port port="22" protocol="tcp" limit value="3/s" reject'

4.网络接口与源地址绑定

bash 复制代码
# 将网卡 eth0 绑定到 public 区域 (永久)
firewall-cmd --permanent --zone=public --change-interface=eth0

# 将来源网段 192.168.50.0/24 绑定到 internal 区域
firewall-cmd --permanent --zone=internal --add-source=192.168.50.0/24

# 从区域移除源地址
firewall-cmd --permanent --zone=internal --remove-source=192.168.50.0/24

5.故障排查与调试

bash 复制代码
firewall-cmd --list-all          # 查看默认区域的完整配置
firewall-cmd --zone=public --list-all  # 查看指定区域完整配置
firewall-cmd --list-all-zones    # 查看所有区域的配置
journalctl -u firewalld -f       # 实时查看 firewalld 服务日志
iptables -L -n -v                # 查看 firewalld 生成的底层 iptables 规则
nft list ruleset				 # 或者如果是 nftables 后端

3.3实验操作

bash 复制代码
场景:永久开放 Web 服务 (80/443) 并禁止 Ping,同时只允许特定管理 IP 访问 SSH。
# 1. 确保服务运行
systemctl enable --now firewalld

# 2. 开放 HTTP 和 HTTPS 服务
firewall-cmd --permanent --zone=public --add-service=http
firewall-cmd --permanent --zone=public --add-service=https

# 3. 禁止 ICMP (Ping) - 注意:某些区域默认允许,需显式移除或设置
# 方法A: 移除 icmp-block-echo-reply (如果之前被块了想恢复) 或直接添加阻塞
firewall-cmd --permanent --zone=public --add-icmp-block=echo-request

# 4. 设置 SSH 富规则:只允许 203.0.113.5 访问,其他拒绝
# 先移除默认的 ssh 服务开放 (如果有的话),防止全开
firewall-cmd --permanent --zone=public --remove-service=ssh
# 添加允许特定 IP 的规则
firewall-cmd --permanent --zone=public --add-rich-rule='rule family="ipv4" source address="203.0.113.5" port port="22" protocol="tcp" accept'
# (可选) 添加一条拒绝其他所有 SSH 的规则,或者依靠默认的区域策略(通常默认是拒绝未明确允许的)

# 5. 重载配置生效
firewall-cmd --reload

# 6. 验证配置
firewall-cmd --zone=public --list-all
相关推荐
bingHHB2 小时前
聚水潭 × 金蝶云星空:日均万单电商如何实现销售出库自动记账
运维·自动化·集成学习
ICT系统集成阿祥2 小时前
BGP邻居状态机详解
运维·服务器
海盗猫鸥2 小时前
「Linux工具」自动化构建make/Makfile
linux
NineData2 小时前
MySQL到StarRocks 同步链路中的建表、DDL 跟随与数据校验
运维·数据库·starrocks·mysql·数据迁移·数据库管理工具·ninedata
星晨雪海2 小时前
MyBatis-Plus 常用 CRUD 方法大全
linux·tomcat·mybatis
2739920292 小时前
Ubuntu 文件系统修复指南
linux·ubuntu·fsck
a8a3022 小时前
IPV6公网暴露下的OPENWRT防火墙安全设置(只允许访问局域网中指定服务器指定端口其余拒绝)
服务器·安全·php
云栖梦泽2 小时前
Linux内核与驱动:2.驱动基础(编译驱动)
linux·服务器·c++
Mariooooooooooo3 小时前
个人5070离线安装nvidia显卡驱动
linux