IPv6 mit der Telekom und Archlinux

Da die VDSL-Verbindung nach einer Neustiefelung meines Rechners nicht mehr starten wollte, musste ich mich mal wieder mit diesem Thema auseinandersetzen. Ursache des Ganzen war, dass adsl.service nicht mehr starten wollte, weil /usr/bin/pppoe-start nicht mehr im Paket rp-pppoe enthalten war.

PPPoE

Da immer alles funktioniert hat, ist vollkommen an mir vorbei gegangen, dass pppd mittlerweile ein Plugin bekommen hatte, das PPPoE über das entsprechende Kernel-Modul abwickelt. Scheint so, dass der RP-PPPoE ausgedient hat. Wie auch immer, um eine Verbindung mit der Telekom nur mit pppd herzustellen, erstelle man folgende Konfigurationsdatei in /etc/ppp/peers namens z. B. tkom:

plugin pppoe.so # dafür muss pppoe.ko geladen sein!
tkom # Interface name
name "<kdnr>#0001@t-online.de" # ppp-Benutzername
persist
defaultroute
+ipv6 # Entscheidend für IPv6-Prefix-Delegation!
mru 1380
mtu 1380
hide-password
noauth

Wenn man dann noch das richtige Passwort in /etc/ppp/pap-secrets hinterlegt hat, sollte sich die Verbindung mit systemctl start ppp@tkom aufbauen lassen. @tkom ist der Name der Konfigurationsdatei in /etc/ppp/peers.

Prefix Delegation

Um ein globales IPv6-Prefix für das interne Netz zu bekommen, benötigt man einen DHCPv6-Client, der es an dem PPP-Interface annimmt. Für dhcpcd sieht die Konfiguration so aus:

duid
waitip 6
ipv6only
interface ppp0
ipv6rs
iaid 1
ia_pd 1 int/0/64/801

Die letzten beiden Zeilen sind entscheidend: iaid definiert eine UUID, die dann in ia_pd (das erste Argument, in diesem Fall 1) benutzt wird, um der Netzwerkkarte mit dem Namen int ein /64-Prefix zuzuweisen. Der letzte Parameter ist das Suffix, was das Interface, an das delegiert wird, bekommt, standardmäßig 1, wenn man es auslässt. Aber Wahrschau: Das ist kein String, sondern ein Integer, der in Hexadezimal umgewandelt wird (801 == 0x321)!

Router Announcements

Um das LAN am IPv6-Leben teilhaben zu lassen, muss das IPv6-Netz auch verkündet werden, und zwar mit radvd. Um dessen Konfiguration auf Stand zu halten, gibt es den Hook /usr/lib/dhcpcd/dhcpcd-hooks/40-delegate, der /usr/local/sbin/delegate_prefix.sh aufruft, wenn es ein neues Prefix gibt. Dieses Skript schreibt eine Konfiguration mit dem neuen Prefix und startet den Trümmer neu.

DHCP

Für DNS, DHCPv4 und DHCPv6 ist dnsmasq zuständig. IPv4-DHCP ist so trivial, dass ich es nicht erklären muss.

DHCPv6 leider komplizierter. Zunächst muss man radvd mit der Option AdvManagedFlag on sagen, dass die Clients überhaupt danach fragen. Wie statische IPv6-Adressen vergeben werden, hängt von dem dem Client ab. ArchLinux mit networkd macht das recht einfach. Man muss lediglich Token=::c0a0:808 in der Sektion [IPv6AccetRA] eintragen, um ebendieses Suffix zu bekommen.

Windows hingegen fragt nach einer DUID via DHCP-SOLICIT oder INFORM. Bei dem entsprechenden dhcp-host= Eintrag beachten, dass ein vorangestelltes id: einen literalen String bedeutet. Um einen Windows-Client zu beglücken, lasse man sich die DUID via ipconfig /all ausgeben, ersetze '-' durch ':' und verteile dann eine IP ohne 'id:' nach dem Gleichheitszeichen.

Online Resizing of KVM drive

Don’t try to resize a disk of a running VM with qemu-img directly. Use virsh instead. NB: This can’t be done via the GUI, either. You have to use the shell.

Gather info:

virsh # domblkinfo <domain> --all --human

Resize virtual disk:

virsh # blockresize <domain> --path <vd?> --size 300GB

Then inside the VM, assuming you’re using LVM and XFS as filesystem, re-read the partition table of the resized disk, then resize the physical volume, then the logical volume and finally the filesystem:

# blockdev --rereadpt /dev/vd?
# pvresize /dev/vd?
# lvextend -l +<no. of extends> /dev/mapper/<lv-name>
# xfs_growfs /dev/mapper/<lv-name>

That’s all, folks!

Dual boot with UEFI

Install Windows first. The setup creates an EFI partition, most likely as /dev/sd?2. We’re gonna need that later. Then turn off fast boot. Enter

powercfg -h off

on the command prompt. Make sure that you have local admin rights. Fast boot is incompatible with dual boot. You’ll get blue screens with repair options otherwise. While at it, set the system clock to UTC. Create this DWORD registry key:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\TimeZoneInformation\RealTimeIsUniversal

and set it to “1”.

Then install linux and mount /dev/sd?2 from above to boot. Then create a new file named arch.conf in /boot/loader/entries:

title   Arch Linux
linux   /vmlinuz-linux
initrd  /initramfs-linux.img
options root=UUID=$(blkid /root/partition) rw audit=0

The paths are relative to /boot, so vmlinuz-linux should be /boot/vmlinuz-linux. Next edit /boot/loader/loader.conf:

console-mode auto
default arch
timeout 5

Assuming that you’re using systemd-boot, run bootctl install and bootctl update, reboot and be happy!

Synergy and SDDM

For SDDM to connect to a synergy server on archlinux, edit /usr/share/sddm/scripts/Xsetup and add:

/usr/bin/synergyc <server IP or server hostname>

There’s just a little problem if you have more than one monitor. The default Xorg config mirrors all screens. That’s no problem, since KDE sets it all up properly. Unfortunately synergyc doesn’t register the changes, so you have to restart it. Since by then synergyc is running as root, you can’t kill it as user. But fear not, there’s a workaround:

  • Allow the user to execute /usr/bin/killall synergyc as root without password (see https://tollana.d-tor.org/notes-to-self/?p=620)
  • Kill all synergy instances in an autostart script and start a user instance preferably in the systemd user session:
#!/bin/bash 
sudo /usr/bin/killall synergyc
systemctl --user restart synergyc
  • make it executable, put it somewhere the user can access it and auto-start it. In KDE: System Settings -> Startup and Shutdown -> Autostart -> Script File
  • make sure that you have synergyc.service in $HOME/.config/systemd/user
[Unit]
Description=Synergy Client Daemon
After=network.target

[Service]
ExecStart=/usr/bin/synergyc --no-daemon <Server IP or Hostname>
Restart=always
RestartSec=3

[Install]
WantedBy=default.target

This works with KillUserProcesses=yes in /etc/systemd/logind.conf.

SUDO Rule Preference

sudo has a last match policy, NOT best match! So, if %wheel is allowed to execute everything as anybody with password, but you want a member of %wheel to execute a specific command without password, the rule for the password-less command has to be ordered after the general rule:

%wheel ALL=(ALL) ALL 
wheelmember ALL=(ALL) NOPASSWD: /usr/bin/mycommand

It says so in man 5 sudoers:

When multiple entries match for a user, they are applied in order. Where there are multiple matches, the last match is used (which is not necessarily the most specific match).

Nevertheless, it was counter-intuitive for me. I expected first or best match, but not last match… Another quirk: When using visudo “:w” won’t update the sudoers file. You have to “:wq”.

Bold font in KDE konsole

To get a bold font in Konsole, do this:

  • First, create a new Profil
  • Edit the profile to use DejaVu Sans Mono, Size and Style doesn’t matter
  • Save it and close Konsole
  • Edit $HOME/.local/share/konsole/<Profile Name>
  • Add or replace the Font Entry under Appearance with
Font=DejaVu Sans Mono,9,-1,0,75,0,0,0,0,0,Bold
  • Now edit $HOME/.config/konsolerc and add
[Desktop Entry] 
DefaultProfile=<Profile Name>
  • Replace [Favorite Profiles] with
[Favorite Profiles] 
Favorites=

Kill all instances of Konsole, start it and never touch that stuff again!

Multi-homed: Telekom, Vodafone and Hetzner

Problem

I refined my network configuration a bit, because there was a problem: When I pinged the Vodafone IPv6 address of hadante from my new, shiny Hetzner box, it wouldn’t answer, because I got the policy routing wrong.

Initially I routed everyting to Hetzner via the Vodafone interface, but that’s plain wrong. This way hadante even sent packets originating from Telekom IP’s via the Vodafone interface, with the Telekom IP as source. What I really wanted:

  1. answer requests to the Vodafone interface via Vodafone
  2. make Telekom the default route

Answer requests to the Vodafone IP

The solution was easy: create a rule to send everything from the Vodafone interface out there. Unfortunately, nothing is as easy as it seems. Because the Vodafone-IPv6-Prefix is semi-static, systemd-networkd policy routing doesn’t work. The routing table can be filled automatically:

[Match] 
Name=ext 

[Network] 
DHCP=yes 
IPv6Token=::dead:b0a1 

[DHCP] 
RouteMetric=4096 
RouteTable=199 

[IPv6AcceptRA] 
RouteTable=199

The RouteTable directive adds the routes acquired by DHCP and Router Announcments to the routing table 199 (aka kd, see /etc/iproute2/rt_tables), but without a rule it doesn’t do anything. The IPv6Token directive sets the IPv6 address to <prefix>::dead:b0a1, by the way.

The rule is added by a perl script written by yours truly. It does something like this (pseudo perl code):

...
$old = <old IPv6 address>;
$new = <new IPv6 address>;
# match old prefix
$old =~ m#^([[:xdigit:]]{1,4}:[[:xdigit:]]{1,4}:[[:xdigit:]]{1,4}:[[:xdigit:]]{1,4}:)#;
# delete old rule
system("/usr/bin/ip -6 rule dele from $1:/64 table kd");
# match new prefix
$new =m#^([[:xdigit:]]{1,4}:[[:xdigit:]]{1,4}:[[:xdigit:]]{1,4}:[[:xdigit:]]{1,4}:)#;
# add new rule
system("/usr/bin/ip -6 rule add from $1:/64 lookup kd");
...

This way both the Telekom IP and the Vodafone IP work from anywhere. As a bonus, IPv6 requests to Hetzner from the delegated Telekom IPv6 network now work, too 🙂

Configuring the Telekom interface

During my network configuration spree I tried to configure the Telekom interface with systemd-networkd instead of dhcpcd, but that didn’t work, unfortunately. I couldn’t get the prefix delegation to the internal interface to work. Supposedly systemd-networkd can do it, but the documentation is, let’s say, sparse at best. After several attempts I gave up and reverted to dhcpcd, as described in this post.

Hardware accelerated transcode

While reading the Linux Magazine on the bowl this morning, I discovered that ffmpeg has hardware support for decoding and encoding. Since I do that quite often, I figured it’s time to try it out. Lo and behold, it works better than I expected! Not on hadante, though. ffmpeg just segfaulted, because the card is way too old and the kernel module doesn’t seem to support it.

On othalla (my almost 4 year old laptop), it works like a charm. ffmpeg said encoding  at 5.5 times the original speed, even over NFS!

The command line I used:

$ ffmpeg -hwaccel cuvid -c:v h264_cuvid -resize 1280x720\
-i in.mkv -acodec copy -scodec copy\
-c:v h264_nvenc -preset slow -b:v 4000K -minrate 4000K out.mkv

It has a NVIDIA GPU, as well as an Intel pixel manager, but cuvid and nvenc only works the (proprietary) NVIDIA driver. Anyhow, as always it’s important where you place the options. Any options before -i is for decoding, anything after is for encoding. This makes:

-hwaccel cuvid -c:v h264_cuvid -resize 1280x720

ffmpeg decode everything via cuvid on the GPU and resize it to 720p. Source was 1080p.

-acodec copy -scodec copy

says: Just copy the audio stream and the subtitle stream to output. Now comes the important:

-c:v h264_nvenc -preset slow -b:v 4000K -minrate 4000K

tells it to let the GPU encode it to x264, preset slow and a minimum bitrate of 4000K. If I do the same via software decoder and encoder, I get barely more than real time speed, perhaps 1.1 or 1.2, depending on the source. With cuvid I get 5.5. Even Hadante with its 12 processors and 32GB only gets a speed of 2.0 to 2.2 max, and it’s hardware is much more current! Like it!

Dusting off the Array! (Part 8)

What now?

Well, forget Part 7 (fortunately). The SSD-Raid is working fine! It always assembled itself after several reboots. That’s good news, I guess!

In the meanwhile I fucked up again. I ordered an external USB-casing without a disk recently. While trying to get it up and running, I accidentally disconnected the USB-thingy connected to my external drives from power. Since then the kernel complains about the 2.5″ USB drive without power supply, but I got it up and running again.

Right now I’m copying all data from that drive to a member of the failed HGST-Array. Hopefully it’s not the failed drive, but we’ll see…

Creating a physical volume with pvcreate didn’t work out of the box. The command bailed out saying that it couldn’t open the device exclusively. At first I thought that it was because of the pre-existing PV-Signature, so I zeroed out the first GB, but that didn’t help, either.  Check-MK came to help, telling me that md127 was in a degraded state.

Of course! The drive contained a RAID-Superblock, so the kernel tried to start the the RAID, but couldn’t. Nevertheless, that kept the drive busy. Stopping it with

# mdadm -S /dev/md127

should have helped, I guess…

Anyway, wrote 1.1TB to the drive without errors. So, chances are that it isn’t the defective drive.

Dusting off the Array! (Part 7)

What happened

Oh my, I really hope this is the final chapter of this fucking story… On Feb. 20th, 2018, one of the HGST disks failed (what a surprise!). Since the serial number reported by hdparm bears absolutely no resemblance to the serial number printed on the label of the disk (thanks a bunch HGST, BTW), I pulled the wrong disk, inserted the spare, started the rebuild and… Lo and behold! The failing disk still failed! My attempts to recover the RAID destroyed it completely.

It was already kaputt when I thought of a way to identify the failing disk’s slot:

# badblocks <reported device by kernel>

This should light up the LED permanently on the external SATA casing.

I was so fed up that I ordered 4 2TB SSD-Disks shortly after that. Yesterday (Mar. 2nd, 2018) I finally had time to install them. Of course this setup has its quirks, too, but at least I can identify the disks via hdparm. The serial reported is actually the serial on the label:

HDD1: SerialNo 1744197E67EE
HDD2: SerialNo 1744197E7B92
HDD3: SerialNo 1744197E7104
HDD4: SerialNo 1744197E836D

The Quirks

Of course it didn’t just work out of the box™. When I booted with the shiny, new SSD disks, hadante got stuck at the BIOS splash screen while HDD3 was throwing a shining, red light. I pulled HDD3 and HDD4, rebooted and got a login prompt. Since SATA is hot-pluggable, I inserted HDD3 and 4. Fortunately, they showed up on the SCSI-Bus (cries of joy!).

I created a RAID5 with:

# mdadm --create /dev/md1 --level=5 --raid-devices=4 /dev/sd[efgh]

and waited until today (Mar. 3rd, 2018) for the rebuild to finish. After that I tested the setup:

  • Power off hadante
  • Turn off the external casing
  • Wait about 30 seconds
  • Turn on the external casing and then hadante
  • Wait eagerly…

… and watch the kernel error messages scrolling down the screen 🙁

The solution

Note the (not really) failing drive by staring at the LEDs of the external casing. Power off hadante and pull the failing drive and any other non-failing drive! It’s important to pull 2 drives, so the kernel cannot assemble the RAID! Then reboot and stop failing the RAID:

# mdadm -S /dev/md?

Now hot-plug the missing drives, reboot again and be amazed how everything magically works again 🙂

From my observations the drives in the external bay are recognized until you cut the power, but that’s just a guess.