Router-Szenario in LXD

Nach dem erfolreichen Einrichten einr nativen Linux-Bridge br0 sowie Installieren und Initialisieren von lxd soll hier das Erstellen von Bridges für eine Übungsumgebung und die Ersteinrichtung zweier Container beschreiben werden.

Zum Einrichten der Bridge unter openSUSE und zur übersichtlichen Konfiguration von LXC siehe openSUSE Leap als Container-Host.

Software installieren

testhost:~ # zypper in lxd lxd-bash-completion
Loading repository data...
Reading installed packagetesthost:~ # usermod -aG lxd tux
testhost:~ #
testhost:~ # systemctl start lxd
testhost:~ # systemctl start lxcfs
testhost:~ #
testhost:~ # systemctl enable lxd
Created symlink /etc/systemd/system/multi-user.target.wants/lxd.service → /usr/lib/systemd/system/lxd.service.
testhost:~ #
testhost:~ # systemctl enable lxcfs
Created symlink /etc/systemd/system/multi-user.target.wants/lxcfs.service → /usr/lib/systemd/system/lxcfs.service.
testhost:~ #

Initialisieren von lxd

testhost:~ # lxd init
Would you like to use LXD clustering? (yes/no) [default=no]:
Do you want to configure a new storage pool? (yes/no) [default=yes]:
Name of the new storage pool [default=default]:
Name of the storage backend to use (btrfs, dir, lvm) [default=btrfs]:
Would you like to create a new btrfs subvolume under /var/lib/lxd? (yes/no) [default=yes]:
Would you like to connect to a MAAS server? (yes/no) [default=no]:
Would you like to create a new local network bridge? (yes/no) [default=yes]:
What should the new bridge be called? [default=lxdbr0]:
What IPv4 address should be used? (CIDR subnet notation, “auto” or “none”) [default=auto]:
What IPv6 address should be used? (CIDR subnet notation, “auto” or “none”) [default=auto]:
Would you like LXD to be available over the network? (yes/no) [default=no]:
Would you like stale cached images to be updated automatically? (yes/no) [default=yes]
Would you like a YAML "lxd init" preseed to be printed? (yes/no) [default=no]:
testhost:~ #
testhost:~ # exit
logout
tux@testhost:~$
tux@testhost:~$ exit
Abgemeldet
Connection to 10.21.21.123 closed.
[tux@artix-wks ~]$ ## Komplett ausgeloggt!!

[tux@artix-wks ~]$ ssh -p 4711 10.21.21.123
Enter passphrase for key '/home/tux/.ssh/id_rsa':
Last login: Thu Aug 20 13:59:46 2020 from 10.21.21.201
Have a lot of fun...
tux@testhost:~$
tux@testhost:~$

tux@testhost:~$ lxc list
To start your first instance, try: lxc launch ubuntu:18.04

+------+-------+------+------+------+-----------+
| NAME | STATE | IPV4 | IPV6 | TYPE | SNAPSHOTS |
+------+-------+------+------+------+-----------+
tux@testhost:~$
tux@testhost:~$ lxc profile list
+---------+---------+
|  NAME   | USED BY |
+---------+---------+
| default | 0       |
+---------+---------+
tux@testhost:~$
tux@testhost:~$ lxc network list
+--------+----------+---------+---------------+---------------------------+-------------+---------+
|  NAME  |   TYPE   | MANAGED |     IPV4      |           IPV6            | DESCRIPTION | USED BY |
+--------+----------+---------+---------------+---------------------------+-------------+---------+
| br0    | bridge   | NO      |               |                           |             | 0       |
+--------+----------+---------+---------------+---------------------------+-------------+---------+
| eth0   | physical | NO      |               |                           |             | 0       |
+--------+----------+---------+---------------+---------------------------+-------------+---------+
| lxdbr0 | bridge   | YES     | 10.31.99.1/24 | fd42:fc0c:b479:f27d::1/64 |             | 1       |
+--------+----------+---------+---------------+---------------------------+-------------+---------+
tux@testhost:~$

Damit haben wir nun einen guten Ausgangspunkt für einfache Szenarien (Client/Server).

LXD-Bridges und Devices hinzufügen

Wir aber wollen mehr: https://pemmann.de/cc/Doc/Testumgebung/Bridged/testnetz-mit-Netzwerkbruecke.html

Profil für externes Arbeiten via br0 anlegen

tux@testhost:~$ lxc profile copy default extbridge
tux@testhost:~$
tux@testhost:~$ lxc profile device remove extbridge eth0
Device eth0 removed from extbridge
tux@testhost:~$
tux@testhost:~$ lxc profile device add extbridge eth0 nic nictype=bridged parent=br0
Device eth0 added to extbridge
tux@testhost:~$

Profil für internes LAN anlegen

tux@testhost:~$ lxc network create lxdbr1 ipv4.nat=false ipv6.nat=false ipv4.address=none ipv6.dhcp=false dns.mode=none
Network lxdbr1 created
tux@testhost:~$
tux@testhost:~$ lxc profile copy default intbridge
tux@testhost:~$
tux@testhost:~$ lxc profile device remove intbridge eth0
Device eth0 removed from intbridge
tux@testhost:~$
tux@testhost:~$ lxc profile device add intbridge eth0 nic nictype=bridged parent=lxdbr1
Device eth0 added to intbridge
tux@testhost:~$
tux@testhost:~$
tux@testhost:~$ lxc profile list
+-----------+---------+
|   NAME    | USED BY |
+-----------+---------+
| default   | 0       |
+-----------+---------+
| extbridge | 0       |
+-----------+---------+
| intbridge | 0       |
+-----------+---------+
tux@testhost:~$
tux@testhost:~$ lxc profile show extbridge
config: {}
description: Default LXD profile
devices:
eth0:
    nictype: bridged
    parent: br0
    type: nic
root:
    path: /
    pool: default
    type: disk
name: extbridge
used_by: []
tux@testhost:~$
tux@testhost:~$
tux@testhost:~$ lxc profile show intbridge
config: {}
description: Default LXD profile
devices:
eth0:
    nictype: bridged
    parent: lxdbr1
    type: nic
root:
    path: /
    pool: default
    type: disk
name: intbridge
used_by: []
tux@testhost:~$

Container „alp-router“ mit 2 NICs erstellen (eth0 via lxdbr0, eth1 via lxdbr1)

tux@testhost:~$ lxc launch -p extbridge images:alpine/3.9 alp-router
Creating alp-router
Starting alp-router
tux@testhost:~$
tux@testhost:~$
tux@testhost:~$ lxc config device add alp-router eth1 nic nictype=bridged parent=lxdbr1 name=eth1
Device eth1 added to alp-router
tux@testhost:~$

Container „alp-server“ mit einer NIC erstellen (eth0 via lxdbr1)

tux@testhost:~$ lxc launch -p intbridge images:alpine/3.9 alp-server
Creating alp-server
Starting alp-server
tux@testhost:~$

LXD-Testumgebung benutzen

Hier soll nun die manuelle IP-Konfiguration der Container vorgenommen werden, danach stehen immer gewisse Tests an.

tux@testhost:~$ lxc exec alp-router ash
~ #
~ # ip -4 addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1000
    inet 127.0.0.1/8 scope host lo
    valid_lft forever preferred_lft forever
6: eth0@if7: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue state UP qlen 1000
    inet 10.1.1.8/24 scope global eth0
    valid_lft forever preferred_lft forever
~ #
~ # ip link show eth1
8: eth1@if9: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN qlen 1000
    link/ether 00:16:3e:86:45:d8 brd ff:ff:ff:ff:ff:ff
~ #
~ # ip -4 addr add 10.2.2.1/24 dev eth1
~ #
~ # ip link show eth1
8: eth1@if9: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN qlen 1000
    link/ether 00:16:3e:86:45:d8 brd ff:ff:ff:ff:ff:ff
~ #
~ #
tux@testhost:~$ lxc list
+------------+---------+-----------------+-----------------------------------------------+-----------+-----------+
|    NAME    |  STATE  |      IPV4       |                     IPV6                      |   TYPE    | SNAPSHOTS |
+------------+---------+-----------------+-----------------------------------------------+-----------+-----------+
| alp-router | RUNNING | 10.2.2.1 (eth1) |                                               | CONTAINER | 0         |
|            |         | 10.1.1.8 (eth0) |                                               |           |           |
+------------+---------+-----------------+-----------------------------------------------+-----------+-----------+
| alp-server | RUNNING |                 | fd42:1263:16b5:7082:216:3eff:feaf:7717 (eth0) | CONTAINER | 0         |
+------------+---------+-----------------+-----------------------------------------------+-----------+-----------+
tux@testhost:~$
tux@testhost:~$

~ # exit
tux@testhost:~$
tux@testhost:~$ lxc exec alp-server ash
~ #
~ # ip link
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
10: eth0@if11: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue state UP qlen 1000
    link/ether 00:16:3e:af:77:17 brd ff:ff:ff:ff:ff:ff
~ #
~ #
~ # ip -4 addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1000
    inet 127.0.0.1/8 scope host lo
    valid_lft forever preferred_lft forever
~ #
~ # ip addr add 10.2.2.2/24 dev eth0
~ #
~ #

~ # ping -c2 10.2.2.1
PING 10.2.2.1 (10.2.2.1): 56 data bytes

--- 10.2.2.1 ping statistics ---
2 packets transmitted, 0 packets received, 100% packet loss
~ #
~ #
~ #
~ # ### Trouble!
~ #
~ # ip -4 addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1000
    inet 127.0.0.1/8 scope host lo
    valid_lft forever preferred_lft forever
10: eth0@if11: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue state UP qlen 1000
    inet 10.2.2.2/24 scope global eth0
    valid_lft forever preferred_lft forever
~ #
~ # #    >> hier ist "UP" zu sehen...   :-)
~ #
~ #
~ #
~ # exit
tux@testhost:~$
tux@testhost:~$ lxc exec alp-router ash
~ #
~ # ip -4 addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1000
    inet 127.0.0.1/8 scope host lo
    valid_lft forever preferred_lft forever
6: eth0@if7: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue state UP qlen 1000
    inet 10.1.1.8/24 scope global eth0
    valid_lft forever preferred_lft forever
8: eth1@if9: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN qlen 1000
    inet 10.2.2.1/24 scope global eth1
    valid_lft forever preferred_lft forever
~ #
~ # #    >> eth1 ist "DOWN"!
~ #
~ # ## Man muss u.U. die NIC erst aktivieren ('ifconfig eth0 up'):
~ # ip link set dev eth1 up
~ #
~ # ip -4 addr show eth1
8: eth1@if9: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue state UP qlen 1000
    inet 10.2.2.1/24 scope global eth1
    valid_lft forever preferred_lft forever
~ #
~ # ping -c2 10.2.2.2
PING 10.2.2.2 (10.2.2.2): 56 data bytes
64 bytes from 10.2.2.2: seq=0 ttl=64 time=0.147 ms
64 bytes from 10.2.2.2: seq=1 ttl=64 time=0.109 ms

--- 10.2.2.2 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 0.109/0.128/0.147 ms
~ #
~ #


~ #
~ # ### Dies ist ein Router:
~ # ip -4 addr show eth0
6: eth0@if7: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue state UP qlen 1000
    inet 10.1.1.8/24 scope global eth0
    valid_lft forever preferred_lft forever
~ #
~ # ip -4 addr show eth1
8: eth1@if9: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue state UP qlen 1000
    inet 10.2.2.1/24 scope global eth1
    valid_lft forever preferred_lft forever
~ #
~ # sysctl net.ipv4.ip_forward
net.ipv4.ip_forward = 1
~ #
~ # #   >> letzteres musste der SUSE-Host bereits aktivieren (wegen br0)
~ #
~ #

~ #
~ # ### Pakete aktualisieren, iptables installieren
~ # # ----------------------
~ # ip route
default via 10.1.1.1 dev eth0  metric 206
10.1.1.0/24 dev eth0 scope link  src 10.1.1.8
10.2.2.0/24 dev eth1 scope link  src 10.2.2.1
~ #
~ # ping -c3 80.80.80.80
PING 80.80.80.80 (80.80.80.80): 56 data bytes

--- 80.80.80.80 ping statistics ---
3 packets transmitted, 0 packets received, 100% packet loss
~ #
~ #
~ # ping -c3 80.80.80.80
PING 80.80.80.80 (80.80.80.80): 56 data bytes
64 bytes from 80.80.80.80: seq=0 ttl=53 time=38.756 ms
64 bytes from 80.80.80.80: seq=1 ttl=53 time=27.726 ms
64 bytes from 80.80.80.80: seq=2 ttl=53 time=27.379 ms

--- 80.80.80.80 ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 27.379/31.287/38.756 ms
~ #

Nach dem Aktivieren des Promiscous-Modus in VirtualBox bezüglich „Adapter 1“ klappt alles.

~ # ls -l /etc/resolv.conf
-rw-r--r--    1 root     root            22 Aug 21 08:53 /etc/resolv.conf
~ #
~ # cat /etc/resolv.conf
nameserver 10.21.21.1
~ #
~ #
~ # apk update
fetch http://dl-cdn.alpinelinux.org/alpine/v3.9/main/x86_64/APKINDEX.tar.gz
fetch http://dl-cdn.alpinelinux.org/alpine/v3.9/community/x86_64/APKINDEX.tar.gz
v3.9.6-61-gde0df29a6f [http://dl-cdn.alpinelinux.org/alpine/v3.9/main]
v3.9.6-60-g89c1232642 [http://dl-cdn.alpinelinux.org/alpine/v3.9/community]
OK: 9774 distinct packages available
~ #
~ # apk add iptables
(1/4) Installing libmnl (1.0.4-r0)
(2/4) Installing jansson (2.11-r0)
(3/4) Installing libnftnl-libs (1.1.1-r0)
(4/4) Installing iptables (1.6.2-r1)
Executing busybox-1.29.3-r10.trigger
OK: 11 MiB in 23 packages
~ #
~ #
~ # iptables -vnL
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target     prot opt in     out     source               destination

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target     prot opt in     out     source               destination

Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target     prot opt in     out     source               destination
~ #
~ # iptables -vnL -t nat
Chain PREROUTING (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target     prot opt in     out     source               destination

Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target     prot opt in     out     source               destination

Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target     prot opt in     out     source               destination

Chain POSTROUTING (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target     prot opt in     out     source               destination
~ #
~ #

~ #
~ # iptables -vnL POSTROUTING -t nat
Chain POSTROUTING (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target     prot opt in     out     source               destination
~ #
~ # iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
~ #
~ # iptables -vnL POSTROUTING -t nat
Chain POSTROUTING (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target     prot opt in     out     source               destination
    0     0 MASQUERADE  all  --  *      eth0    0.0.0.0/0            0.0.0.0/0
~ #
~ #
tux@testhost:~$ lxc exec alp-server ash
~ #
~ #
~ # ip route
10.2.2.0/24 dev eth0 scope link  src 10.2.2.2
~ #
~ # ls -l /etc/resolv.conf
-rw-r--r--    1 root     root             0 Aug 20 13:01 /etc/resolv.conf
~ #
~ #
~ # ip route add default via 10.2.2.1
~ #
~ # echo nameserver 80.80.80.80 > /etc/resolv.conf
~ #
~ # ping -c3 ping.eu
PING ping.eu (88.198.46.60): 56 data bytes
64 bytes from 88.198.46.60: seq=0 ttl=55 time=20.621 ms
64 bytes from 88.198.46.60: seq=1 ttl=55 time=19.725 ms
64 bytes from 88.198.46.60: seq=2 ttl=55 time=18.780 ms

--- ping.eu ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 18.780/19.708/20.621 ms
~ #
~ # apk update
fetch http://dl-cdn.alpinelinux.org/alpine/v3.9/main/x86_64/APKINDEX.tar.gz
fetch http://dl-cdn.alpinelinux.org/alpine/v3.9/community/x86_64/APKINDEX.tar.gz
v3.9.6-61-gde0df29a6f [http://dl-cdn.alpinelinux.org/alpine/v3.9/main]
v3.9.6-60-g89c1232642 [http://dl-cdn.alpinelinux.org/alpine/v3.9/community]
OK: 9774 distinct packages available
~ #
~ # exit
tux@testhost:~$
tux@testhost:~$ lxc list
+------------+---------+-----------------+-----------------------------------------------+-----------+-----------+
|    NAME    |  STATE  |      IPV4       |                     IPV6                      |   TYPE    | SNAPSHOTS |
+------------+---------+-----------------+-----------------------------------------------+-----------+-----------+
| alp-router | RUNNING | 10.2.2.1 (eth1) | fd42:1263:16b5:7082:216:3eff:fe86:45d8 (eth1) | CONTAINER | 0         |
|            |         | 10.1.1.8 (eth0) |                                               |           |           |
+------------+---------+-----------------+-----------------------------------------------+-----------+-----------+
| alp-server | RUNNING | 10.2.2.2 (eth0) | fd42:1263:16b5:7082:216:3eff:feaf:7717 (eth0) | CONTAINER | 0         |
+------------+---------+-----------------+-----------------------------------------------+-----------+-----------+
tux@testhost:~$
tux@testhost:~$

~ #
~ # ### Zurück auf dem "alp-router":
~ #
~ #
~ # iptables -vnL POSTROUTING -t nat
Chain POSTROUTING (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target     prot opt in     out     source               destination
    4   265 MASQUERADE  all  --  *      eth0    0.0.0.0/0            0.0.0.0/0
~ #
~ # #   >> Am Paketzähler sieht man deutlich, dass NAT funktioniert.