Skip to content

Instantly share code, notes, and snippets.

@larkinwc
Created January 24, 2026 22:48
Show Gist options
  • Select an option

  • Save larkinwc/7aa9153e2df116077b26f3b0c14c66c8 to your computer and use it in GitHub Desktop.

Select an option

Save larkinwc/7aa9153e2df116077b26f3b0c14c66c8 to your computer and use it in GitHub Desktop.
Fixes proxmox-firewall issues with netbird on pve 9.1
#!/bin/bash
# fix-proxmox-netbird.sh
# Configures Proxmox VE hosts to work properly with NetBird/WireGuard
#
# Fixes:
# 1. Adds NetBird subnet to Proxmox firewall whitelist
# 2. Disables strict reverse path filtering for WireGuard interface
# 3. Restarts firewall services
set -e
NETBIRD_SUBNET="100.76.0.0/16"
NETBIRD_INTERFACE="wt0"
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
log_info() { echo -e "${GREEN}[INFO]${NC} $1"; }
log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
log_error() { echo -e "${RED}[ERROR]${NC} $1"; }
# Check if running as root
if [[ $EUID -ne 0 ]]; then
log_error "This script must be run as root"
exit 1
fi
# Check if this is a Proxmox host
if [[ ! -d /etc/pve ]]; then
log_error "This doesn't appear to be a Proxmox host (/etc/pve not found)"
exit 1
fi
log_info "Configuring Proxmox host for NetBird compatibility..."
# --- Step 1: Configure rp_filter (reverse path filtering) ---
log_info "Configuring rp_filter settings..."
SYSCTL_FILE="/etc/sysctl.d/90-netbird.conf"
cat > "$SYSCTL_FILE" << 'EOF'
# NetBird/WireGuard compatibility
# Disable strict reverse path filtering to allow VPN traffic
net.ipv4.conf.all.rp_filter=2
net.ipv4.conf.default.rp_filter=2
EOF
# Apply sysctl changes
sysctl --system > /dev/null 2>&1
log_info "rp_filter configured in $SYSCTL_FILE"
# Also set for wt0 interface if it exists
if ip link show "$NETBIRD_INTERFACE" &>/dev/null; then
sysctl -w "net.ipv4.conf.${NETBIRD_INTERFACE}.rp_filter=0" > /dev/null 2>&1
log_info "rp_filter disabled for $NETBIRD_INTERFACE interface"
fi
# --- Step 2: Configure Proxmox Firewall ---
log_info "Configuring Proxmox firewall..."
CLUSTER_FW="/etc/pve/firewall/cluster.fw"
HOST_FW="/etc/pve/nodes/$(hostname)/host.fw"
# Function to add NetBird config to firewall file
add_netbird_firewall_config() {
local fw_file="$1"
local fw_dir=$(dirname "$fw_file")
# Create directory if it doesn't exist
mkdir -p "$fw_dir"
# Check if file exists and already has netbird config
if [[ -f "$fw_file" ]] && grep -q "netbird" "$fw_file" 2>/dev/null; then
log_warn "NetBird config already exists in $fw_file, skipping..."
return 0
fi
# Create or append to firewall config
if [[ ! -f "$fw_file" ]]; then
cat > "$fw_file" << EOF
[OPTIONS]
enable: 1
[IPSET netbird]
$NETBIRD_SUBNET
[RULES]
IN ACCEPT -source +netbird -log nolog
EOF
log_info "Created $fw_file with NetBird rules"
else
# Append to existing file
cat >> "$fw_file" << EOF
# NetBird/WireGuard access rules
[IPSET netbird]
$NETBIRD_SUBNET
[RULES]
IN ACCEPT -source +netbird -log nolog
EOF
log_info "Appended NetBird rules to $fw_file"
fi
}
# Try cluster firewall first (applies to all nodes)
if [[ -d /etc/pve/firewall ]]; then
add_netbird_firewall_config "$CLUSTER_FW"
else
# Fall back to host-specific firewall
add_netbird_firewall_config "$HOST_FW"
fi
# --- Step 3: Restart Firewall Services ---
log_info "Restarting firewall services..."
# Check which firewall service is running
if systemctl is-active --quiet proxmox-firewall 2>/dev/null; then
systemctl restart proxmox-firewall
log_info "Restarted proxmox-firewall (nftables backend)"
elif systemctl is-active --quiet pve-firewall 2>/dev/null; then
systemctl restart pve-firewall
log_info "Restarted pve-firewall (iptables backend)"
else
log_warn "No Proxmox firewall service is running"
fi
# --- Step 4: Verify NetBird is running ---
if systemctl is-active --quiet netbird 2>/dev/null; then
log_info "NetBird service is running"
# Restart to pick up any changes
systemctl restart netbird
log_info "Restarted NetBird service"
else
log_warn "NetBird service is not running"
fi
# --- Step 5: Display current status ---
echo ""
log_info "=== Configuration Complete ==="
echo ""
echo "Firewall config:"
if [[ -f "$CLUSTER_FW" ]]; then
grep -A5 "netbird" "$CLUSTER_FW" 2>/dev/null || true
fi
echo ""
echo "rp_filter settings:"
sysctl net.ipv4.conf.all.rp_filter
sysctl net.ipv4.conf.default.rp_filter
if ip link show "$NETBIRD_INTERFACE" &>/dev/null; then
sysctl "net.ipv4.conf.${NETBIRD_INTERFACE}.rp_filter"
fi
echo ""
log_info "Done! Test connectivity with: ping <netbird-peer-ip>"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment