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 的流量 , 包含桥接口的收 / 发。
Forward 规则目前 仅基于 nftables 的 proxmox-firewall 支持 —— 老版 pve-firewall 会忽略 forward 规则 , 不生效。
13.1.2.区域
- Host
- 进 / 出主机 , 或主机转发的流量。可在数据中心级或主机级定规则 —— 主机级优先于数据中心级。
- VM
- VM / CT 的进 / 出流量。不可定义 forward 规则 , 只能 incoming / outgoing。
- VNet
- 经 SDN VNet 的流量(客户机间或主机 ↔ 客户机)。由于都属 forward 流量 , 只能定 forward 方向规则。
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
开启后默认会阻断主机所有入站流量 —— 仅保留本地网络到 Web GUI(8006)与 SSH(22)的放行。远程管理 PVE 需建规则放行远端 IP 到 8006、 22、 3128(SPICE)等端口。
启用防火墙前 先打开一个到该主机的 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 方向规则 —— 因不存在进 / 出概念 , 影响所有在桥端口之间(含主机接口)移动的流量。
该特性目前 仅 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:
| loglevel | LOGID |
|---|---|
nolog | —— |
emerg | 0 |
alert | 1 |
crit | 2 |
err | 3 |
warning | 4 |
notice | 5 |
info | 6 |
debug | 7 |
典型日志行:
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。
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
启用 / 禁用 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"