Network switch

Root server with IPv6-only KVM guests (II): NAT64, DNS64, and KVM 18

This artic­le is out­da­ted, find its repla­ce­ment in the IPv6-first guide
I’ve updated this artic­le bet­ween 2018 and 2020 con­stant­ly but final­ly deci­ded that I need ano­ther for­mat for this infor­ma­ti­on. So I wro­te the IPv6-first gui­de which you can read online as HTML or PDF docu­ment. It’s CC-BY-SA-licen­sed and its sources can be found on Github
Root ser­ver with IPv6-only KVM guests

In the first part of this artic­le series, I’ve descri­bed how to set up a root ser­ver which can ser­ve KVM guests which only have IPv6 con­nec­ti­vi­ty. I use the Ger­man hos­ting pro­vi­der Hetz­ner as an exam­p­le and descri­be a bridged set­up which fits into that provider’s IPv6 infrastructure.

Network switch

Net­work switch

After the basic set­up, we need some more ser­vices on the host to be able to install the first guest systems.

Create a non-root user on the system.

Hetzner’s instal­la­ti­on pro­cess gene­ra­tes a sys­tem with only the root user. To make it more com­pli­ant with usu­al Ubun­tu beha­viour, add a non-root user:

  • Crea­te user with adduser.
  • Put your ssh public key into .ssh/authorized_keys of that user.

You can now eit­her per­form the fol­lo­wing steps as that user with sudo -s or con­ti­nue as direct­ly log­ged in root via ssh.

NAT64 with Tayga

As I wro­te, our guest sys­tems shall have IPv6-only inter­net. That impli­es that they can­not access sys­tems which are IPv4-only. Unfort­u­na­te­ly, even in 2018, the­re are quite popu­lar sites like which do not have any IPv6 con­nec­ti­vi­ty at all. To make such sys­tems acces­si­ble from the guest sys­tems, we set up a NAT64 ser­vice which per­forms a net­work address trans­la­ti­on for exact­ly this case.

I deci­ded to go with the „Tay­ga” ser­ver. Its scope is limi­t­ed to exact­ly per­form NAT64. This makes it neces­sa­ry to add fur­ther ser­vices to make all this real­ly useable but it also mini­mi­zes con­fi­gu­ra­ti­on com­ple­xi­ty. This is what I did:

  • Install the tay­ga ser­vice by the usual 
  • In /etc/tayga.conf, enable the dis­ab­led ipv6-addr direc­ti­ve as this is nee­ded for working with the well-known pre­fix. You should set the IPv6 address to some­thing ran­dom in your IPv6 subnet: 

    Addi­tio­nal­ly, switch the prefix direc­ti­ve from the acti­va­ted 2001... one to the 64:ff9b::/96 one::

  • The who­le Tay­ga con­fi­gu­ra­ti­on reads like this: 
  • Test the new set­up by start­ing tayga once in foreground: 

    This should give some­thing like this:

  • Stop the manu­al­ly star­ted ins­tance and edit /etc/default/tayga. Set RUN to yes:
  • Launch the service 

    systemctl status tayga should say the Acti­ve sta­te is active (running), the log should end with

  • If the Acti­ve sta­te is active (exited) and the pro­to­col says some­thing about „set RUN to yes”, you have for­got­ten to enable the RUN opti­on in /etc/default/tayga. If you cor­rect that, you have to per­form a stop and a start com­mand after­wards to launch tayga: 

DNS64 with bind

NAT64 is usual­ly used tog­e­ther with a so-cal­led „DNS64” name ser­ver. This is a spe­ci­al­ly con­fi­gu­red name ser­ver. If a cli­ent asks it for an IPv6 name reso­lu­ti­on, i.e. an AAAA name ser­vice record and the­re is only an IPv4 A record for the reques­ted name, the DNS64 name ser­ver „mocks up” an AAAA record mung­ing the IPv4 address and a „well-known pre­fix” to a syn­the­ti­cal IPv6 address. This address – sur­pri­se, sur­pri­se – points direct­ly to a nice­ly pre­pared NAT64 ser­ver so that the IPv6 sys­tem talks to an IPv4 sys­tem trans­par­ent­ly hid­den behind the NAT64 proxy.

DNS64 and NAT64 translate betwwen IP protocols

DNS64 and NAT64 trans­la­te bet­ween IP protocols

Go on like this:

  • Install bind9 on the host: 
  • Our bind is a for­war­ding only-ser­ver only for our own vir­tu­al machi­nes. On Debi­an-deri­ved sys­tems, the bind opti­ons nee­ded for this set­up are loca­ted in /etc/bind/named.conf.options. Edit that file and enter the fol­lo­wing entries: 
  • The actu­al important defi­ni­ti­on is the dns64 sec­tion at the bot­tom of the options defi­ni­ti­ons. It enables the DNS64 mode of bind and defi­nes the IPv6 address ran­ge into which the addres­ses should be converted.
  • It also important to defi­ne listen-on {}; to disable lis­tening on the IPv4 port altog­e­ther – we do not need it. Rest­ric­ting allow-query to the localnets is also important to pre­vent the ser­ver from beco­ming an open DNS relay. We only need it for our inter­nal network.
  • Check the net­work in listen-on-v6 and also check the forwarders. You who­le IP address reso­lu­ti­on will not work if one of the­se is wrong.
  • Restart the dae­mon and check that it is enab­led and running: 

After the­se steps, you have a working DNS64 ser­ver which you can use for all your vir­tu­al machi­nes on the system.

Using an exter­nal DNS64 server
So far, the name ser­ver is only used for DNS64. You can also use the Goog­le ser­vers 2001:4860:4860::6464 and 2001:4860:4860::64 offe­ring this ser­vice. Their repli­es are com­pa­ti­ble with our NAT64 set­up. Howe­ver, having an own ser­ver redu­ces exter­nal depen­den­ci­es and allows for addi­tio­nal ser­vices lateron.

Include NAT64/DNS64 into radvd advertisements

We now have the NAT64/DNS64 ser­vice pair up and run­ning. We will inform the vir­tu­al machi­nes by the rou­ter adver­ti­se­ment dae­mon we have alre­a­dy set up. This sim­pli­fies instal­la­ti­on and admi­nis­tra­ti­on tremendously:

  • Extend /etc/radvd.conf:
  • The RDNSS defi­ni­ti­on descri­bes which DNS ser­ver to access. Use the host’s IP address. If you opted for the Goog­le ser­vers to do the job, wri­te instead 
  • The route sec­tion adver­ti­ses that this sys­tem rou­tes the 64:ff9b:: net­work. Only with this defi­ni­ti­on the vir­tu­al ser­vers know whe­re to send the packets for the emu­la­ted IPv6 addres­ses for the IPv4-only ser­vers to.
  • Restart radvd and check its out­put with radvdump. It should con­tain both the DNS ser­ver and the NAT64 route.
The nasty Hetz­ner pitfall
In their own docu­men­ta­ti­on, Hetz­ner also descri­bes how to set­up radvd. For the DNS ser­vers, howe­ver, they use IPv6 exam­p­le addres­ses from the 2001:db8 realm. It took me three days and seve­re doubts about Hetzner’s IPv6 set­up to find out, that my only mista­ke was to copy the­se wrong IP addres­ses for the DNS ser­ver into the con­fi­gu­ra­ti­on. Don’t make the same mistake…

You have now pre­pared ever­y­thing for the IPv6-only vir­tu­al machi­nes to come: They get their net­work con­fi­gu­ra­ti­on through the cen­tral­ly admi­nis­tra­ted radvd. The adver­ti­sed set­up includes a name ser­ver with DNS64 and a NAT64 rou­te to access IPv4-only systems.

About non-vir­tu­al net­work setups
In my series, I descri­be how to set up a root ser­ver with vir­tu­al machi­nes. Espe­ci­al­ly NAT64/DNS64 is com­ple­te­ly inde­pen­dent of that. If you admi­nis­tra­te a (real) com­pu­ter net­work and want to lay the ground for IPv6-only machi­nes in that, do exact­ly the same with your phy­si­cal machi­nes: Install Tay­ga and the DNS64-capa­ble Bind9 on the rou­ter behind which the IPv6-only sys­tems resi­de. This might be the „fire­wall” of clas­si­cal set­ups. Then, your actu­al com­pu­ters play the role of the vir­tu­al machi­nes in this guide.

Install KVM

We’­re now rea­dy for the final steps! Our net­work is con­fi­gu­red far enough so that we real­ly can start instal­ling vir­tu­al machi­nes on our sys­tem. For this, we, of cour­se, need KVM. For Ubun­tu 18.04 I fol­lo­wed the first steps of this gui­de::

  • Check that the sys­tem sup­ports vir­tua­liza­ti­on at all. Issue 

    and veri­fy that the result is grea­ter than 0.

  • Then, app­ly

    and check that the result is

    If not, the BIOS set­tings of the sys­tem must be cor­rec­ted. Cont­act the hos­ting pro­vi­der to sort that out.

  • Install KVM and the requi­red hel­per packages: 

    This will install a rather lar­ge num­ber of new packa­ges on your host. Final­ly, it will be capa­ble to ser­ver vir­tu­al machines.

  • The libvirtd dae­mon should alre­a­dy be up and run­ning at this point. If this is, for any reason, not the case, start and enable it with the usu­al systemctl com­mands or wha­te­ver the init sys­tem of your host ser­ver requi­res to do this.
  • To sim­pli­fy instal­la­ti­on and admi­nis­tra­ti­on of your vir­tu­al machi­nes, add the „nor­mal” user you crea­ted abo­ve to the libvirt user group. I pre­fer doing this by sim­ply adding the user name to the defi­ni­ti­on in /etc/group:

Well, that’s it! Our sys­tem can get its first vir­tu­al machine!

The first virtual machine

Instal­ling a vir­tu­al machi­ne might sound dif­fi­cult to you if you have never done this befo­re. In fact, it is not. After all, it is even simp­ler than the remo­te instal­la­ti­on on a hos­ted sys­tem once you get used to it. On the phy­si­cal machi­ne, you are depen­dent on what the hos­ting pro­vi­der offers as instal­la­ti­on pro­ce­du­res. KVM offers you more or less a com­ple­te vir­tua­li­zed gra­phi­cal con­so­le which allows acting just as you were sit­ting in front of the (vir­tu­al) computer’s moni­tor. This way, you can install wha­te­ver you like.

Fur­ther­mo­re, if you make a con­fi­gu­ra­ti­on mista­ke on the phy­si­cal host, you might end with a bro­ken machi­ne. If this hap­pens in a vir­tu­al machi­ne, you have seve­ral ways to sol­ve the pro­blem: You can con­nect to the con­so­le and log in direct­ly wit­hout net­work access. If the machi­ne does not boot any­mo­re, you can even mount the vir­tu­al hard disk into the phy­si­cal machi­ne and try to fix. And if the machi­ne is for any reason bro­ken bey­ond repair, you can just throw it away and start over with a fresh installation.

I sug­gest start­ing with a throw-away vir­tu­al machi­ne. It will not con­tain any „real” ser­vices but only show any remai­ning pro­blems in the set­up. Fur­ther, it allows to test and learn the who­le pro­cess of instal­ling a vir­tu­al machi­ne in the set­up. Prepa­re the set­up with the fol­lo­wing steps:

  • Copy the instal­la­ti­on ISO image for the sys­tem to install onto the host.
  • Con­nect to the KVM sys­tem using virt-manager. Of cour­se, you might also use ano­ther cli­ent, but I find this rather easy.
  • Use the ssh con­nec­tion of the nor­mal user crea­ted on the host.
  • Start the host creation.

From here on, things beco­me rather stan­dard. We’­re now in the pro­cess of instal­ling a guest sys­tem in a KVM guest. My best prac­ti­ces are these:

  • Assign as many CPUs to the vir­tu­al machi­ne as the hard­ware has. Only if you suspect the vir­tu­al machi­ne to grab too many resour­ces, redu­ce the CPU number.
  • Use cow2 image file for the vir­tu­al hard disk. It is the most fle­xi­ble way once it comes to migra­ting the vir­tu­al machi­ne and today’s file sys­tems can cope with the dou­ble indi­rec­tion quite well.
  • Give the vir­tu­al machi­ne defi­ni­ti­on the same name the sys­tem will later have.

The one inte­res­t­ing point is the net­work con­fi­gu­ra­ti­on at the very end of the defi­ni­ti­on pro­cess. Here, enter the „Net­work sel­ec­tion” befo­re crea­ting the machi­ne. Sel­ect „Name of com­mon device” and give the name of bridge expli­cit­ly. Here it is br0.

Network setup for virtual machine in virt-manager

Net­work set­up for vir­tu­al machi­ne in virt-manager

If you are rea­dy, press „Crea­te” and sum­mon your first vir­tu­al system.

Ubuntu 18.04 as guest system

We’­re now at a stage whe­re you can install any ope­ra­ting sys­tem which is installable in KVM vir­tu­al machi­nes. I give some advi­ses for the Ubun­tu 18.04 net­work installer:

  • Install by sim­ply pres­sing the „Install” but­ton. I never nee­ded any addi­tio­nal ker­nel parameters.
  • Sel­ect cor­rect key­board or it will dri­ve you nuts.
  • Net­work auto­de­tec­tion will idle around when loo­king for the non-exis­ting DHCP ser­ver. Keep calm. Apart from that, it will sim­ply set­up ever­y­thing correctly.
  • Enter the host­na­me, pre­fer­ra­b­ly the same as the name of the vir­tu­al machi­ne to keep it simple…
  • Check whe­ther you pro­vi­der has their own mir­ror for the instal­la­ti­on ser­ver. Hetz­ner has, the­r­e­fo­re you can save down­load time: 
    • Go to top of mir­ror list and press enter information manually
    • For Hetz­ner: This ser­ver also works also with IPv6. But even IPv4 ser­vers would be pos­si­ble due to our NAT64/DNS64 setup.
    • Set direc­to­ry for the Hetz­ner ser­ver to /ubuntu/packages/
  • You do not need a HTTP proxy.
  • Install should start.
  • I sug­gest to not par­ti­ti­on the vir­tu­al hard disk in any way. It is not needed.
  • Ever­y­thing else is as usu­al. In the soft­ware sel­ec­tion, you should at least sel­ect the „Open­S­SH ser­ver” so that you can log into the sys­tem after installation.
Ubuntu 18.04 within KVM virt-manager

Ubun­tu 18.04 within KVM virt-manager

As this is Ubun­tu 18.04, this machi­ne uses net­plan for net­work con­fi­gu­ra­ti­on. It has a very simp­le defi­ni­ti­on file in /etc/netplan/01-netcfg.yaml:

Net­plan sum­ma­ri­zes rou­ter adver­ti­se­ment in the „dhcp6” statement.

Note that after (re-)booting the vir­tu­al machi­ne, it may take some seconds until it has con­fi­gu­red its net­work inter­face. Once it has done so, ever­y­thing should work wit­hout problems.

Entering the virtual machine in DNS

To work with the long IPv6 addres­ses con­ve­ni­ent­ly, DNS is almost man­da­to­ry. You should enter the vir­tu­al machi­ne now into the domain.

  • Find the vir­tu­al machine’s IP address, e.g. through „ip a”.
  • Crea­te an ent­ry in the DNS zone of the sys­tem. Note that you only enter a AAAA record, not an old-fashio­ned A record for an IPv4 address. The sys­tem just has no IPv4 address…
  • In my opi­ni­on, it makes also sen­se to always crea­te a rever­se IP ent­ry for IPv6 hosts. If for any reason your DNS AAAA ent­ry vanis­hes, you still have the rever­se IP ent­ry which assigns name and IP address. Rever­se IP ent­ries are always mana­ged in the DNS realm of the IP net­work owner. In my case, they are edi­ted in Hetzner’s robot interface.
Reverse IP entries in Hetzner's robot interface

Rever­se IP ent­ries in Hetzner’s robot interface

The SLAAC mecha­nism deri­ves the IP address from the MAC address of the vir­tu­al machi­ne. So, it will be sta­tic even though it has nowhe­re been con­fi­gu­red expli­cit­ly. This who­le mecha­nism works smooth­ly with any modern ope­ra­ting sys­tem. I even made a test instal­la­ti­on of Win­dows 10 which went per­fect­ly wit­hout any IPv4 address.

IPv6-only network settings in Windows 10

IPv6-only net­work set­tings in Win­dows 10

We can now install any num­ber of vir­tu­al machi­nes on our ser­ver. In the next artic­les of this series, I descri­be how I set up some ser­vices on this infra­struc­tu­re. The most important ones are, of cour­se, e‑mail and web servers.

This artic­le is out­da­ted, find its repla­ce­ment in the IPv6-first guide
I’ve updated this artic­le bet­ween 2018 and 2020 con­stant­ly but final­ly deci­ded that I need ano­ther for­mat for this infor­ma­ti­on. So I wro­te the IPv6-first gui­de which you can read online as HTML or PDF docu­ment. It’s CC-BY-SA-licen­sed and its sources can be found on Github

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

18 Gedanken zu “Root server with IPv6-only KVM guests (II): NAT64, DNS64, and KVM

  • Mihai

    Hey Dirk.

    I have a pro­blem with Hetz­ner DNS: 

    Jul 14 13:10:52 nimblevm‑1 named[26207]: timed out resol­ving ‚./DNSKEY/IN’: 2a01:4f8:0:1::add:9898#53
    Jul 14 13:10:53 nimblevm‑1 named[26207]: timed out resol­ving ‚./DNSKEY/IN’: 2a01:4f8:0:1::add:1010#53
    Jul 14 13:10:54 nimblevm‑1 named[26207]: timed out resol­ving ‚./DNSKEY/IN’: 2a01:4f8:0:1::add:9999#53
    Jul 14 13:11:01 nimblevm‑1 named[26207]: resol­ver pri­ming query complete
    Jul 14 13:11:01 nimblevm‑1 named[26207]: mana­ged-keys-zone: Unable to fetch DNSKEY set ‚.’: timed out.

    In radvd.conf:
    inter­face br0
    Adv­Send­Ad­vert on;
    Adv­Ma­na­gedFlag off;
    AdvO­ther­Con­fig­Flag off;
    Adv­De­fault­P­re­fe­rence high;
    pre­fix 2a01:x:x:x::/64
    AdvOn­Link on;
    Adv­Au­to­no­mous on;
    Adv­Rou­ter­Ad­dr on;
    RDNSS 2001:db8:0:a0a1::add:1010
    rou­te 64:ff9b::/96 {

    in bind9:
    options {
    direc­to­ry „/var/cache/bind”;

    forwarders {
    2a01:4f8:0:1::add:1010; # Hetz­ner name servers

    dns­sec-vali­da­ti­on auto;

    auth-nxdo­main no; # con­form to RFC1035
    listen-on {};
    listen-on-v6 {
    allow-query { localnets; };
    dns64 64:ff9b::/96 {
    cli­ents { any; };

    Did you have any idea? (I used Ubun­tu 20.04)

    • Mihai

      I can also ping:

      test@test:~$ ping git​hub​.com
      ping: con­nect: Net­work is unreachable
      test@test:~$ ping goog​le​.com
      PING (2a00:1450:400f:807::200e)) 56 data bytes
      64 bytes from arn09s11​-in​-x0e​.1e100​.net (2a00:1450:400f:807::200e): icmp_seq=1 ttl=119 time=7.57 ms
      64 bytes from arn09s11​-in​-x0e​.1e100​.net (2a00:1450:400f:807::200e): icmp_seq=2 ttl=119 time=7.62 ms

    • Dirk Hillbrecht Autor des Beitrags

      Hel­lo Mihai,

      you have an error in your radvd con­fi­gu­ra­ti­on. The RDNSS ent­ry must point to YOUR OWN phy­si­cal host, NOT to the Hetz­ner DNS ser­vers. So, if the IPv6 address of your host is 2a01:1:2:3:a:b:c:d, the RDNSS sec­tion must read 

      RDNSS 2a01:1:2:3:a:b:c:d

      This way, you announ­ce your own Bind DNS ser­ver to your vir­tu­al machi­nes – and that is nee­ded for the DNS64 mecha­nism. Curr­ent­ly, your radvd announ­ces the Hetz­ner DNS ser­vers to your vir­tu­al machi­nes. When they query it for „git​hub​.com”, it only returns an IPv4 address. The vir­tu­al machi­ne, howe­ver, has no IPv4 con­nec­tion and the­r­e­fo­re can­not access the sys­tem. For goog​le​.com, an IPv6 address is retur­ned – and as the vir­tu­al machi­ne has IPv6 con­nec­ti­vi­ty, it can con­nect to it. When ever­y­thing is con­fi­gu­red cor­rect­ly, your vir­tu­al machi­ne con­nects to „git​hub​.com” using an IPv6 address begin­ning with „64:ff9b” and ending with the hexa­de­ci­mal repre­sen­ta­ti­on of the IPv4 address of git​hub​.com. It’s the one retur­ned by your Bind ser­ver. The con­nec­tion suc­ceeds becau­se of the radvd ser­ver on the host which per­forms an address trans­la­ti­on beween the IPv6 net­work you use intern­al­ly and the exter­nal IPv4 address. git​hub​.com sees a IPv4 con­nec­tion from your host.

      Best regards,

      • Mihai

        Hey Dirk,

        Thanks a lot for your ans­wer. I fixed the radvd con­fi­gu­ra­ti­ons and now when I’m try­ing to ping git​hub​.com from my guest:

        test@test:~$ ping6 git​hub​.com
        PING – 82-118 – 3‑ (64:ff9b::8c52:7603)) 56 data bytes
         — git​hub​.com ping statistics —
        5 packets trans­mit­ted, 0 recei­ved, 100% packet loss, time 4088ms

        • Mihai

          Did you have any idea?
          Is bind9 nee­ded if I use Hetz­ner DNS? If no: What should my con­fig rdvd look like, and also tayga.
          Thanks a lot!

        • Dirk Hillbrecht Autor des Beitrags

          Pin­ging to an IPv6-con­nec­ted sys­tem, e.g. goog​le​.com, still works, right? It looks like NAT64 does not work: The vir­tu­al ser­ver gets a DNS64-pre­pared IPv6 address for the IPv4-only ser­ver but can­not con­nect it.

          The default rou­te of the vir­tu­al ser­ver must point to the host sys­tem. In my set­up, rou­ting looks like this:

          root@virthost:~# ip -6 route show
          64:ff9b::/96 via fe80::4e75:c4ff:fe88:1d14 dev ens3 proto ra metric 1024 pref medium
          2a01:123:456:7890::/64 dev ens3 proto ra metric 100 pref medium
          fe80::/64 dev ens3 proto kernel metric 256 pref medium
          default via fe80::4e75:c4ff:fe88:1d14 dev ens3 proto ra metric 100 pref high

          First line is the NAT64 rou­te, second and third defi­ne the net­works direct­ly reacha­ble on the inter­face, last line is the default rou­te. First and last line opoint to the host sys­tem. It must look simi­lar on your vir­tu­al machi­ne. If it does not, check radvd again. „pre­fix” line con­ta­ins your net­work? Can you ping the host sys­tem from the vir­tu­al machi­ne on its IP addres­ses? Did you have added the MAC address rewri­ting using ebtools as descri­bed in the first artic­le? The­se are the things that come to my mind. Let me know the results.

          • Mihai


            Pin­ging to goog­le still works. Also from my guest I can pin­ging my ipv6 from host.

            ip ‑6 rou­te show
            64:ff9b::/96 via fe80::d65d:64ff:feba:e420 dev enp1s0 pro­to ra metric 1024 expi­res 1771sec pref medium
            2a01:123:456:7890::/64 dev enp1s0 pro­to ra metric 100 expi­res 86371sec pref medium
            fe80::/64 dev enp1s0 pro­to ker­nel metric 256 pref medium
            default via fe80::d65d:64ff:feba:e420 dev enp1s0 pro­to ra metric 100 expi­res 1771sec pref high.

            Pre­fix line con­ta­ins my net­work. I added the MAC address rewri­ting using ebtools.

            But I real­ly don’t under­stand this part:

            After having chan­ged the IP address this way, enter it into DNS:

            Add an AAAA record in the domain the sys­tem should be reacha­ble in.
            Add a PTR record in the hoster’s rever­sal IP ent­ries. If the­re is alre­a­dy an ent­ry for the for­mer address, you can remo­ve it by sim­ply wiping out the ser­ver name and pres­sing „Enter”.
            While you’re at it, also add the A record and the PTR record for the IPv4 address of the Host.

            You use a regis­trar like Hetz­ner DNS ? (I don’t crea­te any domains). Plea­se help me with that (may­be that’s the problem)

            Thanks a lot!

          • Mihai

            Hey Dirk,

            „Ente­ring the vir­tu­al machi­ne in DNS
            To work with the long IPv6 addres­ses con­ve­ni­ent­ly, DNS is almost man­da­to­ry. You should enter the vir­tu­al machi­ne now into the domain.

            Find the vir­tu­al machine’s IP address, e.g. through „ip a”.
            Crea­te an ent­ry in the DNS zone of the sys­tem. Note that you only enter a AAAA record, not an old-fashio­ned A record for an IPv4 address. The sys­tem just has no IPv4 address…
            In my opi­ni­on, it makes also sen­se to always crea­te a rever­se IP ent­ry for IPv6 hosts. If for any reason your DNS AAAA ent­ry vanis­hes, you still have the rever­se IP ent­ry which assigns name and IP address. Rever­se IP ent­ries are always mana­ged in the DNS realm of the IP net­work owner. In my case, they are edi­ted in Hetzner’s robot interface.”

            And also if you can explain me that I real­ly app­re­cia­te it! 

            Thanks a lot!

          • Dirk Hillbrecht Autor des Beitrags

            Hel­lo Mihai, this part dec­scri­bes how you enter the host and the vir­tu­al machi­nes into the DNS name ser­ver for your domain. It stores key-value-pairs of infor­ma­ti­on in so-cal­led „records”. The records have dif­fe­rent „types”. An „A”-record’s key is a com­pu­ter name („”) and the value is an IPv4 address („”), so it allows to retrie­ve the IPv4 address for a host­na­me. An „AAAA” record does the same thing for an IPv6 address. So, for a ser­ver which should be acces­si­ble by both pro­to­cols IPv4 and IPv6, (at least) two records must be put into DNS, one „A” and one „AAAA” record. Rever­se IP records con­tain exact­ly the oppo­si­te infor­ma­ti­on, they allow to retrie­ve a sys­tem name for a given IPv4 or IPv6 address. This all is only important for you if you want to access your host and your vir­tu­al machi­nes from „the inter­net”. And, of cour­se, you need a domain and a regis­trar which allows you to edit the DNS records for the domain. The domain can be hos­ted at the same pro­vi­der as your ser­ver, but it can also be a total­ly inde­pen­dent. Best regards, Dirk

  • Stepan

    I have an issue with radvd.conf on Ubun­tu 20,
    when I add the route clau­se as suggested

    route 64:ff9b::/96 {

    and then reboot, I can­not SSH to ser­ver back and even ping. It hap­pens with eit­her vari­ant of RDNSS clause.
    What do you think can be an issue? I tried to reinstall the ser­ver from res­cue like 5 times and careful­ly exe­cu­te ins­truc­tions and then do reboot after ins­truc­tion to deter­mi­ne the point when exact­ly the ser­ver won’t be accessible.

    • Dirk Hillbrecht Autor des Beitrags

      Hi Ste­pan, thanks for your com­ment. The­re are always small and not-so-small chan­ges bet­ween dif­fe­rent Ubun­tu ver­si­ons. I have deve­lo­ped the ins­truc­tions on Ubun­tu 16.04 and 18.04. I had no chan­ce so far to get hands on a Ubun­tu 20.04 sys­tem to test and check that mys­elf. My guess is, howe­ver, that the­re have been chan­ges in the Net­plan con­fi­gu­ra­ti­on which break IPv6 con­nec­ti­vi­ty. Did the reboot after the initi­al set­up of radvd suc­ceed? Did the sys­tem have both IPv6 addres­ses after the reboot as descri­bed the­re? Did you chan­ge the address sta­ti­cal­ly assi­gned to the phy­si­cal machi­ne from the Net­plan con­fi­gu­ra­ti­on? Could you con­nect to the phy­si­cal machi­ne via that IPv6 address? Note that all this is only gues­sing. Good luck & regards, Dirk

      • Stepan

        Hi Dirk,
        yes, all went good right befo­re the step of chan­ging radvd.conf in the 2nd artic­le. So I had two IPv6 on the br0 inter­face, and then I’ve chan­ged Net­plan con­fig, set sta­tic one ins­tead of the default ::2. I’ve tried to con­nect to the ser­ver via IPv6, all works fine. Just the issue hap­pens exact­ly after I add the route clau­se into radvd.conf. So now I have radvd.conf like this (just my IPv6 net­work pre­fix hidden):

        interface br0
        AdvSendAdvert on;
        AdvManagedFlag off;
        AdvOtherConfigFlag off;
        AdvDefaultPreference high;
        prefix 2a01:xxxx:xxxx:xxxx::/64
        AdvOnLink on;
        AdvAutonomous on;
        AdvRouterAddr on;
        # Google DNS
        #RDNSS 2001:4860:4860::6464
        # Hetzner DNS
        RDNSS 2a01:4f8:0:1::add:9999
        # Local DNS (bind9)
        #RDNSS 2a01:xxxx:xxxx:xxxx:xxxx:5dff:fe0d:dae6
        #route 64:ff9b::/96

        • Dirk Hillbrecht Autor des Beitrags

          Hel­lo Stepan,

          [Note: The reaso­ning here is fal­se, the­re is no pro­blem. See below.]

          I must admit that I have no real idea what is going on but the­re seem to be chan­ges in how Net­plan and the two IP pro­to­cols work. I found this artic­le on Asku­b­un­tu. The ans­wer says (well… gues­ses) that Net­plan needs an expli­cit rou­te for IPv6 to work. My con­fi­gu­ra­ti­on examp­les do not have such a rou­te for IPv6. Per­haps this is the pro­blem. But again – this is only gues­sed until I could mys­elf work on an Ubun­tu 20.04 system.

          Best regards,

          • Dirk Hillbrecht Autor des Beitrags

            I was final­ly able to run the who­le pro­ce­du­re with Ubun­tu 20.04. It work­ed wit­hout pro­blems. So, the reason why it did not work for you, Ste­pan, must be some­whe­re else. I still think that some­thing with the IPv6 set­up or rou­ting went wrong in the first place.

            The only real dif­fe­rence I found bet­ween Ubun­tu 18.04 and 20.04 so far is the packa­ge list for the KVM sys­tem. For Ubun­tu 20.04, I use this one:

            apt install qemu-kvm libvirt-dae­mon bridge-utils vir­tinst libvirt-dae­mon-sys­tem virt-top libguestfs-tools libo­s­in­fo-bin qemu-sys­tem virt-manager

            Apart from that, ever­y­thing went *exact­ly* as with Ubun­tu 18.04.

  • Sebastian

    Hal­lo Dirk,

    vie­len Dank für die­se sehr aus­führ­li­che und unglaub­lich hilf­rei­che Anleitung.
    Ich hat­te es schon fast auf­ge­ge­ben so ein set­up bei Hetz­ner mög­lich zu machen aber dei­ne Anlei­tung hat gera­de alle Stei­ne aus dem Weg geräumt. DANKE!

    Son­ni­ge Grüße

    • Dirk Hillbrecht Autor des Beitrags

      Hal­lo Sebastian,

      das freut mich! Ich weiß nicht, wann du der Anlei­tung gefolgt bist: Ich habe erst kürz­lich im ers­ten Teil den Abschnitt mit der Mas­kie­rung der inter­nen MAC-Adres­sen hin­zu­ge­fügt. Ohne das macht Hetz­ner irgend­wann Stress…

      Vie­le Grü­ße und viel Erfolg beim wei­te­ren Administrieren,

      • Sebastian

        Hal­lo Dirk,

        dan­ke für den Tipp, ich habe es mit umge­setzt. Nun muss ich nur noch einen sinn­vol­len Weg fin­den Ser­ver­diens­te in den Gäs­ten per IP4 anzu­bin­den. Hast du da einen Tipp? Ich schwan­ke zwi­schen Nginx rever­se pro­xy und socat.

        Dir eine son­ni­ge Zeit und bes­te Grüße

        • Dirk Hillbrecht Autor des Beitrags

          Hal­lo Sebastian,

          ich habe das mit einem Rever­se Pro­xy mit Apa­che gemacht. socat hat bei mir nicht zuver­läs­sig funk­tio­niert und so habe ich nur eine Tech­nik zu war­ten. Außer­dem wirk­te socat auf mich arg gebastelt…

          Ciao, Dirk