IPv4 via NAT and IPv6 directly to VM

Rootinator

Member
May 1, 2019
23
0
21
54
Hello,

I only have a single IPv4 address and an entire IPv6 subnet on the host.

IPv4 is already forwarded to the individual VMs via NAT.
I would like to assign each VM an additional IPv6 (without NAT).

IPv4: Forwarding via NAT
IPv6: directly to the VM

How do I proceed?

(Currently vmbr1 is assigned to the VMs as network (for IPv4 NAT))

Here are my /etc/network/interfaces (currently only for IPv4):

Code:
# public IPv4

auto lo
iface lo inet loopback

auto eno1
iface eno1 inet manual

auto vmbr0
iface vmbr0 inet static
        address  192.168.0.100
        netmask  255.255.255.0
        gateway  192.168.0.1
        bridge-ports eno1
        bridge-stp off
        bridge-fd 0

# VM BR

auto vmbr1
iface vmbr1 inet static
        address  10.0.0.1
        netmask  24
        bridge-ports none
        bridge-stp off
        bridge-fd 0
        post-up echo 1 > /proc/sys/net/ipv4/ip_forward
        post-up iptables -t nat -A POSTROUTING -s '10.0.0.0/24' -o vmbr0 -j MASQUERADE
        post-down iptables -t nat -D POSTROUTING -s '10.0.0.0/24' -o vmbr0 -j MASQUERADE


#VM Port forwarding

# VM1
post-up iptables -t nat -A PREROUTING -i vmbr0 -p tcp --dport 80 -j DNAT --to 10.0.0.15:80
post-down iptables -t nat -D PREROUTING -i vmbr0 -p tcp --dport 80 -j DNAT --to 10.0.0.15:80

# VM2
post-up iptables -t nat -A PREROUTING -i vmbr0 -p tcp --dport 8080 -j DNAT --to 10.0.0.10:80
post-down iptables -t nat -D PREROUTING -i vmbr0 -p tcp --dport 8080 -j DNAT --to 10.0.0.10:80
 
You can do regular routing for ipv6 if you use your host as a gateway. Depending on your environment, you'll most likely need to enable NDP-proxying, either manually or with a daemon such as ndppd. Best read up on ndppd, it's way more convenient ;-)
 
How do I manually configure IPv6 so that it is routed directly to the VM?

Since there are not many VMs, I would like to do this without additional software.

(vmbr1 is currently used for the VM IPv4 NAT.)
 
For the most part the same as with ipv4 with some differences.
The main sysctl is is in the "all" interface section: net.ipv6.conf.all.forwarding=1, instead of net.ipv4.ip_forward

Your provider will likely expect the IP to come from your host's MAC address, in this case enable `proxy_ndp` via a sysctl. Assume your WAN interface is called IFACE (use eth0, vmbr0, ens0 etc., whichever your main public global ipv4 address resides on).
Set net.ipv6.conf.IFACE.proxy_ndp=1
Then add a neighbor-proxy entry:
Code:
# ip neigh add proxy 2001:1234::1337 dev IFACE
Note that this only works for fixed addresses, not whole ranges. (ndppd can do either)

The sysctls can be in /etc/sysctl.conf or added via `post-up` scripts like your iptables calls. The `ip neigh` you'll probably want as a `post-up` entry. (and a line with `del` instead of `add` in `pre-down`).

I'd recommend generally reading up more on ipv6, NDP (neighbor discovery protocol) and routing on linux. There are a lot of tiny things which can be easily forgotten which you'll want to remember to check up on when something doesn't work, as well as getting used to using `tcpdump` to trace how far the forwarding is working/not-working on each side.
 
I cannot get IPv6 route + IPv4 NAT to work.

With this configuration the VM is also not accessible via IPv4 port forwarding.
The IPv6 assigned in the VM is never accessible. Neither from internal to external nor from external to internal.
Without IPv6, the VM can be reached from outside via IPv4 NAT.

It would be mega nice if someone could write me a detailed instruction how to set up IPv6 route and IPv4 NAT ;)

Here my modified /etc/network/interfaces

Code:
source /etc/network/interfaces.d/*

auto lo
iface lo inet loopback

# IPv4 Host
auto ens33
iface ens33 inet static
        address 192.168.0.100/24
        gateway 192.168.0.1
        up route add -net 192.168.0.100 netmask 255.255.255.224 gw 192.168.0.1 dev ens33

# IPv6 Host
iface ens33 inet6 static
        address fe80::ffff:ffff:ffff:4441/64
        gateway fe80::1

# VM Bridge IPv4 NAT
auto vmbr1
iface vmbr1 inet static
        address 10.0.0.1/24
        bridge-ports none
        bridge-stp off
        bridge-fd 0
        post-up echo 1 > /proc/sys/net/ipv4/ip_forward
        post-up iptables -t nat -A POSTROUTING -s '10.0.0.0/24' -o ens33 -j MASQUERADE
        post-down iptables -t nat -D POSTROUTING -s '10.0.0.0/24' -o ens33 -j MASQUERADE

# ---------------------------------

# IPv6 proxy

# IPv6 VM1
ip neigh add proxy fe80::ffff:ffff:ffff:10 dev ens33

# ---------------------------------

# VM IPv4 Port forwarding

# VM1
post-up iptables -t nat -A PREROUTING -i vmbr1 -p tcp --dport 80 -j DNAT --to 10.0.0.15:80
post-down iptables -t nat -D PREROUTING -i vmbr1 -p tcp --dport 80 -j DNAT --to 10.0.0.15:80


ens33 = Host-Ethernet
vmbr1 = VM-Bridge
 
Last edited:
Thanks for the advice!

Now IPv4 NAT always works.

What does not work yet is IPv6 routing.

How exactly do I have to configure the "vmbr" that the VM can be reached directly via IPv6?
 

About

The Proxmox community has been around for many years and offers help and support for Proxmox VE, Proxmox Backup Server, and Proxmox Mail Gateway.
We think our community is one of the best thanks to people like you!

Get your subscription!

The Proxmox team works very hard to make sure you are running the best software and getting stable updates and security enhancements, as well as quick enterprise support. Tens of thousands of happy customers have a Proxmox subscription. Get yours easily in our online shop.

Buy now!