Proxmox - IPv6 Configuration

Proxmox - IPv6 Configuration

I rebuilt my server. I don't do it often, but I increased my storage that required a trip back to the documentation and a rethink of how to best utilize the space

This led to a rethink of the fixed IP address problem, related to the IPv6 address space delegation from the ISP.

So, I started from scratch - again, albeit with a better understanding.

Here is the result

First of all, the proxmox server is configured via the router to have a fixed IPv4 address and a SLAAC IPv6 address that is delegated from the WAN interface based on what is issued from the ISP. Since SLAAC is based on the MAC address of the device and these are fixed within the Proxmox server they should not change.

If the LAN network on the router changes due to its delegation from the WAN network the Proxmox server should sort itself out on a DHCPv6 renewal or I can reboot it manually. IPv4 and IPv6 addresses are tracked via DDNS on the domain registry and change automatically.

The Code

First we need to ensure that the host is getting its address correctly by changing the etc/network/interfaces file.

# NOT VLAN aware
# This file is used by the ifupdown package to manage network interfaces.

# /etc/network/interfaces

auto lo
iface lo inet loopback

# Physical NIC left unmanaged
iface enp5s0 inet manual

# Bridge: IPv4 via DHCP
auto vmbr0
iface vmbr0 inet dhcp
    bridge-ports enp5s0
    bridge-stp on
    bridge-fd 0
    dns-nameservers [IPv4 local DNS server address]
    dns-search [your TLD]

# Bridge: IPv6 SLAAC/RA
iface vmbr0 inet6 auto
    accept_ra 2
    privext 0
    dns-nameservers [IPv6 link local DNS server address]
    dns-search [your TLD]

source /etc/network/interfaces.d/*

Note: You will need to change the interface names to reflect your server

Create the following file and place it in accordingly

# /etc/sysctl.d/99-ipv6.conf

# Enable forwarding globally
net.ipv6.conf.all.forwarding=1
net.ipv6.conf.default.forwarding=1

# Proxy NDP (so LXC guests are reachable)
net.ipv6.conf.all.proxy_ndp=1
net.ipv6.conf.default.proxy_ndp=1
net.ipv6.conf.vmbr0.proxy_ndp=1

# Explicitly accept RAs and autoconf on vmbr0
net.ipv6.conf.vmbr0.accept_ra=2
net.ipv6.conf.vmbr0.autoconf=1

Note: This file is for IPv6 ONLY not IPv4
Note: Best practices have not been implemented in this post
Note: Enhance security by creating and modifying this file and the IPv4 one.

Patch the /etc/dhcp/dhclient.conf

# It should look something like this

supersede domain-name "[your TLD]";
prepend domain-name-servers [IPv4 DNS Server]; 

send host-name = gethostname();
request subnet-mask, broadcast-address, time-offset, routers,
        domain-name, domain-name-servers, domain-search, host-name,
        dhcp6.name-servers, dhcp6.domain-search, dhcp6.fqdn, dhcp6.sntp-servers,
        netbios-name-servers, netbios-scope, interface-mtu,
        rfc3442-classless-static-routes, ntp-servers;

Install and configure NNDP

apt update && apt install -y ndppd

# Create the following file

# ndppd configuration for Proxmox VE
# This file is used to proxy NDP requests for LXC containers.
# /etc/ndppd.conf

route-ttl 30000

iface vmbr0 static {
    router no
    timeout 500
    rule ::/0 {
    }
}

Reboot the server. You should be getting no errors from your system logs and all the LXC containers should be getting IPv6 addresses both link local and global

Network Configuration Script

The entire script looks something like this. It's not tested as I hate rebuilding my server as it's a time-consuming task.

#!/bin/bash

# configure-proxmox-network.sh
# This script automates the network configuration for Proxmox VE to set up a bridge with
# DHCP for IPv4 and SLAAC for IPv6, along with necessary sysctl settings and
# ndppd configuration for proxy NDP.

# Nil errors have been detected in the system journal.

# Usage: Run this script as root on your Proxmox VE server.
# Updated: 12-07-2025

set -euo pipefail
echo "=== Proxmox VE Automated Network Configuration ==="

# 1. Backup existing interfaces
echo "→ Backing up /etc/network/interfaces..."
cp /etc/network/interfaces /etc/network/interfaces.bak.$(date +%s)
echo "✓ Backup complete."

# 2. Write minimal DHCP + SLAAC bridge config
echo "→ Applying network config to /etc/network/interfaces..."
cat <<EOF > /etc/network/interfaces
# If you want to manage parts of the network configuration manually,
# /etc/network/interfaces
# NOT VLAN aware
# This file is used by the ifupdown package to manage network interfaces.

auto lo
iface lo inet loopback

# Physical NIC left unmanaged
iface enp5s0 inet manual

# Bridge: IPv4 via DHCP
auto vmbr0
iface vmbr0 inet dhcp
    bridge-ports enp5s0
    bridge-stp on
    bridge-fd 0
    dns-nameservers [IPv4 DNS server]
    dns-search [your TLD]

# Bridge: IPv6 SLAAC/RA
iface vmbr0 inet6 auto
    accept_ra 2
    privext 0
    dns-nameservers [IPv6 link local DNS Server]
    dns-search [your TLD]

source /etc/network/interfaces.d/*
EOF
echo "✓ Network interfaces updated."

# 3. Write sysctl config for IPv6 forwarding, proxying, and RA
echo "→ Writing /etc/sysctl.d/99-ipv6.conf..."
cat <<EOF > /etc/sysctl.d/99-ipv6.conf
# Enable forwarding globally
net.ipv6.conf.all.forwarding=1
net.ipv6.conf.default.forwarding=1

# Proxy NDP (so LXC guests are reachable)
net.ipv6.conf.all.proxy_ndp=1
net.ipv6.conf.default.proxy_ndp=1
net.ipv6.conf.vmbr0.proxy_ndp=1

# Explicitly accept RAs and autoconf on vmbr0
net.ipv6.conf.vmbr0.accept_ra=2
net.ipv6.conf.vmbr0.autoconf=1
EOF
echo "✓ Sysctl configuration written."

# 4. Update DHCP client config
echo "→ Patching /etc/dhcp/dhclient.conf..."
DHCLIENT_FILE="/etc/dhcp/dhclient.conf"
touch "$DHCLIENT_FILE"

# Remove old entries if any
sed -i '/^supersede domain-name /d' "$DHCLIENT_FILE"
sed -i '/^prepend domain-name-servers /d' "$DHCLIENT_FILE"

# Add desired domain and DNS servers
cat <<EOF >> "$DHCLIENT_FILE"
supersede domain-name "[your TLD]";
prepend domain-name-servers [IPv4 DNS address];
EOF
echo "✓ dhclient.conf updated."

# 5. Apply sysctl settings
echo "→ Applying kernel parameters..."
sysctl --system
echo "✓ Kernel parameters applied."

# 6. Restart vmbr0 networking
echo "→ Restarting bridge interface vmbr0..."
ifdown vmbr0 || true
ifup vmbr0
echo "✓ Interface restarted."

# 7. Check IPv6 route
echo "→ Checking for default IPv6 route..."
if ip -6 route | grep -q '^default'; then
    echo "✓ IPv6 default route found."
else
    echo "⚠️ No default IPv6 route—sending RA solicitation..."
    rdisc6 vmbr0 || true
    sleep 2
    ip -6 route | grep '^default' && echo "✓ RA received." || echo "❌ Still no default route."
fi

# 8. Connectivity check
echo "→ Verifying gateway reachability..."
ping -c1 [router IPv4 address] >/dev/null && echo "✓ IPv4 gateway reachable." || echo "⚠️ IPv4 ping failed."
ping6 -c1 [router IPv6 address]%vmbr0 >/dev/null 2>&1 && echo "✓ IPv6 gateway reachable." || echo "⚠️ IPv6 ping failed."

# 9. ndppd installation if needed
echo "→ Ensuring ndppd is installed..."
if ! command -v ndppd >/dev/null 2>&1; then
    apt update && apt install -y ndppd
    echo "✓ ndppd installed."
else
    echo "✓ ndppd already present."
fi

# 10. Configure ndppd
echo "→ Configuring ndppd..."
cat <<EOF > /etc/ndppd.conf
# ndppd configuration for Proxmox VE
# This file is used to proxy NDP requests for LXC containers.
# /etc/ndppd.conf

route-ttl 30000

iface vmbr0 static {
    router no
    timeout 500
    rule ::/0 {
    }
}
EOF
echo "✓ ndppd.conf written."

# 11. Enable and start ndppd
echo "→ Enabling ndppd service..."
systemctl enable ndppd
systemctl restart ndppd
echo "✓ ndppd active."

echo "✅ Network automation script complete. Proxmox VE is ready for containerized IPv6 glory!"
echo "=== End of Proxmox VE Network Configuration ==="

You will need to modify the file and replace the place holders and ensure that your interfaces match. For example the bridge interface (vmbr0) might be called something else and so on.

Extensive testing was carried out. The files were checked again prior to posting.

I have had no problems with this configuration and have used MTR to test both IPv4 and IPv6 connectivity across multiple domains.

I have restarted my router multiple times, and everything rotates their IPv6 correctly altering the first 4 blocks of the IPv6 address.

Next up mail relay. I found a few bugs that required addressing.

#enoughsaid