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