mise 声明式管理 Linux 主机防火墙nftables、firewalld、UFW 三后端配置与 SSH 防锁死实战指南【免费下载链接】misedev tools, env vars, task runner项目地址: https://gitcode.com/GitHub_Trending/mi/mise[bootstrap.linux.firewall]是 mise bootstrap 体系中专门用于声明式管理 Linux 主机防火墙的配置段。它同时支持 nftables、firewalld 与 UFW 三种后端把 mise 自己管理的规则与主机上其他无关规则严格隔离并在通过 SSH 执行引导时内置防锁死保护。阅读完本文你将掌握防火墙配置的完整参数体系、三种后端的选择与能力边界、规则对账reconcile与删除语义以及如何借助status/apply --dry-run在真正变更前预览策略并安全收敛主机。认识[bootstrap.linux.firewall]mise 的 bootstrap 模块docs/bootstrap 目录下的系列指南负责把一台新机器收敛到配置描述的状态。防火墙是其中位于「特权系统资源」层的一类在 src/cli/bootstrap.rs 的注释中可以确认bootstrap 依次处理 packages软件包、privileged files/directories特权文件、system/user services系统与用户服务、firewall防火墙以及 Compose projects——也就是文档所说的「防火墙收敛发生在软件包、特权文件与系统服务之后Compose 项目之前」。这一顺序保证如果配置里声明了要安装并启动某个防火墙后端如firewalld该后端会先就绪之后才会应用它的策略。其核心设计目标有三点声明式对账配置描述目标状态mise 通过比对「保存的规则模型」与「运行时实际状态」来决定创建、更新、删除还是无操作Noop。规则隔离mise 管理的规则带有专属标记nftables 的mise_bootstrap表、firewalld 的mise-bootstrap-in/mise-bootstrap-out策略、UFW 的mise:name注释不会误删主机上其他工具维护的规则。默认拒绝入站默认策略是入站拒绝default_incoming deny、出站放行default_outgoing allow并在 SSH 场景下提供多重锁死防护。一个完整的入门示例来自 docs/bootstrap/firewall.md如下放行 HTTPS并把 SSH 限制为仅来自单个管理网段。[bootstrap.linux.firewall] backend auto state enabled default_incoming deny default_outgoing allow [[bootstrap.linux.firewall.rules]] name https port 443 protocol tcp action allow [[bootstrap.linux.firewall.rules]] name ssh-admin port 22 protocol tcp source 203.0.113.10/32 action limit注意示例中的203.0.113.10/32是文档保留测试网段应用前必须替换为你的真实管理网段并把22换成目标主机实际的 SSH 端口。backend auto只负责选择一个已安装的后端不会替你去安装任何防火墙命令——确保所选后端命令已存在否则会失败关闭。三种后端auto 解析顺序与各后端行为backend是顶层配置项源码中的定义位于 src/system/firewall.rs取值及行为如下backend含义关键行为auto默认自动选择① 复用更早一次 mise 运行记录的后端若其命令仍可用② 优先选择已经处于活动状态的 firewalld 或 UFW 安装③ 依次尝试 nftables、firewalld、UFW 中可用者。全部不可用时直接报错no supported firewall backend foundnftables原生 nftables维护隔离的inet mise_bootstrap表与持久化的mise-bootstrap-firewall.servicesystemd 单元运行时替换是原子化、经语法校验的 nft 事务firewalldfirewalld维护永久策略mise-bootstrap-in与mise-bootstrap-out且只在永久配置通过--check-config校验后才执行--reloadufwUFW按声明顺序安装带有mise:name注释的规则先于默认策略应用全部规则就绪后才启用 UFW从源码看resolve_backendsrc/system/firewall.rs完整实现了上述 auto 逻辑而显式指定后端的规则是「失败关闭」ensure_backend_available会检查对应命令ufw/firewall-cmd/nft是否存在缺失即报错。无论哪种方式最终选定的后端与生效状态都会在status与plan中可见。nftables 后端细节规则渲染为独立的inet mise_bootstrap表入站链input、出站链output都以带mise-bootstrap:digest注释的方式标识归属与内容摘要。应用前先用nft -c -f -check 模式做语法校验通过后才写入/etc/mise/bootstrap/firewall.nft权限 0600与 systemd 单元文件/etc/systemd/system/mise-bootstrap-firewall.service最后执行systemctl daemon-reload与enable见apply_nftablessrc/system/firewall.rs。内置的基线规则允许 established/related 连接、回环接口lo、ICMP 与 IPv6-ICMP之后才是用户规则。firewalld 后端细节使用策略policy机制而非简单 zone入站策略mise-bootstrap-iningressANY→ egressHOST、出站策略mise-bootstrap-outHOST→ANY优先级固定-1000并写入mise-bootstrap:digest描述见apply_firewalldsrc/system/firewall.rs。所有变更先落永久配置--check-config校验通过后再单次--reload避免中间态导致现有 SSH 连接被切断。对账校验会检查 target、ingress/egress zones、优先级以及 rich rule 集合是否与期望一致firewalld_policy_matchessrc/system/firewall.rs。UFW 后端细节每条规则以ufw action ... comment mise:name形式安装mise:前缀是归属标记删除时只删除带有该标记的规则。默认策略在规则之后设置ufw default policy incoming与ufw default policy outgoing最后ufw --force enablefinish_ufw_applysrc/system/firewall.rs。策略与规则state、默认策略与规则字段全解顶层statestate接受enabled默认、disabled或absent枚举定义见 src/system/firewall.rsenabled应用并保持防火墙策略处于运行状态。disabled保留mise 保存的规则模型但从运行时移除 nftables/firewalld 策略对 UFW 则是全局禁用 UFWufw --force disable见disable_backend。absent只删除 mise 管理的规则与元数据。关键语义仅仅从配置中删除整个[bootstrap.linux.firewall]段什么都不做删除必须显式声明state absent。disabled与absent在交互确认时会提示为「破坏性变更」destructive changes见apply中的destructive判定src/system/firewall.rs。默认策略default_incoming与default_outgoing接受allow、deny、reject。默认值为入站 deny、出站 allowdefault_incoming()函数与枚举默认值src/system/firewall.rs。三者的后端映射略有差异nftables 下deny与reject都映射为链策略dropreject会在链尾追加一条显式reject规则firewalld 映射为DROP/REJECTUFW 则直接使用deny/reject关键字。规则字段每条[[bootstrap.linux.firewall.rules]]支持以下字段结构体定义见 src/system/firewall.rs字段必填取值说明name是ASCII 字符串稳定的规则标识符用于对账与归属标记仅允许字母、数字、-、_长度不超过 64validate_namesrc/system/firewall.rsstate否present默认/absent显式删除某条规则direction否incoming默认/outgoing规则方向action否allow默认/limit/deny/reject规则动作protocol视情况tcp/udp/sctp/dccp见下方约束port否数字或闭区间字符串如8000-8010端口或端口范围设置了 port 就必须设置 protocol否则解析直接报错source/destination否IPv4 或 IPv6 CIDR 网段源 / 目的网段interface否网卡名仅 nftables 与 UFW 支持长度上限 15允许-、_、.、:文档与源码共同强调的规则约束端口必须有协议port.is_some() rule.protocol.is_none()时直接bailsrc/system/firewall.rs。不允许 IPv4/IPv6 混用一条规则里source与destination不能一个 IPv4 一个 IPv6src/system/firewall.rs。规则名不能重复同一配置作用域内重名直接报错merge_toml_config与from_toml双重校验。后端能力边界UFW 只支持 TCP/UDP使用 SCTP/DCCP 报错建议改选 nftables 或 firewalldfirewalld 的 policy 规则无法安全表达按接口匹配因此带interface的规则在 firewalld 后端会被拒绝src/system/firewall.rs。mise 的做法是报错要求你改选 nftables 或 UFW而不是悄悄弱化规则。action limit的限速语义limit用于按源地址对新建入站 TCP 连接限速且要求direction incoming且protocol tcp否则校验报错。不同后端采用后端原生的算法故意不做成精确等价UFW使用原生 limit 动作——某地址 30 秒内 6 次连接尝试后即被拒绝。nftables为 IPv4 与 IPv6 分别建立有界 metermise_limit_index_ip/_ip6令牌桶速率 12 次/分钟、突发 5 个包meter 超时 30 秒渲染逻辑见 src/system/firewall.rs。firewalld只能对整条规则限速无法做到按源隔离mise 因此直接拒绝limit 规则避免单个源耗尽共享速率预算校验见 src/system/firewall.rs。归属权与删除语义exclusive 与保留未声明规则默认情况下非 exclusive后续配置会保留之前管理过但本次未提及的规则。这来自effective_request的合并逻辑src/system/firewall.rs当exclusive false且存在已保存状态时所有此前为present且本次未声明的规则会被继承。由此想删除某条具体规则用同名规则声明state absent分层layered配置可以各自声明自己的规则而互不干扰——本地配置会覆盖继承的同名规则merge_toml_config按 local 覆盖 inherited同名规则就地替换src/system/firewall.rs。只有当你确信配置拥有整台主机的完整防火墙时才设置exclusive true。它会把未声明的 mise 规则全部清除在 UFW 后端下exclusive 模式会执行ufw reset见 src/system/firewall.rs这同时会删掉与 mise 无关的 UFW 规则因此永远被当作破坏性操作要求确认。先预览再变更status 与 apply 命令族防火墙管理入口是mise bootstrap firewall子命令CLI 定义见 src/cli/bootstrap.rs包含apply与status两个子命令# 查看当前防火墙对账状态表格形式 mise bootstrap firewall status # 以 JSON 输出便于脚本化解析 mise bootstrap firewall status --json # 存在未收敛项时以退出码 1 结束适合 CI mise bootstrap firewall status --missing # 只打印将要执行的命令不真正变更 mise bootstrap firewall apply --dry-run # 跳过交互确认直接应用 mise bootstrap firewall apply --yesstatus的输出列包含 Action / Resource / Current / Desired直接展示每个资源顶层防火墙firewall:linux与每条规则firewall-rule:name的当前状态与期望状态src/cli/bootstrap.rs。--dry-run会结合后端渲染出将要执行的命令列表preview_commands如 nftables 的nft -f ...、firewalld 的--reload、UFW 的逐条规则与--force enable让你在真正动手前核对选定的后端、默认策略、规则顺序与删除项。需要强调的是plan描述的是 mise 期望的变更不是端到端的连通性测试。同一台主机上可能还有其他防火墙系统或容器网络如 Docker在起作用因此文档建议从真正使用该服务的网络侧验证最终可达性。SSH 防锁死保护默认策略 deny/reject 时的安全网当 bootstrap 通过 SSH 运行且入站默认策略为deny或reject时mise 会在变更前读取SSH_CONNECTION环境变量格式客户端地址 客户端端口 服务器地址 服务器端口解析见 src/system/firewall.rs并执行严格检查必须存在至少一条 present 的入站 TCP allow 或 limit 规则同时覆盖对端地址peer、服务器地址与服务器端口且不带 interface 约束——因为SSH_CONNECTION无法告知入口网卡带接口约束的 allow 不能证明会保住当前会话校验逻辑validate_safety_with_rulessrc/system/firewall.rs。否则apply 在提权之前就会失败。几条值得注意的细节带interface约束的 allow 规则不能算作覆盖SSH 场景下会继续寻找无约束的覆盖规则。若阻塞规则deny/reject先于可证明的 allow 规则出现nftables/UFW 后端会直接报错顺序敏感firewalld 后端因无法保证 allow 一定生效也会报错。当SSH_CONNECTION被 sudo、env -i或包装脚本剥离时mise 会向上遍历/proc进程树检测是否存在 sshd 祖先ssh_ancestor_presentsrc/system/firewall.rs检测到 SSH 派生进程但无SSH_CONNECTION会失败关闭无法检查祖先链时同样失败关闭宁可拒绝也不冒险断连。如果确实是有意为之的带外out-of-band部署可以用allow_lockout true显式跳过这道检查——这是文档明确给出的逃生舱。e2e 测试 e2e/cli/test_bootstrap_firewall 完整验证了这一系列场景未覆盖对端、规则为absent、目的地址不匹配等情况都会在apply --dry-run --yes时以「no incoming TCP allow rule covers peer ...」失败且锁死校验发生在后端检查与提权之前。在「中间态不会断连」层面三个后端的策略各不相同nftables整个规则集原子安装先-c语法校验再一次性应用不存在半套规则。firewalld先改永久策略最后单次校验通过的--reload中间态同样不会影响已建立的 SSH 会话。UFW非 exclusive更新时先为完整替换规则集打上唯一随机mise-transition:nonce:标记并安装旧规则仍在线再删除旧的 mise 规则随后安装正式规则并清理过渡标记——若中途被打断下一次运行会安全清理残留的过渡规则apply_ufwsrc/system/firewall.rs。删除时还从后往前逐条删除保证较早的 SSH allow 在整代规则被清掉前始终有效。分层配置与合并规则mise 的多层配置global → local同样适用于防火墙段prepare_request_from_config按 global → local 顺序合并各配置文件的[bootstrap.linux.firewall]src/system/firewall.rs标量backend、state、默认策略、exclusive、allow_lockout由更局部的配置覆盖规则按name合并——同名规则由更局部的声明整体替换新名字追加。单元测试 src/system/firewall.rs 验证了继承 scalar 并按名合并规则的完整行为。安全模型受限特权助手协议防火墙管理仅限 Linux并复用与 bootstrap 的 accounts、files、services 相同的受限特权助手协议typed plan序列化后的FirewallRequest通过 stdin 传给提权后的__apply-firewall-plan/__inspect-firewall-plan隐藏子命令src/system/firewall.rs配置值永远不会被插值进 root shell 命令。状态文件保存在/var/lib/mise/bootstrap/firewall.json权限 0600原子写入内容摘要digest与实时指纹live fingerprintnftables 为规则集的 SHA-256共同用于检测漂移。这一点在文档中总结为Typed plans travel on stdin; config values are never interpolated into a root shell command.参考与延伸阅读本指南核心来源docs/bootstrap/firewall.md防火墙模块完整实现src/system/firewall.rs非 Linux 平台的防火墙占位实现src/system/firewall_non_linux.rsCLI 子命令定义与调度src/cli/bootstrap.rs端到端测试SSH 锁死保护场景e2e/cli/test_bootstrap_firewall配置结构测试e2e/config/test_schema_bootstrap_firewallbootstrap 模块其他指南docs/bootstrap【免费下载链接】misedev tools, env vars, task runner项目地址: https://gitcode.com/GitHub_Trending/mi/mise创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考