3

I am currently facing an issue about my current setup. I basically have a dedicated server to which a /64 IPv6 subnet have been assigned (2a01:4f8:221:1e81::/64). Connectivity on the host is working fine, as I can ping from there ipv6.google.com.

Also, this is the configuration:

root@void ~ # ifconfig vmbr0
vmbr0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 10.250.0.1  netmask 255.255.0.0  broadcast 10.250.255.255
        inet6 2a01:4f8:221:1e81:1:ffff:ffff:ffff  prefixlen 80  scopeid 0x0<global>
        inet6 2a01:4f8:221:1e81:212:ffff:ffff:ffff  prefixlen 80  scopeid 0x0<global>
        inet6 2a01:4f8:221:1e81:253:ffff:ffff:ffff  prefixlen 80  scopeid 0x0<global>
        inet6 2a01:4f8:221:1e81:251:ffff:ffff:ffff  prefixlen 80  scopeid 0x0<global>
        inet6 fe80::70a5:a1ff:fed6:8c0  prefixlen 64  scopeid 0x20<link>
        ether 4a:5a:df:ab:a8:bc  txqueuelen 1000  (Ethernet)
        RX packets 949686094  bytes 162428268530 (151.2 GiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 285868499  bytes 143826674082 (133.9 GiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

root@void ~ #

Routing table:

root@void ~ # ip -6 route show
2a01:4f8:221:1e81:1::/80 dev vmbr0 proto kernel metric 256 pref medium
2a01:4f8:221:1e81:212::/80 dev vmbr0 proto kernel metric 256 pref medium
2a01:4f8:221:1e81:251::/80 dev vmbr0 proto kernel metric 256 pref medium
2a01:4f8:221:1e81:253::/80 dev vmbr0 proto kernel metric 256 pref medium
2a01:4f8:221:1e81::/64 dev eth0 proto kernel metric 256 pref medium
fe80::/64 dev eth0 proto kernel metric 256 pref medium
fe80::/64 dev vmbr0 proto kernel metric 256 pref medium
default via fe80::1 dev eth0 metric 1024 pref medium
root@void ~ #

Problem comes once I ssh into a virtual machine and configure the network. In this example, I have the following configuration:

hypnotize@irc:~$ cat /etc/network/interfaces | tail -n4
iface eth0 inet6 static
    address 2a01:4f8:101:3172:251::3
    netmask 80
    gateway 2a01:4f8:101.3172:251:ffff:ffff:ffff
hypnotize@irc:~$

So, ifconfig looks like:

hypnotize@irc:~$ sudo ifconfig
[sudo] password for hypnotize:
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 10.250.3.6  netmask 255.255.0.0  broadcast 10.250.255.255
        inet6 fe80::9474:f1ff:fe6f:4bc3  prefixlen 64  scopeid 0x20<link>
        inet6 2a01:4f8:101:3172:251::3  prefixlen 80  scopeid 0x0<global>
        ether 96:74:f1:6f:4b:c3  txqueuelen 1000  (Ethernet)
        RX packets 177  bytes 16270 (15.8 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 161  bytes 18477 (18.0 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 0  (Local Loopback)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

hypnotize@irc:~$

While routing table appears:

hypnotize@irc:~$ ip -6 route show
2a01:4f8:101:3172:251::/80 dev eth0 proto kernel metric 256
fe80::/64 dev eth0 proto kernel metric 256
hypnotize@irc:~$

Unfortunately, when I try to ping6 it says "connect: Network is unreachable". I have net.ipv6.conf.all.forwarding enabled.

Do you see any error in my configuration? Thanks in advance


I have corrected the typo, and now it says:

root@irc:/home/hypnotize# ping6 ipv6.google.com
PING ipv6.google.com(fra16s20-in-x0e.1e100.net (2a00:1450:4001:821::200e)) 56 data bytes
From 2a01:4f8:101:3172:251::3 (2a01:4f8:101:3172:251::3) icmp_seq=1 Destination unreachable: Address unreachable
From 2a01:4f8:101:3172:251::3 (2a01:4f8:101:3172:251::3) icmp_seq=2 Destination unreachable: Address unreachable
From 2a01:4f8:101:3172:251::3 (2a01:4f8:101:3172:251::3) icmp_seq=3 Destination unreachable: Address unreachable
^C
--- ipv6.google.com ping statistics ---
5 packets transmitted, 0 received, +3 errors, 100% packet loss, time 4032ms

root@irc:/home/hypnotize#

Also, the routing table, now looks better, at least it has a default entry:

root@irc:/home/hypnotize# ip -6 route show
2a01:4f8:101:3172:251::/80 dev eth0 proto kernel metric 256
fe80::/64 dev eth0 proto kernel metric 256
default via 2a01:4f8:101:3172:251:ffff:ffff:ffff dev eth0 metric 1024
root@irc:/home/hypnotize#
Michael Hampton
  • 244,070
  • 43
  • 506
  • 972
alestark
  • 31
  • 3
  • `when I try to ping6 it says ` - When you try to ping what? The `hypnotize` system doesn't have a `::/0` route, so it would only be able to connect to `fe80::/64` and `2a01:4f8:101:3172:251::/80`. Not sure why it doesn't have a gateway, given your config, but you need to fix that. – Zoredache Sep 25 '19 at 19:06
  • Sorry, my mistake. I was meaning "when I try to ping6 ipv6.google.com". However, can you kindly instruct me about how to put in place that route? Thanks and regards – alestark Sep 25 '19 at 19:30
  • This looks like Hetzner, yes? I don't think you can bridge VMs directly to the host's NIC due to Hetzner's switch port security. On my Hetzner root server running KVM virtual machines I route to virtual networks instead, and the host NIC is not bridged to anyhting. – Michael Hampton Sep 25 '19 at 19:53
  • Yes, it's hetzner. So, you think that my configuration lacks or is against Hetzner's security policies? In this case, how do you suggest to fix? – alestark Sep 25 '19 at 19:54

1 Answers1

7

Like many enterprises, Hetzner runs switch port security on its network switches, meaning that only authorized MAC addresses can talk to the network. This means that the hardware address of the NIC in your server can speak, but the virtual MAC addresses of your virtual machines cannot. Thus it does not work to bridge your VMs directly to the outside world. (If you have ordered extra IPv4 addresses, then Hetzner will allow you to generate virtual MAC addresses for each of them that you can assign to your VMs, which will let this setup work, but if you haven't got extra IPv4 addresses or don't want to buy them, then you cannot do.)

I have a KVM virtual machine host on Hetzner, where the VMs are mostly reachable only by IPv6, and this is how I set it up.

Instead of bridging directly to the host NIC, I create virtual networks for each /80, and assign VMs to those virtual networks. The host will then route between the host NIC and the virtual networks, which are not bridged (layer 2) but routed (layer 3).

So the host is configured as:

IPV6ADDR="2a01:4f8:150:43ea::2/64"
IPV6_DEFAULTGW="fe80::1"

The libvirt virtual networks are configured as /80 networks. Virt-manager cannot handle creating /80 networks, so you will need to write the XML yourself. Here is an example:

<network>
  <name>v6net1</name>
  <forward mode='route'/>
  <bridge name='v6net1' stp='on' delay='0'/>
  <domain name='v6net1'/>
  <ip address='192.168.101.1' netmask='255.255.255.0'>
    <dhcp>
      <range start='192.168.101.128' end='192.168.101.254'/>
    </dhcp>
  </ip>
  <ip family='ipv6' address='2a01:4f8:150:43ea:1::1' prefix='80'>
    <dhcp>
      <range start='2a01:4f8:150:43ea:1::1000' end='2a01:4f8:150:43ea:1::ffff'/>
    </dhcp>
  </ip>
</network>

Now, all virtual machines' NICs are added to the v6net1 network, and get an address in this /80 from DHCPv6. You could assign them manually if you wanted though. This creates a bridge v6net1, but the host NIC is not part of the bridge. Thus traffic is routed between the VMs and the outside world, and when leaving the host the traffic has the host's MAC address.

This doesn't cover global IPv4 connectivity, e.g. masquerading or port forwarding. I handle this separately in firewalld, outside of libvirt, and do not use libvirt's NAT functionality. If you just want a simple NAT so VMs can connect out to IPv4 hosts, and don't need incoming traffic, use <forward mode='nat'> instead. You could also omit IPv4 setup entirely, for pure IPv6-only VMs.

Michael Hampton
  • 244,070
  • 43
  • 506
  • 972