Chapter 13 · Proxmox VE Firewall

第 13 章 Proxmox VE 防火墙

方向与区域 , 集群 / 主机 / VM / VNet 四级配置文件 , 规则语法与安全组 , IP 别名与 IP 集合 , 服务与命令 , 默认规则 , 日志 , IPv6 , 端口列表 , 以及基于 nftables 的 proxmox-firewall 技术预览。

13.Proxmox VE 防火墙Proxmox VE Firewall

Proxmox VE 防火墙让你轻松保护 IT 基础设施 —— 为集群内所有主机设规则 , 或为 VM 与容器单独设规则。宏、安全组、 IP 集合与别名等特性让这件事更简单。

配置虽然集中存于集群文件系统 , 但基于 iptables 的防火墙服务 在每个集群节点上独立运行, 从而实现 VM 之间完整隔离;这种分布式结构也比集中式防火墙方案带宽高得多。

防火墙完整支持 IPv4 与 IPv6 —— IPv6 透明处理 , 默认双栈过滤 , 无需为 IPv6 另建规则。

13.1.方向与区域Directions & Zones

PVE 防火墙把网络分组为多个逻辑 zone , 每个 zone 独立定规则 , 视 zone 可分别对进 / 出 / 转发流量定规则。

13.1.1.方向

In
进入本 zone 的流量。
Out
离开本 zone 的流量。
Forward
穿过本 zone 的流量。在 Host zone 这包括主机作为网关 / NAT 时的路由流量;在 VNet 层 , 影响一切经过该 VNet 的流量 , 包含桥接口的收 / 发。
NOTE

Forward 规则目前 仅基于 nftables 的 proxmox-firewall 支持 —— 老版 pve-firewall 会忽略 forward 规则 , 不生效。

13.1.2.区域

Host
进 / 出主机 , 或主机转发的流量。可在数据中心级或主机级定规则 —— 主机级优先于数据中心级。
VM
VM / CT 的进 / 出流量。不可定义 forward 规则 , 只能 incoming / outgoing。
VNet
经 SDN VNet 的流量(客户机间或主机 ↔ 客户机)。由于都属 forward 流量 , 只能定 forward 方向规则。
NOTE

VNet 级规则目前 仅 nftables 版 proxmox-firewall 支持, 老版会忽略。

13.2.配置文件Configuration Files

所有防火墙配置存于 PVE 集群文件系统 , 自动分发到所有节点;变更时 pve-firewall 自动刷新底层 iptables。可用 GUI( Datacenter → Firewall 或 Node → Firewall)或直接编辑文件。

配置文件由 key-value 段组成 , # 开头与空行视为注释;段以 [段名] 开始。

13.2.1.集群级配置

路径 :/etc/pve/firewall/cluster.fw, 可含以下段:

[OPTIONS]
集群级防火墙选项:
  • ebtables: <boolean>(默认 1):集群级启用 ebtables 规则。
  • enable: <integer>(默认 0):集群级启 / 禁用防火墙。
  • log_ratelimit: [enable=]<1|0>[,burst=N][,rate=<rate>]:日志限速;burst 默认 5(限速前可先放行的初始突发量), enable 默认 1, rate 默认 1/second。
  • policy_forward: <ACCEPT|DROP>、 policy_in: <ACCEPT|DROP|REJECT>、 policy_out: <ACCEPT|DROP|REJECT>。
[RULES]
集群级对所有节点生效的防火墙规则。
[IPSET <name>]
集群级 IP 集合定义。
[GROUP <name>]
集群级安全组定义。
[ALIASES]
集群级别名定义。
启用防火墙

默认完全禁用 , 须显式打开:

[OPTIONS]
# enable firewall (cluster-wide setting, default is disabled)
enable: 1
NOTE

开启后默认会阻断主机所有入站流量 —— 仅保留本地网络到 Web GUI(8006)与 SSH(22)的放行。远程管理 PVE 需建规则放行远端 IP 到 8006、 22、 3128(SPICE)等端口。

WARN

启用防火墙前 先打开一个到该主机的 SSH, 以便出问题时还能登录。

为简化上述 , 可建一个名为 management 的 IPSet 把远程管理 IP 加进去 —— 防火墙会自动生成允许访问 GUI 的规则。

13.2.2.主机级配置

路径 :/etc/pve/nodes/<nodename>/host.fw —— 可覆盖 cluster.fw、调整日志级别与 netfilter 相关选项。

[OPTIONS]
主机级选项:
  • enable(默认 1):启用主机防火墙规则。
  • log_level_forward / log_level_in / log_level_out:转发 / 入 / 出流量日志级别(alert | crit | debug | emerg | err | info | nolog | notice | warning)。
  • log_nf_conntrack(默认 0):启用 conntrack 日志。
  • ndp(默认 1):启用 NDP(邻居发现协议)。
  • nf_conntrack_allow_invalid(默认 0):允许无效连接跟踪包。
  • nf_conntrack_helpers:启用指定协议的 conntrack helper , 可选 amanda / ftp / irc / netbios-ns / pptp / sane / sip / snmp / tftp。
  • nf_conntrack_max(默认 262144, 最小 32768):跟踪连接的最大数。
  • nf_conntrack_tcp_timeout_established(默认 432000)、 nf_conntrack_tcp_timeout_syn_recv(30 – 60 , 默认 60):conntrack 超时。
  • nftables(默认 0):启用 nftables 版防火墙(技术预览)。
  • nosmurfs:启用 SMURFS 过滤。
  • protection_synflood(默认 0)、 protection_synflood_burst(默认 1000)、 protection_synflood_rate(默认 200):按源 IP 的 SYN flood 防护。
  • smurf_log_level、 tcp_flags_log_level:相应日志级别。
  • tcpflags(默认 0):过滤非法 TCP flag 组合。
[RULES]
主机专属规则。

13.2.3.VM / 容器配置

路径 :/etc/pve/firewall/<VMID>.fw, 可含:

[OPTIONS]
  • dhcp(默认 0):允许 DHCP。
  • enable(默认 0):启 / 禁用防火墙规则。
  • ipfilter:启用默认 IP 过滤 —— 等价于给每个接口加空的 ipfilter-net<id> ipset , 隐式含合理默认限制(如把 IPv6 link-local 限制为由接口 MAC 派生的那个)。容器会隐式加入已配 IP。
  • log_level_in / log_level_out:日志级别。
  • macfilter(默认 1):启 / 禁用 MAC 过滤。
  • ndp(默认 1):启用 NDP。
  • policy_in: <ACCEPT|DROP|REJECT>、 policy_out: <ACCEPT|DROP|REJECT>。
  • radv:允许发送 Router Advertisement。
[RULES]
VM / CT 规则。
[IPSET <name>]
IP 集合。
[ALIASES]
IP 别名。
为 VM 与容器启用防火墙

每个虚拟网卡都有独立的 firewall 启用标志 —— 可按接口选择性启用 , 这是在总 enable 之外额外的要求。

13.2.4.VNet 配置

路径 :/etc/pve/sdn/firewall/<vnet_name>.fw。用于在 VNet 层级全局设防火墙配置 , 免去为 VNet 中每台 VM 单独设。 只能含 FORWARD 方向规则 —— 因不存在进 / 出概念 , 影响所有在桥端口之间(含主机接口)移动的流量。

NOTE

该特性目前 仅 nftables 版 proxmox-firewall 可用。

FORWARD 链是双向的 —— 要双向互通得建两条规则。例如放行到指定主机的 HTTP:

FORWARD ACCEPT -dest 10.0.0.1 -dport 80
FORWARD ACCEPT -source 10.0.0.1 -sport 80
[OPTIONS]
enable(默认 0)、 log_level_forward、 policy_forward: <ACCEPT|DROP>。
[RULES]
VNet 专属规则。

13.3.防火墙规则Firewall Rules

规则由 方向(IN / OUT / FORWARD)与 动作(ACCEPT / DENY / REJECT)组成 , 可指定宏(预定义规则与选项集合)。规则行前加 | 即禁用。

[RULES]

DIRECTION ACTION [OPTIONS]
|DIRECTION ACTION [OPTIONS] # 已禁用的规则

DIRECTION MACRO(ACTION) [OPTIONS] # 使用预定义宏

匹配细化选项:

--dest <string>
限制目的 IP —— 单个 IP、 IP 集合(+ipsetname)、 IP 别名 , 也可地址段 20.34.101.207-201.3.9.99 或逗号分隔列表。 IPv4 与 IPv6 不要混列。
--dport <string>
限制 TCP/UDP 目的端口 —— 可用 /etc/services 服务名或数字(0 – 65535), 范围 \d+:\d+(如 80:85), 逗号组合。
--icmp-type <string>
仅当 proto 为 icmp 或 icmpv6 / ipv6-icmp 时有效。
--iface <string>
接口名 —— VM / CT 用网络配置键名(net\d+), 主机规则可任意字符串。
--log <level>
本规则的日志级别。
--proto <string>
IP 协议 —— 名称(tcp / udp)或 /etc/protocols 数字。
--source <string>
限制源 IP , 同 --dest 语法。
--sport <string>
限制 TCP/UDP 源端口。

示例:

[RULES]
IN SSH(ACCEPT) -i net0
IN SSH(ACCEPT) -i net0 # 注释
IN SSH(ACCEPT) -i net0 -source 192.168.2.192       # 仅允许来自 192.168.2.192 的 SSH
IN SSH(ACCEPT) -i net0 -source 10.0.0.1-10.0.0.10   # 允许 IP 段 SSH
IN SSH(ACCEPT) -i net0 -source 10.0.0.1,10.0.0.2,10.0.0.3
IN SSH(ACCEPT) -i net0 -source +mynetgroup          # 允许 ipset mynetgroup
IN SSH(ACCEPT) -i net0 -source myserveralias        # 允许别名 myserveralias

|IN SSH(ACCEPT) -i net0 # 已禁用的规则

IN DROP   # 丢弃所有入站包
OUT ACCEPT # 放行所有出站包

13.4.安全组Security Groups

安全组是集群级定义的规则集合 , 可被所有 VM 规则复用。例如定义 webserver 组放行 http / https:

# /etc/pve/firewall/cluster.fw

[group webserver]
IN ACCEPT -p tcp -dport 80
IN ACCEPT -p tcp -dport 443

在 VM 防火墙中引用:

# /etc/pve/firewall/<VMID>.fw

[RULES]
GROUP webserver

13.5.IP 别名IP Aliases

IP 别名把网络 / IP 与名字关联 —— 可在 IP 集合定义、防火墙规则的 source / dest 里引用名字。

13.5.1.标准别名 local_network

该别名自动定义。查看当前值:

# pve-firewall localnet
local hostname: example
local IP address: 192.168.2.100
network auto detect: 192.168.0.0/20
using detected local_network: 192.168.0.0/20

防火墙会用该别名自动建立集群通信(corosync、 API、 SSH)所需的放行。可在 cluster.fw 的 ALIASES 段覆盖 —— 单机在公网时建议显式指定本机 IP:

# /etc/pve/firewall/cluster.fw
[ALIASES]
local_network 1.2.3.4 # 用单个 IP

13.6.IP 集合(IP Sets)IP Sets

IP 集合用来定义主机 / 网络分组 , 在规则的 source / dest 中用 +name 引用。例如放行来自 management 集合的 HTTP:

IN HTTP(ACCEPT) -source +management

13.6.1.标准 IP 集合 management

仅作用于主机防火墙(不作用 VM 防火墙)。该集合中的 IP 被允许做常规管理操作(PVE GUI、 VNC、 SPICE、 SSH)。本地集群网络会自动加入该集合(别名 cluster_network)以便主机间通信(multicast、 ssh 等):

# /etc/pve/firewall/cluster.fw

[IPSET management]
192.168.2.10
192.168.2.10/24

13.6.2.标准 IP 集合 blacklist

来自这些 IP 的流量会被每台主机与每台 VM 的防火墙丢弃。

# /etc/pve/firewall/cluster.fw

[IPSET blacklist]
77.240.159.182
213.87.123.0/24

13.6.3.标准 IP 集合 ipfilter-net*

这类过滤属于 VM 某网卡 , 主要防 IP 欺骗 —— 若某接口存在此集合 , 则该接口任何出站包源 IP 若不匹配 ipfilter 集会被丢弃。

已配置 IP 的容器 , 若此集合存在(或通过 VM 防火墙 Options 中的 IP Filter 总开关激活), 集合会隐式含其 IP。 VM 与容器都会隐式含由 MAC 派生的标准 IPv6 link-local 地址 , 以便邻居发现工作。

# /etc/pve/firewall/<VMID>.fw

[IPSET ipfilter-net0] # 仅允许 net0 上指定 IP
192.168.2.10

13.7.服务与命令Services and Commands

每节点运行两个服务:

  • pvefw-logger:NFLOG 守护进程(ulogd 的替代)。
  • pve-firewall:更新 iptables 规则。

另有 CLI pve-firewall:

# pve-firewall start
# pve-firewall stop

查状态:

# pve-firewall status

该命令会读取并编译所有规则 —— 配置有错会输出告警。查看生成的 iptables:

# iptables-save

13.8.默认防火墙规则Default firewall rules

13.8.1.数据中心入 / 出 DROP/REJECT

数据中心入 / 出策略为 DROP/REJECT 时 , 下列流量仍对集群所有 PVE 主机放行:

  • loopback 流量
  • 已建立连接
  • IGMP 协议流量
  • management 主机 → 8006(Web 界面)
  • management 主机 → 5900 – 5999(VNC Web 控制台)
  • management 主机 → 3128(SPICE proxy)
  • management 主机 → 22(SSH)
  • 集群网络 UDP 5405 – 5412(corosync)
  • 集群网络 UDP 组播
  • ICMP type 3(Destination Unreachable)、 4(拥塞控制)、 11(Time Exceeded)

下列流量 被丢弃但即使开日志也不记录:

  • 无效连接状态的 TCP
  • 与 corosync 无关(非 5405 – 5412)的广播 / 组播 / anycast
  • TCP 到 43
  • UDP 到 135、 445
  • UDP 到 137 – 139
  • 源端口 137 到 1024 – 65535 的 UDP
  • UDP 到 1900
  • TCP 到 135、 139、 445
  • 源端口 53 的 UDP

其余流量按策略丢 / 拒并记录 —— 受 Firewall → Options 中 NDP、 SMURFS、 TCP flag 过滤等附加开关影响。检查实际规则:

# iptables-save

输出也被纳入 System Report(GUI 节点 Subscription 标签或 pvereport)。

13.8.2.VM / CT 入 / 出 DROP/REJECT

丢 / 拒 VM 的全部流量 , 但根据配置为 DHCP、 NDP、 Router Advertisement、 MAC / IP 过滤等设例外。数据中心的丢 / 拒规则会继承 , 但主机级那些「放行入 / 出」例外 不 对 VM 生效。同样可用 iptables-save 查看实际规则。

13.9.防火墙规则日志Logging of firewall rules

默认所有防火墙过滤日志关闭。要启用 , 需在 Firewall → Options 中设进 / 出方向的 loglevel —— 主机与 VM/CT 各自独立。启用后可在 Firewall → Log 看输出。标准规则仅部分丢 / 拒包会记录(见 §13.8)。

loglevel 不 影响记多少 —— 它只改变日志行上作为前缀的 LOGID, 便于过滤与后处理。 level 取值与对应 LOGID:

loglevelLOGID
nolog——
emerg0
alert1
crit2
err3
warning4
notice5
info6
debug7

典型日志行:

VMID LOGID CHAIN TIMESTAMP POLICY: PACKET_DETAILS

主机防火墙时 VMID = 0。

13.9.1.用户规则的日志

可为每条用户规则单独设 log-level , 与标准规则的 log-level 相互独立。 Web UI 在规则创建 / 修改时可设;也可用 pvesh API 或在配置文件的相应规则后加 -log <loglevel>。以下两者等价:

IN REJECT -p icmp -log nolog
IN REJECT -p icmp

而:

IN REJECT -p icmp -log debug

会输出带 debug 标记的日志。

13.10.小贴士Tips and Tricks

13.10.1.放行 FTP

FTP 协议用 21 端口 + 若干动态端口 —— 既要放行 21, 又要加载 ip_conntrack_ftp:

modprobe ip_conntrack_ftp

并把 ip_conntrack_ftp 加入 /etc/modules 以便重启仍生效。

13.10.2.Suricata IPS 集成

可接入 Suricata IPS(入侵防御系统)—— 防火墙 ACCEPT 的包才会转给 IPS; reject / drop 的包不会到 IPS。

在 PVE 主机装 suricata:

# apt-get install suricata
# modprobe nfnetlink_queue

别忘把 nfnetlink_queue 加入 /etc/modules。为指定 VM 启用 IPS:

# /etc/pve/firewall/<VMID>.fw

[OPTIONS]
ips: 1
ips_queues: 0

ips_queues 把该 VM 绑定到某个 CPU queue。可用 queue 见 /etc/default/suricata:

# /etc/default/suricata
NFQUEUE=0

13.11.IPv6 说明Notes on IPv6

防火墙有若干 IPv6 专属选项。要点 :IPv6 不再用 ARP, 而用 NDP(邻居发现)—— 在 IP 层工作 , 依赖 IP 地址。为此使用由接口 MAC 派生的 link-local 地址。主机与 VM 层默认 启用 NDP 选项 以允许 NDP 包收发。

NDP 除邻居发现外还用于自动配置、路由器公告等。默认 VM 可发 router solicitation(查询路由)、收 router advertisement, 实现无状态自动配置;但 VM 不能自称路由器 —— 除非设 Allow Router Advertisement(radv: 1)。

关于 NDP 所需 link-local 地址 , 可启用 IP Filter(ipfilter: 1)—— 效果等价于给 VM 各网卡加 ipfilter-net* ipset 并纳入对应 link-local 地址(详见 §13.6.3)。

13.12.Proxmox VE 使用的端口Ports used by Proxmox VE

  • Web 界面 :8006 (TCP, TLS 上的 HTTP/1.1)
  • VNC Web 控制台 :5900 – 5999 (TCP, WebSocket)
  • SPICE proxy:3128 (TCP)
  • sshd(用于集群动作):22 (TCP)
  • rpcbind:111 (UDP)
  • sendmail:25 (TCP, 出站)
  • corosync 集群流量 :5405 – 5412 (UDP)
  • 在线迁移(VM 内存与本地盘数据):60000 – 60050 (TCP)

13.13.nftablesnftables

proxmox-firewall 是作为 pve-firewall 替代的新实现 , 底层基于 nftables 而非 iptables。

WARN

proxmox-firewall 目前为 技术预览, 可能有 bug 或与旧版不兼容 , 不适合生产。

它使用同样的配置文件与格式 , 切换时旧配置可直接沿用;功能大部分一致 , 但有几点例外:

  • 使用 Linux bridge 时 , 不再 额外创建防火墙桥(fwbrX)。 OVS 桥上的客户机接口仍会有防火墙桥。
  • 客户机流量目前 不支持 REJECT(会改为 DROP)。
  • 使用 NDP / Router Advertisement / DHCP 选项时总会创建防火墙规则 , 与默认策略无关。
  • 客户机规则对有 conntrack 条目的连接也会评估。

13.13.1.安装与启用

apt install proxmox-firewall

在 Web UI(Host → Firewall → Options → nftables)或主机配置文件 /etc/pve/nodes/<node>/host.fw 启用:

[OPTIONS]

nftables: 1
NOTE

启用 / 禁用 proxmox-firewall 后 , 需重启所有运行中 VM 与容器, 新 / 旧防火墙才能正确工作。

设置该 key 后新服务接管 , 可查状态:

systemctl status proxmox-firewall

也可检查生成的规则集(见 §13.13.3), 并确认 pve-firewall 不再生成 iptables 规则(见 §13.7)。回切旧防火墙 :把配置值设回 0/No。

13.13.2.使用

proxmox-firewall 创建并管理两张表 :proxmox-firewall 与 proxmox-firewall-guests。如需 PVE 配置之外的自定义规则 , 可建自己的表 —— proxmox-firewall 只动它自己的表 , 不会干扰你的表。

不再用 pve-firewall CLI —— 它是 systemd 服务 , 通过 systemctl 控制:

systemctl start proxmox-firewall
systemctl stop proxmox-firewall

停止服务会移除其生成的所有规则。查状态:

systemctl status proxmox-firewall

13.13.3.常用命令

查看当前规则集:

nft list ruleset

调试 :用 compile 子命令导出生成命令; PVE_LOG 环境变量会让日志打到 STDERR, 便于排查 nftables 规则集生成问题:

PVE_LOG=trace /usr/libexec/proxmox/proxmox-firewall compile > firewall.json

nftables 规则集由 骨架规则集(内置在 proxmox-firewall 二进制中)与从配置生成的规则组成。取骨架:

/usr/libexec/proxmox/proxmox-firewall skeleton

两条命令输出都可直接管给 nft。以下命令从零重建整个 nftables 规则集:

/usr/libexec/proxmox/proxmox-firewall skeleton | nft -f -
/usr/libexec/proxmox/proxmox-firewall compile | nft -j -f -

想让守护进程运行时输出更详细 , 可编辑其 systemd 服务:

systemctl edit proxmox-firewall

加入 PVE_LOG 环境变量覆盖:

[Service]
Environment="PVE_LOG=trace"