About two years ago I started implementing a server setup which is based on virtual machines for the services and a physical host orchestrating them. The special feature was that all virtual machines are only connected via IPv6. I only needed IPv4 on the physical host and on virtual machines with services where an external IP protocol conversion was impossible (hello, e‑mail…).
Originally, I planned five to six articles in this series. I published three: One about the basic setup of the physical host, one about the basic setup of the virtual machines and one about how to implement an e‑mail server on this setup. Unfortunately, things got a bit stuck after that. The articles about web servers, integration with Let’s Encrypt and implementing a Cryptpad instance were somehow finished but I never got them „over the line” and online.
Nevertheless, I used my computer with all these schemes constantly (and still use it, you just read this article on it…) and even started implementing it on other systems. I found some mistakes and shortcomings in the setup and corrected them in the blog articles. I even got some amount of feedback from people who – successfully – used my instructions to implement the described IPv6-based server schemes on their own servers. Marvellous!
By July 2020, two things happened – totally unrelated but almost at the same time. First was a lengthy conversation with a reader of my articles. He tried to implement the server with Ubuntu 20.04 and ran into strange problems. I also had tried this setup once by the end of May 2020, but I did not dig really deep into it and oversaw the problems.
The second thing was my company. We decided to move some production systems onto a new server cluster and those servers should – for the first time – also be virtualized and IPv6-based for the main communication channels.
Both incidents lead me deeper into my setup again. I checked the Ubuntu 20.04 problems and was able to circumvent the problem, which I think is raised by the systemd-networkd daemon. I fixed some quirks in the IPv4 configuration. I added information about routing, fixed a bunch of – well – incorrect statements and overall brought the documents back in shape.
And I decided, that some blog articles are not sufficient as base for the ongoing work on this documentation. So, I moved everything into Asciidoc documents, reorganized and sorted it and made a „real” large guide document of it (which I sometimes refer to as „book”…).
So, bad news: Today, the article series about IPv6 networking on KVM setups in this blog ends. But, good news: It is replaced by a much better document! Just look for
The IPv6 First Guide – Network Configurations With Linux And KVM
Read it as HTML document on http://ipv6-first-guide.hillbrecht.de.
Read it as PDF document on http://ipv6-first-guide.hillbrecht.de/ipv6-first-guide.pdf.
Or download or browse its Asciidoc sources on https://github.com/dirkhillbrecht/ipv6-first-guide.
The guide does not only include the (updated) content of the blog articles, but also all the stuff which was unpublished so far. Namely:
- How to obtain SSL certificates from Let’s encrypt
- How to setup web servers on IPv6-only machines and make them accessible from IPv4 clients
- How to install a Cryptpad instance on a IPv6-only machine and make it accessible from IPv4
These are rather large topics and I am quite happy that I finally managed to publish all this stuff.
I have released the whole guide under the CC-BY-SA license, so feel free to get it, enhance it, correct it.
Hi Dirk,
thx for this Guide.
I almost made it, but got stuck at obtaining dhcpV6 ip for the virtual machine.
I use virt-install command line and preseed file for the
Debian Installer but it should work without preseed.
Here is my script.
preseed=”/KVM/preseed.cfg”
#Overwrite MAC if not exist yet.…; \
echo „Please enter new Hostname”; read host;\
[ ‑z ${mac} ] && mac=$(openssl rand ‑hex 3 | sed „s/\(..\)/\1:/g; s/.$//; s/^/52:54:00:/”);\
echo „Mac ist: ${mac} und hostname ist ${host}”; \
echo ‑e ‚HTTP/1.1 200 OK\r\n’; cat ${preseed} | nc ‑lv 127.0.0.1 8080 ‑q 1 & \
sudo virt-install –cpu host –virt-type kvm –name ${host} \
–network=bridge:br0,model=virtio,mac=${mac} \
–memory 2096 –vcpus=4 \
–controller type=scsi,model=virtio-scsi \
–disk path=/KVM/${host}.qcow2,format=qcow2,bus=scsi,discard=‚unmap’,cache=none,size=20 \
–location http://deb.debian.org/debian/dists/buster/main/installer-amd64/ \
–os-type linux –os-variant debian10 –accelerate –hvm \
–graphics spice,keymap=de-de,listen=0.0.0.0 –video qxl –channel spicevmc \
–console pty,target_type=serial \
–initrd-inject=${preseed} \
–extra-args=„url=http://127.0.0.1:8080/preseed.cfg DEBCONF_DEBUG=5”;
When debian installer try to configure DHCP it dont get an IP and my syslog says…
Feb 23 21:44:44 h2910728 kernel: [20908.431781] audit: type=1400 audit(1614113084.037:81): apparmor=„STATUS” operation=„profile_load” profile=„unconfined” name=„libvirt-4baf6ec7-f85f-4ff5-9779-f573f200d1c7” pid=6106 comm=„apparmor_parser”
Feb 23 21:44:44 h2910728 kernel: [20908.530129] audit: type=1400 audit(1614113084.133:82): apparmor=„STATUS” operation=„profile_replace” info=„same as current profile, skipping” profile=„unconfined” name=„libvirt-4baf6ec7-f85f-4ff5-9779-f573f200d1c7” pid=6109 comm=„apparmor_parser”
Feb 23 21:44:44 h2910728 kernel: [20908.603012] audit: type=1400 audit(1614113084.209:83): apparmor=„STATUS” operation=„profile_replace” info=„same as current profile, skipping” profile=„unconfined” name=„libvirt-4baf6ec7-f85f-4ff5-9779-f573f200d1c7” pid=6112 comm=„apparmor_parser”
Feb 23 21:44:44 h2910728 systemd-udevd[6117]: Using default interface naming scheme ‚v240’.
Feb 23 21:44:44 h2910728 kernel: [20908.676933] audit: type=1400 audit(1614113084.281:84): apparmor=„STATUS” operation=„profile_replace” info=„same as current profile, skipping” profile=„unconfined” name=„libvirt-4baf6ec7-f85f-4ff5-9779-f573f200d1c7” pid=6115 comm=„apparmor_parser”
Feb 23 21:44:44 h2910728 kernel: [20908.680594] br0: port 2(vnet0) entered blocking state
Feb 23 21:44:44 h2910728 kernel: [20908.732107] br0: port 2(vnet0) entered disabled state
Feb 23 21:44:44 h2910728 kernel: [20908.742826] device vnet0 entered promiscuous mode
Feb 23 21:44:44 h2910728 systemd-udevd[6117]: link_config: autonegotiation is unset or enabled, the speed and duplex are not writable.
Feb 23 21:44:44 h2910728 systemd-networkd[801]: vnet0: Gained carrier
Feb 23 21:44:44 h2910728 kernel: [20908.752990] br0: port 2(vnet0) entered blocking state
Feb 23 21:44:44 h2910728 kernel: [20908.763609] br0: port 2(vnet0) entered listening state
Feb 23 21:44:44 h2910728 kernel: [20908.849308] audit: type=1400 audit(1614113084.453:85): apparmor=„STATUS” operation=„profile_replace” info=„same as current profile, skipping” profile=„unconfined” name=„libvirt-4baf6ec7-f85f-4ff5-9779-f573f200d1c7” pid=6126 comm=„apparmor_parser”
Feb 23 21:44:45 h2910728 ntpd[871]: bind(27) AF_INET6 fe80::fc54:ff:fe2a:2faf%18#123 flags 0x11 failed: Cannot assign requested address
Feb 23 21:44:45 h2910728 ntpd[871]: unable to create socket on vnet0 (24) for fe80::fc54:ff:fe2a:2faf%18#123
Feb 23 21:44:45 h2910728 ntpd[871]: failed to init interface for address fe80::fc54:ff:fe2a:2faf%18
Feb 23 21:44:45 h2910728 systemd-networkd[801]: vnet0: Gained IPv6LL
Feb 23 21:44:47 h2910728 ntpd[871]: Listen normally on 25 vnet0 [fe80::fc54:ff:fe2a:2faf%18]:123
Feb 23 21:44:47 h2910728 ntpd[871]: new interface(s) found: waking up resolver
Feb 23 21:44:59 h2910728 kernel: [20923.782886] br0: port 2(vnet0) entered learning state
Feb 23 21:45:14 h2910728 kernel: [20938.887015] br0: port 2(vnet0) entered forwarding state
Feb 23 21:45:14 h2910728 kernel: [20938.897935] br0: topology change detected, propagating
Any Ideas?