Proxmox 9 - Network Config

This caused me another headache and took far too long considering I had a good start from rebuilding the version 8 server.
It turned out to be a simple mistake that was staring me in the face.
Below is the code
#!/bin/bash
# configure-proxmox-network.sh
# Proxmox VE 9 + Debian 13 with dhcpcd, enhanced for diagnostics and fallback
set -euo pipefail
LOGFILE="/var/log/proxmox-net-setup-$(date +%Y%m%d-%H%M%S).log"
exec > >(tee -a "$LOGFILE") 2>&1
echo "=== Proxmox VE Network Configuration (Enhanced) ==="
# ─────────────────────────────────────────────────────────────
# 1. Backup interfaces and other fixes required for dhcpcd
echo "→ Backing up /etc/network/interfaces..."
cp /etc/network/interfaces /etc/network/interfaces.bak.$(date +%Y%m%d-%H%M%S)
echo "✓ Backup complete."
echo "→ Ensuring dhcpcd is installed and active..."
if ! systemctl is-active --quiet dhcpcd; then
apt update && apt install -y dhcpcd5
systemctl enable dhcpcd
systemctl start dhcpcd
echo "✓ dhcpcd installed and started."
else
echo "✓ dhcpcd already active."
fi
echo "→ Overwriting AppArmor override for dhclient..."
cat <<EOF > /etc/apparmor.d/local/usr.sbin.dhclient
# Allow dhclient to create UNIX sockets and request capabilities
network,
capability,
EOF
echo "✓ AppArmor override written."
echo "→ Reloading AppArmor profile for dhclient..."
apparmor_parser -r /etc/apparmor.d/usr.sbin.dhclient && echo "✓ AppArmor profile reloaded." || echo "⚠️ AppArmor reload failed — check profile existence."
echo "✓ AppArmor reloaded."
# ─────────────────────────────────────────────────────────────
# 2. Write bridge config
echo "→ Writing new /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 auto
bridge-ports enp5s0
bridge-stp on
bridge-fd 0
dns-nameservers 192.168.1.1
dns-search braedach.com
# Bridge: IPv6 SLAAC/RA - basically static but will shift if router does.
iface vmbr0 inet6 auto
accept_ra 2
privext 0
dns-nameservers fe80::f6e2:c6ff:feee:63e3
dns-search braedach.com
EOF
echo "✓ Interfaces file updated."
# ─────────────────────────────────────────────────────────────
# 3. Configure dhcpcd
echo "→ Writing /etc/dhcpcd.conf overrides..."
cat <<EOF >> /etc/dhcpcd.conf
denyinterfaces enp5s0
interface vmbr0
ipv6rs
hostname pxe
clientid
static domain_name_servers=192.168.1.1 fe80::f6e2:c6ff:feee:63e3
static domain_search=braedach.com
EOF
echo "✓ dhcpcd.conf updated."
# ─────────────────────────────────────────────────────────────
# 4. Sysctl tuning
echo "→ Writing /etc/sysctl.d/99-ipv6.conf..."
cat <<EOF > /etc/sysctl.d/99-ipv6.conf
net.ipv6.conf.all.forwarding=1
net.ipv6.conf.default.forwarding=1
net.ipv6.conf.all.proxy_ndp=1
net.ipv6.conf.default.proxy_ndp=1
net.ipv6.conf.vmbr0.proxy_ndp=1
net.ipv6.conf.vmbr0.accept_ra=2
net.ipv6.conf.vmbr0.autoconf=1
EOF
sysctl --system
echo "✓ Kernel parameters applied."
# ─────────────────────────────────────────────────────────────
# 5. Restart dhcpcd
echo "→ Restarting dhcpcd..."
systemctl restart dhcpcd
sleep 2
# ─────────────────────────────────────────────────────────────
# 6. Bring up interfaces
echo "→ Bringing up interfaces..."
ip link set vmbr0 up
# ─────────────────────────────────────────────────────────────
# 7. Validate IP assignment
echo "→ Validating IP assignment..."
HAS_IPV4=false
HAS_IPV6=false
if ip addr show vmbr0 | grep -q "inet "; then
echo "✓ IPv4 address assigned."
HAS_IPV4=true
else
echo "⚠️ No IPv4 address — attempting fallback..."
ip addr add 192.168.1.10/24 dev vmbr0
ip route add default via 192.168.1.1 || true
HAS_IPV4=true
echo "✓ Static IPv4 fallback applied."
fi
if ip addr show vmbr0 | grep -q "inet6 "; then
echo "✓ IPv6 address assigned."
HAS_IPV6=true
else
echo "⚠️ No IPv6 address — sending RA solicitation..."
rdisc6 vmbr0 || true
sleep 2
ip -6 addr show vmbr0 | grep -q "inet6 " && {
echo "✓ RA received."
HAS_IPV6=true
} || echo "❌ Still no IPv6 address."
fi
# ─────────────────────────────────────────────────────────────
# 8. Check default routes
echo "→ Checking default routes..."
ip route | grep -q '^default' && echo "✓ IPv4 default route OK." || echo "⚠️ No IPv4 default route."
ip -6 route | grep -q '^default' && echo "✓ IPv6 default route OK." || echo "⚠️ No IPv6 default route."
# ─────────────────────────────────────────────────────────────
# 9. DNS resolution test
echo "→ Testing DNS resolution..."
getent hosts google.com >/dev/null && echo "✓ DNS resolution working." || echo "❌ DNS resolution failed."
# ─────────────────────────────────────────────────────────────
# 10. Ensure ndppd is installed
echo "→ Checking ndppd..."
if ! command -v ndppd >/dev/null; then
apt update && apt install -y ndppd
echo "✓ ndppd installed."
else
echo "✓ ndppd already present."
fi
# ─────────────────────────────────────────────────────────────
# 11. Write ndppd config
echo "→ Writing /etc/ndppd.conf..."
cat <<EOF > /etc/ndppd.conf
route-ttl 30000
iface vmbr0 static {
router no
timeout 500
rule ::/0 {
}
}
EOF
systemctl enable ndppd
systemctl restart ndppd
echo "✓ ndppd active."
# ─────────────────────────────────────────────────────────────
# 12. Runtime diagnostics
echo "→ Final diagnostics:"
ip addr show vmbr0
ip route show
ip -6 route show
cat /etc/resolv.conf
echo "✅ Network configuration complete. Log saved to $LOGFILE"
echo "=== End of Script ==="
Fully tested and working with one minor hiccup
App armor is giving a little grief on dhclient but will work it out and update the code.
This is going to take a while. I may as well check every piece of code and every part to the system design and architecture and clean up my file system. Yes, I took a massive backup but nothing like a fresh start.
Notes:
1. Create and external backup and test it
2. Rebuild the server with the USB stick you made on version 9 release
3. Configure and test your dynamic networking - all router controlled
4. Setup the time server
5. Install fail2ban
6. Setup the mail relay server
7. Create the user accounts
8. Setup iptables and test the hell out of them
9. Integrate AbuseIPDB account
10. Test the LXC containers, networking and so on.
11. Start rebuilding all the docker servers and stacks - or you can just restore them.
Proxmox is a great hypervisor. You don't need much to start but I would not be running it on Pi hardware. Obviously the more you want from it - AI models being one I can think of - the more grunt you need.
#enoughsaid.