Skip to content

Proxmox Network & Firewall Design

Overview

This document describes the network architecture and firewall design for the Proxmox cluster hosted at OVH. The design uses Proxmox SDN with two zone types to provide controlled network segmentation, automatic DHCP distribution, and internet access for guest workloads.

Terminology

Term Definition
Node A Proxmox host (pve1, pve2, pve3)
Host The Proxmox node itself, in the context of its network stack and firewall
Guest Any workload running on Proxmox — both VMs and LXC containers
VNet A virtual network segment defined in Proxmox SDN
Simple Zone An SDN zone type that provides node-local networking with built-in DHCP and SNAT
VLAN Zone An SDN zone type that maps to an existing Linux bridge with VLAN tagging

Note

Node and host often refer to the same physical system. Node is used in the infrastructure context; host is used when discussing network and firewall behavior.

Assumptions

  • 3 Proxmox nodes on OVH, each with a public and a private connection
  • Proxmox SDN is enabled
  • IPAM: pve
  • DHCP is served by dnsmasq running on each node
  • Internet access for guests is provided via SNAT
  • IPv4 forwarding is enabled on all nodes (net.ipv4.ip_forward=1)

SDN Zones

Two zone types are defined.

Zone ID Type Details
simple Simple Node-local, automatic DHCP enabled
vlan VLAN Bridge: vmbr1

VNets and Subnets

VNet Zone Subnet Gateway SNAT DHCP Range
ingress simple 172.16.5.0/24 172.16.5.1 Yes 172.16.5.2 – 172.16.5.10
isolated simple 172.16.10.0/24 172.16.10.1 Yes 172.16.10.100 – 172.16.10.200
k8group simple 172.16.20.0/24 172.16.20.1 Yes 172.16.20.100 – 172.16.20.200
mgmt vlan (tag 100) 172.16.100.0/24 172.16.100.1 Yes

Network Roles

ingress — entry point for externally reachable services (reverse proxy, ingress).

  • Accepts inbound internet traffic via DNAT
  • Forwards requests to the isolated network
  • Exits to the internet via SNAT

isolated — internal application workloads.

  • Default restricted access
  • Accepts traffic from ingress on specific ports only
  • Exits to the internet via SNAT

k8group — dedicated network for Kubernetes workloads.

  • DNS and egress access
  • Isolated from other application VNets

mgmt — shared management plane for internal services (VLAN 100).

  • Hosts services that need to reach each other: Guacamole, OpenBao, and similar infrastructure components
  • Node-to-node cluster traffic
  • Firewall rules are under active refinement

Warning

Subnet separation alone does not provide isolation. Traffic between guests in the same VNet must also be restricted at the firewall level.

DHCP and DNS

Simple Zone provides built-in DHCP through dnsmasq running on each node. The zone-specific instance dnsmasq@simple.service must be used — the default dnsmasq.service must remain inactive.

# Verify correct state
systemctl status dnsmasq                 # must be inactive
systemctl status dnsmasq@simple.service  # must be active

Note

The default dnsmasq.service and dnsmasq@simple.service must not run simultaneously.

Node Routing

IPv4 forwarding must be enabled on all nodes for VNet transit, SNAT, and DNAT to work.

echo "net.ipv4.ip_forward=1" >> /etc/sysctl.d/99-proxmox.conf
sysctl -p /etc/sysctl.d/99-proxmox.conf

# Verify
sysctl net.ipv4.ip_forward
# Expected: net.ipv4.ip_forward = 1

Warning

This setting must be applied on every node.

Firewall Layers

Proxmox firewall rules are evaluated at four distinct levels.

Known issue — dual firewall services

On pve3, both proxmox-firewall.service and pve-firewall.service are currently active. This is an incorrect state. Only proxmox-firewall.service should be running. pve-firewall.service must be stopped and disabled.

systemctl stop pve-firewall
systemctl disable pve-firewall

Cluster Level

Sets default policies and shared rules that apply to all nodes.

Configured default policies:

policy_in      = DROP
policy_forward = DROP
policy_out     = ACCEPT

Host Level

Rules applied to the Proxmox node's own network stack.

  • IN: traffic destined for the host itself (e.g., DHCP, DNS served by dnsmasq)
  • FORWARD: traffic passing through the host between VNets

Note

If traffic is destined for the host, it is IN. If it is passing through the host to another destination, it is FORWARD.

Guest Level

Rules applied to individual VMs or LXC containers.

  • IN: traffic entering the guest
  • OUT: traffic leaving the guest

VNet Level

Rules scoped to traffic within the same VNet. Only FORWARD applies here. Traffic arriving from a different VNet is evaluated at the host/cluster FORWARD layer.

Security Groups

Three security groups are defined at the cluster level.

cluster_management

Protects Proxmox node-to-node communication and management access.

Direction Protocol Source Destination Port Purpose
IN +dc/management_private All traffic from private management IPs
IN tcp +dc/management_public 22, 8006 SSH and Proxmox web UI
IN udp +dc/management_public 5405, 5412 Corosync cluster communication
IN tcp +dc/management_public 22 SSH access

cluster_in

Handles host-level IN rules for DHCP and DNS services.

Direction Macro Protocol Source Port Purpose
IN DHCPfwd DHCP forwarding
IN DNS DNS (all sources)
IN DNS DNS (all sources, second rule)
IN udp +sdn/ingress-all 67 DHCP from ingress guests
IN udp +sdn/isolated-all 67 DHCP from isolated guests

cluster_forward

Main transit rules for traffic passing through the host between VNets and to the internet.

# Protocol Source Destination Port Macro Comment
DNS +sdn/ingress-all DNS egress for ingress network
DNS +sdn/isolated-all DNS egress for isolated network
icmp +sdn/ingress-no-gateway ICMP egress from ingress guests
tcp +sdn/ingress-all 80, 443 HTTP Internet egress from ingress
tcp +sdn/isolated-all 80, 443 Internet egress from isolated
tcp +sdn/ingress-all +sdn/isolated-all 8080, 8443 ingress → isolated (backend)
tcp +sdn/ingress-all +sdn/isolated-all 8081 ingress → isolated (alt port)
DNS +sdn/k8group-all DNS egress for k8group
tcp +sdn/k8group-all 80, 443 Internet egress from k8group

Application-specific rules (Guacamole → VM SSH, monitoring ports) are added as named rules within this group with descriptive comments.

Traffic Flows

1. Host-local: DHCP

Guest → Bridge → Host (IN) → dnsmasq → DHCP Offer → Guest

Handled by cluster_in security group, rules for ports 67/udp.

2. Host-local: DNS

Guests query the host dnsmasq on port 53, which forwards to upstream DNS.

Guest → dnsmasq (IN) → upstream DNS (FORWARD)

Handled by cluster_in (DNS macro for IN) and cluster_forward (DNS macro for FORWARD).

3. North-South: Internet → Ingress Guest

Inbound traffic arrives at the node's WAN IP and is forwarded to an ingress guest via DNAT.

Internet → Node WAN IP → DNAT → Ingress Guest

DNAT configuration (/etc/network/nat.nft):

table inet nat {

    chain prerouting {
        type nat hook prerouting priority -100;

        iifname "vmbr0" ip protocol tcp tcp dport 80   dnat to 172.16.5.4:80
        iifname "vmbr0" ip protocol tcp tcp dport 443  dnat to 172.16.5.4:443
        iifname "vmbr0" ip protocol tcp tcp dport 8443 dnat to 172.16.5.4:8443
        iifname "vmbr0" ip protocol tcp tcp dport 4317 dnat to 172.16.5.4:4317
        iifname "vmbr0" ip protocol tcp tcp dport 4318 dnat to 172.16.5.4:4318
    }

    chain postrouting {
        type nat hook postrouting priority 100;

        # Guacamole → arc SSH via OVH private network
        oifname "vmbr1" ip saddr 172.16.10.115 ip daddr 192.168.10.2 ip protocol tcp tcp dport 22206 snat to 192.168.10.3
    }
}

172.16.5.4 is the ingress guest (reverse proxy). Inbound internet traffic on ports 80, 443, 8443, 4317, and 4318 is forwarded to it.

The postrouting SNAT rule enables Guacamole (at 172.16.10.115) to reach the arc server (192.168.10.2:22206) through the OVH private network interface (vmbr1), appearing as source 192.168.10.3.

4. East-West: Ingress → Isolated

The ingress reverse proxy forwards requests to backend services in the isolated network.

Ingress Guest → Host (FORWARD) → Isolated Guest

Handled by cluster_forward rules for +sdn/ingress-all+sdn/isolated-all on ports 8080, 8443, 8081.

5. South-North: Guest → Internet (SNAT)

Guest traffic exits through the node via Simple Zone SNAT.

Guest → Host (FORWARD) → SNAT → Internet

Handled by cluster_forward rules for port 80, 443 egress per VNet.

NAT Service

DNAT rules must persist across reboots and Proxmox firewall reloads.

# /etc/systemd/system/nat.service
[Unit]
Description=Load NAT nftables rules after Proxmox firewall
After=proxmox-firewall.service
Wants=proxmox-firewall.service
PartOf=proxmox-firewall.service

[Service]
Type=oneshot
ExecStart=/usr/sbin/nft -f /etc/network/nat.nft
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target
systemctl daemon-reload
systemctl enable nat.service
systemctl start nat.service

Management IPSets

Two IPSets are defined at the datacenter level.

IPSet Purpose
management_private Node-to-node cluster communication addresses
management_public External addresses allowed to reach the Proxmox management interface

Warning

Define and verify these IPSets before enabling any DROP policies to avoid losing host access.

Operational Checks

# 1. Firewall services — only proxmox-firewall must be active
systemctl is-active proxmox-firewall.service   # must be active
systemctl is-active pve-firewall.service       # must be inactive

# 2. IPv4 forwarding
sysctl net.ipv4.ip_forward                # must return 1

# 3. nftables
systemctl status nftables                 # must be active

# 4. dnsmasq (zone-based)
systemctl status dnsmasq                  # must be inactive
systemctl status dnsmasq@simple.service   # must be active

# 5. NAT service
systemctl status nat.service              # must be active