Artix Linux als Container-Host

Artix Linux, ein Arch Linux Derivat (= ohne Systemd), soll mit Linux Containern via LXD ausgestattet werden und zugleich als bind9-Nameserver fungieren.

Hier unter parkt ein fertiges VirtualBox-Maschinchen, das auf freundliche Nutzung wartet (2,5 GB im Download):

sha256sum Artix-Base-mit-LXD_2020-06-28.ova
ef9e1830d0907ab6adc56a82bd01f2409d7f0c5be8eb2dc25138b7440c699c16  Artix-Base-mit-LXD_2020-06-28.ova

Unter Mint, nativ (in VBox v5) kann es beim Importieren der VM-Konfiguration zu Problemen kommen. Dann einfach entpacken:

tar xf Artix-Base-mit-LXD_2020-06-28.ova

Danach liegt eine virtuelle Festplatte (.vmdk-Datei) mit gleichem Namen vor, die in eine frische VBox-Maschine eingebunden werden kann.

btrfs als Dateisystem

Die neue VM für LPI 202 hat btrfs als Basis:

[artix ~]# btrfs fi show
Label: 'ROOT'  uuid: 71c93161-b70f-4a4c-86b8-96f87c5b0d52
    Total devices 1 FS bytes used 2.24GiB
    devid    1 size 50.00GiB used 6.02GiB path /dev/sda1

[artix ~]#
[artix ~]# btrfs sub list /
ID 257 gen 1183 top level 5 path @
ID 258 gen 1182 top level 5 path @log
ID 259 gen 1157 top level 5 path @pkg
ID 260 gen 10 top level 5 path @snapshots
ID 263 gen 1180 top level 257 path .snapshots
ID 335 gen 1168 top level 257 path var/lib/lxd/storage-pools/default
ID 341 gen 1136 top level 335 path var/lib/lxd/storage-pools/default/containers/alp2
ID 342 gen 1174 top level 335 path var/lib/lxd/storage-pools/default/containers/alp1
ID 360 gen 1149 top level 263 path .snapshots/1/snapshot
ID 361 gen 1156 top level 263 path .snapshots/2/snapshot
ID 362 gen 1160 top level 263 path .snapshots/3/snapshot
ID 363 gen 1170 top level 335 path var/lib/lxd/storage-pools/default/images/b42c5c14d519c404c0e9c16cae39735640fd3a079310269dbfa857c5d2a1c61c
ID 364 gen 1180 top level 263 path .snapshots/4/snapshot
[artix ~]#

Das Snapshots-Feature kommt hierbei an 2 Stellen zum Einsatz:

  1. Für automatische snapper-Snapshots des Wurzeldateisystems (Verzeichnis /.snapshots)

  2. Für Linux-Container Schnappschüsse via lxd/lxc (Verzeichnis /var/lib/lxd)

Zu a)

[artix ~]# snapper ls
# | Type   | Pre # | Date                     | User | Cleanup  | Description                                                                 | Userdata
---+--------+-------+--------------------------+------+----------+-----------------------------------------------------------------------------+---------
0  | single |       |                          | root |          | current                                                                     |
1  | single |       | Sun Jun 28 19:25:21 2020 | root | timeline | timeline                                                                    |
2  | pre    |       | Sun Jun 28 19:28:29 2020 | root | number   | pacman -Syu                                                                 |
3  | post   |     2 | Sun Jun 28 19:29:45 2020 | root | number   | archlinux-keyring artix-mirrorlist bison ca-certificates-mozilla dhcpcd ... |
4  | single |       | Mon Jun 29 09:55:05 2020 | root | timeline | timeline                                                                    |
5  | single |       | Mon Jun 29 10:01:00 2020 | root | timeline | timeline                                                                    |
[artix ~]#
[artix ~]# ## Hilfsscript, das nur die nötigsten Spalten ausgibt, um Platz zu sparen:
[artix ~]# cat /usr/local/sbin/snapper-ls
snapper ls --columns number,type,pre-number,description,date
[artix ~]#
[artix ~]# snapper-ls
# | Type   | Pre # | Description                                                                 | Date
---+--------+-------+-----------------------------------------------------------------------------+-------------------------
0  | single |       | current                                                                     |
1  | single |       | timeline                                                                    | Sun Jun 28 19:25:21 2020
2  | pre    |       | pacman -Syu                                                                 | Sun Jun 28 19:28:29 2020
3  | post   |     2 | archlinux-keyring artix-mirrorlist bison ca-certificates-mozilla dhcpcd ... | Sun Jun 28 19:29:45 2020
4  | single |       | timeline                                                                    | Mon Jun 29 09:55:05 2020
5  | single |       | timeline                                                                    | Mon Jun 29 10:01:00 2020
[artix ~]#
[artix ~]#

Zu b) Siehe hier unter „Automatic BTRFS integration“…

Festschreiben der IP-Konfiguration

Siehe dazu auch https://wiki.artixlinux.org/Main/OpenRC

Die Ausgangssituation sieht so aus (gg ist ein Kommandoalias, der nur alle aktivierten Zeilen ausgibt):

[artix ~]# alias gg
alias gg='grep -v '\''^\s*#\|^$'\'''
[artix ~]#
[artix ~]# gg /etc/conf.d/net
config_enp0s3="dhcp"
[artix ~]#

Nun editieren wir die Datei /etc/conf.d/net und ändern sie in etwa auf die folgenden Werte:

#config_enp0s3="dhcp"
config_enp0s3="192.168.2.236/24"
routes_enp0s3="default via 192.168.2.1"
dns_servers_enp0s3="127.0.0.1"
dns_search_enp0s3="dom1.test"

Nach dem Ausführen von rc-service net.enp0s3 restart kann es bereits an Testen der neuen Adressierung gehen.

Nur zum Verständnis, wie das Startskript „net.enp0s3“ eingebunden ist:

[artix ~]# ls -l /etc/init.d/net.enp0s3
lrwxrwxrwx 1 root root 18 Apr 25 14:51 /etc/init.d/net.enp0s3 -> /etc/init.d/net.lo
[artix ~]#
[artix ~]# #   >> Der Symlink muss tatsächlich auf /etc/init.d/net.lo zeigen...
[artix ~]#
[artix ~]# ls -l /etc/init.d/net.lo
-rwxr-xr-x 1 root root 19791 Jan 10 10:37 /etc/init.d/net.lo
[artix ~]#
[artix ~]# rc-service -l | grep net
net-online
net.enp0s3
net.lo
netmount
[artix ~]#

Basic DNS server configuration

Siehe dazu speziell für Artix/Arch Linux: https://wiki.archlinux.de/title/BIND

Software installieren

Wir gehen hier davon aus, dass ein aktualisiertes System vorliegt (ansonsten: pacman -Syu).

Die Software ist dann ruckzuck mittels pacman -S bind bind-openrc bind-tools whois installiert.

Konfiguration als Cache only Nameserver

Ähnlich wie bei Debian wollen wir gern ein Verzeichnis ‚/etc/bind‘ haben, das die Zonendateien beherbergt:

[artix ~]# ls -ld /etc/bind*
-rw-r--r-- 1 root root 1991 Jun 18 03:15 /etc/bind.keys
-rw-r--r-- 1 root root  447 Apr 11 22:27 /etc/bindresvport.blacklist
[artix ~]#
[artix ~]# ## Verzeichnis anlegen, Rechte setzen und Dateien verschieben:
[artix ~]# mkdir -m 770 /etc/bind
[artix ~]# chgrp named /etc/bind
[artix ~]# mv /var/named/* /etc/bind/

In der /etc/named.conf via ‚directory‘-Anweisung das neue Zonendateiverzeichnis einbinden sowie die Zeile allow-recursion { 127.0.0.1; }; um die lokalen Netze ergänzen:

[artix ~]# vi /etc/named.conf
[artix ~]# head -21 /etc/named.conf
// vim:set ts=4 sw=4 et:

options {
    #directory "/var/named";
    directory "/etc/bind";
    pid-file "/run/named/named.pid";

    // Uncomment these to enable IPv6 connections support
    // IPv4 will still work:
    //  listen-on-v6 { any; };
    // Add this for no IPv4:
    //  listen-on { none; };

    allow-recursion { 127.0.0.1; 192.168.2.0/24; 10.2.2.0/24; };
    allow-transfer { none; };
    allow-update { none; };

    version none;
    hostname none;
    server-id none;
};

Die Config in Sachen Troubleshooting prüfen und komplett ausgeben:

[artix ~]# named-checkconf /etc/named.conf ; echo $?
0
[artix ~]#
[artix ~]# named-checkconf -p /etc/named.conf
options {
    directory "/etc/bind";
    hostname none;
    pid-file "/run/named/named.pid";
    server-id none;
    version none;
    allow-recursion {
        127.0.0.1/32;
        192.168.2.0/24;
        10.2.2.0/24;
    };
    allow-transfer {
        "none";
    };
    allow-update {
        "none";
    };
};
zone "localhost" IN {
    type master;
    file "localhost.zone";
};
zone "0.0.127.in-addr.arpa" IN {
    type master;
    file "127.0.0.zone";
};
zone "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa" {
    type master;
    file "localhost.ip6.zone";
};
[artix ~]#

Nun starten wir den Service und richten ihn für Autostart ein:

[artix ~]# rc-service named restart
* Starting named ...
* Checking named configuration ...        [ ok ]
[artix ~]#
[artix ~]#
[artix ~]# pgrep -alfi named
7861 /usr/bin/named -u named
[artix ~]#
[artix ~]#
[artix ~]# rc-update add  named
* service named added to runlevel default
[artix ~]#

rndc-Key erstellen

Anders als bei Debian ist hier kein rndc-Key vorhanden, der sich aber recht leicht erzeugen lässt:

[artix ~]# find /etc -name "*rndc*"
[artix ~]#
[artix ~]# rndc-confgen -a
wrote key file "/etc/rndc.key"
[artix ~]#
[artix ~]# find /etc -name "*rndc*" -ls
173770      4 -rw-------   1 root     root          100 Jun 29 15:05 /etc/rndc.key
[artix ~]#

Jetzt müssen noch die Rechte angepasst und der Daemon neu gestartet werden:

[artix ~]# chmod 640 /etc/rndc.key
[artix ~]# chgrp named /etc/rndc.key
[artix ~]#
[artix ~]# rc-service named restart
* Stopping named ...
* Checking named configuration ...                        [ ok ]
* Starting named ...
* Checking named configuration ...                        [ ok ]
[artix ~]#

Und schon kann es ans Testen gehen (besonders auch das Caching):

[artix ~]# ## LPI-relevant:
[artix ~]# rndc reload
server reload successful
[artix ~]#
[artix ~]# dig hamburg.de
...

[artix ~]# rndc dumpdb
[artix ~]#
[artix ~]# grep -C2 hamburg /etc/bind/named_dump.db
            129573  AAAA    2003:8:14::106
; glue
hamburg.de.         129573  NS      ns2.mcs.de.
            129573  NS      ns1.mcs.de.
; secure
[artix ~]#

Als Log-Datei kommt hier übrigens /var/log/everything/current in Frage, auf der VM läuft der elogind-daemon.

Weiteres zur Einrichtung von rndc ist unter https://tecadmin.net/configure-rndc-for-bind9/ zu finden.

Eine eigene DNS-Zone erstellen

Begriffe: Domäne, Zone

  • Domäne: Nur ein Teil des Namensraumes

  • Zone = Verwaltungseinheit einer Domäne

In userem Beispiel:

  • Gesamter Namensraum (FQDN des Hosts): artix.dom1.test.

  • Diese TLD ist für Tests reserviert: test.

  • Unser Name für eine Domäne ist „dom1“, die Zonendatei kann dann z.B. ‚db.dom1.test‘ heißen

Zuerst erstellen wir aus der ‚localhost.zone‘ unsere eigene Datenbankdatei und passen sie mit unserem Lieblingseditor an:

[artix ~]# cd /etc/bind
[artix bind]#
[artix bind]# ls -l
total 52
-rw-r----- 1 root  named   466 Jun 18 03:15 127.0.0.zone
-rw-r----- 1 root  named   506 Jun 18 03:15 localhost.ip6.zone
-rw-r----- 1 root  named   517 Jun 18 03:15 localhost.zone
-rw-r--r-- 1 named named   821 Jun 30 10:40 managed-keys.bind
-rw-r--r-- 1 named named  2516 Jun 30 10:40 managed-keys.bind.jnl
-rw-r--r-- 1 named named 30112 Jun 29 15:17 named_dump.db
[artix bind]#
[artix bind]# # Mit '-p' wird der Gruppenbesitz 'named' übernommen:
[artix bind]# cp -p localhost.zone db.dom1.test
[artix bind]#
[artix bind]# vi db.dom1.test

Im Ergebnis sieht die Datei db.dom1.test so aus:

@                               1D IN SOA   artix.dom1.test. root.artix.dom1.test. (
                                    42    ; serial (yyyymmdd##)
                                    3H    ; refresh
                                    15M   ; retry
                                    1W    ; expiry
                                    1D )  ; minimum ttl

                                1D  IN  NS      artix.dom1.test.

artix.dom1.test.                1D  IN  A       192.168.2.236

Ein erster Syntaxcheck zeigt, dass alles i.O. ist:

[artix bind]# named-checkzone dom1.test ./db.dom1.test
zone dom1.test/IN: loaded serial 42
OK
[artix bind]#

Einbindung der Zonedatei

Nun müssen wir einfach noch die Zonendatei ein der Hauptkonfigurationsdatei einbinden:

[artix bind]# vi /etc/named.conf

38 zone "dom1.test" IN {
39     type master;
40     file "db.dom1.test";
41 };
42
[artix bind]# grep -A3 'zone "dom1' /etc/named.conf
zone "dom1.test" IN {
    type master;
    file "db.dom1.test";
};
[artix bind]#
[artix bind]#
[artix bind]# cat /etc/resolv.conf
# Generated by netifrc for interface enp0s3
search dom1.test
nameserver 127.0.0.1
[artix bind]#

Beim ersten Mal sollten wir den Server gründlich neu starten:

[artix bind]# rc-service named restart
* Stopping named ...
* Checking named configuration ...                                                                                         [ ok ]
* Starting named ...
* Checking named configuration ...                                                                                         [ ok ]
[artix bind]#

Sollte etwas nicht funktionieren, ist es wichtig, immer einen Blick auf tail -f /var/log/everything/current zu werfen.

Und schon können wir ans Testen gehen:

[artix bind]# nslookup artix.dom1.test
Server:             127.0.0.1
Address:    127.0.0.1#53

Name:       artix.dom1.test
Address: 192.168.2.236

[artix bind]#

Hierbei tritt NICHT die Warnmeldung „Non-authoritative answer:“ auf, weil wir selber die Zone auf dieser Maschine hosten, also befugt sind, authoritativ zu antworten.

Weitere A-Records hinzufügen:

[artix bind]# echo 'd10wks.dom1.test.                1D  IN  A       192.168.2.222' >> db.dom1.test
[artix bind]# echo 'testvm.dom1.test.                1D  IN  A       10.0.0.1' >> db.dom1.test
[artix bind]# rndc reload
server reload successful
[artix bind]#
[artix bind]# host d10wks.dom1.test
d10wks.dom1.test has address 192.168.2.222
[artix bind]#

ZUSAMMENFASSUNG

Eine eigene Zone ist relativ schnell angelegt:

  1. Zonefile namens /etc/bind/db.dom1.test mit folgendem Inhalt erstellen:

@                               1D IN SOA   artix.dom1.test. root.artix.dom1.test. (
                                    42    ; serial (yyyymmdd##)
                                    3H    ; refresh
                                    15M   ; retry
                                    1W    ; expiry
                                    1D )  ; minimum ttl

                                1D  IN  NS      artix.dom1.test.

artix.dom1.test.                1D  IN  A       192.168.2.236
d10wks.dom1.test.               1D  IN  A       192.168.2.222
testvm.dom1.test.               1D  IN  A       10.0.0.1
  1. Zonendatei in die /etc/named.conf einbinden:

zone "dom1.test" IN {
    type master;
    file "db.dom1.test";
};

Und natürlich nicht vergessen, den named-Service neu zu starten.

Hinzufügen der Stammhinweise (root server)

[artix bind]# pwd
/etc/bind
[artix bind]#
[artix bind]#
[artix bind]# dig +bufsize=1200 +norec NS . @a.root-servers.net | egrep -v ';|^$' | sort > root.hints
[artix bind]#

[artix bind]# head -3 root.hints
.                   518400  IN      NS      a.root-servers.net.
.                   518400  IN      NS      b.root-servers.net.
.                   518400  IN      NS      c.root-servers.net.
[artix bind]#
[artix bind]#
[artix bind]# # Eine Zone für die Weltwurzel vom Typ "hint" hinzufügen:
[artix bind]# vi /etc/named.conf
[artix bind]#
[artix bind]# grep -C4 'type hint' /etc/named.conf
    server-id none;
};

zone "." IN {
    type hint;
    file "root.hints";
};

zone "localhost" IN {
[artix bind]#

Siehe dazu auch:

Bind9 mit TSIG für Apache Vhosts

Es sollen hier lediglich die wichtigsten Konfigurationsdateien für ein bind9-Szenario mit abgesicherter Replikation für namensbasierte, virtuelle Hosts in Apache vorgestellt werden. Ein HOWTO will dieses Kapitel nicht darstellen, es kann lediglich Beispiele aufzeigen, für die ein grundlegendes Verständnis der jeweiligen Protokolle und Mechanismen Voraussetzung ist.

ACHTUNG: Bitte vorher jeweils die /etc/hosts bereinigen, damit nicht schon die Antwort aus der lokalen IP-Adressen/Hostnamen-Zuordnung gegeben wird!

Die IP-Adressen des Primary DNS Servers „Artix Linux“, der u.a. auch als LXC-Host auftritt, schaut so aus:

[artix ~]# ip -4 addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    inet 127.0.0.1/8 brd 127.255.255.255 scope host lo
    valid_lft forever preferred_lft forever
2: enp0s3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    inet 192.168.2.236/24 brd 192.168.2.255 scope global enp0s3
    valid_lft forever preferred_lft forever
3: lxdbr0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN group default qlen 1000
    inet 10.2.2.1/24 scope global lxdbr0
    valid_lft forever preferred_lft forever
[artix ~]#

Die IP-Adresse des Secondary DNS Servers ist 10.2.2.2, siehe dazu weiter unten.

Und dies ist der Inhalt der Konfigurationsdatei für bind9 (Artix/Arch-Linux hat die Datei anders als Debian nicht aufgeplittet):

[artix ~]# cat /etc/named.conf
// vim:set ts=4 sw=4 et:
options {
    directory "/etc/bind";
    pid-file "/run/named/named.pid";
    allow-recursion { 127.0.0.1; 192.168.2.0/24; 10.2.2.0/24; };
    allow-transfer { none; };
    allow-update { none; };
    version none;
    hostname none;
    server-id none;
    forward first;
    forwarders { 194.25.2.129; };
};

acl "TRANSFER" { 10.2.2.2; };
include "/etc/bind/tsig.key";

zone "." IN {
    type hint;
    file "root.hints";
};

zone "localhost" IN {
    type master;
    file "localhost.zone";
};

zone "0.0.127.in-addr.arpa" IN {
    type master;
    file "127.0.0.zone";
};

zone "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa" {
    type master;
    file "localhost.ip6.zone";
};

zone "dom1.test" IN {
    type master;
    notify yes;
    allow-transfer { TRANSFER; };
    file "db.dom1.test";
};

zone "2.168.192.in-addr.arpa" IN {
    type master;
    file "db.192.168.2";
};

zone "kunde1.test" IN {
        type master;
        notify yes;
        allow-transfer { TRANSFER; };
        file "/etc/bind/db.kunde1.test";
};

zone "kunde2.test" IN {
        type master;
        notify yes;
        allow-transfer { TRANSFER; };
        file "/etc/bind/db.kunde2.test";
};
[artix ~]#

Die vier für unsere Zwecke speziell erstellten Zonendateien sehen folgendermaßen aus:

[artix ~]# cat /etc/bind/db.dom1.test
@                               1D IN SOA   artix.dom1.test. root.artix.dom1.test. (
                                    53    ; serial (yyyymmdd##)
                                    3H    ; refresh
                                    15M   ; retry
                                    1W    ; expiry
                                    1D )  ; minimum ttl

                                1D  IN  NS      artix.dom1.test.
                                1D  IN  NS      dev1.dom1.test.

artix.dom1.test.                1D  IN  A       192.168.2.236
d10wks.dom1.test.               1D  IN  A       192.168.2.222
dev1.dom1.test.                 1D  IN  A       10.2.2.2
deb1.dom1.test.                 1D  IN  A       10.2.2.3
ida.dom1.test.                  1D  IN  A        3.255.77.254
[artix ~]#
[artix ~]# cat /etc/bind/db.192.168.2
@                  1D IN SOA   artix.dom1.test. root.artix.dom1.test. (
                                    42    ; serial (yyyymmdd##)
                                    3H    ; refresh
                                    15M   ; retry
                                    1W    ; expiry
                                    1D )  ; minimum ttl

                1D  IN  NS      artix.dom1.test.
236                1D  IN  PTR     artix.dom1.test.
222                1D  IN  PTR     d10wks.dom1.test.
[artix ~]#
[artix ~]# cat /etc/bind/db.kunde1.test
@                               1D IN SOA   artix.kunde1.test. root.artix.kunde1.test. (
                                    59    ; serial (yyyymmdd##)
                                    3H    ; refresh
                                    15M   ; retry
                                    1W    ; expiry
                                    1D )  ; minimum ttl

@                                1D  IN  NS      artix.kunde1.test.
@                                1D  IN  NS      dev1.kunde1.test.

artix.kunde1.test.               1D  IN  A       192.168.2.236
dev1.kunde1.test.                1D  IN  A       10.2.2.2
@                                1D  IN  A       10.2.2.2
www                              1D  IN  CNAME   dev1
[artix ~]#
[artix ~]# cat /etc/bind/db.kunde2.test
@                               1D IN SOA   artix.kunde2.test. root.artix.kunde2.test. (
                                    59    ; serial (yyyymmdd##)
                                    3H    ; refresh
                                    15M   ; retry
                                    1W    ; expiry
                                    1D )  ; minimum ttl

@                                1D  IN  NS      artix.kunde2.test.
@                                1D  IN  NS      dev1.kunde2.test.

artix.kunde2.test.               1D  IN  A       192.168.2.236
dev1.kunde2.test.                1D  IN  A       10.2.2.2
@                                1D  IN  A       10.2.2.2
www                              1D  IN  CNAME   dev1
[artix ~]#

Die Rechte müssen natürlich auch passen:

[artix ~]# chmod 640 /bind/db.*
[artix ~]# chgrp named /bind/db.*
[artix ~]#
[artix ~]# /etc/init.d/named restart
* Stopping named ...
* Checking named configuration ...                                                                                                    [ ok ]
* Starting named ...
* Checking named configuration ...                                                                                                    [ ok ]
[artix ~]#

Das Erzeugen des geheimen, symmetrischen Schlüssels auf Devuan-Linux ist im Verzeichnis /etc/bind mittels

dnssec-keygen -a HMAC-MD5 -b 512 -n HOST rndc-key

schnell erledigt, unter Artix/Arch Linux müsste dafür das Kommando tsig-keygen verwendet werden.

Aus der Datei Krndc-key*.private entnehmen wir den „Key“, den wir in der folgenden Datei bei „secret“ hinterlegen. Eine solche Datei wird ganz ähnlich auf dem anderen Nameserver angelegt, wobei bei „server“ der jeweils andere Nameserver angegeben werden muss:

[artix ~]# cat /etc/bind/tsig.key
key "TRANSFER" {
    algorithm hmac-md5;
    secret "c0oK9PtTfAF05/WGs+uAPX7/ksSHdy6z/Al4B9iIrUZgl9Kwiu+9etlsQIPYlSt9Ij4dwNMU9uRk2XUyJLd78A==";
};

server 10.2.2.2 {
    keys {
            TRANSFER;
    };
};
[artix ~]#

Auf dem Secondary-Nameserver:

root@dev1:~# cat /etc/bind/named.conf
// This is the primary configuration file for the BIND DNS server named.
//
// Please read /usr/share/doc/bind9/README.Debian.gz for information on the
// structure of BIND configuration files in Debian, *BEFORE* you customize
// this configuration file.
//
// If you are just adding zones, please do that in /etc/bind/named.conf.local

include "/etc/bind/named.conf.options";
include "/etc/bind/named.conf.local";
include "/etc/bind/named.conf.default-zones";
include "/etc/bind/tsig.key";
root@dev1:~#
root@dev1:~# cat /etc/bind/named.conf.local
//
// Do any local configuration here
//

// Consider adding the 1918 zones here, if they are not used in your
// organization
//include "/etc/bind/zones.rfc1918";

zone "dom1.test" {
        type slave;
        masters { 10.2.2.1; };
};

zone "kunde1.test" {
        type slave;
        masters { 10.2.2.1; };
};

zone "kunde2.test" {
        type slave;
        masters { 10.2.2.1; };
};
root@dev1:~#
root@dev1:~#
root@dev1:~# /etc/init.d/bind9 restart
[....] Stopping domain name service...: bind9waiting for pid 747 to die
. ok
[ ok ] Starting domain name service...: bind9.
root@dev1:~#

HINWEIS: Zonendateien gibt es hier nicht, sie werden vom Primary-Nameserver automatisch repliziert.

Apache: namensbasierte vHosts

Fehlen uns zum Gesamtverständnis nur noch die Konfigurationsdateien der virtuellen Apache-Hosts:

[artix ~]# lxc exec dev1 bash
root@dev1:~#
root@dev1:~# ip -4 addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    inet 127.0.0.1/8 scope host lo
    valid_lft forever preferred_lft forever
4: eth0@if5: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000 link-netnsid 0
    inet 10.2.2.2/24 brd 10.2.2.255 scope global eth0
    valid_lft forever preferred_lft forever
root@dev1:~#
root@dev1:~#
root@dev1:~#
root@dev1:~# cat /etc/apache2/sites-enabled/kunde1.conf
<VirtualHost *:80>
        ServerName www.kunde1.test
        ServerAlias dev1.kunde1.test kunde1.test
        DocumentRoot /srv/vhosts/kunde1

        <Directory /srv/vhosts/kunde1/>
        Options FollowSymLinks

        # AXPE: Standard bis einschließlich Apache 2.2:
        #Order allow,deny
        #Allow from all

        # AXPE: Ab Version 2.4 ist eine Zeile ausreiched, um alles zu erlauben:
        Require all granted
        </Directory>

        ErrorLog ${APACHE_LOG_DIR}/error-kunde1.log
        CustomLog ${APACHE_LOG_DIR}/access-kunde1.log combined

</VirtualHost>
# vim: syntax=apache ts=4 sw=4 sts=4 sr noet
root@dev1:~#
root@dev1:~#
root@dev1:~#
root@dev1:~# cat /etc/apache2/sites-enabled/kunde2.conf
<VirtualHost *:80>
        ServerName www.kunde2.test
        ServerAlias dev1.kunde2.test kunde2.test
        DocumentRoot /srv/vhosts/kunde2

        <Directory /srv/vhosts/kunde2/>
        #Options FollowSymLinks
        Require all granted
        </Directory>

        ErrorLog ${APACHE_LOG_DIR}/error-kunde2.log
        CustomLog ${APACHE_LOG_DIR}/access-kunde2.log combined

</VirtualHost>
# vim: syntax=apache ts=4 sw=4 sts=4 sr noet
root@dev1:~#
root@dev1:~# exit
exit
[artix ~]#

Nach einem gründlichen Neustart des Artix-Hosts mittels reboot sollte es dann so aussehen:

[tux@artix ~]$ lxc list
+------+---------+-----------------+------+-----------+-----------+
| NAME |  STATE  |      IPV4       | IPV6 |   TYPE    | SNAPSHOTS |
+------+---------+-----------------+------+-----------+-----------+
| alp1 | STOPPED |                 |      | CONTAINER | 0         |
+------+---------+-----------------+------+-----------+-----------+
| alp2 | STOPPED |                 |      | CONTAINER | 0         |
+------+---------+-----------------+------+-----------+-----------+
| deb1 | STOPPED |                 |      | CONTAINER | 0         |
+------+---------+-----------------+------+-----------+-----------+
| dev1 | RUNNING | 10.2.2.2 (eth0) |      | CONTAINER | 0         |
+------+---------+-----------------+------+-----------+-----------+
[tux@artix ~]$
[tux@artix ~]$
[tux@artix ~]$ wget -qO- www.kunde1.test
Willkommen bei Kunde 001
[tux@artix ~]$
[tux@artix ~]$ wget -qO- kunde1.test
Willkommen bei Kunde 001
[tux@artix ~]$
[tux@artix ~]$ wget -qO- dev1.kunde1.test
Willkommen bei Kunde 001
[tux@artix ~]$

[tux@artix ~]$ wget -qO- www.kunde2.test
Welcome in the world of Mr. Two...!
[tux@artix ~]$
[tux@artix ~]$ wget -qO- kunde2.test
Welcome in the world of Mr. Two...!
[tux@artix ~]$
[tux@artix ~]$ wget -qO- dev1.kunde2.test
Welcome in the world of Mr. Two...!
[tux@artix ~]$

[tux@artix ~]$ lxc exec dev1 bash
root@dev1:~#
root@dev1:~# wget -qO- kunde1.test
Willkommen bei Kunde 001
root@dev1:~#
root@dev1:~# wget -qO- kunde2.test
Welcome in the world of Mr. Two...!
root@dev1:~#
root@dev1:~# host www.kunde1.test
www.kunde1.test is an alias for dev1.kunde1.test.
dev1.kunde1.test has address 10.2.2.2
root@dev1:~#
root@dev1:~# host dev1.kunde1.test
dev1.kunde1.test has address 10.2.2.2
root@dev1:~#
root@dev1:~# host kunde1.test
kunde1.test has address 10.2.2.2
root@dev1:~#
root@dev1:~#
root@dev1:~# host www.kunde2.test
www.kunde2.test is an alias for dev1.kunde2.test.
dev1.kunde2.test has address 10.2.2.2
root@dev1:~#
root@dev1:~# ## ...usw.

Iptables-Regeln für PAT

Wir benötigen für die Weiterleitung von Datenpaketen zu den hinter NAT (VBox NatNetwork) aufgestellten Linux-Containern ein paar besondere Regeln. Dieses allgemein mit Port Address Translation (PAT) bezeichnete Verfahren wird auch gern Port-Forwarding genannt. Es wird z.B. auch eingesetzt, um aus dem Internet heraus durch den heimischen WLAN-Router hindurch auf spezielle, im LAN laufende Dienste, zugreifen zu können.

Dazu entfernen wir erst einmal temporär alle Regeln aus den drei Standardtabellen (-F, --flush), damit die von lxd automatisch erzeugten Regeln (für Bridge „lxdbr0“) im Endeffekt nicht doppelt vorhanden sind:

iptables -F
iptables -F -t nat
iptables -F -t mangle

Die folgenden Zeilen sind beispielhafte, manuell im Artix-Host zu setzende Paketfilterregeln, um Datenpakete mittels PAT zu den in Linux-Containern laufenden Diensten umzuleiten. Sie werden hierbei nur temporär gesetzt, später dann aber mittels des unten genannten Kommandos /etc/init.d/iptables save persistent gemacht:

# Für www, squid proxy und samba
iptables -t nat -A PREROUTING  -i enp0s3 -p tcp --dport 80 -j DNAT --to-destination 10.2.2.2:80
iptables -t nat -A PREROUTING  -i enp0s3 -p tcp --dport 443 -j DNAT --to-destination 10.2.2.2:443
iptables -t nat -A PREROUTING  -i enp0s3 -p tcp --dport 3128 -j DNAT --to-destination 10.2.2.3:3128
iptables -t nat -A PREROUTING  -i enp0s3 -p tcp --dport 445 -j DNAT --to-destination 10.2.2.3:445
iptables -t nat -A PREROUTING  -i enp0s3 -p tcp --dport 139 -j DNAT --to-destination 10.2.2.3:139
iptables -t nat -A PREROUTING  -i enp0s3 -p udp --dport 137 -j DNAT --to-destination 10.2.2.3:137
iptables -t nat -A PREROUTING  -i enp0s3 -p udp --dport 138 -j DNAT --to-destination 10.2.2.3:138

# Für DC-Dienste, => https://www.aventistech.com/2020/02/firewall-ports-required-to-join-ad-domain/
iptables -t nat -A PREROUTING  -i enp0s3 -p udp --dport 53 -j DNAT --to-destination 10.2.2.3:53
iptables -t nat -A PREROUTING  -i enp0s3 -p tcp --dport 389 -j DNAT --to-destination 10.2.2.3:389
iptables -t nat -A PREROUTING  -i enp0s3 -p udp --dport 389 -j DNAT --to-destination 10.2.2.3:389
iptables -t nat -A PREROUTING  -i enp0s3 -p tcp --dport 88 -j DNAT --to-destination 10.2.2.3:88
iptables -t nat -A PREROUTING  -i enp0s3 -p udp --dport 123 -j DNAT --to-destination 10.2.2.3:123
iptables -t nat -A PREROUTING  -i enp0s3 -p tcp --dport 53 -j DNAT --to-destination 10.2.2.3:53
iptables -t nat -A PREROUTING  -i enp0s3 -p tcp --dport 464 -j DNAT --to-destination 10.2.2.3:464
iptables -t nat -A PREROUTING  -i enp0s3 -p tcp --dport 636 -j DNAT --to-destination 10.2.2.3:636
iptables -t nat -A PREROUTING  -i enp0s3 -p udp --dport 636 -j DNAT --to-destination 10.2.2.3:636
iptables -t nat -A PREROUTING  -i enp0s3 -p tcp --dport 3268 -j DNAT --to-destination 10.2.2.3:3268
iptables -t nat -A PREROUTING  -i enp0s3 -p tcp --dport 135 -j DNAT --to-destination 10.2.2.3:135

Damit die Firewallregeln beim Systemstart automatisch eingelesen werden, benötigen wir noch das Softwarepaket iptables-openrc:

pacman -Sy iptables-openrc

Nun können wir schließlich wie erwähnt das aktuelle Regelwerk abspeichern, dafür sorgen, dass die Regeln beim Systemstart automatisch geladen werden und die zusätzlichen Regeln für die lxd-Bridge wieder erzeugen lassen:

/etc/init.d/iptables save
rc-update add iptables
rc-service lxd restart

Mit obigem /etc/init.d/iptables save wurde das Skript /var/lib/iptables/rules-save geschrieben, was lediglich unsere eigenen Regeln enthält; die von lxd stehen dort nicht drin, sie werden automatisch beim Starten der Bridge erzeugt. Der Inhalt des Skriptes sieht dann insgesamt so aus:

# Generated by iptables-save v1.8.5 on Tue Jul 21 16:05:51 2020
*raw
:PREROUTING ACCEPT [40145:44972055]
:OUTPUT ACCEPT [20876:1800837]
COMMIT
# Completed on Tue Jul 21 16:05:51 2020
# Generated by iptables-save v1.8.5 on Tue Jul 21 16:05:51 2020
*mangle
:PREROUTING ACCEPT [6618:9972725]
:INPUT ACCEPT [6473:9953309]
:FORWARD ACCEPT [145:19416]
:OUTPUT ACCEPT [5084:533389]
:POSTROUTING ACCEPT [5229:552805]
COMMIT
# Completed on Tue Jul 21 16:05:51 2020
# Generated by iptables-save v1.8.5 on Tue Jul 21 16:05:51 2020
*nat
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
[0:0] -A PREROUTING -i enp0s3 -p tcp -m tcp --dport 80 -j DNAT --to-destination 10.2.2.2:80
[0:0] -A PREROUTING -i enp0s3 -p tcp -m tcp --dport 443 -j DNAT --to-destination 10.2.2.2:443
[0:0] -A PREROUTING -i enp0s3 -p tcp -m tcp --dport 3128 -j DNAT --to-destination 10.2.2.3:3128
[0:0] -A PREROUTING -i enp0s3 -p tcp -m tcp --dport 135 -j DNAT --to-destination 10.2.2.3:135
[0:0] -A PREROUTING -i enp0s3 -p tcp -m tcp --dport 445 -j DNAT --to-destination 10.2.2.3:445
[0:0] -A PREROUTING -i enp0s3 -p tcp -m tcp --dport 139 -j DNAT --to-destination 10.2.2.3:139
[0:0] -A PREROUTING -i enp0s3 -p udp -m udp --dport 137 -j DNAT --to-destination 10.2.2.3:137
[0:0] -A PREROUTING -i enp0s3 -p udp -m udp --dport 138 -j DNAT --to-destination 10.2.2.3:138
[0:0] -A PREROUTING -i enp0s3 -p udp -m udp --dport 53 -j DNAT --to-destination 10.2.2.3:53
[0:0] -A PREROUTING -i enp0s3 -p tcp -m tcp --dport 389 -j DNAT --to-destination 10.2.2.3:389
[0:0] -A PREROUTING -i enp0s3 -p udp -m udp --dport 389 -j DNAT --to-destination 10.2.2.3:389
[0:0] -A PREROUTING -i enp0s3 -p tcp -m tcp --dport 88 -j DNAT --to-destination 10.2.2.3:88
[0:0] -A PREROUTING -i enp0s3 -p udp -m udp --dport 123 -j DNAT --to-destination 10.2.2.3:123
[0:0] -A PREROUTING -i enp0s3 -p tcp -m tcp --dport 53 -j DNAT --to-destination 10.2.2.3:53
[0:0] -A PREROUTING -i enp0s3 -p tcp -m tcp --dport 464 -j DNAT --to-destination 10.2.2.3:464
[0:0] -A PREROUTING -i enp0s3 -p tcp -m tcp --dport 636 -j DNAT --to-destination 10.2.2.3:636
[0:0] -A PREROUTING -i enp0s3 -p udp -m udp --dport 636 -j DNAT --to-destination 10.2.2.3:636
[0:0] -A PREROUTING -i enp0s3 -p tcp -m tcp --dport 3268 -j DNAT --to-destination 10.2.2.3:3268
COMMIT
# Completed on Tue Jul 21 16:05:51 2020
# Generated by iptables-save v1.8.5 on Tue Jul 21 16:05:51 2020
*filter
:INPUT ACCEPT [6513:9955645]
:FORWARD ACCEPT [145:19416]
:OUTPUT ACCEPT [5108:535437]
COMMIT
# Completed on Tue Jul 21 16:05:51 2020

HINWEISE/TIPPS:

  • Die unter /etc/iptables/ liegenden Dateien spielen hierbei KEINE Rolle! Bei Debian ist das anderes, dort werden die aktuellen Regeln via iptables-save in die Datei /etc/iptables/rules.v4 geschrieben.

  • Damit Systemd-Distributionen in LXD unter Artix laufen:

    • vi +34 /etc/init.d/cgroups # Diese Zeile darunter einfügen: mkdir -p /sys/fs/cgroup/systemd

    • vi +99 /etc/fstab # Diese Zeile darunter einfügen: systemd  /sys/fs/cgroup/systemd  cgroup  none,name=systemd  0 0

Siehe dazu auch iptables-persistent bei Debian