Gateway mit Linux Network Namespaces

In dieser Anleitung sollen alle nötigen Schritte gezeigt werden, um auf einer nahezu beliebigen Linux Maschine ein Freifunk Gateway in einem separatem Network Namespace zu betreiben. Inspiriert ist die Konstruktion durch diese Anleitung zu Routing mit Wireguard.
== Motivation ==
; Überblick
: Namespaces bieten eine elegante Alternative um auf (vorhandenen) Systemen zusätzlich Freifunk zu integrieren ohne zu schwer ins Hostsystem einzugreifen. Gleichzeitig ist diese Lösung schlanker als eine VM, oder sogar Container, wobei diese Anleitung auch gut als Blaupause für einen Docker-, oder LXC-Container benutzt werden kann. Wer schon einen Linuxrouter betreibt und jetzt zusätzlich ein Freifunknetz zum Beispiel über ein separates VLAN bereit stellen möchte, braucht so keine extra Hardware, hat aber aber trotzdem eine saubere Trennung zwischen seinen Netzen.
; Keine aufwendiges Policy Routing nötig
: Die aktuelle Firmware und andere Anleitungen benutzen Policy Routing, um Routingloops usw. aufzulösen. Die Rules sind kompliziert und müssen separate für IPv4 und IPv6 erstellt werden. Mit Networknamespaces ist dies nicht mehr nötig.
== Namespaces ==
Den meisten sollten Container ein Begriff sein. Mit Containern kann man Prozesse vom Hostsystem isolieren, ohne gleich eine Virtuelle Maschine starten zu müssen. Der Linux Kernel stellt dazu Namespaces bereit, mit denen einzelne Teile des Systems separat vom Hostsystem isoliert werden können. Man kann Beispielsweise die Sicht auf das Dateisystem, Prozesse, Benutzer und eben Netzwerk separat einschränken. Nimmt man alles richtig zusammen, kann man mit diesen Namespaces Container bauen.
Die Liste aller Namespaces findet ihr in der man 7 namespaces man-page.
In dieser Anleitung benutzen wir aber nur den Network Namespace und später den UTS Namespace. Wir behalten also mehr oder weniger die Umgebung bei (Dateisysteme, Prozesse...) und isolieren nur Netzwerk und den UTS Namespace.
Die wichtigsten Programme um mit diesen Namespaces umzugehen sind:
* man 8 ip-netns
* man 1 unshare
* man 1 nsenter
=== Network Namespaces ===
Aus der man 8 ip-netns man-page:
A network namespace is logically another copy of the network stack,
with its own routes, firewall rules, and network devices.
Wir werden einen Networknamespace erstellen, indem sämtlicher Freifunkverkehr verwaltet wird - komplett getrennt vom Hostsystem. 
=== Network Namespace TL;DR ===
 # ip netns add f3
 # ip netns
 f3
 # ip netns exec f3 /bin/bash
 # ip a 
 1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN group default qlen 1000
 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
 # exit
 # ip netns del f3
 # ip netns
 #
In diesem Beispiel wird mit ip netns add f3 ein Network Namespace mit dem Namen "f3" erstellt.
 
ip netns zeigt alle vorhanden Namespaces außer den default Namespace an. 
ip netns exec [NAME] [CMD] startet einen neuen Prozess [CMD] in einem Network Namespace mit dem Namen [NAME]. Im Beispiel wird eine neue Bash im f3 Namespace gestartet.
Ein neuer Namespace hat immer ein unkonfiguriertes lo Interface. Dieses ist nicht das gleiche Interface wie im default Namesapce.
Mit exit oder Ctrl-D wird die Shell beendet und man ist wieder im default Namespace.
ip netns del [NAME] löscht einen Namespace
=== UTS Namespace (Optional) ===
Network Namespaces erstellen leider keinen separaten Hostname zur Verfügung. Dazu braucht es den UTS Namespace. 
 host # touch /tmp/uts
 host # unshare --uts=/tmp/uts hostname f3-test
 host # nsenter --uts=/tmp/uts /bin/bash
 f3-test # exit
 host # umount /tmp/uts
Mit unshare erstellen wir einen neuen UTS Namespace und assoziieren diesen mit der Datei /tmp/uts. Als Befehl geben wir unshare hostname f3-test mit. Dieser Befehl wird in dem neuen Namespace ausgeführt und setzt dort den Hostname zu f3-test.
ns-enter kann jetzt verwendet werden um weitere Prozesse in diesem Namespace zu starten, im Beispiel wieder eine Shell. Wenn eure Shell passend konfiguriert ist und stets euren Hostname anzeigt, dann solltet ihr im Prompt sofort f3-test stehen haben.
Da die ganze Namespacemagie Bindmounts benutzt, kann man mit umount den Namespace wieder löschen. Dazu müssen aber alle Prozesse darin beendet sein, oder umount blockiert.
== TODO ==
* Network Namespace
* UTS Namespace
* wireguard
* babeld
* dnsmasq
* monitoring
* firewall
* shell screencaps