Dieser Artikel beschreibt die Konfiguration eines Wireguard - VPN-Servers auf debian 9 (stretch,stable). Sämtlicher IPv4- als auch IPv6-Verkehr eines Roadwarriors soll durch Wireguard getunnelt werden. Als Server kommt ein Hetzner-Cloud-server CX11 zum Einsatz. Für 2,96€ im Monat bekommt man genügend Leistung, eine fixe IPv4-Adresse und ein IPv6-Netz (/64) zugewiesen.

Wireguard ist eine moderne VPN-Lösung mit einer sehr schmalen Codebasis. Wireguard implementiert nur wenige, dafür aber aktuelle Verschlüsselungsverfahren und läuft, anders als zum Beispiel OpenVPN, im Kontext des Kernels. Eine detaillierte Beschreibung des Protokolls und eine Übersicht über die verwendeten kryptografischen Verfahren kann man im Wireguard-whitepaper nachlesen. In den nächsten Monaten (stand März 2019) soll Wireguard Aufnahme in den Linux-Kernel finden. Für debian 10 testing und unstable/sid stehen aktuelle Pakete in den debian-repositories bereit. Die Installation auf allen gängigen Linux-Distributionen und BSD-Systemen ist auf der Wireguard-Homepage beschrieben. Als Transportprotokoll setzt Wireguard ausschließlich auf UDP, möchte man stattdessen TCP einsetzen (einziger Grund wäre eine Blockierung von UDP), muss man Wireguard zum Beispiel über WebSockets tunneln.

Das Szenario

  1. Sämtlicher Verkehr soll über einen Tunnel geroutet werden.
  2. Die DNS-Auflösung und das Caching soll vom VPN-Server übernommen werden.
  3. Die Konfiguration auf dem VPN-Server soll persistent sein.
  4. Die Clientkonfiguration soll per QR-Code auf Apple-IOS/Android übertragen werden.

Installation

Da Wireguard ein Kernelmodul benötigt, muss das System zu dessen Übersetzung vorbereitet werden:

sudo apt-get install linux-headers-$(uname -r) build-essential

Für debian 9 stretch/stable existieren noch keine Pakete im offiziellen repository, daher muss das unstable-repository auf dem System verfügbar gemacht werden. Bei debian 10 kann dieser Schritt übersprungen werden. Dabei werden alle Pakete aus unstable jedoch so niedrig priorisiert, dass alle Pakete aus stable bei Updates den Vorzug erhalten, außer explizit installierten Paketen aus unstable:

$ sudo echo "deb http://deb.debian.org/debian/ unstable main" > /etc/apt/sources.list.d/unstable.list
$ sudo printf 'Package: *\nPin: release a=unstable\nPin-Priority: 90\n' > /etc/apt/preferences.d/limit-unstable

Im Anschluss wird Wireguard installiert und das Kernelmodul wird automatisch übersetzt und geladen:

$ sudo apt update && apt install wireguard

Ob das Kernelmodul geladen ist, lässt sich leicht überprüfen:

$ sudo lsmod | grep wireguard

Routing aktivieren

Damit der VPN-Server IPv4 und IPv6 Pakete weiterleitet muss diese Funktionalität dem Kernel mitgeteilt werden:

$ sysctl net.ipv4.ip_forward=1
$ sysctl net.ipv6.conf.all.forwarding=1

Um diese Einstellungen auch nach einem Neustart zu setzen, sind folgende Zeilen zur Datei /etc/sysctl.d/99-sysctl.conf zu ergänzen:

net.ipv4.ip_forward=1
net.ipv6.conf.all.forwarding=1

Erstellen der Schlüssel

Wireguard basiert auf dem Konzept des Crypto-Routing. Jeder Kommunikationsteilnehmer an einem VPN besitzt ein asymmetrisches Schlüsselpaar, der jeweilige öffentliche Schlüssel wird demjenigen Kommunikationspartner mitgeteilt, der über den Kommunikationskanal kommunizieren darf. Die Schlüssel sind sehr kurze base64-kodierte ECDH-Schlüssel. Die Schlüssel können auf jedem System, auf auf dem Wireguard verfügbar ist, generiert werden.

Schlüsselpaar für den VPN-Server:

$ wg genkey > vpn-server.seckey
$ wg pubkey < vpn-server.seckey > vpn-server.pubkey

Schlüsselpaar für einen weiteren Kommunikationsteilnehmer:

$ wg genkey > mobile.seckey
$ wg pubkey < mobile.seckey > mobile.pubkey

Optional ist die Generierung eines weiteren pre shared keys um eine weitere Schicht symmetrischer Verschlüsselung hinzuzufügen. Gründe hierfür werden in Abschnitt 5.2 des Wireguard-Whitepapers erläutert.

$ wg genpsk > vpn.psk

Wireguard-Konfiguration des VPN-Servers

Es existieren zwei Möglichkeiten Wireguard zu betreiben, man kann mithilfe von wg einen Tunnel etablieren und Kommunikationspartner (peers) hinzufügen. Alternativ dazu hat man die Möglichkeit eine Konfigurationsdatei zu erstellen, welche später von wg-quick eingelesen wird. Die zweite Möglichkeit hat den Vorteil, dass sich wg-quick auch gleich um die Erstellung und Konfiguration der Wireguard-Netzwerkschnittstelle (im Beispiel: wg0) kümmert. Zudem bringt das Debian-Paket auch gleich ein Systemd-Interface-Template mit, was ein Start des VPNs erleichtert und keine zusätzlichen Systemd-Kenntnisse erfordert.

Bevor die Konfiguration von Wireguard erfolgen kann, noch einige Worte zur IP-Adresskonfiguration von Hetzner. IPv4-Adressen werden durch Hetzner per DHCP vergeben, sind aber persistent. IPv6 Adressen werden stattdessen statisch konfiguriert, Hetzner verwendet dazu auf ihren debian Cloud-Servern die debian networking-scripte. Die IP-Adresskonfiguration findet sich unter: /etc/network/interfaces.d/50-cloud-init.cfg.

Exemplarisch sind folgende Adressen auf dem Interface eth0 konfiguriert:

IPv4: 203.0.113.1/32
IPv6: 2001:db8:ffff:ffff::1/64

Da Wireguard über das virtuelle Tunnelinterface wg0 kommuniziert, müssen, jeweils für IPv4 und IPv6, interne Tunnel-Netze und Adressen vergeben werden. Für IPv4 wählt man ein privates Netz gemäß RFC1918, in diesem Beispiel verwenden wir 172.16.100.0/24. Dem VPN-Server wird später die erste Adresse aus diesem Bereich zugewiesen. Die Adressen aus diesem privaten IPv4-Bereich müssen später noch einer Adressumsetzung auf die öffentliche Adresse 203.0.113.1 unterzogen werden.

Bei IPv6 hingegen reicht es aus das öffentliche Netz 2001:db8:ffff:ffff::/64 zu segmentieren. Zum Beispiel kann man das Netz in 256 Subnetze unterteilen: 2001:db8:ffff:ffff::/72. Die IPv6-Adresse auf eth0 ändert sich dadurch nicht, lediglich die Netzgröße. Daher muss diese in der Datei /etc/network/interfaces.d/50-cloud-init.cfg angepasst werden:

#address 2001:db8:ffff:ffff::1/64
address 2001:db8:ffff:ffff::1/72

Im Anschluss muss die Konfiguration neu eingelesen werden:

$ sudo systemctl restart networking.service

Das zweite Netz aus dem IPv6-Bereich (2001:db8:ffff:ffff:100:/72) wird für die internen Tunneladressen verwendet.

Die Konfigurationsdatei von Wireguard muss nach dem Wireguard-Interface benannt benannt werden: /etc/wireguard/wg0.conf. In diesem Beispiel lauscht der Wireguard-VPN-Server auf dem Port upd/443 auf eth0. Lediglich die Schlüssel müssen noch ergänzt werden:

[Interface]                                                                                  
Address = 172.16.100.1/24                                                                     
Address = 2001:db8:ffff:ffff:100::1/72                                                       
SaveConfig = true                                                                            
PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
ListenPort = 443                                                                             
PrivateKey = [vpn-server.seckey]                                   

[Peer]
PublicKey = [mobile.pubkey]
PresharedKey = [vpn.psk]
AllowedIPs = 172.16.100.0/24, 2001:db8:ffff:ffff:100::/72

Wireguard kann nun mittels wg-quick gestartet werden:

$ sudo wg-quick up /etc/wireguard/wg0.conf

Sollte der VPN-Server ohne Probleme starten, kann man die Konfiguration mittels Systemd persistent machen:

$ sudo systemctl enable wg-quick@wg0

DNS-Auflösung auf dem VPN-Server

Die Teilnehmer am VPN-Netzwerk sollen DNS-Anfragen durch den Tunnel an den VPN-Server richten können. In diesem Beispiel wird dnsmasq verwendet, aber auch andere resolver wie unbound können verwendet werden.

Eine exemplarische Konfiguration für dnsmasq (/etc/dnsmasq.conf):

# Quad9 - Initiative https://www.quad9.net/
server=9.9.9.9
server=149.112.112.112
server=2620:fe::fe
server=2620:fe::9

listen-address=127.0.0.1,172.16.100.1
bind-interfaces

cache-size=1000

Neustart von dnsmasq:

$ systemctl restart dnsmasq.service

Damit DNS-Anfragen an dnsmasq gerichtet werden, müssen auf dem VPN-Server die Nameserver in der Datei /etc/resolv.conf auf eine Loopbackadresse verweisen. Dazu wird in der Datei /etc/dhclient/dhclient.conf folgende Zeile auskommentiert:

#prepend domain-name-servers 127.0.0.1;
prepend domain-name-servers 127.0.0.1;

Im Anschluss muss die Konfiguration neu eingelesen werden:

$ sudo systemctl restart networking.service

Wireguard-Konfiguration des Clients

Die Datei kann auf einem beliebigen System erstellt werden:

[Interface]
Address = 172.16.100.2/24, 2001:db8:ffff:ffff:100::2/72
PrivateKey = [mobile.seckey]
DNS = 172.16.100.1

[Peer]
PublicKey = [vpn-server.pubkey]
PresharedKey = [vpn.psk] 
AllowedIPs = 0.0.0.0/0, ::/0
Endpoint = 203.0.113.1:443

Diese Datei kann nun als QR-Code kodiert werden und mithilfe der Android-/IOS-App eingelesen werden

$ qrencode -t ansiutf8 < client.conf

Das neue Zertifikat ist gültig bis zum 15.01.2020.

services:

  • web
  • jabber
  • owncloud

fingerprints

SHA256:

51:49:8D:68:E8:2E:94:67:33:26:88:D5:14:85:16:60:65:D2:8E:F8:01:48:37:1D:1D:0C:87:6D:B6:89:84:87

SHA1:

DE:C8:CC:B4:2F:E7:6F:7C:92:1F:5B:B3:53:58:A8:C2:D0:83:03:5B

Das neue Zertifikat ist gültig bis zum 15.01.2019.

services:

  • web
  • jabber
  • owncloud

fingerprints

SHA256:

18:44:C1:49:24:32:82:C5:DC:11:C8:23:6E:9C:42:6A:AE:AC:9E:C8:D6:60:B0:4C:CA:19:7D:05:6A:A5:41:03

SHA1:

5D:E1:83:5F:DD:C9:BF:E4:1E:5D:59:86:57:8E:6D:2D:64:DE:F1:4E

In Latex2e ist es möglich simple Programmierung durchzuführen, ohne das auf eine andere Programmiersprache zurück gegriffen werden muss. Nichtsdestotrotz unterstütz Latex natürlich eine Fülle an Programmierschnittstellen für alle gängigen Sprachen (z.B. Lua, Python, Perl, Bash …).

Das Grunddokument

Als Grunddokument dient folgender Aufbau, dass Paket ifthen stellt grundlegende Kontrollstrukturen, Vergleichsoperatoren und Schleifen zur Verfügung:

\documentclass[a4paper,10pt]{scrartcl}
\usepackage[utf8]{inputenc}
\usepackage{ifthen}

\begin{document}

...

\end{document}

Einfache Funktionen und Variablen

Man kann einfache Funktionen definieren, indem man neue Kommandos erzeugt. Im folgenden Beispiel wird ein Kommando mit zwei Pflichtargumenten erzeugt:

\newcommand{\distanz}[2]{Geben Sie die Distanz zwischen #1 und #2 an!\\\\}

Das Kommando kann auch noch nachträglich verändert werden:

\renewcommand{\distanz}[3]{Geben Sie die Distanz zwischen #1, #2 und #3 an!\\\\}

Eine einfache String-Variable wird ebenso angelegt und verändert:

\newcommand{\zielort}{Bonn}
\renewcommand{\zielort}{Berlin}

Die Funktion kann nun aufgerufen werden:

\distanz{Kiel}{Hannover}{\zielort}

Ausgabe

Geben Sie die Distanz zwischen Kiel, Hannover und Berlin an!

ganzzahlige Variablen

Ganzzahlvariablen (auch negativ) heißen in Latex counter und werden folgendermaßen deklariert und mit einem Wert versehen:

\newcounter{zaehler}
\setcounter{zaehler}{100}

Der Wert eines counters kann auch inkrementiert werden:

\stepcounter{zaehler}   %zaehler++ -> 101

Das Addieren und Subtrahieren geht ebenso:

\addtocounter{zaehler}{10}  %111
\addtocounter{zaehler}{-11} %100

Kontrollstrukturen und Schleifen

Jetzt kommt das Paket ifthen zum Tragen. Es bietet eine if-then-else-Anweisung und eine while-Schleife. Die Gesamtdokumentation dieses Paketes findet man hier.

Um lesend auf eine Variable/einen counter zuzugreifen, z.B. für einen Vergleich, dient folgende Anweisung:

\value{zaehler}

Möchte man stattdessen den aktuellen Wert als Dezimalzahl ausgeben:

\arabic{zaehler}

Um die Anwendung der Schleife und der if-Kontrollstruktur zu verdeutlichen dient folgendes Beispiel:

\newcounter{i}
\setcounter{i}{100}

\whiledo{\value{i} > 0}{
    \noindent Wie viele Flaschen Bier sind noch da?\\
    \addtocounter{i}{-1}

    Es sind noch \textbf{\arabic{i}} Flaschen Bier im Kühlschrank.\\\\

    \ifthenelse{\value{i} = 0}{\textbf{Es ist kein Bier mehr Da!}}

}

Ausgabe

Wie viele Flaschen Bier sind noch da?
Es sind noch 99 Flaschen Bier im Kühlschrank.

Wie viele Flaschen Bier sind noch da?
Es sind noch 98 Flaschen Bier im Kühlschrank.

...

Wie viele Flaschen Bier sind noch da?
Es sind noch 0 Flaschen Bier im Kühlschrank.

Es ist kein Bier mehr Da!

what I have

  • grml-2017.06.iso on a usb-stick (Kernel 4.9)

  • old Data from an BIOS installation -> Debian 9 (Kernel 4.9)

what I want:

  • a fully encrypted system (including /boot) with UEFI-Boot

  • btrfs with subvolumes

1. create Partitions using gdisk

On UEFI-Systems you have to use gpt partitions and create a UEFI partition.

/dev/sda1   512M    type EF00 # UEFI partition
/dev/sda2   X       type 8300 # DM-CRYPT-LUKS
/dev/sda3   Y       type 8200 # SWAP

mkfs.vfat /dev/sda1

2. create LuskContainer

The second partition is used for a LUKS-container:

cryptsetup luksFormat /dev/sda2

3 .map the container and create btrfs on top of it

cryptsetup luksOpen /dev/sda2 sda2_crypt

mkfs.btrfs -L system /dev/mapper/sda2_crypt

4. mount and create subvolumes

mount /dev/mapper/sda2_crypt /target

btrfs subvolume create /target/@            -> later mounted to /
btrfs subvolume create /target/@home        -> later mounted to /home
btrfs subvolume create /target/@var         -> later mounted to /var
btrfs subvolume create /target/@snapshots   -> later mounted to /.snapshots

5. mount new subvolumes

umount /target

mount -o subvol=@ /dev/mapper/sda2_crypt /mnt/NEW-SYSTEM

mkdir /target/{home,var,.snapshots}

mount -o subvol=@home       /dev/mapper/sda2_crypt /target/home
mount -o subvol=@var        /dev/mapper/sda2_crypt /target/var
mount -o subvol=@snapshots  /dev/mapper/sda2_crypt /target/.snapshots

6. set default subvolume (mounted if no subvol option given)

Get the volumed ids:

btrfs subvolume list -p /target

Set the default subvolume:

btrfs subvolume set-default VOL-ID /target

7. copy old files

mount -o ro /dev/OLD_DEVICE /source

rsync -aAHX --info=progress2 --exclude={"/proc/*","/sys/*","/run/*","/var/run/*", \
                                        "/dev/*","/tmp/*"} /source/ /target/

8. mount EFI partition and prepare chroot environment

mkdir /target/boot/efi

mount /dev/sda1 /target/boot/efi

sudo mount --bind /dev  /target/dev
sudo mount --bind /proc /target/proc
sudo mount --bind /sys  /target/sys

chroot /target

If your old System was installed on a BIOS-System, you need to have to install the grub2 version needed for efi systems.

apt-get install grub-efi-amd64

9. modify the fstab and cryptab

example /etc/crypttab:

sda2_crypt  UUID=9c562dde-650d-4de9-9462-faf22d75fea5    luks,discard

example /etc/fstab:

proc                    /proc       proc    defaults                            0       0
/dev/mapper/sda2_crypt  /           btrfs   subvol=@,defaults,noatime           0       0
/dev/sda3               none        swap    sw                                  0       0

UUID=X                  /home       btrfs   subvol=@home,defaults,noatime       0       0
UUID=X                  /var        btrfs   subvol=@var,defaults,noatime        0       0
UUID=X                  /.snapshots btrfs   subvol=@snapshots,defaults,noatime  0       0

UUID=Y                  /boot/efi   vfat    rw                                  0       0

10. modify grub settings

echo "GRUB_ENABLE_CRYPTODISK=y" >> /etc/default/grub

sudo grub-install --target=x86_64-efi --efi-directory /boot/efi --bootloader=debian \
                  --boot-directory=/boot/efi/EFI/debian --recheck

sudo grub-mkconfig -o /boot/efi/EFI/debian/grub/grub.cfg

sudo update-initramfs -u -k all

11. boot into your new system

You have to enter the luks-key two times, one time for grub and one time for Linux.

ToDo

LSO is used by modern operating systems like GNU/Linux. LSO is a performance capability where TCP segments, when transmitted from the network stack to the network adapter, melted to a large segment, often bigger then the MTU from the network adapter. This behaviour speeds up the transition a lot. The opposite of LSO (Large Send Offload) is called LRO (Large Receive Offload).

LSO often causes confusion, if network sniffing is not done directly from wire. Because tcpdump and wireshark are showing heavily overlength packets if a TCP stream is captured on a adapter connected to a Linux-Box.

LSO and LRO are implemented in the Linux kernel as TSO and GSO/GRO.

Your are able to deactivate this behaviour, then your network capture looks more like wiretapping. The following commands are executed as root on Linux 4.9, with wlp2s0 as the (wireless) network device.

check the state for this capabilities:

# ethtool --show-offload wlp2s0 | grep offload
tcp-segmentation-offload: off
udp-fragmentation-offload: off [fixed]
generic-segmentation-offload: on
generic-receive-offload: on
large-receive-offload: off [fixed]
rx-vlan-offload: off [fixed]
tx-vlan-offload: off [fixed]
l2-fwd-offload: off [fixed]
hw-tc-offload: off [fixed]

Obviously tcp-segmentation-offload (TSO) is not in use, but GSO generic-segmentation-offload and GRO generic-receive-offload are.

To disable GSO and GRO execute the following command

# ethtool -K wlp2s0 gro off
# ethtool -K wlp2s0 gso off

further reading:

Wikipedia-LRO

eduPERT

Wireshark-Wiki (example did not work for me)

Seitdem ich das erste mal an einem C64 saß und die Kompaktheit und Lautlosigkeit dieses formschönen Brotkastens genoss, fragte ich mich, warum niemals wieder ein bezahlbarer Rechner mit adäquater Leistung und ohne Lüfter produziert wurde. Sicherlich, gab es in den letzten Jahrzehnten eine Unmenge an lüfterlosen Rechnern, speziell im Industriebereich. Diese sind aber oft für spezielle Anwendungen konzipiert und für den SOHO bereich viel zu teuer gewesen. Auf der andern Seite gab es die Raspberries, von denen ich auch eine Handvoll besitze. Aber als Desktop-Ersatz sind sie ebenso wenig geeignet.

Als Desktop verstehe ich einen PC, welche mir die Möglichkeit bietet mindestens zwei Monitore anzuschließen und eine größere Anzahl an Schnittstellen mitbringt, als zum Beispiel ein Notebook. Die Leistung soll natürlich nicht unterirdisch sein und in etwa mit einem 5-6 Jahre alten PC mithalten können.

Ich bin fündig geworden, in einem Artikel bei Heise-online wurde ein neuer Barebone der Firma Shuttle vorgestellt. Der DX30 besticht durch sein Volumen von nur 1,35 Litern und einem aktuellen SOC-Prozessor der Intel Kaby Lake-Generation. Er ist Lüfterlos und bietet eine NVMe-kompatible M2-Schnittstelle für SSDs, sowie eine zusätliche SATA Schnittstelle. Mit zwei seriellen RS-232 Anschlüssen ist auch beim DX30 die Nutzung im industriellen Umfeld noch möglich. Der DX30 ist extrem sparsam und verbraucht nur noch ein zehntel der Energie den mein 8 Jahre alter Desktop-PC benötigte.

Zuletzt stellt sich jetzt noch die Frage, wieviel langsamer ist der DX30 im Vergleich zu meinem alten Desktop-Rechner. Da es nur ein einfacher vergleich sein soll, erinnerte ich mich an einen Beitrag von fefe, indem fefe eigentlich die Geschwindigkeit von Skriptsprachen miteinander vergleichen wollte. Ziel war es, eine große Datei einzulesen, die enthaltenen Worte zu zählen und diese und die Anzahl auszugeben. Zwar eine naive herangehensweise, aber als simpler Vergleich ausreichend. Als Eingagedatei diente mir ein Wikipedia-Dump der slovakischen Wikipedia vom 01.08.2016: skwiki-20160801-pages-articles-multistream.xml.


Benchmarks wordprocessing
SpracheNeu (real)Alt (real)
gcc 60m49,179s0m44.297s
g++ 61m11,920s1m2.738s
OpenJDK 1.81m12,677s1m12.558s
PHP 71m28,062s1m22.261s
perl 5.242m24,382s1m58.661s
python 2.73m11,056s2m36.912s
lua 5.33m6,586s3m1.549s
ruby 2.35m22,457s4m19.293s
bash 4.310m23,156s10m26.901s

Wie deutlich zu sehen ist, ist der DX30 langsamer als der alt PC mit einem Athlon II X4 2,3 Ghz. Aber die Vorteile, wie die Geräuschlosigkeit und der Stromverbauch relativieren diese Ergebnisse in meinen Augen wieder.

cluj.pm-logo

From August 24 to August 26 I attended to the YAPC::EU 2016 in Cluj-Napoca (Klausenburg). Thanks for the really good organization to the nice organization team from Cluj.pm.

All presentation are online (youtube).

RIPE NCC Logo

Since yesterday I own a RIPE Atlas probe, that means I am a part of the biggest Internet measurement network ever made. With the collected data from the probes it is possible to monitor a big part of the Internet, independent from the Internet service providers. The data is used for science and monitor purposes. The probe has the ability to do checks, some of the common checks are visualized. With every check (mainly uptime) you earn credits and with enough of them you can create checks of your own and the check will be executed by the Atlas-network.

At home I put the probe in a separated network, but in fact there is no socket (remote and local) running on the probe.

There are a lot of Atlas probes out there check out the network coverage.

The Atlas probe is for free. Please join the Network and help to monitor the Internet.

vim-logo

This morning I decided to create another vim cheat sheet. One that works for me. There are a lot of cheat sheets outside, but the most lack of complexity and the other ones are simply not printable on a single page. I wrote a cheat sheet that covers a lot of commands, for example: tabs, searching, splitting and comprehensive editing commands. This all fits on a single page. You may download the sheet (pdf) from my site or you can clone it from GitHub.

git clone https://github.com/meetunix/vimcheat.git