Date: 2024-06-24
I just want to run a lightweight LXC as an IPv6 router in Proxmox.
In this article, we’ll configure the following:
route-3-host
as an Alpine LXC that acts as a simple IPv6 router.eth0
as route-3-host
’s WAN interface that obtains IPv6 addresses via DHCPv6.
vmbr0
on the Proxmox host. This should already exist.eth1
as route-3-host
’s LAN interface that provides IPv6 addresses via SLAAC.
vmbr3
on the Proxmox host. We’ll create this too.test-3-host
as an Alpine LXC whose traffic will go through route-3-host
.
Let’s set up route-3-host
along with its network bridge interface vmbr3
.
route-3-host
eth0
vmbr0
vmbr3
route-3-host
-> Network -> Add
eth1
vmbr3
Now boot up the new route-3-host
LXC and login as root.
You’ll be greeted with some text that mentions running setup-alpine
, but we already did the initial setup in Proxmox, so let’s overwrite the Message of the Day:
echo '# Main screen turn on.' >/etc/motd
Freshen up the system by updating packages:
apk update
apk upgrade
Verify that route-3-host
can reach the internet over IPv6:
nslookup ip6only.me
Configure sysctl
to enable IPv6 forwarding across all devices:
# Enable forwarding.
cat >/etc/sysctl.conf <<"HEREDOC"
net.ipv6.conf.default.forwarding=1
net.ipv6.conf.all.forwarding=1
HEREDOC
rc-update add sysctl default
rc-service sysctl start
Verify that both eth0
and eth1
report a “1” value for IPv6 forwarding:
cat /proc/sys/net/ipv6/conf/eth0/forwarding
cat /proc/sys/net/ipv6/conf/eth1/forwarding
Configure dhcpcd
to obtain an IPv6 address on eth0
along with an IPv6 prefix to delegate to eth1
:
apk add dhcpcd
cat >/etc/dhcpcd.conf <<"HEREDOC"
noipv6rs
ipv6ra_noautoconf
interface eth0
ipv6rs
ia_na 1
ia_pd 2 eth1/0
interface eth1
ipv6only
HEREDOC
rc-service networking restart
Verify that route-3-host
can still reach the internet over IPv6:
nslookup ip6only.me
ping -6 -c 3 grencez.dev
Verify that route-3-host
has 2 IPv6 addresses for eth0
and another 2 for eth1
:
ip -6 address show dev eth0
ip -6 address show dev eth1
For both interfaces, expect to see a link-local address that begins with fe8
and a global address that doesn’t.
An IPv4 address may also exist for eth0
(run ip -4 address
to check).
If you don’t want it anymore, add an “ipv6only” line under “interface eth0” in /etc/dhcpcd.conf
and restart the networking
service again.
Configure radvd
to advertise that route-3-host
can act as a router for SLAAC clients on eth1
:
apk add radvd
cat >/etc/radvd.conf <<"HEREDOC"
interface eth1 {
AdvSendAdvert on;
prefix ::/64 {
AdvOnLink on;
AdvAutonomous on;
};
};
HEREDOC
rc-update add radvd default
rc-service radvd start
In order to test, let’s create the client LXC named test-3-host
.
This time we let Proxmox know how we actually intend to obtain IP addresses.
test-3-host
eth0
vmbr3
2606:4700:4700::1111,2001:4860:4860::8888
(Cloudflare and Google DNS servers)test-3-host
-> Firewall -> Options
Boot up the new test-3-host
LXC and hope for the best!
Try to lookup a hostname first in order to test DNS resolution:
nslookup grencez.dev
ping -c 3 grencez.dev
Next we should ensure that a firewall is actually blocking traffic.
On test-3-host
, grab one of the addresses returned by ip address
and try pinging it from route-3-host
.
The ping command should not show any responses; 100% packet loss.
You should also be able to see these DROPped ping attempts in the Proxmox UI at test-3-host
-> Firewall -> Log.
I’d like to eventually use this Alpine LXC to replace a pfSense VM in my Proxmox host and run similar setups on dedicated hardware. Router operating systems actually kind of suck. But there’s a few more challenges to tackle:
route-3-host
could also act as a DNS server.eth0
. Just not in an LXC.