Unterschiedliche Variationen zum Einrichten und Aktivieren einer Netzwerkverbindung nach unterschiedlichen Anfordungen.
Dieses Tutorial richtet sich an erfahrene Linux-Anwender und an engagierte und neugierige Beginner, die die Zusammenhänge in ihrem Netzwerk unter Linux besser verstehen möchten! Für mich ist dieser Artikel keine „wissenschaftlich fundierte Arbeit“, ich befasse mich hierbei eher mit der Intention zu einem Essay mit diesem Thema und gestatte mir dabei einige Freiheiten. Ein wichtiger Hinweis gleich zu Beginn: Die hier besprochenen Lösungen sind nicht selektiv oder alleine für sich anwendbar. Das bedeutet, eine einzelne Lösung ist ohne Berücksichtigung des Kontextes in den hier besprochenen Rahmenbedingungen nicht konfliktfrei einsetzbar.
Inhaltsübersicht über die Kapitel dieses Artikels:
> Feststellen der vorhandenen Netzwerkinterfaces
> Feststellen der für die aktuelle Netzwerkverbindung verwendeten Programme
> Deaktivieren des Default-Setups für Netzwerkverbindungen
Einrichten eines über ...
> ... ETH verbundenen Anwender-PCs via DHCP
> ... ETH verbundenen dedizierten Server-Systems mit Static-IP
> ... WLAN verbundenen stationär genutzten Laptops
> ... ETH verbundenen Anwender-PCs mit lokalen VMs
Virtuelle Maschinen (libvirt/KVM) für den Ad-Hoc-Gebrauch isolierter Anwendungen, z.B. Online- Banking. Die VMs sind reguläre LAN-Clients, sind via Bridge mit dem LAN verbunden und sowohl der Host-PC als auch die VMs beziehen via DHCP eine IP-Adresse vom DSL-Router.
> ... WLAN verbundenen Anwender-PCs mit lokalen Vms
Wie zuvor, nur via WLAN.
> ... WLAN/ETH verbundenen Anwender-PCs mit lokalen Vms
Virtuelle Maschinen (libvirt/KVM) für den Ad-Hoc-Gebrauch isolierter Anwendungen, z.B. Online- Banking. Die VMs laufen in einem vom LAN isolierten Subnet, sind via Bridge verbunden , erfahren aber ein NAT auf dem Host-PC.
> ... ETH verbundenen Servers mit lokalen VMs als dedizierte Systeme
Virtuelle Maschinen (libvirt/KVM) für isolierte Anwendungen, z.B. FTP-Server, Pihole, VPN-Server, oder ähnliches. Die VMs sind reguläre LAN-Clients, sie sind via Bridge mit dem LAN verbunden und sowohl der Host-PC als auch die VMs sind mit im LAN gültigen IP-Adressen eingerichtet. Sowohl Server als auch VMs sind Headless-Systeme, also ohne unmittelbare Interaktion durch User. Der Zugriff auf Server und VMs erfolgt remote. Die VMs werden headless via SSH und VNC eingerichtet.
|
Immer wieder liest man in den verschiedenen Linux-Foren besondere Fragen, die sich mit den scheinbar unlösbaren Problemen bei der Einrichtung einer Netzwerkverbindung befassen. In Wirklichkeit sind die Probleme meistens eher trivialer Natur und wenn man weiß wie, sind sie oft in Sekunden zu beheben. Nur ist gerade bei diesem Sachverhalt ein bestimmter Umstand die Ursache dafür, dass die Probleme tatsächlich scheinbar unlösbar sind, wenn man nicht gerade selber ein Linux-Profi ist.
Selbst bei so harmlosen Problemen, wie
» fehlende Firmware für eine WLAN-Karte
» Netzwerkinterface heißt auf einmal nicht mehr wie erwartet eth0 oder wlan0, sondern hat neuerdings einen kryptischen Namen
» bei multiplen Interfaces gleichen Typs (z.B. wlan0 und wlan1), die den Namen zufällig nach einem Reboot wechseln
» beim Einrichten von statischen IP-Adressen, wofür es 101 unterschiedliche Methoden gibt, die je nach Umfeld falsch oder richtig oder einfach nur wirkungslos sein können
» beim gleichzeitigen Aktivieren mehrerer Interfaces wie eth+wlan, eth+eth, wlan+wlan, virtuelle Inferfaces zusammen mit physischen NICs in verschiedenen Kombinationen, etc.
» bei der grundsätzlich notwendigen Antwort auf die Frage, wie das Netzwerk überhaupt gestartet wird
ist man als Linux-Anfänger mangels Erfahrung und Sachkenntnis schnell hoffnungslos überfordert, dieses Problem zu lösen. Die Ursachen für die scheinbare Unlösbarkeit sind vielfältig.
Tja, solche Randbedingungen verkomplizieren leider durchaus so manches Bemühen bei der Problembeseitigung. Ich möchte diesen Absatz trotzdem keinesfalls als Kritik verstanden wissen, denn das ist es wirklich nicht. Gerade diese unglaubliche Variabilität, gerade diese vielen Möglichkeiten machen aus Linux ein faszinierendes Betriebssystem ohne Grenzen und unnötige Beschränkungen. Wer allerdings ein uniformes Linux will und als Konsequenz diese Variabilität als Hindernis oder sogar als Schlecht empfindet, der hat Linux nicht verstanden – ein solcher User ist definitiv mit Windows besser bedient.
Hier nun mal ein kurzer Überblick über die möglichen und alternativ nutzbaren Wege zur Einrichtung von Netzwerkverbindungen, aus dem man durchaus auch eine Ursache für so manche Irritation und der scheinbaren Unlösbarkeit bei diesem Thema erahnen kann.
Das Netzwerk kann gestartet werden, mithilfe
- systemd-networkd
- des häufig installierten Networkmanagers
- eines von verschiedenen grafischen Networkmanagement-Tools, wie connman, wicd, etc.
- des traditionellem Scripts /etc/init.d/networking, was über den Umweg der historischen runlevels gestartet wird
- der systemd-Unit ifup@service und Einträgen in /etc/networking/interfacess
- manueller CLI-Kommandos aus dem Paket iproute2
- manueller CLI-Kommandos aus dem Paket net-tools, was (trotz Status deprecated) immer noch installiert werden kann
- eigener Scripte
- wpa_supplicant bei WLAN-Verbindungen
Darüber hinaus sind dann oft auch noch unterschiedliche Zusatztools für den Netzwerkbetrieb installiert, völlig unberücksichtigt davon, ob die bei dieser Installation überhaupt sinnvoll sind oder eher nur als verkomplizierende Bloatware betrachtet werden müssen, wie z.B.
- dnsmasq, als schmaler DNS und DHCP-Server, oder
- das mächtige Tool ‚dhcpcd5‘ oder
- die einzeln installierbaren schmaleren Pakete ‚isc-dhcp-client‘ oder ‚isc-dhcp-server‘
Bei der Betrachtung von Abhängigkeiten bestimmter Prozesse zum Netzwerk gibt es ebenfalls völlig unterschiedliche Interpretationen, wie der Umstand „Netzwerk OK“ definiert werden kann, zum Beispiel:
- Netzwerk-Interfaces sind vorhanden, wurden vom Kernel erkannt, Firmware ist OK und sind via systemd-UDEV mit Symlinks versehen.
- Die Interfaces wurde gestartet und deren Status ist von DOWN auf UP gewechselt, z.B. von ifup@service.
- Ein Programm zur Herstellung von Netzwerkverbindungen wurde gestartet, z.B. der Networkmanager.
- Ein solches Programm zur Herstellung von Netzwerkverbindungen hat für ein NIC erfolgreich eine Verbindung hergestellt.
- Was ist mit einem zweiten Netzwerk, wenn z.B. ein WLAN-Interface einen Accesspoint mit Bridge zum ersten NIC herstellen soll?
- Eine IPv4-Adresse wurde für ein NIC vom DHCP-Client angefordert, z.b. von isc-dhcp-client.
- Eine IPv4-Adresse wurde für ein NIC via DHCP erhalten und dem Interface zugewiesen.
- Gibt es ein zweites Interface? Müssen beide NICs für die Feststellung „Netzwerk OK“ verbunden sein?
- Das IPv6-Netzwerk für das Interface ist mit einer Link-Local-Adresse konfiguriert.
- Via Prefix-Delegation wurde ein IPv6-ISP-Prefix empfangen.
- Mithilfe der ‚Stateless Address Autoconfiguration“ (SLAAC) wurde vom Kernel eine IPV6-Adresse generiert.
- Über die eingerichteten IP-Adressen ist ein Default-Gateway erreichbar, IPv4? IPv6? Beide?
- Über die eingerichteten IP-Adressen ist ein bestimmter Server im LAN erreichbar, IPv4? IPv6? Beide?
Jeder einzelne dieser Zustände kann geprüft werden. Jeder einzelne Aspekt kann entsprechend seiner Anforderung das Ergebnis haben „Netzwerk OK“. Und wie man selber den Zustand „Netzwerk OK“ definiert, ist fast willkürlich und allein abhängig von den eigenen Anforderungen oder dem Ziel eines bestimmten Jobs.
Für die meisten Anwender, die gar nicht so sehr in die Tiefe schauen wollen, ist das Netzwerk dann verfügbar und als OK deklariert, wenn z.B. bestimmte Ziele erreichbar sind, egal ob es eine Web-Site im Internet oder der eigene Server im LAN ist. Aber alles auf dem Weg dahin wird oft erst dann wichtig, wenn diese Ziele zum gewünschten Zeitpunkt auf einmal nicht mehr erreicht werden können. Ein häufig auftretendes Problem ist beispielsweise fehlende Firmware für WLAN-NICs oder beim Mount-Befehl auf einen Netzwerk-Share, wenn der Mount-Versuch bereits erfolgt, bevor das eigentliche Ziel (Server) über die fertige und erfolgreich hergestellte Netzwerk-Verbindung erreichbar ist. Das passiert gerne bei langsamen Netzwerk-Starts, bei einer schlechten WLAN-Verbindung oder bei einer vielleicht älteren und insgesamt langsameren Hardware, bei der das Netzwerk einfach seine Zeit braucht.
Alle hier oberhalb aufgeführten Programme haben jeweils irgendwo im Verzeichnis /etc ihre eigenen Konfigurationsdateien, für deren Inhalt mit Parameternamen und jeweiligem Wert bezogen auf die individuelle Interpretation/Auswirkung durch das Programm wiederum keine allgemeingültige Bedeutung besteht … jedes Programm fragt völlig individuell seine Konfigurationsparameter ab und handelt individuell danach, obwohl andere Programme mit ähnlichen Parametern auf anderen Wegen ein absolut gleiches Ergebnis erreichen könnten. Und zu guter Letzt erfordern bestimmte Netzwerk-Schnittstellen bzw. -Anforderungen auch noch spezielle Paketfilterregeln, wenn z.B. virtuelle TUN-Devices bei VPN-Verbindungen via NAT durch das physische Device eines als Server arbeitenden Systems geleitet geleitet werden müssen. Das gleiche gilt, wenn virtuellen Maschinen innerhalb eines ansonsten isolierten Netzwerks via NAT eine Verbindung zum DSL-Router ermöglicht werden soll.
Da fragt man sich doch ernsthaft „wer soll das alles noch überblicken und verstehen?“ Ganz klar ist hierbei zu erkennen, dass man vor dieser Vielfalt an potentiellen Problemquellen als Laie nur noch kapitulieren kann und sich letztlich dann doch immer um Hilfe bemühen muss. Ich habe mir deshalb hier in diesem Artikel vorgenommen, die Basics für Netzwerkverbindungen mal ein wenig zu beleuchten – mit der Hoffnung, dass der eine oder andere danach seine Probleme auf der Grundlage besseren Verstehens selber lösen kann. Dabei beschreite ich allerdings nicht unbedingt den durch die Default-Vorgaben der Distributionen eingeschlagenen üblichen Weg, sondern ich verlasse die eingetretenen Pfade. Ich verlasse sogar sehr konsequent diese Pfade und ich habe dafür eine eigene konkrete Begründung. Meine oberste Prämisse ist: Einfach, Robust und Reproduzierbar! Alles drei reduziert meinen Wartungsaufwand und die Notwendigkeit, sich bei jedem Eingriff erst mal wieder neu in die Materie einlesen zu müssen. Also ist meine persönliche Devise: tue nichts komplizierter, als es unbedingt sein muss… so einfach wie möglich, so kompliziert wie nötig… verwende keine anderen Programme als genau die, die für diese Aufgabe zwingend notwendig sind… wenn man das gleiche mit vorhandenen Board-Mitteln ohne ein zusätzliches Programm erreichen kann, entferne das überflüssige Programm zur Reduzierung der Menge installierter Programme. Das bedeutet, mein allererster Lösungsansatz ist es nicht, Probleme zu lösen, sondern zuerst potentielle Problemquellen zu beseitigen. Sind die beseitigt, befasse ich mich mit einer effizienten, stabilen und störungsarmen Lösung. Ich bitte darum, dass jetzt hier nicht als Empfehlung aufzufassen, es genau so zu tun, ich beschreibe hier lediglich, wie ich diese technischen Probleme gelöst habe und mit welchen Absichten ich das getan habe.
Gerade für die letzte Anforderung (also bezogen auf unnötige Zusatz-Prozesse) findet man sehr schnell eine einleuchtende Erklärung, warum es bei bestimmten Anforderungen durchaus sinnvoll sein kann, auf solche Prozesse zu verzichten und diese unnötigen Programme sogar komplett zu deinstallieren: Ein Samba-Server im lokalen Netzwerk muss für die Clients natürlich immer unter der gleichen IP-Adresse erreichbar sein, dafür verwendet man auf diesem System idealerweise eine statische IP-Adresse. Das kann man sehr leicht mit einem einzeiligen Befehl erreichen, der beim Start des Systems ausgeführt wird. Für diese Mini-Aufgabe hat Debian bereits alles an Board, es ist nicht notwendig, irgendwas hinzu zu installieren… auch nicht einen als Daemon laufenden dhcp-client, damit man die gewünschte statische IP in dessen Konfiguration eintragen kann, damit das Programm dann am Ende diesen einzeiligen Befehl ausführt. Die Kernfrage ist, wozu benötigt man überhaupt einen dhcp-Daemon als dhcp-Client, wenn das Netzwerkinterface doch sowieso eine statische IP-Adresse erhalten soll? Oder welchen sinnvollen Zweck erfüllt überhaupt avahi, wenn der Rechner patchkabelverbunden als stationärer dedizierter Server mit Static-IP betrieben werden soll… ?… die Antworten lauten: braucht man nicht! gar keinen! Also ist besser gefragt: welche Anforderungen an bestimmte Netzwerkeigenschaften erfordern besondere zusätzliche Programme, welche meist obligatorisch installierten Programme sind vor dem beabsichtigten Einsatzzweck hingegen vollkommen überflüssig?
Und als wichtigster Aspekt ist noch einmal festzustellen, dieser Artikel spiegelt nur meine Meinung darüber, warum ich auf welchen Wegen die Probleme löse, es ist auf keinen Fall eine Empfehlung, alles andere über Bord zu werfen und es genau so zu tun. Das Ziel dieses Artikels ist es, Zusammenhänge zu verstehen, Lösungsalternativen bewerten und einschätzen zu können und am Ende darüber die eigenen Probleme erfolgreich zu beseitigen.
|
Schauen wir uns nun das folgende Bild an, um etwas besser zu verstehen, welche möglichen Zielsetzungen für welche Geräte innerhalb eines privaten Netzwerks gelten könnten:
Wir sehen hier oberhalb eine Netzwerk-Darstellung, die vermutlich in den wesentlichen Bestandteilen den weitaus größten Anteil aller privaten Netzwerke relativ übereinstimmend abbildet, unabhängig davon, ob im Einzelfall vielleicht mehr/andere Geräte verwendet werden, im anderen Fall weniger. Nicht die Anzahl der Geräte definiert, was ein Netzwerk ist, sondern die Art und Weise der Verbindung und der Kommunikation untereinander – hinsichtlich der Netzwerk-Topologie wird das also weitestgehend passen. Zum einen sind es also ein oder mehrere mobile Geräte, die sich via WLAN mit einem handelsüblichen DSL-Router verbinden, zum zweiten sind es ein bzw. mehrere stationäre PCs, die via Patchkabel mit dem Router verbunden sind. Es ist zusätzlich ein zentraler File-Server zur Speicherung von Dateien (SAMBA oder NFS) eingerichtet, weiterhin vielleicht ein VPN-Server für den Zugang ins heimische Netzwerk über das Internet, vielleicht auch noch ein VM-Server, der virtuelle Maschinen für unterschiedliche isolierte Aufgaben betreibt, oder ein Print-Server für den angeschlossenen Drucker. Das können jeder für sich durchaus physisch vorhandene, separate echte Maschinen sein, die als dedizierte Server aktiv sind, oder es sind nur virtuelle Maschinen, die innerhalb eines physischen PCs eingerichtet sind. Ebenso können die verschiedenen Server-Funktionalitäten durchaus auch alle von einer einzelnen Maschine geleistet werden – sofern sie ausreichend leistungsfähig ausgestattet ist. Die mit roter Bezeichnung versehenen Systeme sind die, die als Geräte mit Service-Funktion von den Client-Systemen gezielt und reproduzierbar angesprochen werden müssen/sollen, die wir also immer unter der gleichen IP-Adresse finden wollen.
Rein technisch betrachtet sind alle dargestellten Geräte, egal welche Aufgabe sie unseren Wünschen entsprechend zu erfüllen haben, letztlich dennoch nur gleichwertige Clients unseres zentralen DSL-Routers. Der Router ist das Gerät, welches die lokale Netzdomain repräsentiert und der als Standard-Gateway das Tor ins Internet darstellt – für den Router gibt es kein niederwertig oder höherwertig, client ist client. Aber durch die Tatsache, dass gleich trotzdem noch lange nicht gleich bedeutet und wir die Geräte mit besonderen Aufgaben priorisieren, existieren schließlich durch unsere Anforderungen und durch unsere Vorstellung über die Geräte doch noch konkrete Unterschiede – aber man muss verstehen, dass diese Unterschiede primär nur in unserem Denken über diese Hardware existieren.
Einer der wichtigsten Unterschiede ist: Bestimmte Systeme sind von uns als End-User-Geräte vorgesehen, mit Bildschirm, Tastatur und Maus und bestimmte andere Systeme arbeiten als headless eingerichtete Server-Systeme, die weder über Eingabegeräte noch über einen Bildschirm verfügen. An diesen Headless-Systemen melden sich üblicherweise (und sinnvollerweise) auch keine User zur Erledigung normaler Desktop-Aufgaben an, die Zugriffe auf diese Systeme erfolgen nicht durch physische Interaktion und im Dialog vor Ort, sondern nur auf digitalen Wegen über die Netzwerkkommunikation. Und gerade deshalb müssen diese Headless-Systeme innerhalb des lokalen Netzwerks immer auf die gleiche Weise ansprechbar oder erreichbar sein. Das betrifft also alle als Server im LAN arbeitenden Systeme. Wenn ich z.B. beim Start meines Arbeitsplatz-PCs die Netzwerklaufwerke meines Files-Servers via Mount-Units automatisch verbunden haben möchte, so muss der Server natürlich konsequent immer unter der gleichen IP-Adresse im Netzwerk erreichbar sein. Das gleiche gilt ebenso für alle anderen als digitale Dienstleister arbeitenden Systeme, die von anderen Maschinen im LAN via IP-Adresse erreichbar sein müssen, z.B. bei SSH-Zugriffen zur Fernwartung an Headless-Systemen, bei Remote-Desktop-Zugriffen, bei lokalen Mail-Servern, bei einem Print-Server, beim Blick auf den Camera-View.
Die Notwendigkeit, dass einzelne Systeme eine statische IP im lokalen Netzwerk benötigen, ist allerdings im Default-Verhalten eines handelsüblichen DSL-Routers oft nicht automatisch berücksichtigt. Korrekterweise arbeitet der Router meistens zunächst einmal als DHCP-Server. Das bedeutet, wenn sich ein Client-Gerät im Netzwerk anmeldet, vergibt der Router automatisch eine freie IP-Adresse und beachtet dabei, dass diese IP-Adresse momentan einmalig im Netzwerk vergeben ist, um einen konfliktfreien Datenverkehr zu gewährleisten. Das bedeutet aber manchmal auch, dass die vom Router vergebene IP-Adresse für ein Client-Gerät an einem Tag anders sein kann, als sie am Vortag war. Normalerweise kann man in der Web-Oberfläche des Router eine Einstellung vornehmen, womit für ein bestimmtes Client-Gerät immer die gleiche IP-Adresse reserviert wird - dann würde das Gerät immer die gleiche IPAdresse erhalten. Aber manchmal möchte man auch IP-Adressen zur leichteren Erinnerung manuell fest vorgeben und nicht die pseudostatischen verwenden, die der Router nach seinem Ermessen vergeben hat. Aus der Sicht eines Client-Gerätes wären das nämlich trotzdem keine echten statischen IPs, sondern weiterhin eine vom Router per DHCP-Server zugewiesene – nur wird die aller Voraussicht nach immer gleich bleiben.
Gleichbleibend zu meinen anderen Artikeln verwende ich auch hier wieder das Lokale Netzwerk 10.0.1.0/24 als Test-Umgebung. Der Test-PC, den ich nacheinander mit unterschiedlichen Variationen malträtiere, hat kontinuierlich die u.g. IP-Adresse.
IP-Range des lokalen Heimnetzwerks: 10.0.1.0/24 Default-Gateway: 10.0.1.1 IP-Adresse lokaler Test-PC: 10.0.1.56 $ date Mi 17. Jun 14:27:54 CEST 2020 $ lsb_release -a Distributor ID: Debian Description : Debian GNU/Linux 10 (buster) Release : 10 Codename : buster $ ip r s | grep default default via 10.0.1.1 dev eth0 |
Manchmal hat man also eigene Vorstellungen, nach welcher Logik feste IP-Adressen verwendet werden sollen. Zum Beispiel sollen die dafür relevanten Geräte im 4. Segment der IP eine konstante, unserer eigenen Vorstellung der Netzwerk-Logik entsprechende Ziffer erhalten:
10.0.1.1 | für den DSL-Router |
10.0.1.2 | für den Fileserver |
10.0.1.3 | für den Druck-Server |
10.0.1.4 | für den lokalen DNS mit Pihole |
10.0.1.10 und 10.0.1.11 | für zwei IP-Cams |
10.0.1.20, 10.0.1.21 und 10.0.1.22 | für drei headless auf dem Server betriebene virtuelle Maschinen |
10.0.1.50 bis 10.0.1.99 | für alle normalen Client-Geräte eine flexibel zugeteilte IP-Adresse via DHCP |
Ich persönlich halte es jedenfalls nicht für sinnvoll, ausnahmslos für alle Geräte statische IP-Adressen vorzusehen. Das würde mir viel zu viel sinnlose Wartungsarbeit bereiten. Aus technischer Sicht hat das auch überhaupt keine Vorteile, und auch sicherheitstechnisch ist das m.M.n. völlig irrelevant. Die tatsächlichen Vorteile statischer IP-Adressen bei einigen ausgewählten Geräten sind rein subjektiver, menschlicher Natur … man erinnert sich halt leichter, die Handhabung wird für mich als Anwender und Chef-Betreuer im Heimnetzwerk leichter. Aber weil ich z.B. unsere Smartphones überhaupt nicht über das Netzwerk erreichen muss und die selber meistens nur Internet-Clients sind, ist mir letztlich völlig egal, welche IP-Adresse der Router denen bei Aktivierung des Handy-WLANs vergibt. Das gleiche betrifft beispielsweise meinen eigenen PC … welche lokale IP-Adresse der im LAN hat, ist doch wirklich so unwichtig, wie nur irgendwas. Ich will nur alle Systeme mit Server-Funktionen immer unter konstant gleicher IP-Adresse erreichbar haben, alles andere ist mir dabei relativ egal.
|
Feststellen der vorhandenen Netzwerkinterfaces
Bei der erstmaligen Einrichtung einer Netzwerkverbindung auf einem Linux-System, ebenso beim Untersuchen von Problemen oder beim Beseitigen von Störungen, ist ausnahmslos und grundsätzlich und wirklich immer die erste Maßnahme, den Ist-Zustand der Netzwerkinterfaces (NIC) festzustellen. Die Kenntnis über die Namen der Interfaces, deren Verbindungsstatus und ggf. auch die MAC-Adressen sind meiner Meinung nach zwingend notwendig. |
Selbstverständlich kann man auch vieles über die im Desktop-Environment implementierten grafischen Dialoge ermitteln, aber leider führt die Vielfalt solcher Benutzerschnittstellen in den Distributionen häufig viel schneller zur Verwirrung, als das sie wirklich hilfreich bei einer Diagnose sind. Darüber hinaus vertrete ich die Meinung, dass das Tun und Ergebnis eines GUI-Dialogs für mich als Anwender häufig sehr intransparent ist… weil ich meistens nicht erkennen kann, welcher Parameter (wie heißt der?), mit welchem Inhalt (ist tatsächlicher Value und Anzeige im Dialog identisch?), in welcher Konfigurationsdatei (wo ist sie gespeichert?), mit welchen Auswirkungen (gibt‘s auch andere Möglichkeiten?) geändert wird.
Und wie ich schon sagte, sehr oft unterstützen solche Dialoge entweder nur die Anforderungen an simple Basic-Funktionen oder sie erschlagen mich mit einer unübersichtlichen bunten Vielfalt und Möglichkeiten, wobei ich mich doch eigentlich viel mehr auf die Lösung eines bestimmten Problems fokussieren möchte. Für mich ist das Grund genug, auf solche Dialoge zu verzichten und die Probleme an der Wurzel anzugehen… also direkt im Betriebssystem. Diese Prämisse gilt übrigens grundsätzlich und ist meine bevorzugte Vorgehensweise… ich will wissen, welches Programm was tut, wie ich das beeinflussen kann, was ich an welchen Stellen dafür tun muss und ob so ein Programm am Ende vielleicht auch nur ein eigentlich überflüssiges Komfort-Tool ist. Gerade bei den reinen Komfort-Tools bin ich der Meinung, dass man bei günstigen Bedingungen besser damit bedient ist, wenn man genau darauf verzichtet. Das ist letztlich dann auch die Vorgehensweise, die mir im Laufe der Zeit in gewissen Grenzen ermöglicht hat, das Betriebssystem meines PC deutlich besser zu verstehen und ihn deswegen insgesamt auf sicherere und sehr störungsarme Weise zu betreiben.
Die folgende Liste zeigt die zwei gefundenen und für Netzwerkverbindungen geeigneten Interfaces auf meinem Test-PC. Die Bezeichnungen eth0 und wlan0 sind i.ü.S. nicht mehr als nur die aktuellen bezeichnenden Eigenschaften bestimmter Hardware auf diesen PCs. Auf einem anderen PC können andere Bezeichnungen angezeigt werden. Das ist aber unproblematisch, es handelt sich hierbei nur um symbolische Namen, mit denen wir eine bestimmte Hardware ansprechen können.
$ ip link show | grep -i broadcast 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 3: wlan0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000 |
Ein Beispiel ohne aktive Netzwerkverbindungen:
$ ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever 2: eth0: <BROADCAST,MULTICAST> mtu 1500 qdisc pfifo_fast state DOWN group default qlen 1000 link/ether d0:3g:ff:9a:xy:zz brd ff:ff:ff:ff:ff:ff 3: wlan0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000 link/ether dd:1e:ca:ae:08:6b brd ff:ff:ff:ff:ff:ff |
Ein Beispiel mit aktiver WLAN-Verbindung in einem IPv4-LAN:
$ ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever 2: eth0: <BROADCAST,MULTICAST> mtu 1500 qdisc pfifo_fast state DOWN group default qlen 1000 link/ether d0:3g:ff:9a:xy:zz brd ff:ff:ff:ff:ff:ff 3: wlan0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000 link/ether 08:0766b:bb:kk:ae brd ff:ff:ff:ff:ff:ff inet 10.0.1.38/24 brd 10.0.1.255 scope global dynamic wlan0 valid_lft 863977sec preferred_lft 863977sec |
Ein Beispiel mit aktiver kabelgebundener Netzwerkverbindung mit IPv4 und IPv6:
$ ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 link/ether d0:3g:ff:9a:xy:zz brd ff:ff:ff:ff:ff:ff inet 10.0.1.56/24 brd 10.0.1.255 scope global dynamic eth0 valid_lft 863991sec preferred_lft 863991sec inet6 2022:1687:6219:h500:15a8:622:3040:c8db/64 scope global temporary dynamic valid_lft 7187sec preferred_lft 3587sec inet6 2022:1687:6219:h500:d23g:ffff:fe9a:xyzz/64 scope global dynamic mngtmpaddr valid_lft 7187sec preferred_lft 3587sec inet6 fe80::d23g:ffff:fe9a:xyzz/64 scope link valid_lft forever preferred_lft forever 3: wlan0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000 link/ether dd:1e:ca:ae:08:6b brd ff:ff:ff:ff:ff:ff |
Betrachten wir kurz, welche Informationen im letzten Beispiel enthalten sind:
- Es werden 3 Netzwerkinterfaces gelistet:
1: lo – das loopback-Interface zur systeminternen Kommunikation
2: eth0 – ein kabelgebundenes Netzwerkinterface zur externen Kommunikation
3: wlan0 – ein mit Funk arbeitendes Netzwerkinterface zur externen Kommunikation
- Das via Patchkabel mit einem Netzwerk verbundene Interface eth0 zeigt an zwei Stellen den Status ‚UP‘. Das erste bezieht sich auf den physischen Status des Interfaces, es ist also grundsätzlich betriebsbereit. Die aktuelle Eigenschaft ‚state UP‘ bezieht sich auf den Status einer Netzverbindung, UP=verbunden, DOWN=nicht verbunden
- Beim aktiv verbundenen Interface eth0 lautet die
- MAC-Adresse: d0:3g:ff:9a:xy:zz
- lokal gültige IPv4: 10.0.1.56
- global gültige temporäre IPv6 (privacy extensions): 2022:1687:6219:h500:15a8:622:3040:c8db
- global gültige reguläre IPv6 (MAC-Related): 2022:1687:6219:h500:d23g:ffff:fe9a:xyzz
- lokal gültige Link-Local-Adresse: fe80::d23g:ffff:fe9a:xyzz
- Das Interface wlan0 ist derzeit nicht mit einem Netzwerk verbunden
Das bei den IP-Adressen angezeigte Attribut ‚global‘ ist leider ein wenig irritierend. Denn hinsichtlich der IPv4-Adresse, die oberhalb auch mit „global“ bezeichnet ist, besteht die Besonderheit, dass diese eben nicht global gültig ist. Von der IANA wurden bereits 1994 drei private IP-Adressbereiche festgelegt, die bis heute noch gültig sind. Jeder der drei Bereiche liegt in einer anderen Klasse des historischen (!) Netzklassen-Konzepts. Mittels Subnetmasks unter der Prämisse „Classless Inter-Domain Routing (CIDR)“ besteht heute allerdings höchste Flexibilität darin, beliebig verkleinerte Netze im gesamten reservierten Adressraum zu definieren. In der folgenden Tabelle wird jetzt deutlich, dass die oberhalb festgestellte IPv4-Adresse 10.0.1.56/24 nur eine im privaten Netzwerk nutzbare IP-Adresse ist, die keinen Zugang zum Internet ermöglicht.
Reservierte Adressbereiche für IPv4. Beispiele:
Netzadressbereich | CIDR-Notation | Historische Netzklasse | Zweck |
10.0.0.0 bis 10.255.255.255 172.16.0.0 bis 172.31.255.255 192.168.0.0 bis 192.168.255.255 | 10.0.0.0/8 172.16.0.0/12 192.168.0.0/16 | A B C | Private Adressen für lokale Netzwerke ohne Zugang zum öffentlichen Adressraum (Internet) |
169.254.0.0 bis 169.254.255.255 | 169.254.0.0/16 |
| Link-Local-Addresses haben nur Gültigkeit innerhalb abgeschlossener Netzwerksegmente |
127.0.0.0 bis 127.255.255.255 | 127.0.0.0/8 |
| Loopback-Addresses = localhost, die Selbst-Adresse eines Hosts/NICs |
224.0.0.0 bis 239.255.255.255 | nicht definiert (Leading-Bits 1110) |
| Multicast-Adressen |
Lokal bedeutet also, diese IPv4-Adresse ist immer nur im lokalen Netzwerk gültig und wird nicht ins Internet geroutet. Global bedeutet hingegen, diese Adresse ist sowohl im lokalen Netzwerk gültig und sie wird auch ins Internet geroutet. Globale IP-Adressen sind deshalb im Moment der Verwendung weltweit gültig und in diesem Moment definitiv immer exklusive und einmalige Unikate. Lokale Adressen hingegen müssen zum Zeitpunkt der Verwendung nur im lokalen Netzwerk einmalig und exklusiv für ein einzelnes Netzwerkinterface sein. Aus globaler Perspektive betrachtet, also mit Blick auf die restliche Welt, könnte diese gleiche lokale IP-Adresse noch tausende Male zur gleichen Zeit in anderen privaten Netzen existieren.
Bei Anfragen durch unseren PC an Empfänger im Internet (z.B. Web-Seiten über Firefox oder zum Mailhoster mit Thunderbird, etc.) werden solcherart private Absender-IPv4-Adressen durch den DSL-Router mit der öffentlichen IP-Adresse des DSL-Routers im Rahmen der Network-Address-Translation (NAT) ersetzt. Die Empfänger im Internet sehen also nicht die lokale/private IP des PCs, sondern nur die öffentliche, exklusive, einmalige IP des DSL-Routers. Im Gegensatz dazu ist bei Anfragen ins Internet über IPv6-Global-Unicast-Addresses der Kontakt zwischen den Geräten quasi End-to-End. Beide Seiten sehen die jeweils öffentliche IP der Gegenseite. Wobei es uns nicht möglich ist festzustellen, ob für das eigentliche Zielsystem der Gegenseite nicht trotzdem auch NAT durchgeführt wird.
Ein paar ergänzende Information mit bildlicher Darstellung über das Thema NAT sind weiter < unten > im Artikel und auch in meinem Artikel < security > enthalten.
Ganz allgemein wird gesagt, das NAT in Verbindung mit der bei IPv4-DSL-Accounts täglich üblichen Zwangstrennung eine gewisse Datenschutzfunktion innehat. Dieser Gedanke setzt allerdings voraus, dass es keine andere Möglichkeiten der Wiedererkennung und des Trackings geben würde. Die gibt es aber leider. Und vermutlich hat NAT gegen das Tracking deswegen wohl eine eher untergeordnete Relevanz. Wer sich beispielsweise nicht über die Möglichkeiten des Browser-Fingerprints bewusst ist, oder die Gefahr durch Cookies, oder durch eindeutig identifizierbare Surface-Daten, oder der Meldung „ich bins“ durch verwendete und ggf. gesendete Werbe-ID-Kennziffern (in einem den Datenschutz missachtenden Programm/PlugIn/AddOn), der braucht sich über die Sicherheit durch NAT wahrscheinlich auch keine weiteren Gedanken zu machen. Nichtsdestotrotz kann man natürlich auch die Wiedererkennung durch eine quasi-statisch gleichbleibende IPv6-Adresse (Interface-ID), die gebunden an die MAC-Adresse maschinell durch SLAAC erzeugt wurde, durchaus mit der Verwendung der Privacy Extensions erschweren. Aber auch das eliminiert nicht die anderen real existierenden Tracking-Risiken. Speziell zum Thema IP-Adressen sind < hier > noch ein paar weitere Informationen enthalten.
Wie zuvor gibt es auch für IPv6-Adressen reservierte Bereiche. Beispiele:
Netzadressbereich | Zweck | |
fe80::/64 | LLA | Link-Local-Adresses haben nur Gültigkeit innerhalb abgeschlossener Netzwerksegmente |
fc00::/7 (fc00... bis fdff...) | ULA | Unique Local Addresses für lokale Netzwerke bzw. über Tunnel verbundene lokale Netze ohne Zugang zum öffentlichen Adressraum (Internet) |
2000::/3 (2000... bis 3fff...) | GUA | Global Unicast Addresses für die Verwendung im öffentlichen Adressraum (Internet) |
::1/128 | lo | Loopback = localhost, die Selbst-Adresse eines Hosts/NICs |
ff00::/8 (ff...) |
| Multicast-Adressen |
Unter Debian und den durch systemd vorgegebenen Spielregeln für „Predictable Network Interface Names“, mit denen der Name eines Interfaces reproduzierbar vorhergesagt werden kann, ist es durchaus normal, dass im Gegensatz zu früher die Interfaces nicht mehr eth0 oder wlan0 heißen, sondern einen von der Hardware abhängigen Namen verwenden. Das bedeutet, der früher vom Kernel ermittelte Name des Netzwerkinterfaces lautet nicht mehr in zählweise aufsteigend eth* oder wlan*, sondern ist Firmware-, Topologie-, Ortsinformationsabhängig. Das hat durchaus einige Vorteile, es kann aber in Einzelfällen geradezu kryptische Ausmaße annehmen:
$ ip link show | grep -i broadcast 2: eth0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000 3: wlp2s87554345532ac0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP mode DORMANT group default qlen 1000 $ ip a s dev wlp2s87554345532ac0 | grep 'link/ether' link/ether dd:1e:ca:km:08:xy brd ff:ff:ff:ff:ff:ff |
Denn wie hier im oberen Beispiel benannt ist der Name wlp2s87554345532ac0 des WLAN-Interfaces in keinster Weise von Vorteil. Im Gegenteil, so ein Namens-Unglück ist denkbar anwenderunfreundlich, man kann ihn sich kaum merken, jegliche Handhabung, also auch die Administration des Netzwerks, wird damit erschwert. Wenn ein NIC maschinell so unmöglich bezeichnet wurde, ist es angebracht, dass auf eine leichtere Bezeichnung zu ändern.
Die Umbenennung des NICs auf einen freundlicheren Namen ist schnell passiert. Dazu wird die folgende Datei angelegt und der neue Name wird an die MAC-Adresse des Interfaces gebunden. Weil MAC-Adressen weltweit einmalig sind, kann es später bei der Identifikation des Interfaces auch nicht mehr zu Verwechselungen kommen, falls im Rechner gelegentlich noch ein zweites WLAN-Interface verwendet wird.
$ su - # nano /etc/systemd/network/10-wlan0.link | |
| [Match] MACAddress=dd:1e:ca:km:08:xy Type=wlan
[Link] Name=wlan0 |
Nach dem reboot des System sollte das Netzwerkinterface dann diesen manuell vorgegebenen Namen innehaben, was man wiederum mit dem obigen ip-Kommando bestätigen kann. Hier ist unbedingt zu beachten, das an den vorherigen Name gebundene alte Verbindungen jetzt nicht mehr funktionieren.
|
Feststellen der für die aktuelle Netzwerkverbindung verwendeten Programme
Neben dem zuvor erworbenen Wissen über die vorhandene Hardware (und bevor auch nur an irgendeiner Stelle irgendetwas verändert wird), ist es eben so unerlässlich, unbedingt den Istzustand der verwendeten Software festzustellen. Zuerst haben wir uns also angesehen, welche Netzwerkinterfaces vorhanden sind und mit welchem symbolischem Namen wir mit einem bestimmten Interface umgehen müssen, als nächstes befassen wir uns mit der dafür notwendigen bzw. bisher verwendeten Software. Dabei ist der wichtigste Aspekt die Firmware, oder -mit anderen Worten gesagt- die Hardware-Treiber. Ohne die entsprechende Firmware ist es nicht möglich, ein Netzwerkinterface in Betrieb zu nehmen.
$ su - # nano /etc/apt/sources.list deb http://deb.debian.org/debian/ buster main contrib non-free deb http://security.debian.org/debian-security buster/updates main contrib non-free deb http://deb.debian.org/debian/ buster-updates main contrib non-free # apt update # apt full-upgrade |
Im folgenden als Beispiel konstruierten Journalauszug erkennen wir, dass die Netzwerkverbindung weder Kabelgebunden noch via Funk möglich wäre, weil die entsprechenden Hardware-Treiber (Firmware) fehlt. Weiterhin sehen wir, dass hier der Networkmanager erfolglos versucht hat, eine Verbindung herzustellen.
# journalctl -b | grep -i "firmware" Jul 07 14:19:55 tomspc dhclient[466]: Failed to get interface index: No such device Jul 07 14:19:56 tomspc kernel: r8169 0000:03:00.0: firmware: failed to load rtl_nic/rtl8168e-3.fw Jul 07 14:19:56 tomspc kernel: iwlwifi 0000:05:00.0: firmware: failed to load iwlwifi.ucode (-2) Jul 07 14:19:56 tomspc kernel: iwlwifi 0000:05:00.0: Direct firmware load for iwlwifi.ucode failed with error -2 Jul 07 14:19:56 tomspc NetworkManager[380]: <warn> device (wlan0): firmware may be missing. |
# apt search rtl_nic/rtl8168e firmware-realtek/stable,now 20190114-2 Binary firmware for Realtek wired/wifi/BT adapters # apt search iwlwifi firmware-iwlwifi/stable 20190114-2 Binary firmware for Intel Wireless cards # apt install firmware-realtek firmware-iwlwifi # systemctl reboot |
Im nächsten Schritt versuchen wir festzustellen, welche Programme bisher entweder eine Netzwerkverbindung erfolgreich herstellen können oder welche Programme es zumindest versuchen und aufgrund von Fehlern scheitern.
Für eine erste Diagnose zur Feststellung des Istzustands empfehle ich ‚systemctl‘ zur Abfrage der von systemd automatisch in der Bootphase gestarteten Dienste zu verwenden. Es handelt sich hier um die jeweiligen Ausgaben auf verschiedenen PCs. # systemctl -l | egrep -i "network|connect" |
1. Auf meinem Laptop wurde zum Beispiel der im Bash-Foreground laufende Network-Manager selnic gestartet: |
selnic.service loaded active exited Connect to Network (Wired or WLAN-SSID) |
2. Auf diesem System wurde das sysv-Script /etc/init.d/networking gestartet: |
networking.service loaded active exited Raise network interfaces |
3. Auf diesem PC wird das Netzwerk durch systemd-networkd.service gestartet. |
systemd-networkd.service loaded active running Network Service |
4. Auf diesem PC wurde der Network-Manager und das sysv-Script /etc/init.d/networking gestartet: |
networking.service loaded active exited Raise network interfaces NetworkManager.service loaded active running Network Manager |
5. Auf diesem PC wird das Netzwerk durch eine Custom-Service-Unit gestartet: |
network.service loaded active exited thlu: Start network connectivity |
6. Auf diesem PC wurde der Network-Manager ‚connman‘ und das sysv-Script /etc/init.d/networking gestartet: |
connman.service loaded active running Connection service networking.service loaded active exited Raise network interfaces |
Stellvertretend für alle obigen Varianten schauen wir uns nur den Status der Service-Units des letzten Systems an. Die Vorgehensweise ist bei allen anderen immer gleich. |
# systemctl status connman.service ● connman.service - Connection service Loaded: loaded (/lib/systemd/system/connman.service; enabled; vendor preset: enabled) Active: active (running) since Wed 2020-07-08 18:50:41 CEST; 52s ago Main PID: 414 (connmand) CGroup: /system.slice/connman.service └─414 /usr/sbin/connmand -n
Jul 08 18:50:42 lxqt connmand[414]: enp1s0 {add} route fe80:: gw :: scope 0 <UNIVERSE> Jul 08 18:50:44 lxqt connmand[414]: enp1s0 {add} route 2022:1687:6219:h500:: gw :: scope 0 <UNIVERSE> Jul 08 18:50:46 lxqt connmand[414]: enp1s0 {add} address 2022:1687:6219:h500:d23g:ffff:fe9a:xyzz/64 label (null)
# systemctl status networking.service ● networking.service - Raise network interfaces Loaded: loaded (/lib/systemd/system/networking.service; enabled; vendor preset: enabled) Active: active (exited) since Wed 2020-07-08 18:50:41 CEST; 8min ago Process: 333 ExecStart=/sbin/ifup -a --read-environment (code=exited, status=0/SUCCESS) Main PID: 333 (code=exited, status=0/SUCCESS)
Jul 08 18:50:41 lxqt systemd[1]: Starting Raise network interfaces... Jul 08 18:50:41 lxqt systemd[1]: Started Raise network interfaces. |
Zusätzlich empfehle ich, auch einen Blick ins Journal zu werfen. Um einen Eindruck von den möglichen Ergebnissen bei der Suche im Journal zu vermitteln, beschreibe ich hier im folgenden die Log-Auszüge von verschiedenen Systemen, welches jedes für sich das Netzwerk auf eine eigene Art startet. # journalctl -b | egrep -i "network|connection" |
1. Der folgende Journal-Auszug deutet auf das alte sysv-Script /etc/init.d/networking in Verbindung mit ifup@.service hin: |
Jun 23 14:10:57 pc1 systemd[1]: Started Raise network interfaces. Jun 23 14:10:57 pc1 systemd[1]: Reached target Network. |
|
2. Auf diesem PC wird das Netzwerk durch systemd-networkd gestartet: |
Jun 23 14:49:04 pc2 systemd[1]: Started Network Service. Jun 23 14:49:04 pc2 systemd[1]: Reached target Network. |
|
3. Auf diesem PC wird das Netzwerk durch den Netzwerk-Manager ‚connman‘ gestartet: |
Jun 23 14:17:30 lxqt systemd[1]: Started Connection service. Jun 23 14:17:30 lxqt systemd[1]: Reached target Network. Jun 23 14:17:30 lxqt connmand[448]: Connection Manager version 1.36 |
|
5. Auf diesem Laptop wird das Netzwerk durch den Bash-Netzwerk-Manager ‚selnic‘ gestartet: |
Jun 23 14:06:55 lappi systemd[1]: Started thlu:selnic.service: Connect to Network (Wired or WLAN-SSID). Jun 23 14:06:55 lappi systemd[1]: Reached target Network. |
|
4. Auf meinem PC wird das Netzwerk aufgrund besonderer Anforderungen durch eine spezielle Service-Unit gestartet: |
Jun 23 14:17:00 thomaspc systemd[1]: Started thlu:network.service Start network connectivity. Jun 23 14:17:00 thomaspc systemd[1]: Reached target Network. |
Weil man nun anhand der überall sehr ähnlichen Log-Texte kaum unterscheiden kann, welcher Prozess letztlich für den Start des Netzwerks verantwortlich ist, kann sich diese spezielle Diagnose durchaus ein wenig anspruchsvoll gestalten. Aber die Kombination aus Journaleinträgen und der Liste gestarteter Service-Units sollte allemal ausreichen, um sich ausreichend Klarheit zu verschaffen. Wir sollten an diesem Punkt angekommen nun eindeutig wissen, welche Netzwerk-Hardware installiert ist und welche Programme sich bisher um die Herstellung einer Netzwerksverbindung gekümmert haben. Mit den nun folgenden nächsten Schritten werden die Voraussetzungen geschaffen, das Netzwerk erstmalig unmittelbar und direkt zu starten, um dann anschließend die in dieser Distribution als Default-Programme installierten Mechanismen zu deaktivieren.
|
Einrichten eines über ETH verbundenen Anwender-PCs via DHCP
Sitzen wir allerdings gerade an einem normalen Desktop-PC, mit Bildschirm, Tastatur und Maus, kann eigentlich nicht viel passieren, wir können ganz entspannt alle Arbeiten ausführen, ohne dabei ein großes Risiko einzugehen, irgendwas unwiderruflich kaputtzumachen. Wenn jetzt hierbei wirklich ein Fehler passiert, alles kein Problem, wir können ja jederzeit alle Änderungen wieder rückgängig machen und darüber dann erreichen, dass nach einem Restart des Rechners wieder der Default-Zustand besteht – einschließlich entweder der aktiven Netzwerkverbindung oder auch der zuvor bestehenden Probleme. Also gilt folgende Devise: Sehr, sehr sorgfältig bei einer Headless-Einrichtung arbeiten. Und trotzdem auch sehr sorgfältig bei jeder anderen Einrichtung arbeiten, auch wenn wir diese direkt an Tastatur und Bildschirm wieder reparieren könnten.
Achtung! Sowohl diese als auch alle weiteren folgenden Service-Units sind nicht konfliktfrei mit anderen das Netzwerk startenden Programmen. Das bedeutet als Voraussetzung, wenn diese oder eine der folgenden Service-Units aktiviert werden sollen, müssen vorher ggf. konkurrierende Programme oder Dienste deaktiviert werden. Die dazu notwendigen Maßnahmen sind im nächsten Kapitel beschrieben.
Zielvorstellung bzw. beabsichtigter Verwendungszweck für diese Service-Unit: Stationäre kabelverbundene PCs, die eine lokale IPv4-Adresse bzw. einen IPv6-Prefix vom DHCP-Server (DSL-Router) beziehen. |
$ su - # nano /etc/systemd/system/network.service [Unit] Description=thlu:network.service: Start network connectivity After=basic.target Before=network.target shutdown.target Wants=network.target
[Service] Environment="PATH=/bin:/usr/sbin:/usr/bin" Type=oneshot RemainAfterExit=yes
ExecStartPre=ip link set dev eth0 up ExecStart=dhclient -4 eth0
ExecStop=dhclient -r eth0 ExecStopPost=ip link set dev eth0 down
[Install] WantedBy=multi-user.target
|
# cd /etc/systemd/system # systemctl start network.service | Neue Netzwerkverbindung aktivieren Teststart, um auf Fehler zu prüfen |
# systemctl status network.service ● network.service - thlu:network.service: Start network connectivity Loaded: loaded (/etc/systemd/system/network.service; enabled; vendor preset: enabled) Active: active (exited) since Wed 2020-03-25 16:55:12 CET; 4s ago Process: 521 ExecStartPre=/sbin/ip link set dev eth0 up (code=exited, status=0/SUCCESS) Process: 522 ExecStart=/sbin/dhclient -4 eth0 (code=exited, status=0/SUCCESS) Main PID: 522 (code=exited, status=0/SUCCESS) Tasks: 1 (limit: 2200) Memory: 3.5M CGroup: /system.slice/network.service └─523 /sbin/dhclient -4 eth0
Mär 25 16:55:11 tomsvpngw systemd[1]: Starting thlu:network.service: Start network connectivity... Mär 25 16:55:11 tomsvpngw dhclient[523]: DHCPDISCOVER on eth0 to 255.255.255.255 port 67 interval 6 Mär 25 16:55:11 tomsvpngw dhclient[523]: DHCPOFFER of 10.0.1.56 from 10.0.1.1 Mär 25 16:55:11 tomsvpngw dhclient[523]: DHCPREQUEST for 10.0.1.56 on eth0 to 255.255.255.255 port 67 Mär 25 16:55:11 tomsvpngw dhclient[523]: DHCPACK of 10.0.1.56 from 10.0.1.1 Mär 25 16:55:11 tomsvpngw dhclient[522]: RTNETLINK answers: File exists Mär 25 16:55:12 tomsvpngw dhclient[523]: bound to 10.0.1.56 -- renewal in 429397 seconds. Mär 25 16:55:12 tomsvpngw systemd[1]: Started thlu:network.service: Start network connectivity. # systemctl enable network.service Created symlink /etc/systemd/system/multi-user.target.wants/network.service → /etc/systemd/system/network.service. |
Die vorstehende Service-Unit verwendet im ExecStart-Statement zur Abfrage einer IP-Adresse beim DHCP-Server (üblicherweise ist das DSL-Router) natürlich einen lokalen DHCP-Client. Es muss also unbedingt sichergestellt sein, dass auch ein lokaler DHCP-Client verfügbar ist, denn ohne dieses Programm würde die Unit unweigerlich fehlschlagen. An dieser Stelle ist das Verständnis wichtig, dass bei der Anforderung „nomaler Client-PC“ nur eine DHCP-Client-Instanz benötigt wird. Bei diesem PC handelt es sich also nicht um ein System, was als DHCP-Server oder gar Router verwendet werden soll. Ein zusätzlich installierter DHCP-Server wie ‚dnsmasq‘ oder oder ‚isc-dhcp-server‘ oder wie die meiner Meinung nach sehr überladene Client-SW ‚dhcpcd5‘ ist somit völlig überflüssig und wären diese Pakete installiert, so würde ich sie wie im nächsten Kapitel beschrieben entfernen.
# dpkg -l | grep isc-dhcp ii isc-dhcp-client 4.4.1-2 amd64 DHCP client for automatically obtaining an IP address ii isc-dhcp-common 4.4.1-2 amd64 common manpages relevant to all of the isc-dhcp packages |
Fehlen diese beiden Pakete, werden sie installiert:
# apt install isc-dhcp-client isc-dhcp-common |
|
Deaktivieren des Default-Setups für Netzwerkverbindungen
Die Deaktivierung des Default-Setups zur Verhinderung potentieller Störungsquellen sowie die Entfernung eigentlich unnötiger Software sollte uns nun, nachdem wir uns erfolgreich Klarheit über die Hardware (Interfaces) und Software (Firmware und Network-Tools) verschafft haben, nicht mehr weiter schwer fallen. Für die hier folgend beschriebenen Services, die auf dem eigenen System nicht aktiv sind oder die möglicherweise gar nicht installiert sind, werden die betroffenen Maßnahmen deshalb natürlich übersprungen.
Dieses Tutorial funktioniert unter Debian, Raspbian und aller Wahrscheinlichkeit gleichermaßen auch unter Arch Linux, Ubuntu oder Mint. Weil aber die möglichen Beispiele zu den folgenden Services erwartungsgemäß völlig unterschiedlich auf den Systemen oder durch die Ziele einer Distribution eingerichtet und aktiviert sind, ist nicht vorhersagbar, welche Schritte ausgeschlossen sind und welche durchgeführt werden müssen. Ich habe hier versucht, etliche unterschiedliche Situationen abzubilden, die aber niemals alle zusammen auf einem System installiert sein können. Deshalb bitte sehr aufmerksam arbeiten und jeden Service anhand seines Status prüfen. Ist ein Service nicht ‚active‘, so wird an dieser Stelle auch nichts unternommen oder verändert. Im Idealfall besteht am Anschluss an die vorherigen Kapitel jetzt aber eine genaue Kenntnis darüber, welche Services außer Betrieb genommen werden sollen.
# cd / # find /etc -iname "*networking" -print /etc/rc0.d/K01networking /etc/rc6.d/K01networking /etc/rcS.d/S01networking /etc/default/networking /etc/init.d/networking |
Hier wurde eine Verbindung nach altem Standard gefunden: sysv = obsolet => ausplanen
|
# systemctl status ifup@eth0.service ● ifup@eth0.service - ifup for eth0 Loaded: loaded (/lib/systemd/system/ifup@.service; static; vendor preset: enabled) Active: active (exited) since Sat 2019-06-08 # systemctl mask ifup@eth0.service Created symlink /etc/systemd/system/ifup@eth0 .service → /dev/null. | |
# update-rc.d networking remove # systemctl status networking.service ● networking.service - Raise network interfaces Loaded: loaded (/lib/systemd/system/networking.service; enabled; vendor preset: enabled) Active: active (exited) since Thu 2020-03-05 14:37:31 CET; 21s ago # systemctl mask networking.service Created symlink /etc/systemd/system/networking.service → /dev/null. # find /etc -iname "*networking" -print /etc/default/networking /etc/init.d/networking | |
| |
Für die folgenden Beispiele entweder die Service-Units einzeln auf active und enabled prüfen oder explizit nur die ansprechen, die zuvor (s.o.) ermittelt wurden! | |
# systemctl status NetworkManager.service ● NetworkManager.service - Network Manager Loaded: loaded (/lib/systemd/system/NetworkManager.service; enabled; vendor preset: enabled) Active: active (running) since Sat 2019-06-08 # systemctl mask NetworkManager.service Created symlink /etc/systemd/system/NetworkManager.service → /dev/null. | |
# systemctl status connman.service ● connman.service - Connection service Loaded: loaded (/lib/systemd/system/connman.service; enabled; vendor preset: enabled) Active: active (running) since Mon 2020-06-22 21:26:06 CEST; 18s ago # systemctl mask connman.service Created symlink /etc/systemd/system/connman.service → /dev/null. | |
# systemctl status systemd-networkd ● systemd-networkd.service - Network Service Loaded: loaded (/lib/systemd/system/systemd-networkd.service; enabled; vendor preset: enabled) Active: active (running) since Sat 2019-06-08 # systemctl mask systemd-networkd Created symlink /etc/systemd/system/systemd-networkd.service → /dev/null. | |
# systemctl status wpa_supplicant.service ● wpa_supplicant.service - WPA supplicant Loaded: loaded (/lib/systemd/system/wpa_supplicant.service; enabled; vendor preset: enabled) Active: active (running) since Thu 2020-03-05 15:01:35 CET; 9min ago) # systemctl mask wpa_supplicant.service Created symlink /etc/systemd/system/wpa_supplicant.service → /dev/null. | |
# systemctl status dhcpcd.service ● dhcpcd.service - LSB: IPv4 DHCP client with IPv4LL support Loaded: loaded (/etc/init.d/dhcpcd; generated) Active: active (running) since Thu 2020-03-05 15:01:35 CET; 9min ago # systemctl mask dhcpcd.service Created symlink /etc/systemd/system/dhcpcd.service → /dev/null. | |
# systemctl status isc-dhcp-server.service ● isc-dhcp-server.service - LSB: DHCP server Loaded: loaded (/etc/init.d/isc-dhcp-server; generated) Active: active (running) since Thu 2020-03-06 14:02:25 CET; 6min ago # systemctl mask isc-dhcp-server.service Created symlink /etc/systemd/system/isc-dhcp-server.service → /dev/null. | |
# systemctl -l | grep avahi avahi-daemon.service loaded active running Avahi mDNS/DNS-SD Stack avahi-daemon.socket loaded active running Avahi mDNS/DNS-SD Stack Activation Socket # systemctl mask avahi-daemon.service avahi-daemon.socket Created symlink /etc/systemd/system/avahi-daemon.service → /dev/null. Created symlink /etc/systemd/system/avahi-daemon.socket → /dev/null. # systemctl reboot |
Nach dem Reboot wird eine Erfolgskontrolle durchgeführt. Natürlich fragen wir auch hier wieder nur die Services ab, die wir zuvor manuell deaktiviert haben:
# systemctl status ifup@eth0 networking NetworkManager systemd-networkd wpa_supplicant dhcpcd isc-dhcp-server ● ifup@eth0.service Loaded: masked (Reason: Unit ifup@eth0.service is masked.) Active: inactive (dead)
● networking.service Loaded: masked (Reason: Unit networking.service is masked.) Active: inactive (dead)
● NetworkManager.service Loaded: masked (Reason: Unit NetworkManager.service is masked.) Active: inactive (dead)
● systemd-networkd.service Loaded: masked (Reason: Unit systemd-networkd.service is masked.) Active: inactive (dead)
● wpa_supplicant.service Loaded: masked (Reason: Unit wpa_supplicant.service is masked.) Active: inactive (dead)
● dhcpcd.service Loaded: masked (Reason: Unit dhcpcd.service is masked.) Active: inactive (dead)
● isc-dhcp-server.service Loaded: masked (Reason: Unit isc-dhcp-server.service is masked.) Active: inactive (dead)
# systemctl status avahi-daemon.service avahi-daemon.socket ● avahi-daemon.service Loaded: masked (Reason: Unit avahi-daemon.service is masked.) Active: inactive (dead)
● avahi-daemon.socket Loaded: masked (Reason: Unit avahi-daemon.socket is masked.) Active: inactive (dead) |
Die folgende Abfrage zeigt uns den Zustand des Interfaces (UP?), den Verbindungsstatus (state UP?) und ob via DHCP erfolgreich eine IP bezogen werden konnte:
$ ip a $ systemctl status network.service |
|
Einrichten eines über ETH verbundenen dedizierten Server-Systems mit Static-IP
Weil im bisherigen Verlauf dieses Artikels bereits alle relevanten Vorarbeiten und Voraussetzungen relativ umfassend besprochen wurden, beschränke ich mich jetzt hier und auch bei den noch folgenden Service-Units primär auf auf die eigentliche Einrichtung der Netzverbindung eines einzelnen Systems mit besonderen Anforderungen.
Zielvorstellung bzw. beabsichtigter Verwendungszweck für diese Service-Unit: Ein stationärer kabelverbundener PC, der z.B. als Samba-Server die statische IPv4-Adresse 10.0.1.2 zugewiesen bekommen soll. IPv6-Global-Unicast-Adressen sind davon nicht betroffen und werden unabhängig davon via RA-Prefix-Delegation und SLAAC erstellt. | |
$ su - # nano /etc/systemd/system/network.service [Unit] Description=thlu:network.service: Start network connectivity After=basic.target Before=network.target shutdown.target Wants=network.target
[Service] Environment="PATH=/bin:/usr/sbin:/usr/bin" Type=oneshot RemainAfterExit=yes
| |
ExecStartPre=ip addr add 10.0.1.2/24 dev eth0 ExecStartPre=ip link set eth0 up ExecStartPre=ip route add default via 10.0.1.1 ExecStart =true
ExecStop=ip link set eth0 down ExecStopPost=ip addr flush dev eth0 ExecStopPost=ip route del default via 10.0.1.1
[Install] WantedBy=multi-user.target | = Zugewiesene Static-IP-Adresse = Verwendete Interface = Default-Gateway |
# cd /etc/systemd/system # systemctl start network.service | Teststart, um auf Fehler zu prüfen. Wenn Fehlerfrei, dann neue Netzwerkverbindung aktivieren |
# ip a 1: lo: *snip* 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 link/ether d0:3g:ff:9a:xy:zz brd ff:ff:ff:ff:ff:ff inet 10.0.1.2/24 scope global eth0 valid_lft forever preferred_lft forever # systemctl status network.service ● network.service - thlu:network.service: Start network connectivity Loaded: loaded (/etc/systemd/system/network.service; disabled; vendor preset: enabled) Active: active (exited) since Wed 2020-07-15 14:37:35 CEST; 37s ago Process: 7101 ExecStartPre=/usr/sbin/ip addr add 10.0.1.2/24 dev eth0 (code=exited, status=0/SUCCESS) Process: 7102 ExecStartPre=/usr/sbin/ip link set eth0 up (code=exited, status=0/SUCCESS) Process: 7103 ExecStartPre=/usr/sbin/ip route add default via 10.0.1.1 (code=exited, status=0/SUCCESS) Process: 7104 ExecStart=/usr/bin/true (code=exited, status=0/SUCCESS) Main PID: 7104 (code=exited, status=0/SUCCESS)
Jul 15 14:37:35 thomaspc systemd[1]: Starting thlu:network.service: Start network connectivity... Jul 15 14:37:35 thomaspc systemd[1]: Started thlu:network.service: Start network connectivity. # systemctl enable network.service Created symlink /etc/systemd/system/multi-user.target.wants/network.service → /etc/systemd/system/network.service. |
|
Einrichten eines über WLAN verbundenen stationär genutzten Laptops
Manchmal trifft es zu, dass ein Laptop oder Notebook ausschließlich stationär genutzt wird. Wir nutzen selber mehrere mobile Linux-Geräte, aber einige von denen verlassen trotzdem nie das Haus, obwohl sie durchaus komfortabel tragbar und mobil sind. Bei diesen Systemen bietet es sich natürlich an, auch hier einfach eine statische Verbindung herzustellen – nur eben über WLAN. Wozu benötige ich einen WLAN-Network-Manager, wenn doch das Gerät sowieso nie bewegt wird und nie einen anderen Accesspoint verwendet. Auch für solche Systeme sind schnell die Verbindungseinstellungen hergestellt, mit denen sich das Gerät direkt nach dem Einschalten zuverlässig mit dem DSL/WLAN-Router verbindet.
Generell gilt derzeit für alle WLAN-Verbindungen auf einem Linux-System, dass wpa_supplicant installiert sein muss. Dieses Programm stellt die Funkverbindung zwischen zwei WLAN-Geräten her. Damit ist also noch nicht die logische Netzwerkverbindung selber gemeint, sondern i.ü.S. trifft eher der Vergleich zum Patchkabel zu. Auch das Patchkabel zwischen zwei Geräten stellt noch nicht die logische Netzwerkverbindung auf TCP/IP-Ebene des Netzwerk-Stacks her, hier ist es erst mal nur eine physische Verbindung, beim WLAN ist es erst mal nur eine Funkverbindung. Bitte überprüfen, ob die Pakete installiert sind:
# dpkg -l wpasupplicant iw ||/ Name Version Architektur Beschreibung +++-==============-=============-============-============================================== ii iw 5.0.1-1 amd64 tool for configuring Linux wireless devices ii wpasupplicant 2:2.7+git amd64 client support for WPA and WPA2 (IEEE 802.11i) |
Wenn diese beiden Pakete noch nicht vorhanden sind, müssen sie jetzt installiert werden: |
# apt install wpasupplicant iw |
Sofern die Pakete bereits vorhanden waren oder direkt nach dem wir sie installiert haben, können wir sofort testen, ob unsere WLAN-Hardware funktioniert. Ich weise jetzt natürlich nicht mehr darauf hin, dass die Firmware für die WLAN-Hardware auch wirklich installiert ist… denn das hatten wir ja schon weiter oben sichergestellt. Bitte daran denken, wenn das WLAN-Interface eine andere Bezeichnung als wlan0 hat, muss natürlich diese andere Bezeichnung hier verwendet werden. Und wie erfreulich, mein eigener Test-Accesspoint wurde beim Scan natürlich auch sofort gefunden:
# ip link set wlan0 up # iw wlan0 scan | grep -i ssid SSID: Toms_AP SSID: FRITZ!Box 7430 IS SSID: Vodafone Hotspot SSID: FRITZ!Box 7412 SSID: DIRECT-06-HP DeskJet 2600 series SSID: Vodafone-30AB SSID: UschisNetz SSID: KalleKloppersFritte usw... # ip link set wlan0 down |
Mit den nächsten Schritten legen wir manuell eine Datei mit den aktuellen und für diese Aufgabe notwendigen Verbindungseinstellungen für unseren Accesspoint/unsere SSID an. Der Name dieser Datei ist nicht vorgegeben, wie können sie nennen, wie wir wollen. Ich halte es nur für günstig und auch sinnvoll, wenn sie einfach den Namen der SSID übernimmt, dann gibt es nie Irritationen darüber, wofür diese Datei gedacht ist. Mit der erste Maßnahmen legen wir quasi ein Basic-Format an, welches bereits das verschlüsselte WLAN-Password enthält:
SSID WLAN-Password # wpa_passphrase Toms_AP mein_geheimes_wlan_password >/etc/wpa_supplicant/toms_ap.conf # cat /etc/wpa_supplicant/toms_ap.conf network={ ssid="Toms_AP" #psk="mein_geheimes_wlan_password" psk=7425aa1c7133ea8f5b412a99c51fc6f32371719c03f3550f5d5cb780accbd8c3 } |
Nun wird der vorgegebene Inhalt noch um einige weitere notwendige Angaben ergänzt … zum Beispiel mit den unterstützten Verschlüsselungsmethoden. Und wir entfernen natürlich die Klar-Text-Darstellung unseres WLAN-Passwortes. Hier noch ein wichtiger Hinweis: Andere Verschlüsselungen als RSN oder WPA sollten aus Sicherheitsüberlegungen nicht mehr verwendet werden, denn eine schwache Verschlüsselung kann heute durchaus schon gehackt und mitgehört werden.
# nano /etc/wpa_supplicant/toms_ap.conf ctrl_interface=/var/run/wpa_supplicant ap_scan=1
network={ scan_ssid=1 priority=20 id_str="Guest"
ssid="Toms_AP" psk=7425aa1c7133ea8f5b412a99c51fc6f32371719c03f3550f5d5cb780accbd8c3
proto=WPA RSN group=CCMP TKIP pairwise=CCMP TKIP key_mgmt=WPA-PSK } |
Wenn die Datei eingerichtet ist und abschließend noch einmal sorgfältig kontrolliert wurde, dass keine Tipp- oder Übertragungsfehler enthalten sind, kann sofort getestet werden, ob sie funktioniert:
# ip link set dev wlan0 up # wpa_supplicant -B -i wlan0 -c /etc/wpa_supplicant/toms_ap.conf # dhclient wlan0 | Interface und Verbindung öffnen, eine IP-Adresse anfordern |
# ip a | Wenn eine IP-Adresse aus dem lokalen Netzwerk angezeigt wird, sollte es jetzt möglich sein, mit einem Browser Web-Seiten im Internet zu öffnen- |
# pkill -f /etc/wpa_supplicant/toms_ap.conf # ip link set dev wlan0 down # ip addr flush dev wlan0 | Zum Schluss den laufenden Prozess beenden und aufräumen |
Wenn alle Tests erfolgreich verlaufen sind, spricht nun überhaupt nichts mehr dagegen, diese Einstellungen auch beim Start des Gerätes zu verwenden und die Netzwerkverbindung via WLAN automatisch herzustellen.
Wie zuvor wird dafür wieder eine systemd-Service-Unit verwendet. Hier besteht allerdings eine kleine Besonderheit. Um dem Kernel meines Testsystems die Zeit zu geben, den externen USB-Wlan-Stick zu erkennen und mit dem Symlink als wlan0 zu bezeichnen, habe ich ihm 3 Wartesekunden gegönnt. Ohne diese 3 Sekunden konnte es in seltenen Fällen passieren, dass die Service-Unit gestartet wurde, bevor der Stick korrekt erkannt wurde… und natürlich muss die Unit dann infolgedessen und verständlicherweise fehlschlagen.
Zielvorstellung bzw. beabsichtigter Verwendungszweck für diese Service-Unit: Stationär verwendete via WLAN verbundene PCs/Laptops/Notbooks, die eine lokale IPv4-Adresse bzw. einen IPv6-Prefix vom DHCP-Server (DSL-Router) beziehen. |
$ su - # nano /etc/systemd/system/network.service [Unit] Description=thlu:network.service: Start wireless network connectivity After=basic.target Before=network.target Wants=network.target
[Service] Environment="PATH=/bin:/usr/sbin:/usr/bin" Type=oneshot RemainAfterExit=yes
ExecStartPre=sleep 3 ExecStartPre=ip link set dev wlan0 up ExecStartPre=wpa_supplicant -B -i wlan0 -c /etc/wpa_supplicant/toms_ap.conf ExecStart =dhclient wlan0
ExecStop =pkill -f /etc/wpa_supplicant/toms_ap.conf ExecStopPost=dhclient -r wlan0 ExecStopPost=ip link set dev wlan0 down ExecStopPost=ip addr flush dev wlan0
[Install] WantedBy=multi-user.target |
# cd /etc/systemd/system # systemctl start network.service | Teststart, um auf Fehler zu prüfen. Wenn fehlerfrei, dann wie zuvor neue Netzwerkverbindung aktivieren |
# ip a # systemctl status network.service # systemctl enable network.service Created symlink /etc/systemd/system/multi-user.target.wants/network.service → /etc/systemd/system/network.service. |
Ich verwende für solche Fälle bei unsere mobilen Geräten selbstverständlich auch ein Programm zur Unterstützung bei ad hoc hergestellten WLAN-Verbindungen an fremden Access-Points. Dafür nutze ich selnic, meinen eigenen kleinen Netzwerk-Manager, der menügeführt und komfortabel exakt das gleiche tut, wie hier zuvor beschrieben wurde.
|
Einrichten eines über ETH verbundenen PCs mit lokalen VMs (libvirt/KVM, Bridge, LAN-Client, DHCP)
Auf meinem eigenen PC nutze ich zusätzlich zu den normalen Desktop-Anwendungen mehrere virtuelle Maschinen für unterschiedliche Zwecke. Der Hintergrund ist einfach, es sollen gewisse Prozesse von meiner persönlichen Desktop-Oberfläche und von meinem persönlichen Datenbereich nicht nur ausgeschlossen werden, sie sollen sogar konsequent von allen möglicherweise erreichbaren privaten Daten isoliert werden und tatsächlich nur wie unter Quarantäne-Bedingungen laufen. Das betrifft zum Beispiel meinen Browser, mit dem ich im Internet surfe, oder eine zweite VM, die ausdrücklich nur für Online-Banking verwendet wird. Die VMs sind so eingerichtet, dass sie über ihren beabsichtigten Zweck hinaus keinerlei andere Funktionen oder Programme beinhalten oder Zugriff auf irgendwelche Daten oder Ressourcen unseres Netzwerks haben. Im Endeffekt hat das die Auswirkung, dass mein persönliches Home-Dir, also mein eigener Linux-User-Account auf dem PC, niemals einen direkten Kontakt mit irgendwelchen Web-Sites des Internets hat. Für die nun folgenden Lösungsvorschläge mit jeweils sehr anspruchsvollen Zielen halte ich es für obligatorisch, das vom Installer eingerichtete oder in der Distribution implementierte Default-Setup der Netzwerkverbindung wie beschrieben zu deaktivieren. Konflikte hierbei durch konkurrierende oder ähnliche Prozesse sind wirklich völlig unnötige Problemursachen.
Einschränkungen hinsichtlich des Bedienungskomforts habe ich durch die VMs nicht. Ich habe ein Browser-Icon auf dem Desktop, das klicke ich völlig unspektakulär an und der Browser öffnet sich. Das einzige auffällige ist eine kurze Verzögerung von 4-5 Sekunden. Solange braucht es vorher die VM von der SSD zu starten. Die VM (ein Debian-System) verlangt natürlich keine extra Anmeldung, der Browser startet dort von alleine. Also ist die Bedienung bis auf die Wartezeit eigentlich die gleiche, wie ohne VM. Meine VMs sind alle mit einem Debian ohne Standard-Desktop-Environment eingerichtet. Zu einem anfangs ‚leeren‘ Debian wurden dann manuell nur der X-Server und Openbox dazu installiert, laufende Dienste gibt es keine. Mehr ist nicht notwendig, ein Mehr an Desktop-Environment würde möglicherweise nur die Startzeit unnötigerweise verlängern. Für meinen Browser (FF ESR) verwende ich eine eigene user.js, die, so hoffe ich, meine Ansprüche an den Schutz der Privatsphäre ebenfalls unterstützt.
Warum mach ich das? Weil ich das als eine der sehr wenigen tatsächlich vorhandenen Möglichkeiten betrachte, der digitalen Entmündigung bezogen auf das Recht der exklusiven Verfügungshoheit meiner digitalen Privatsphäre und all meiner privaten Daten entgegenzutreten. Das mag für eine Sichtweise „Ich habe keine Geheimnisse, ich habe nichts zu verbergen und jeder kann alles sehen.“ befremdlich sein. Tja, auf solcherart Unkenntnis über die digitale Realität einzugehen ist hier aber leider nicht möglich, das würde den Rahmen sprengen. Nur soviel dazu, die Annahme dass das nicht existiert, von dem man nichts weiß und was man selber auch nicht unmittelbar schmerzhaft spürt, ist letztlich die Grundlage dafür, dass die Menschen tatsächlich digital entmündigt werden. Das passiert quasi hinterhältig über die Zugänge zum Internet, kontinuierlich, verborgen im für die meisten Anwender undurchschaubaren digitalen Labyrinth der Netzwerke, und zwar ohne das die Anwender das bemerken oder dem bewusst zugestimmt haben.
Ein nachdenkenswertes Zitat von Edward Snowden:
"Arguing that you don't care about the right to privacy because you have nothing to hide is no different than saying you don't care about free speech because you have nothing to say.“
Sinngemäß übersetzt:
""Zu argumentieren, dass Ihnen das Recht auf Privatsphäre egal ist, weil Sie nichts zu verbergen haben, ist nichts anderes als zu sagen, dass Ihnen Redefreiheit egal ist, weil Sie nichts zu sagen haben."“
Ohne die ‚bridge-utils‘ ist es grundsätzlich nicht möglich, die VM als eigenständigen LAN-Client einzurichten. In dem Fall bleibt nur das Masquerading durch den Host-PC. Für die Einrichtung einer solchen VM über ein Bridge-Device sind also als zwingende Voraussetzung zuerst die entsprechenden Pakete zu installieren, falls sie im Moment noch fehlen:
# dpkg -l qemu-system-x86 virt-manager virt-viewer dpkg-query: Kein Paket gefunden: qemu-system-x86 dpkg-query: Kein Paket gefunden: virt-manager dpkg-query: Kein Paket gefunden: virt-viewer
# apt install qemu-system-x86 virt-manager virt-viewer
# dpkg -l bridge-utils dpkg-query: Kein Paket gefunden: bridge-utils
# apt install bridge-utils | Prüfen, ob notwendige Pakete installiert sind.
Nur fehlende Pakete installieren! |
Eine Service-Unit zum Start des Bridge-Netzwerks zwischen Host und VM.
Zielvorstellung bzw. beabsichtigter Verwendungszweck für diese Service-Unit: Ein stationärer kabelverbundener Desktop-PC, der zusätzlich lokale ad hoc vom Anwender zu startende VMs beinhaltet. Die VMs treten im lokalen Netz als eigenständige Clients mit einer eigenen IP-Adresse im LAN auf. Und weil die VMs eigenständige LAN-Clients sind, ist dadurch verhindert, dass die Datenpakete einer VM im LAN nicht als scheinbar ursprünglich vom physischen Host kommend erkannt werden, was der Falle bei Host-NAT via Masquerading wäre. Die Netzwerkanbindung der VM erfolgt über ein virtuelles Bridge-Device. | |
$ ip a s dev eth0 | grep 'link/ether' link/ether d0:3g:ff:9a:xy:zz brd ff:ff:ff:ff:ff:ff $ su - # nano /etc/systemd/system/network.service [Unit] Description=thlu:network.service Start network connectivity After=basic.target Before=network.target shutdown.target Wants=network.target Conflicts=shutdown.target
| |
[Service] Environment="PATH=/bin:/usr/sbin:/usr/bin" Type=oneshot RemainAfterExit=yes
ExecStartPre=ip link add br0 type bridge ExecStartPre=ip link set br0 type bridge stp_state 0 ExecStartPre=ip link set br0 type bridge forward_delay 0 ExecStartPre=ip link set br0 address d0:3g:ff:9a:xy:zz ExecStartPre=sysctl -w net.ipv6.conf.br0.forwarding=1 ExecStartPre=sysctl -w net.ipv6.conf.br0.disable_ipv6=0 ExecStartPre=sysctl -w net.ipv6.conf.br0.autoconf=1 ExecStartPre=sysctl -w net.ipv6.conf.br0.use_tempaddr=2 ExecStartPre=sysctl -w net.ipv6.conf.br0.accept_ra=2 ExecStartPre=ip link set eth0 master br0 ExecStartPre=ip link set eth0 up ExecStartPre=ip link set br0 up ExecStartPre=dhclient -v br0 ExecStart =true
|
= MAC-Adresse entspricht der von eth0 = Interface-Konfiguration für IPv6 via sysctl = ipv6 erlauben = Autokonfiguration via SLAAC erlauben = Privacy Extensions erlauben = Router-Advertisement trotz forwarding erlauben |
ExecStop =ip link set eth0 nomaster ExecStopPost=ip link set eth0 down ExecStopPost=ip addr flush dev eth0 ExecStopPost=ip link set br0 down ExecStopPost=ip addr flush dev br0 ExecStopPost=ip link del br0 type bridge
[Install] WantedBy=multi-user.target | Bei Shutdown aufräumen |
Diese Service-Unit darf natürlich jetzt noch nicht in Betrieb genommen werden, es sind zuerst noch weitere Voraussetzungen zu schaffen. Die wichtigste Maßnahme ist, IPv6 dann zu konfigurieren, wenn der heimische DSL-Vertrag entweder auf Dual-Stack oder DS Lite beruht. In beiden Fällen wird vom DSL-Provider IPv6 unterstützt und ein ISP-Prefix wird vermutlich über das Router-Advertisement und dem Neighbor Discovery Protocol auf die Client-Geräte verteilt.
Mit den Einstellungen der Kernel-Parameter für IPv6 wird folgendes erreicht:
# nano /etc/sysctl.d/sysctl_ipv6_tpc.conf net.ipv6.conf.all.forwarding=1
net.ipv6.conf.default.disable_ipv6=0 net.ipv6.conf.default.forwarding=1 net.ipv6.conf.default.autoconf=0 net.ipv6.conf.default.use_tempaddr=0 net.ipv6.conf.default.accept_ra=0
net.ipv6.conf.eth0.disable_ipv6=1 net.ipv6.conf.eth0.forwarding=0 net.ipv6.conf.eth0.autoconf=0 net.ipv6.conf.eth0.use_tempaddr=0 net.ipv6.conf.eth0.accept_ra=0
# sysctl --system |
forwarding für alle Interfaces erlauben
für neue NICs ipv6 erlauben (für dynam.-gener. br0) - forwarding erlauben - keine Autokonfiguration (SLAAC) durchführen - Privacy Extensions (Temp-Adressen) nicht erlauben - RA nicht erlauben
für das bestehende NIC eth0 IPv6 verbieten - forwarding verbieten - keine Autokonfiguration durchführen - Privacy Extensions (Temp-Adressen) nicht erlauben - kein Router Advertisement erlauben
Einstellung on-the-fly aktivieren |
Der Zweck dieser Einstellungen und der Service-Unit ist es, das physische Interfaces eth0 in einen promiskuitiven Modus zu versetzen und das virtuelle Bridge-Interface br0 als primäres Interface zu deklarieren. Im Normalfall leitet eth0 als alleiniges Interface nur IP-Pakete (TCP/UDP im Netzwerk-Stack) an den Kernel weiter, deren Ziel die IP-Adresse dieses System ist. Im promiskuitiven Modus werden auch IP-Pakete weitergeleitet, die eine andere IP-Adresse als Ziel habe… hier wird also das Bridge-Device zum maßgeblichen Interface und die VMs mit eigener IP zu Empfängern der an sie addressierten IP-Pakete. Zusätzlich wird verhindert, dass das physische Interface eth0 über IP-Adressen überhaupt als regulärer Client mit dem Netzwerk verbunden ist. Damit im Netzwerk-Datenverkehr über gleichzeitig vorhandene physische und virtuelle Interfaces nicht miteinander konkurrierende aktive IP-Adressen für Konflikte sorgen, muss außerdem verhindert werden, dass der Kernel via SLAAC automatisch IPv6-Adressen für eth0 generiert.
Mit IPv6 wird das systemisch etwas anders gehandhabt, als man das von IPv4 kennt. Bei IPv4 gibt es lediglich zwei Möglichkeiten, entweder es wird eine IP-Adresse vom DHCP-Server angefordert oder man vergibt eine manuelle IP-Adresse. Bei IPv6 wird im Regelfall keine Adresse vom DHCP-Server angefordert und es wird auch keine Global-Unicast-Adresse manuell angelegt. Der Kernel selber erstellt dynamisch eine MAC-basierte globale IPv6-Adresse, sobald er vom DSL-Router über das Neighbor Discovery Protocol einen Netzwerk-Prefix erhält. Und genau das wird hier mit diesen ausdrücklichen Einstellungen für das physische Interface eth0 unterbunden.
Und ja, wenn man ein reines und eher traditionelles IPv4-Netzwerk hat, kann man diese Schritte zum Setzen der Kernel-Parameter selbstverständlich überspringen. In dem Fall müssen natürlich auch die sysctl-Statements aus der Service-Unit entfernt werden, die werden dann einfach nicht benötigt:
ExecStartPre=sysctl -w net.ipv6.conf.br0.forwarding=1 ExecStartPre=sysctl -w net.ipv6.conf.br0.disable_ipv6=0 ExecStartPre=sysctl -w net.ipv6.conf.br0.autoconf=1 ExecStartPre=sysctl -w net.ipv6.conf.br0.use_tempaddr=2 ExecStartPre=sysctl -w net.ipv6.conf.br0.accept_ra=2 |
Die notwendigen Vorbereitungen sollten jetzt abgeschlossen sein. Also können wir die Service-Unit nun für einen Fehler-Test manuell starten:
# cd /etc/systemd/system # systemctl start network.service # systemctl status network.service | Teststart, um auf Fehler zu prüfen. Wenn der Status Fehlerfrei ist, die Anzeige des ip-Statements korrekt ist und IP-Adressen vergeben sind, dann neue Netzwerkverbindung mit enable aktivieren |
# ip a 1: lo: *snip*
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master br0 state UP group default qlen 1000 link/ether d0:3g:ff:9a:xy:zz brd ff:ff:ff:ff:ff:ff
3: br0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000 link/ether d0:3g:ff:9a:xy:zz brd ff:ff:ff:ff:ff:ff inet 10.0.1.56/24 brd 10.0.1.255 scope global dynamic br0 valid_lft 863991sec preferred_lft 863991sec inet6 2022:1687:6219:h500:15a8:622:3040:c8db/64 scope global temporary dynamic valid_lft 7187sec preferred_lft 3587sec inet6 2022:1687:6219:h500:d23g:ffff:fe9a:xyzz/64 scope global dynamic mngtmpaddr valid_lft 7187sec preferred_lft 3587sec inet6 fe80::d23g:ffff:fe9a:xyzz/64 scope link valid_lft forever preferred_lft forever | |
# systemctl enable network.service Created symlink /etc/systemd/system/multi-user.target.wants/network.service → /etc/systemd/system/network.service. |
Sieht das Ergebnis sinngemäß wie oberhalb angezeigt aus…?… perfekt… alles richtig gemacht. Wenn nun über den Virt-Manager einer neue lokale VM erstellt werden soll, kann im Settings-Menü der VM das Netzwerkinterface auf folgende Weise konfiguriert werden. Gegebenenfalls ist dabei an einer bestimmten Stelle im anfänglichen Dialog für den Namen der VM, Festplattenspeicher, etc. der Menüpunkt „Konfigruation vor dem Start bearbeiten“ anzuwählen.
Ich empfehle für das Management lokaler in der eigenen grafischen Desktop-Umgebung betriebener libvrt/KVM-VMs immer den Virt-Manager für die Erstellung und anschließend den im Manager integrierten Virt-Viewer zur Anzeige der gestarteten VM zu verwenden. Ich empfinde das als äußerst komfortabel gelöst und es bietet in jeder Hinsicht eine gute Unterstützung.
Wenn Anwender allerdings ein Terminal-Fenster bevorzugen (so wie ich), so kann man das natürlich auch dort ein wenig direkter handhaben:
$ export LIBVIRT_DEFAULT_URI='qemu:///system'
$ virt-install --connect qemu:///system \ --virt-type=kvm \ --network=bridge=br0,model=virtio \ --name=testsystem \ --memory 4096 \ --vcpus=4 \ --disk=/var/lib/libvirt/images/testsystem.cow2,format=qcow2,size=8 \ --cdrom=/tmp/firmware-10.4.0-amd64-netinst.iso \ --noautoconsole \ --os-type=linux \ --os-variant=debian10 \ --hvm \ --graphics spice,listen=127.0.0.1 | Ist im Terminal notwendig, wenn die VM-Prozesse vom angemeldeten Users bedient werden sollen.
Dieses mehrzeilige „Kommando-Paket“ komplett als 1 Befehl im Terminal ausführen.
- Name der VM, kann geändert werden - Der VM zugewieser RAM (hier sind 8 GB installiert) - Anzahl CPUs erlauben (dieses System hat nur 4) - Default-Dir, änderbar (dann Rechte beachten) - Installer-ISO (liegt in Dir mit rwx r-x r-x)
Achtung: Bitte dieses „Kommando-Paket“ nicht direkt per Copy/Paste in ein Terminal einfügen, sondern lieber den Umweg über einen Editor wählen, um zu kontrollieren, ob sich unerwünschte Leerzeilen eingeschlichen haben. Wenn ja müssen diese zuerst entfernt werden! |
Installation wird gestartet … Zuweisen von 'testsystem.cow2' 8 GB Sie können mit der Konsole verbinden, um den Installationsvorgang abzuschließen. | |
$ virt-viewer testsystem | Öffnen des virtuellen Monitors, hier den Installer |
Ist die VM einmal erfolgreich eingerichtet, kann sie sowohl sehr einfach über den Virt-Manager als auch manuell im Terminal mit den folgenden Befehlen geöffnet werden. Bei mir sind diese 3 Befehle in einem Mini-Bash-Script hinterlegt, der Start erfolgt über einen von mir eingerichteten Desktop-Starter mit passendem Icon.
$ export LIBVIRT_DEFAULT_URI='qemu:///system' | Umgebungsvariable für die Qemu/KVM-Infrastruktur. Ist notwendig, damit ein Anwender die VM im Terminal bedienen kann. Die VM-Prozesse selber laufen dann unter dem virtuellen User libvirt-qemu. |
$ virsh start testsystem Domain testsystem started $ virt-viewer testsystem & | VM starten und den virtuellen Monitor anzeigen. Weil die Anzeige mit ‚&‘ in den Hintergrund gelegt wurde, kann das Terminal mit der Eingabe exit beendet werden. |
Werfen wir einfach mal einen Blick auf meinen Server mit aktuell drei laufenden VMs mit je 2 CPUs und je 2 GB RAM. Wie man sieht, belasten die VMs die Host-CPU fast gar nicht, obwohl sie voll funktionsfähig aktiv sind. Und der belegte RAM mit ~3,3 GB passt auch nicht zu den 3*2=6 GB für die drei VMs, zumal gleichzeitig auch noch andere Server-Dienste auf dem Rechner laufen, wie Cups, Dovecot, Postfix, OpenVPN, OpenSSH. Das bedeutet, die VMs beanspruchen viel weniger, als ich ihnen über ihre Konfiguration eigentlich erlaubt habe.
Ich habe diese drei VMs nur deshalb sparsam konfiguriert, weil sie alle nur ein Basic-Debian enthalten, ohne grafisches Desktop-Environment. In diesem besonderen Fall ist es sogar fast so, dass 2 CPUs und je 2 GB RAM für diese bestimmten Service-Funktionen hier fast schon overdressed sind. Das spiegelt sich auch in der Image-File-Größe wieder. Die Dateigröße beträgt jeweils 6 GB, davon sind bei allen allerdings nur ca. 2,5 bis 3 GB belegt.
Etwas anders sieht es auf meinem Desktop-PC aus, wo es nicht um Services geht, sondern wo ich die VMs interaktiv über deren grafische Oberfläche bediene. Mein PC stellt zur Verfügung: 4 CPUs, 8 GB RAM, 256 GB SSD. Die Standard-Maße für die VMs lauten 4-4-8, also jeweils vier CPUs, vier GB Ram und acht GB Filesize.
Auch hier ist so, dass die VMs die erlaubten Ressource gar nicht grundsätzlich belegen … im Gegenteil, sind sie im IDLE-Zustand, bemerke ich auf dem PC fast gar nicht, dass eine oder zwei laufen. Mir ist aber andererseits wichtig, dass mich die VM, wenn ich dort interaktiv tätig bin, nicht ständig damit nervt, dass ich auf Reaktionen warten muss, weil sie unterdimensioniert eingerichtet wurde. Ich will, dass sich mein Programm (z.B. der Browser) in der VM so verhält, als würde es ‚vorne‘ direkt im PC laufen. Dahinter steht die Erkenntnis, wenn ich in der VM surfe, bin ich sowieso nicht gleichzeitig ‚vorne‘ auf dem PC aktiv, also kann ich bei der VM auch etwas großzügiger sein. Klar, lass ich vorne rechen- und speicherintensive Jobs laufen, so etwas wie Rendern oder einen Film encoden, dann kann es schon passieren, dass mir auf dem PC was fehlt, weil ich der VM vielleicht zu viel gegeben habe. Aber weil das Starten und Schließen der VM ist hier sowieso nur eine Sekundensache ist, würde ich bei solchen Anforderungen die VM eben kurz schließen und bei Bedarf, wenn der Job ‚vorne‘ durch ist, sie einfach neu starten. Tja, den eigenen Best-Way muss man selber anhand seiner eigenen Gewohnheiten finden.
Soweit es die 8 GB Filesize angeht, ist diese Größe für mich ausreichend, weil ich -wie oben schon mal erwähnt- keinen Standard-Desktop installiere, sondern aus Performance-Überlegungen immer nur ein Basic-System, und darauf dann den X-Server, Openbox und nur das ausdrücklich benötigte Programm. Für einen Standard-Desktop würde ich immer mindestens 10 GB vorsehen, vielleicht sogar besser 20 GB. Aber auch das muss man für sich selber herausfinden, weil eben nicht vorhersagbar ist, was die eigene VM noch alles leisten soll.
Ganz zum Schluß, wenn die mit einer grafischen Umgebung ausgestattete VM läuft, kann man noch folgende komfortable Einrichtungen vornehmen.
Auf dem Host-PC: | |
# mkdir /media/kvm-share-dir # chown root:root /media/kvm-share-dir # chmod 777 /media/kvm-share-dir | Einrichten eines gemeinsam genutzten Share-Directory |
# virsh edit surfer <devices> <filesystem type='mount' accessmode='mapped'> <source dir='/media/kvm-share-dir'/> <target dir='sharedir'/> </filesystem> </devices> | Kann auch grafisch über den Virt-Manager eingerichtet werden
Diese 4 Zeilen innerhalb der bereits in der Datei bestehenden Sektion <devices> einfügen |
|
|
Alternativ kann auch im Virt-Manager im Settings-Menü der VM über die Option „Gerät hinzufügen“ und dann über die Gerätebezeichnung „Dateisystem“ das gemeinsame Verzeichnis als Ressource der VM hinzugefügt werden.
‚sharedir‘ ist der symbolische Name des Verzeichnisses, unter dem die VM darauf zugreifen kann. Das tatsächliche Verzeichnis auf dem Host-PC ist der VM nicht bekannt. | |
In der laufenden VM: | |
# apt install spice-vdagent | Unterstützt in der VM ein bidirektionales Clipboard zwischen Host und VM. |
# mkdir -p /media/kvm-share-dir # chown root:root /media/kvm-share-dir # chmod 777 /media/kvm-share-dir | Einrichten eines gemeinsam genutzten Verzeichnisses und der Mount des Verzeichnisses mit dem symlink „sharedir“ vom Host-PC. |
# mount sharedir /media/kvm-share-dir -t 9p -o trans=virtio,version=9p2000.L | |
Die folgende Serve-Unit verbindet das Share-Dir in der VM automatisch bei Systemstart: | |
# nano /etc/systemd/system/kvm-share-dir.service [Unit] Description=thlu:kvm-share-dir.service Mount a KVM-Host-Share-Directory After=basic.target Conflicts=shutdown.target
[Service] Type=oneshot RemainAfterExit=yes ExecStart=/usr/bin/mount sharedir /media/kvm-share-dir -t 9p -o rw,trans=virtio,version=9p2000.L ExecStop=/usr/bin/umount sharedir
[Install] WantedBy=multi-user.target
# cd /etc/systemd/system # systemctl enable kvm-share-dir.service |
|
Einrichten eines über WLAN verbundenen PCs mit lokalen VMs (libvirt/KVM, Bridge, LAN-Client, DHCP)
Dieses Kapitel wird das kürzeste in meinem Artikel. Die Antwort und die einfache Lösung lautet: Geht nicht!
Nun ja, vermutlich sollte ich nicht sagen, dass es generell nicht funktionieren wird, aber man sollte besser davon ausgehen, dass es sehr wahrscheinlich in 99 von 100 Fällen nicht gehen wird. Es liegt möglicherweise auch gar nicht an der Hardware, das die das vielleicht nicht leisten kann, es wird stattdessen sehr viel wahrscheinlicher daran liegen, dass es schlichtweg softwareseitig durch Firmware oder Geräte-Treiber nicht unterstützt wird.
Dafür gibt es verschiedene äußerst schwer zu handhabende Ursachen:
● Wifi-Pakete sind zum Schutz der Übertragung, die theoretisch von jedem geeigneten Funkempfänger bemerkt wird, auf besondere Weise zwischen zwei Geräten verschlüsselt (WPA, RSN, etc.)
● Wifi-Pakete sind anders aufgebaut als die normalen Standard-Ethernet-Frames. Im physischen Layer des WLAN-Protokolls werden die normalen für das Internet oder für ein lokales Netzwerk gedachten Ethernet-Frames deshalb für den Transport per Funk in WLAN-Frames eingebettet.
● Wifi-Pakete sind in der Kommunikation zwischen 2 Geräten zwingend an die jeweilige MAC-Adresse der WLAN-Interfaces gebunden, und das schon noch bevor überhaupt über IP-Adressen eine logische Netzwerk-Zugehörigkeit hergestellt ist. Vor dem Hintergrund, das Ethernet-Frames in WLAN-Frames eingebettet werden, wären also die IP-Adressen (SRC und DST im Ethernet-Header) auf der Funkstrecke selber sowieso bedeutungslos.
Warum ist das so…?… für zwei miteinander kommunizierende WLAN-Geräte bestehen, weil sie nicht physisch unmittelbar über ein Kabel miteinander verbunden sind, nur eingeschränkte Identifikationsmöglichkeiten für den Kommunikationspartner… und das vor dem Hintergrund, dass möglicherweise im Umkreis der beiden Geräte weitere 100 Geräte aus der Nachbarschaft auf dem gleichen Funkkanal aktiv sind. Das heißt, die zweifelsfreie Authentizität meiner kabelverbundenen Geräte, die zuhause in meinem unmittelbaren Einflussbereich liegen, kann ich bei WLAN-Geräten nicht ebenso zweifelsfrei feststellen… selbst dann nicht, wenn ich mit meinem Handy im Wohnzimmer sitze. Die letztliche Authentifizierung bzw. die Legitimierung zur ‚Anmeldung am privaten Funkverkehr‘ erfolgt nur über die gemeinsame Kenntnis des gültigen WLAN-Schlüssels auf den beiden Geräten. Wäre der jedoch gehackt, so könne sich ein Fremdgerät problemlos via MAC-Spoofing als mein Handy ausgeben.
Man muss also davon ausgehen, dass jedes WLAN-taugliche Gerät mit aktiviertem WLAN-Interface, egal ob mit oder ohne aktive Netzanbindung, auch alle WLAN-Frames fremder Geräte aus der näheren Nachbarschaft empfängt, die nicht für ihn selber gedacht sind…. was allerdings unkritisch ist, wenn sie verschlüsselt sind. Zur Identifikation der Pakete sind deshalb die während der Kommunikation gesendeten Frames zwingend an die MAC-Adressen der WLAN-Interfaces von Sender und Empfänger gebunden, wodurch diese Maßgabe einen kompletten Widerspruch zu einem im promiskuitiven Modus betriebenen Netzwerkinterface darstellt. Wir erinnern uns, ein promiskuitives Interface empfängt nicht nur die Pakete, für die es selber via IP der Empfänger ist, sondern auch die Pakete anderer Empfänger… eben unserer VMs. Und da liegt das Problem, die Quelle eines gesendeten Ethernet-Pakets aus dem virtuellen Betriebssystem wäre ja nicht das WLAN-Interface des Hosts, sondern ein virtuelles Ethernet-Interface mit eigener und vom WLAN-Interface abweichender MAC-Adresse. Fazit: Das kann also auf dem Host, der das Bridge-Gerät zur Verüfung stellt, ohne eine Paket-Manipulation nicht funktionieren.
● Der vorherige Punkt ist übrigens ein ausreichend guter Grund für den Kernel, drahtlose Netzwerkgeräte nicht an einem Linux-Host-Bridge-Gerät zu unterstützen
● Im Virtual-Box-Manual (https://www.virtualbox.org/manual/ch06.html#network_bridged) wird zu dieser Frage erklärt:
Note
Bridging to a wireless interface is done differently from bridging to a wired interface, because most wireless adapters do not support promiscuous mode. All traffic has to use the MAC address of the host's wireless adapter, and therefore Oracle VM VirtualBox needs to replace the source MAC address in the Ethernet header of an outgoing packet to make sure the reply will be sent to the host interface. When Oracle VM VirtualBox sees an incoming packet with a destination IP address that belongs to one of the virtual machine adapters it replaces the destination MAC address in the Ethernet header with the VM adapter's MAC address and passes it on. Oracle VM VirtualBox examines ARP and DHCP packets in order to learn the IP addresses of virtual machines.
Oracle‘s Virtual Box kann das also… ja richtig… die tun das… aber das passiert in der Virtualisierungssoftware auf dem Host durch ein hartes Umschreiben der MAC-Adresse des Ethernet-Headers eines jeden ausgehenden IP-Paketes aus der VM auf die MAC-Adresse des sendenden WLAN-Interfaces. Bei eingehenden Paketen an die VM muss die Umschreibung in anderer Richtung (auf die MAC der VM) erneut erfolgen. Oracle hat also eine eigene Lösung entwickelt, die allerdings nur mit Virtual Box funktioniert. In gewisser Weise kann man diese Lösung auch als MAC-Spoofing bezeichnen, denn der WLAN-Partner weiß faktisch nicht, dass er nicht mit dem System spricht, von dem er wegen der MAC glaubt, das er mit ihm spricht. In Wahrheit spricht er nämlich mit einem anderen System, nämlich mit der VM.
|
Einrichten eines über WLAN/ETH verbundenen PCs mit lokalen VMs (libvirt/KVM, Bridge, Host-NAT, DHCP)
Wenn es also, wie im vorherigen Kapitel festgestellt wurde, nicht möglich ist, eine auf einem Laptop laufende VM über das WLAN-Interface zu bridge‘n, muss es natürlich eine andere Möglichkeit geben, der VM den Zugang zum LAN oder ins Internet zu ermöglichen. Ja, die gibt es, sogar mit einem aktiven Bridge-Device, aber eben anders als im vor-vorherigen Kapitel beschrieben, wo die VM selber LAN-Client ist.
Hier ist die VM kein LAN-Client mit einer eigenen zum LAN passenden IP-Adresse. Hier findet stattdessen beim Transport der TCP/UDP-IP-Datenpakete von der VM ins LAN/Internet auf dem Host-PC eine Absender-IP-Adress-Übersetzung (NAT) statt, wodurch die eigentliche Quelle der Pakete (die VM) für andere Geräte im LAN unsichtbar bleibt. Andere Teilnehmer im LAN sehen die Datenpakete so, als wäre der Host-PC der Ursprung. Beim Weg ins Internet über das Default-GW findet bei IPv4 sogar ein weiteres Mal NAT statt. Die VM läuft somit in dem isolierten Netzwerk 192.168.122.0/24, das normale Netzwerk ist 10.0.1.0/24.
Das Bridge-Device verbindet hierbei nicht das virtuelle VM-Netzwerkinterface mit dem physischen Host-Netzwerkinterface (ETH o. WLAN) als Netzwerk-Brücke, stattdessen verbindet es das virtuelle VM-Interface mit einem virtuellen Host-Interface. Die Kommunikation ins LAN oder ins Internet aus der VM heraus erfolgt dann auf dem Host über simples Masquerading der aus der VM kommenden IP-Datenpakete und der anschließenden Weiterleitung an das Standard-Gateway. Für libvirt/KVM handelt es sich bei dieser Vorgehensweise um das Default-Netzwerk-Setup, welches den Anwender durch den Virt-Manager best-möglich unterstützt und welches automatisch für eine neue VM angelegt wird.
So wie die Lösung im vorherigen Kapitel die kürzeste war, so wird das hier voraussichtlich wohl die längste werden. Das liegt daran, um das mal so lapidar zu umschreiben, dass das erfolgreiche Zusammenspiel mehrerer Mitspieler tatsächlich umfangreiches Wissen um die Spielregeln erfordert und das jeder Spieler zur richtigen Zeit an richtiger Stelle auf dem Spielfeld bereit ist.
Im Terminal können wir nachsehen, wie libvirt/KVM die Netzwerk-Infrastruktur anhand der vorgegebenen Default-Parameter anlegt… und falls es im Moment noch nicht so ist, so ist das das Ziel, zu dem dieses Kapitel führen soll:
# ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 link/ether d0:3g:ff:9a:xy:zz brd ff:ff:ff:ff:ff:ff inet 10.0.1.56/24 brd 10.0.1.255 scope global dynamic eth0 valid_lft 863975sec preferred_lft 863975sec
3: virbr0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default qlen 1000 link/ether d0:3g:ff:9a:aa:bb brd ff:ff:ff:ff:ff:ff inet 192.168.122.1/24 brd 192.168.122.255 scope global virbr0 valid_lft forever preferred_lft forever
4: virbr0-nic: <BROADCAST,MULTICAST> mtu 1500 qdisc pfifo_fast master virbr0 state DOWN group default qlen 1000 link/ether d0:3g:ff:9a:aa:bb brd ff:ff:ff:ff:ff:ff |
eth0 ist das bereits bekannte physische Netzwerkinterface des Host-PCs, hier aktiv über die IP 10.0.1.56 mit dem lokalen Netzwerk und dem Default-Gateway verbunden. virbr0 ist das Bridge-Device, welches im weitesten Sinne selber gleichzeitig Client, Router und DHCP-Server des isolierten Netzwerks 192.168.122.0/24 ist virbr0-nic ist das virtuelle Netzwerkinterface auf dem Host-PC, welches durch die Bridge als Netzwerkbrücke mit dem Netzwerkinterface in der VM verbunden ist |
Im grafischen Dialog des Virt-Managers sieht das bei den individuell zur VM gehörenden Einstellungen für die Option ‚NIC‘ vor dem Start der Netzwerk-Infrastruktur wie folgt aus: |
Nach dem Start des virtuellen Netzwerks ändert sich der Status von Inaktiv auf |
Darüber hinaus gehört zu dieser Netzwerk-Infrastruktur ein automatisch angelegtes Regelwerk für den Paketfilter: |
# nft list ruleset table ip filter { chain INPUT { type filter hook input priority 0; policy accept; iifname "virbr0" meta l4proto udp udp dport 53 counter packets 0 bytes 0 accept iifname "virbr0" meta l4proto tcp tcp dport 53 counter packets 0 bytes 0 accept iifname "virbr0" meta l4proto udp udp dport 67 counter packets 0 bytes 0 accept iifname "virbr0" meta l4proto tcp tcp dport 67 counter packets 0 bytes 0 accept } chain FORWARD { type filter hook forward priority 0; policy accept; oifname "virbr0" ip daddr 192.168.122.0/24 ct state related,established counter packets 0 bytes 0 accept iifname "virbr0" ip saddr 192.168.122.0/24 counter packets 0 bytes 0 accept iifname "virbr0" oifname "virbr0" counter packets 0 bytes 0 accept oifname "virbr0" counter packets 0 bytes 0 reject iifname "virbr0" counter packets 0 bytes 0 reject } } table ip nat { chain POSTROUTING { type nat hook postrouting priority 100; policy accept; ip saddr 192.168.122.0/24 ip daddr 224.0.0.0/24 counter packets 0 bytes 0 return ip saddr 192.168.122.0/24 ip daddr 255.255.255.255 counter packets 0 bytes 0 return meta l4proto tcp ip saddr 192.168.122.0/24 ip daddr != 192.168.122.0/24 counter masquerade to :1024-65535 meta l4proto udp ip saddr 192.168.122.0/24 ip daddr != 192.168.122.0/24 counter masquerade to :1024-65535 ip saddr 192.168.122.0/24 ip daddr != 192.168.122.0/24 counter packets 0 bytes 0 masquerade } } table ip mangle { chain POSTROUTING { type filter hook postrouting priority -150; policy accept; oifname "virbr0" meta l4proto udp udp dport 68 counter packets 0 bytes 0 # CHECKSUM fill } } |
Was sind hierbei die primären Anforderungen:
1. Eine isoliertes Netzwerk mit einem eigenen IP-Range und einem DHCP-Server herstellen (dnsmasq)
2. Eine Netzwerk-Brücke zur späteren Verbindung von VM und physischen Host herstellen (bridge-utils)
3. Paketfilter-Regeln fürs Masquerading generieren (iptables oder nftables)
4. Die VM starten, Netzwerkverbindung herstellen (nwm, networking oder ifup@.service)
Die Default-Netzwerk-Infrastruktur (sowie wie auch jedes andere eigene Modell, welches man selber manuell angelegt hat) kann auf verschiedene Wege gestartet werden.
Zum Beispiel manuell im Terminal: | |
$ export LIBVIRT_DEFAULT_URI='qemu:///system'
| Umgebungsvariable für die Qemu/KVM-Infrastruktur setzen. Achtung: Das ist immer einmalig notwendig, wenn ein neues User-Terminal geöffnet wird. In einem Terminal mit root-Rechten ist das nicht erforderlich. Man kann dieses Statement natürlich auch direkt ans Ende der eigenen .bashrc eintragen... kein Problem, das geht, kann man machen. |
$ virsh list --all Id Name State ----------------------------- - tor shut off 1 archlinux running - jdl2 shut off - lmde shut off - lxqt shut off - Win7 shut off
$ virsh net-list --all Name State Autostart Persistent ------------------------------------------------ default inactive no yes | Vorhandene VMs auflisten
Vorhandene Netzwerk-Setups auflisten. Hier ist nur das „default“-Setup deklariert. |
$ virsh net-start default $ virsh start {vm-name} $ virt-viewer {vm-name} & $ virsh net-destroy default | > das Netzwerk „default“ manuell starten > die lokale VM mit {vm-name} starten > die gestartete VM anzeigen > nach Shutdown der VM das Netzwerk schließen |
|
|
$ virsh net-list --all Name State Autostart Persistent ------------------------------------------------ default inactive no yes
$ virsh net-autostart default Network default marked as autostarted
$ virsh net-list --all Name State Autostart Persistent ------------------------------------------------ default inactive yes yes
| Einrichten des Autostarts der Netzwerk-Infrastruktur beim Hochfahren des Rechners. Damit ist der manuelle Start über $ virsh net-start default nicht mehr notwendig. |
|
|
$ virsh net-autostart {netname} --disable | Deaktivieren des Autostarts für das angegebene Netzwerk |
|
|
Oder über die grafischen Dialoge des Virtmanagers, wofür es 2 Möglichkeiten gibt. Entweder das ausgewählte Netzwerk nur für die aktuelle Sitzung mit dem Start- oder Stop-Button nach Bedarf ein- und ausschalten. Oder die Checkbox für den Autostart aktivieren, wodurch die Netzwerk-Infrastruktur automatisch beim Starten des Host-PCs gestartet wird. | |
| |
Die vom Virtmanager verwendete default-Netzwerk-Infrastruktur enthält sogar im Namen der jeweiligen Konfigurationsdateien als Hinweis „default“. Die primären Einstellungen für dieses Netzwerk sowie für eine bestimmte VM befinden sich auf meinen Debian-Systemen in den folgenden Verzeichnissen/Dateien: | |
# cat /etc/libvirt/qemu/networks/default.xml # cat /var/lib/libvirt/dnsmasq/default.conf # cat /etc/libvirt/qemu/{vm-name}.xml | grep "<interface" -A 5 |
|
Zusätzlich werden beim Start dieser Netzwerk-Infrastruktur im Hintergrund (!) auch noch die für NAT notwendigen Regeln im Paketfilter des Host-PCs gesetzt. Diese Masquerading-Regeln sind letztlich dafür verantwortlich, dass überhaupt eine bidirektionale Kommunikation mit Absender- und Empfänger-IP-Adressen zwischen VM und ‚irgendwem‘ außerhalb des Hosts erfolgen kann. Ohne Masquerading würde es so sein, dass TCP-Pakete aus der VM zwar jeden Empfänger erreichen können, nur wird es nie möglich sein, dass Antwort-Pakete von diesen Empfänger wieder die VM erreichen. Das liegt einfach daran, dass die VM in einem isolierten Subnetz arbeitet, dessen IP-Range ein anderer ist, als der des lokalen regulären Netzwerks des DSL-Routers. Das bedeutet, weil die Antwort-Pakete an die IP-Adresse der VM ein anderes/fremdes Subnetz adressieren, gehen diese Pakete den gleichen Weg aller Pakete, die eine vom lokalen Netz abweichende Empfänger-IP-Adresse haben… und zwar durch das Default-Gateway (DSL-Router) ins Internet. Aber weil es auch dort für diese IP-Adresse keinen passenden Empfänger gibt, werden solche Pakete einfach ‚sterben‘, sie werden bei irgendeinem Knotenpunkt, ISP, RZ (was auch immer) verworfen.
Ich betrachte hier im folgenden Listing allerdings nur die wirklich wichtigen Regeln, denn sofern keine Firewall auf dem Desktop-PC/Laptop den Datenverkehr grundsätzlich behindert, sind tatsächlich nur diese folgenden die unbedingt notwendigen Regeln.
table ip nat { chain POSTROUTING { type nat hook postrouting priority 100; policy accept; ip saddr 192.168.122.0/24 ip daddr 224.0.0.0/24 counter packets 0 bytes 0 return ip saddr 192.168.122.0/24 ip daddr 255.255.255.255 counter packets 0 bytes 0 return meta l4proto tcp ip saddr 192.168.122.0/24 ip daddr != 192.168.122.0/24 counter packets 0 bytes 0 masquerade to :1024-65535 meta l4proto udp ip saddr 192.168.122.0/24 ip daddr != 192.168.122.0/24 counter packets 0 bytes 0 masquerade to :1024-65535 ip saddr 192.168.122.0/24 ip daddr != 192.168.122.0/24 counter packets 0 bytes 0 masquerade } } |
Eine erwähnenswerte Besonderheit ist das hier praktizierte zusätzliche Port-NAT für alle Daten-Pakete mit der Empfänger-Adresse eines fremden Subnetzes (von dem aber irgendwie dann eigentlich doch alle Pakete betroffen sind). Privilegierte Ports <1024 werden auf unprivilegierte Ports >1023 übersetzt. Dabei handelt es sich im Grunde um einen archaischen und qualitativ minderwertigen Sicherheitsmechanismus, bei dem nicht vertrauenswürdige Anwendungen keine Ports unter 1024 benutzen dürfen und Gast-VMs in Bezug auf die Verwendung der IP-Adresse des Hosts als nicht vertrauenswürdig gelten. Kann man so machen, muß man aber nicht…. ich tu‘s jedenfalls nicht.
Falls doch noch eine lokale Desktop-Firewall störend in den Datenverkehr eingreift, sind ggf. noch weitere Regeln für DNS und DHCP zu setzen. Dazu kann man sich aber einfach anschauen, welche Regeln die default-Infrastruktur anlegt und diese dann einfach übernehmen… damit sollten dann zu erwartende Blockier-Probleme erfolgreich beseitigt sein.
Das Thema „Default-Netzwerk-Infrastruktur“ kann jetzt prima mit der Erstellung einer neuen VM abgeschlossen werden, weil ja seitens des Netzwerks alle Vorarbeiten erfolgreich erledigt wurden. Eine neue VM kann komfortabel über den Virtmanager erstellt werden, einschließlich dem Start der hier besprochenen Netzwerk-Infrastruktur. Aber sie kann auch genauso komfortabel mit wenigen Befehlen innerhalb des Terminals erzeugt werden:
$ export LIBVIRT_DEFAULT_URI='qemu:///system' $ virsh net-start default
$ virt-install --connect qemu:///system \ --virt-type=kvm \ --network network=default \ --name testsystem \ --memory 4096 \ --vcpus=4 \ --disk=/var/lib/libvirt/images/testsystem.cow2,format=qcow2,size=8 \ --cdrom=/tmp/firmware-10.4.0-amd64-netinst.iso \ --noautoconsole \ --os-type linux \ --os-variant debian10 \ --hvm \ --graphics spice,listen=127.0.0.1
| Shell-Vars setzen, Netzwerk starten
Dieses mehrzeilige „Kommando-Paket“ komplett als 1 Befehl im Terminal ausführen.
- Name der VM, kann geändert werden - Der VM zugewieser RAM (hier sind 8 GB installiert) - Anzahl CPUs erlauben (dieses System hat nur 4) - Default-Dir, änderbar (dann Rechte beachten) - Installer-ISO (liegt in Dir mit rwx r-x r-x)
Achtung: Bitte dieses „Kommando-Paket“ nicht direkt per Copy/Paste in ein Terminal einfügen, sondern lieber den Umweg über einen Editor wählen, um zu kontrollieren, ob sich unerwünschte Leerzeilen eingeschlichen haben. Wenn ja müssen diese zuerst entfernt werden! |
Installation wird gestartet … Zuweisen von 'testsystem.cow2' 8 GB Sie können mit der Konsole verbinden, um den Installationsvorgang abzuschließen. | |
$ virt-viewer testsystem & | Öffnen des virtuellen Monitors, hier den Installer |
|
|
$ virsh list --all $ virsh start testsystem $ virt-viewer testsystem & | Nach Abschluß der Installation und dem Auto-Shutdown kann es sein, dass sie nicht neu gestartet wurde. Ansonsten... fertig... das wars... |
|
|
$ virsh net-destroy default | Nach Shutdown der VM das virtuelle Netzwerk beenden |
Ich vermute mal, der eine oder andere wird schon geahnt haben, dass das bisherige in diesem Kapitel alles nur ein Vorgeplänkel für das war, was jetzt folgt. Ja, stimmt… :-) ... aber dieses Vorgeplänkel war nötig. Einerseits glaube ich, dass es ein großer Vorteil ist den Ehrgeiz zu haben, so viel wie möglich dessen zu verstehen, was der eigene PC so tut. Und andererseits bin ich zweifelsfrei der Meinung, das mich bei diesem speziellen Thema nur das Verständnis über die Zusammenhänge in die Lage versetzt, ein relativ komplexes Konstrukt noch zu verbessern. Und noch mal ja, ich bin der Meinung, dass das durchaus verbesserungswürdig ist.
Tja, um das eigentliche Problem auf den Punkt zu bringen, bzw. einen Seitenblick auf real existierende Risiken zu werfen, ich habe ein sehr großes Problem mit den von libvirt/KVM automatisch erstellten Paket-Filter-Regeln. Meine Beweggründe sind einfach zu verstehen, wenn man sich einmal die kausal miteinander verbundenen Aspekte dieser Kette anschaut:
Speziell über das Thema Sicherheit, wovon gerade mein Reise-Laptop ausdrücklich betroffen ist, habe ich in den Artikeln < security > und < openvpn > ausführlich geschrieben. Und natürlich orientieren sich auch genau daran meine Ansprüche an die auf meinem Laptop laufenden VMs. Vor diesem Hintergrund betrachte ich es natürlich als absolutes NoGo, dass ein beliebiges installiertes Programm die von mir vorgegebenen Regeln dergestalt verändert, dass es eigene Regeln einfügt und diese ggf. sogar vor meinen eigenen Regeln Entscheidungen treffen. Das ist für mich eine Frage des Prinzips… und so etwas ist prinzipiell ausgeschlossen.
Wer hier an dieser Stelle vielleicht der Meinung wäre „ich surfe doch mit meinem Läppi über offene WLAN-Accesspoints in irgendeinem Urlaubsausland nur in der VM… da ist doch mein Läppi sicher…. “ unterliegt hier einem großen Irrtum. Der Laptop ist vielleicht vor den eigenen Fahrlässigkeiten sicher, die man selber im Internet anstellt, aber er ist eben überhaupt nicht sicher vor dem Accesspoint. Und gerade von einem fremden Netzwerk, in dem der eigene Laptop Mitglied ist, dessen Zustand und Integrität ich nicht kenne und dessen Absichten mir überhaupt nicht bekannt sind, geht meiner Einschätzung nach die größte Gefahr für meinen Laptop aus, kompromittiert zu werden. Ich kann ja noch nicht mal feststellen, ob der wirkliche Betreiber dieses Accesspoints der gleiche ist, von dem ich glaube, dass er der Betreiber ist, also z.B. der Wirt einer Gastätte, eines Cafe‘s.
Wie sieht also die Lösung für dieses Problem aus? Ganz einfach, ich kreiere meine eigene Netzwerk-Infrastruktur und folge damit unverändert der eigentlichen Intention dieses ganzen Artikels: Deaktivieren von potentiellen Problemquellen und die vorherigen Funktionen durch eine stabile und störungsarme eigene Lösung ersetzen. Wie bisher bei allen Lösungsansätzen dieses Artikels folge ich auch hier unverändert dem einmal eingeschlagenen Weg mit systemd-Service-Units.
Das lokale Netzwerk ist wie gehabt: Das virtuelle/isolierte Netzwerk ist: | 10.0.1.0 /24 172.16.0.0 /24 |
Zielvorstellung bzw. beabsichtigter Verwendungszweck für die folgenden Service-Units: Ein mobiles Linux-Gerät (Laptop, Netbook, etc.), welches sich via WLAN an einem Accesspoint verbindet und zusätzlich lokale vom Anwender bei Bedarf zu startende VMs bereitstellt. Die Netzwerkanbindung der VM erfolgt über ein virtuelles Bridge-Device, die Datenpakete der VMs erfahren allerdings durch den Paketfilter des Host-PCs via Masquerading eine Network-Address-Translation (NAT). | ||
$ hexdump -vn5 -e '/5 "02"' -e '/1 ":%02x"' -e '"\n"' /dev/urandom 02:af:7d:64:fd:33 | Eine UUID-MAC-Adresse für die virtuellen Devices erzeugen. Bit 1 im ersten Byte der MAC-Adresse ist das "Locale-Bit“, das anzeigt, dass es keine OEM-Adresse ist und das sie möglicherweise nicht eindeutig ist. Da es sich hier aber um ein lokales Setup handelt, ignorieren wir das. | |
| ||
Die Service-Unit zum Starten des Netzwerkes. Die Unit startet zusätzlich dnsmasq und die Paketfilter-Regeln. | ||
$ su - # nano /etc/systemd/system/kvm-isolated-network.service [Unit] Description=thlu:isolated-network.service Start isolated Network Wants=network.target After=basic.target network.target Requires=kvm-isolated-network-dns.service kvm-isolated-network-nft.service Before=kvm-isolated-network-dns.service kvm-isolated-network-nft.service Conflicts=shutdown.target
[Service] Environment="PATH=/bin:/usr/sbin:/usr/bin" Type=oneshot RemainAfterExit=yes
ExecStart=sysctl -w net.ipv4.ip_forward=1 ExecStart=ip link add br0 type bridge ExecStart=ip addr add 172.16.0.1/24 broadcast 172.16.0.255 dev br0 ExecStart=ip link set br0 address 02:af:7d:64:fd:33 ExecStart=ip link set br0 up ExecStart=ip tuntap add dev tap0 mode tap user root ExecStart=ip link set tap0 address 02:af:7d:64:fd:33 ExecStart=ip link set tap0 master br0 ExecStart=ip link set tap0 up
ExecStop=ip link set tap0 down ExecStop=ip link del tap0 ExecStop=ip link set br0 down ExecStop=ip link del br0
[Install] WantedBy=multi-user.target |
Die oberhalb generierte MAC für beide Devices zuweisen.
| |
| ||
Die Service-Unit zum Starten des DHCP-Servers mit dnsmasq: | ||
# nano /etc/systemd/system/kvm-isolated-network-dns.service [Unit] Description=thlu:isolated-network-dns.service Start dnsmask Requires=kvm-isolated-network.service
[Service] Environment="PATH=/bin:/usr/sbin:/usr/bin" Type=forking RemainAfterExit=yes
ExecStart=dnsmasq --conf-file=/etc/dnsmasq.d/kvm-isolated-network-dnsmasq.conf --dhcp-script=/usr/lib/libvirt/libvirt_leaseshelper ExecStop=pkill -f kvm-isolated-network-dnsmasq.conf
[Install] WantedBy=kvm-isolated-network.service | ||
| ||
Die Service-Unit zum Setzen sehr einfacher Paketfilter-Regeln. In diesem einfachen Beispiel werden die wenigen notwendigen Regeln automatisch beim Starten des isolierten KVM-Netzes gesetzt und beim Beenden ebenso automatisch wieder entfernt. Dieses automatische Entfernen wäre allerdings bei einem quasi-persistenten ‚größeren‘ Regelwerk kontraproduktiv, wenn eine passende Unit zum Beispiel weitere explizite Regeln enthalten würde oder wenn sie einfach via nft -f {filename} ein komplettes individuelles Regelwerk laden würde. In einem solchem Fall empfiehlt es sich, Requires durch Wants zu ersetzen. Dann wird diese Unit zwar wie zuvor mitgestartet, aber bei Ende des KVM-Netzwerks nicht gleichzeitig auch beendet. Wäre als weitere denkbare Möglichkeit eine Desktop-Firewall installiert und aktiviert, ist es sogar unbedingt ratsam, diese Unit komplett aus den Abhängigkeiten zu entfernen und die notwendigen Regeln manuell über deren Frontend-Dialoge in die FW einzutragen. | ||
# nano /etc/systemd/system/kvm-isolated-network-nft.service [Unit] Description=thlu:isolated-network-nft.service Set Netfiler Requires=kvm-isolated-network.service
[Service] Environment="PATH=/bin:/usr/sbin:/usr/bin" Type=oneshot RemainAfterExit=yes
ExecStart=sleep 3 ExecStart=nft flush ruleset ExecStart=nft add table ip filter ExecStart=nft add chain ip filter forward "{ type filter hook forward priority 0 ; policy accept; counter; }" ExecStart=nft add chain ip filter input "{ type filter hook input priority 0 ; policy accept; counter; }" ExecStart=nft add chain ip filter output "{ type filter hook output priority 0 ; policy accept; counter; }" ExecStart=nft add chain ip filter postrouting "{ type nat hook postrouting priority 100 ; policy accept; }" ExecStart=nft add rule ip filter postrouting ip saddr 172.16.0.0/24 ip daddr 224.0.0.0/24 return ExecStart=nft add rule ip filter postrouting ip saddr 172.16.0.0/24 ip daddr 255.255.255.255 return ExecStart=nft add rule ip filter postrouting ip saddr 172.16.0.0/24 ip daddr != 172.16.0.0/24 masquerade
ExecStop=nft flush ruleset
[Install] WantedBy=kvm-isolated-network.service | ||
| ||
Die Konfigurationseinstellungen für den DHCP-Server mit dnsmasq: | ||
# nano /etc/dnsmasq.d/kvm-isolated-network-dnsmasq.conf strict-order pid-file=/var/run/dnsmasq.pid except-interface=lo bind-dynamic interface=br0 dhcp-range=172.16.0.2,172.16.0.10 dhcp-no-override dhcp-leasefile=/var/lib/libvirt/dnsmasq/default.leases dhcp-lease-max=253 dhcp-hostsfile=/var/lib/libvirt/dnsmasq/default.hostsfile addn-hosts=/var/lib/libvirt/dnsmasq/default.addnhosts | ||
| ||
Die letzte noch fehlende Maßnahme ist entweder der manuelle Start der Netzwerk-Infrastrukrur, oder das Einrichten für den automatischen Start beim Booten des Host-PCs. Ein einmaliger Start der Service-Units ist auf jeden Fall sinnvoll, um auf Fehler zu prüfen. | ||
$ su - # systemctl start kvm-isolated-network.service | Manuelle Handhabung vor und nach dem Start der VM. Bitte dabei die unterschiedlichen Rechte zur Ausführung der Statements beachten. | |
# systemctl status kvm-isolated-network kvm-isolated-network-dns kvm-isolated-network-nft ● kvm-isolated-network.service - thlu:isolated-network.service Start isolated Network Loaded: loaded (/etc/systemd/system/kvm-isolated-network.service; disabled; vendor preset: enabled) Active: active (exited) since Wed 2020-07-29 16:23:31 CEST; 1min 52s ago
Jul 29 16:23:31 thomaspc systemd[1]: Starting thlu:isolated-network.service Start isolated Network... Jul 29 16:23:31 thomaspc systemd[1]: Started thlu:isolated-network.service Start isolated Network.
● kvm-isolated-network-dns.service - thlu:isolated-network-dns.service Start dnsmask Loaded: loaded (/etc/systemd/system/kvm-isolated-network-dns.service; disabled; vendor preset: enabled) Active: active (running) since Wed 2020-07-29 16:23:31 CEST; 1min 52s ago Process: 8624 ExecStart=/usr/sbin/dnsmasq --conf-file=/etc/dnsmasq.d/kvm-isolated-network-dnsmasq.conf ...
Jul 29 16:23:31 thomaspc dnsmasq[8628]: gestartet, Version 2.80, Cachegröße 150 Jul 29 16:23:31 thomaspc systemd[1]: Started thlu:isolated-network-dns.service Start dnsmask.
● kvm-isolated-network-nft.service - thlu:isolated-network-nft.service Set Netfiler Loaded: loaded (/etc/systemd/system/kvm-isolated-network-nft.service; disabled; vendor preset: enabled) Active: active (exited) since Wed 2020-07-29 16:23:32 CEST; 1min 52s ago
Jul 29 16:23:31 thomaspc systemd[1]: Starting thlu:isolated-network-nft.service Set Netfiler... Jul 29 16:23:32 thomaspc systemd[1]: Started thlu:isolated-network-nft.service Set Netfiler. | ||
# exit $ export LIBVIRT_DEFAULT_URI='qemu:///system' $ virsh start {vm-name} $ virt-viewer {vm-name} & $ su - # systemctl stop kvm-isolated-network.service |
| |
|
| |
# cd /etc/systemd/system # systemctl enable kvm-isolated-network.service | Alternativ für den automatischen Start beim Booten des System aktivieren |
An dieser Stelle muss ich zugeben, dass das Wechselspiel, mal als User zu arbeiten, mal als root, durchaus auch verwirrend sein kann. Das liegt daran, das Schreibzugriffe auf /etc/* oder Starts von Service-Units nur root vorbehalten sind, aber die eigentliche VM soll dennoch nur unter den unprivilegierten Rechten eines normalen Users laufen und nicht unter der UID 0. Der grafische Virtmanager umgeht das offensichtlich, weil er vermutlich direkt mit dem libvirt-Daemon unter UID 0 kommuniziert… denn ohne dem könnte er weder virtuelle Interfaces noch Paketfilter-Regeln anlegen.
Die Interface-Einstellungen für eine schon existierende VM sehen mit den neuen Settings ein wenig anders aus, als bei der Default-Netzwerk-Infrastruktur:
Die Einstellungen der VM können aber auch wieder einfach direkt im Terminal geändert werden. Dazu die Datei öffnen, passenden Abschnitt suchen, entsprechend ändern, speichern, fertig. Ein wichtiger Hinweis: die MAC-Adresse einer schon bestehenden VM muss hierbei nicht geändert werden. Wenn sich nur das Interface ändert, kann die alte MAC-Adresse durchaus weiter eingetragen sein:
# virsh edit {vm-name}
<devices>
<interface type='bridge'>
<mac address='d0:3g:ff:9a:aa:bb'/>
<source bridge='br0'/>
<model type='virtio'/>
</interface>
</devices>
Mit der laufenden neuen Netzwerk-Infrastruktur jetzt neu zu erstellende VMs über die grafischen Dialoge des Virtmanagers sind eigentlich selbsterklärend, natürlich muss auch da das virtuelle Interface br0 eingesetzt werden. Für eine neu zu erstellende VM im Terminal wird das neue Netzwerk mit der virtuellen Bridge wie folgt gesetzt:
$ virt-install --connect qemu:///system \
--virt-type=kvm \
--network=bridge=br0,model=virtio \
--name=testsystem \
:::
usw. wie zuvor
Achtung: Später, in der laufenden (!) VM, wird noch IPv6 deaktiviert, weil hier in diesem Beispiel gemäß der Einstellungen weder das Router Advertisement noch das Neighbor Discovery Protocol für IPv6 vom Host-Betriebssystem unterstützt wird. Diese Datei wird also im Verzeichnis /etc/… der laufenden VM angelegt. Die VM ist somit eine reine IPv4-VM. Der IPv6-Network-Stack auf dem Host-PC ist davon nicht betroffen:
# nano /etc/sysctl.d/kvm-isolated-network-noipv6.conf
net.ipv6.conf.default.disable_ipv6=1
net.ipv6.conf.all.disable_ipv6=1
|
Einrichten eines über ETH verbundenen Servers mit lokalen VMs als dedizierte Systeme
Mit diesem letzten Kapitel befasse ich mich mit meinem Server im LAN. Es ist ein ‚kleiner‘ NUC, der headless betrieben wird, also nicht über Bildschirm, Tastatur und Maus verfügt. Die komplette Wartung erfolgt über das Netzwerk, wovon natürlich auch alle installierten Services betroffenen, die über die normale Netzwerkverbindung hinausgehend ebenfalls unmittelbar mit Netzwerk-Einrichtung zu tun haben. Das sind hier z.B. OpenVPN, welches zwei virtuelle Netzwerke plus virtuelle Interfaces herstellt, ebenso wie 3 virtuelle Debian-Systeme, für die das gleiche gilt.
Dementsprechend umfangreich sieht auch die Interface-Konfiguration auf dem Rechner aus. Passend zu den Beispielen in meinen anderen Artikeln verwende ich hier wieder durchgängig die gleichen via IP definierten Subnetze:
Heim-Netzwerk | 10.0.1.0/24 |
Gateway und DHCP-Server | 10.0.1.1 |
VPN-Netzwerk (UDP) | 10.0.8.0/24 |
VPN-Netzwerk (TCP) | 10.0.9.0/24 |
|
|
Server …
… ist auch OpenVPN-Gateway und DHCP-Server für die Remote-VPN-Clients, wie Laptop, Notebox, Smartphones: UDP/IP = TCP/IP = | 10.0.1.2
10.0.8.1 10.0.9.1 |
|
|
Die drei VMs sind wegen der Notwendigkeit der gleichbleibenden Erreichbarkeit des eingerichteten Services im LAN jeweils als reguläre LAN-Clients mit einer statischen LAN-IP eingerichtet. | 10.0.1.20 10.0.1.21 10.0.1.22 |
$ ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master br0 state UP group ...
link/ether ?:?:?:?:?:? brd ff:ff:ff:ff:ff:ff
3: wlan0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
link/ether ?:?:?:?:?:? brd ff:ff:ff:ff:ff:ff
4: br0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
link/ether 02:af:7d:64:fd:33 brd ff:ff:ff:ff:ff:ff
inet 10.0.1.2/24 scope global br0
valid_lft forever preferred_lft forever
inet6 2022:16b8:z:y:x:w:v:u/64 scope global temporary dynamic
valid_lft 6945sec preferred_lft 3345sec
inet6 2022:16b8:b:c:d:e:f:g/64 scope global dynamic mngtmpaddr
valid_lft 6945sec preferred_lft 3345sec
inet6 fe80::b4/64 scope link
valid_lft forever preferred_lft forever
5: tun0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group ...
link/none
inet 10.0.8.1/24 brd 10.0.8.255 scope global tun0
valid_lft forever preferred_lft forever
inet6 fd00:10:0:8::1/64 scope global
valid_lft forever preferred_lft forever
inet6 fe80::261/64 scope link stable-privacy
valid_lft forever preferred_lft forever
6: tun1: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group ...
link/none
inet 10.0.9.1/24 brd 10.0.9.255 scope global tun1
valid_lft forever preferred_lft forever
inet6 fd00:10:0:9::1/64 scope global
valid_lft forever preferred_lft forever
inet6 fe80::271/64 scope link stable-privacy
valid_lft forever preferred_lft forever
7: vnet0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master br0 state UNKNOWN ...
link/ether 02:10:0:1:02:01 brd ff:ff:ff:ff:ff:ff
inet6 fe80::01/64 scope link
valid_lft forever preferred_lft forever
8: vnet1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master br0 state UNKNOWN ...
link/ether 02:10:0:1:02:02 brd ff:ff:ff:ff:ff:ff
inet6 fe80::02/64 scope link
valid_lft forever preferred_lft forever
9: vnet2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master br0 state UNKNOWN ...
link/ether 02:10:0:1:02:03 brd ff:ff:ff:ff:ff:ff
inet6 fe80::03/64 scope link
valid_lft forever preferred_lft forever
Weil meine grundsätzliche Herangehensweise zur Lösung der Probleme bei der erfolgreichen Einrichtung der Netzwerk-Infrastruktur in den vorherigen Kapiteln sukzessive aufbauend und umfassend beschrieben ist, verzichte ich hier auf wiederholte Erklärungen und ergänze nur, wenn es um neue Aspekte geht.
Zielvorstellung bzw. beabsichtigter Verwendungszweck für die folgende Service-Unit: Ein stationär eingesetzter Server, der verschiedene virtuelle Maschinen bereit stellt, die jede für sich reguläre LAN-Clients sind. Zusätzlich werden die für OpenVPN notwendigen tun-Devices erstellt. OpenVPN selber wird mit einer eigenen Service-Unit gestartet. | |
$ ip a s dev eth0 | grep 'link/ether' link/ether d0:3g:ff:9a:xy:zz brd ff:ff:ff:ff:ff:ff $ su - | MAC-Adresse vom phys. NIC wird für das virtuelle Bridge verwendet. |
# nano /etc/systemd/system/network.service [Unit] Description=thlu:network.service Start network connectivity After=network.target Wants=network.target
[Service] Type=oneshot RemainAfterExit=yes Environment="PATH=/bin:/usr/sbin:/usr/bin"
ExecStart=ip link add br0 type bridge ExecStart=ip link set br0 type bridge stp_state 0 ExecStart=ip link set br0 type bridge forward_delay 0 ExecStart=ip link set br0 address d0:3g:ff:9a:xy:zz ExecStart=ip addr add 10.0.1.2/24 dev br0 ExecStart=sysctl -w net.ipv4.ip_forward=1 ExecStart=sysctl -w net.ipv6.conf.all.forwarding=1 ExecStart=sysctl -w net.ipv6.conf.br0.forwarding=1 ExecStart=sysctl -w net.ipv6.conf.br0.disable_ipv6=0 ExecStart=sysctl -w net.ipv6.conf.br0.autoconf=1 ExecStart=sysctl -w net.ipv6.conf.br0.use_tempaddr=2 ExecStart=sysctl -w net.ipv6.conf.br0.accept_ra=2 ExecStart=ip link set eth0 master br0 ExecStart=ip link set eth0 up ExecStart=ip link set br0 up ExecStart=ip route add default via 10.0.1.1 ExecStart=openvpn --mktun --dev tun0 ExecStart=openvpn --mktun --dev tun1 ExecStart=ip link set tun0 up ExecStart=ip link set tun0 up
ExecStop=ip link set eth0 nomaster ExecStop=ip link set eth0 down ExecStop=ip addr flush dev eth0 ExecStop=ip link set br0 down ExecStop=ip addr flush dev br0 ExecStop=ip link del br0 type bridge ExecStop=ip link set tun0 down ExecStop=ip link set tun1 down ExecStop=openvpn --rmtun --dev tun0 ExecStop=openvpn --rmtun --dev tun1
[Install] WantedBy=multi-user.target | |
Das Hardware-Interface eth0 erhält keine IPv4, sicherstellen, dass der Kernel auch keine IPv6 via SLAAC generiert: | |
# nano /etc/sysctl.d/sysctl_ipv6_server.conf net.ipv6.conf.all.forwarding=1
net.ipv6.conf.default.disable_ipv6=0 net.ipv6.conf.default.forwarding=1 net.ipv6.conf.default.autoconf=0 net.ipv6.conf.default.use_tempaddr=0 net.ipv6.conf.default.accept_ra=0
net.ipv6.conf.eth0.disable_ipv6=1 net.ipv6.conf.eth0.forwarding=1 net.ipv6.conf.eth0.autoconf=0 net.ipv6.conf.eth0.use_tempaddr=0 net.ipv6.conf.eth0.accept_ra=0 | |
Ein manueller Teststart. Wenn der Teststart fehlerfrei verlaufen ist und die Netzwerkverbindung hergestellt ist, dann kann die Service-Unit für den Systemstart aktiviert werden: | |
# cd /etc/systemd/system # systemctl start network.service
# systemctl status network.service ● network.service - thlu:network.service Start network connectivity Loaded: loaded (/etc/systemd/system/network.service; enabled; vendor preset: enabled) Active: active (exited) since Sun 2020-08-02 12:21:19 CEST; 2h 34min ago Process: 462 ExecStart=/usr/sbin/ip link add br0 type bridge (code=exited, status=0/SUCCESS) Process: 481 ExecStart=usw….. Main PID: 601 (code=exited, status=0/SUCCESS) Aug 02 12:21:19 server systemd[1]: Started thlu:network.service Start network connectivity.
# systemctl enable network.service Created symlink /etc/systemd/system/multi-user.target.wants/network.service → /etc/systemd/system/network.service. |
Weil es sich bei diesem Server hier um einen Headless betriebenen Server handelt, muss natürlich für alle späteren Wartungsarbeiten OpenSSH-Server installiert und gestartet sein, ein berechtigter Benutzer und die Pubkey-Authentifizierung für die SSH-Verbindung ist eingerichtet. Wenn das gegeben ist, kann ich mich nun von jedem beliebigen anderen Client-System im LAN via SSH auf dem Server anmelden und eine VM erstellen, starten oder stoppen. Für den reinen Installationsvorgang auf der VM mit Debian nach dem Start der VM ist SSH zunächst nicht mehr notwendig, die Remote-Bedienung des Installers erfolgt bequem vom eigenen PC über einen VNC-Viewer. | |
$ ssh thomas@10.0.1.2 | Via SSH zum Server verbinden |
$ su - # mkdir /srv/qemu # chown root:libvirt-qemu /srv/qemu # chmod 770 /srv/qemu # ls /srv/qemu insgesamt 8,0K drwxrwx--- 2 root libvirt-qemu 4,0K 2020-08-02 15:52 . drwxr-xr-x 3 root root 4,0K 2020-08-02 15:52 .. | Auf dem Server notwendige Vorbereitungen und dann den Start des Installers durchführen. |
# virt-install --connect qemu:///system \ --virt-type=kvm \ --network=bridge=br0,model=virtio \ --name testsystem \ --memory 2048 \ --vcpus=2 \ --disk=/srv/qemu/testsystem.cow2,format=qcow2,size=8 \ --cdrom=/tmp/firmware-10.4.0-amd64-netinst.iso \ --noautoconsole \ --os-type linux \ --os-variant debian10 \ --hvm \ --graphics vnc,port=60000,listen=0.0.0.0,keymap='de' | Die Installation erfolgt durch root, später wird die VM unter dem virtuellen User ‚libvirt-qemu‘ laufen.
Achtung: Bitte dieses „Kommando-Paket“ nicht direkt per Copy/Paste in ein Terminal einfügen, sondern lieber den Umweg über einen Editor wählen, um zu kontrollieren, ob sich unerwünschte Leerzeilen eingeschlichen haben. Wenn ja müssen diese zuerst entfernt werden!
Die Verbindung aus dem LAN zur VM erfolgt via vncviewer über den Port 60000. Natürlich kann man auch den Default-Port für VNC (5900) verwenden, ich nehme hier nur einen anderen, um zu zeigen, dass das geht und wie es geht. |
Installation wird gestartet … Zuweisen von 'testsystem.cow2' 8 GB Sie können mit der Konsole verbinden, um den Installationsvorgang abzuschließen. | |
# exit | Die aktivierte SSH-Verbindung kann wahlweise geschlossen werden oder auch offen bleiben. |
Ich verlasse jetzt den Server und starte auf meinem eigenen PC ein neues lokales Terminal, um dort in einem Remote-Fenster alle Fragen des Installers zu beantworten: | |
$ vncviewer 10.0.1.2:60000 & | Die Verbindung von meinem PC zur auf dem Server neu einzurichtenden VM erfolgt mit der IP-Adresse des Server über den ‚vncviewer‘ aus dem Debian-Paket ‚xtightvncviewer‘. Diese Lösung hat sich hier über lange Zeit als sehr zuverlässig und stabil erwiesen. |
Wenn der Installer fehlerfrei durchgelaufen und die Installation erfolgreich abgeschlossen ist, wurde die neue VM am Ende automatisch geschlossen. Also wird die neue VM kurzerhand in der noch offenen SSH-Verbindung zum Server direkt auf dem Server einfach wieder neu gestartet:
# virsh list --all
Id Name State
-------------------------------
- testsystem shut off
# virsh start testsystem
Domain testsystem started
Die VM ist nach dem erfolgreichen ersten Start mit einem z.B. neu installierten Debian ab jetzt immer via VNC-Viewer erreichbar. Gleichermaßen sollte der DSL-Router diese neue VM jetzt auch als eigenständigen LAN-Client mit einer eigenen LAN-IP in seiner Client-List anzeigen, mit der vom DSL-Router via DHCP vergebenen IP. Und sobald in der VM auch der OpenSSH-Server installiert und eingerichtet wurde, kann die VM alternativ zum VNC-Zugang jederzeit auch direkt via SSH von anderen LAN-Clients adressiert werden.
Wenn es notwendig ist, der VM eine statische IP zu vergeben, kein Problem…. was dazu notwendig ist, wurde bereits weiter oben in diesem Artikel besprochen. Die VM hat im Grunde genommen die gleichen Möglichkeiten und stellt die gleichen Anforderungen, wie jeder andere aus Hardware bestehende PC auch, der im lokalen Netzwerk betrieben wird.
Eine auf dem Server eingerichtete VM kann -sofern man das möchte- mit dem folgenden Befehl einschließlich aller Konfigurationsdaten vollständig entfernt werden:
# virsh undefine testsystem –remove-all-storage
Domain testsystem has been undefined
Volume 'vda'(/srv/qemu/testsystem.cow2) removed.
|
Haftungsausschluss: Ich erhebe keinen Anspruch darauf, dass dieser Artikel vollständig fehlerfrei ist und ich behaupte das auch nicht. Sowohl - durch meine Fehler hier - wie auch durch vorhandene Fehler in den hier verwendeten Linux-Programmen - sowie durch ggf. zeitgleich auftretende äußere mechanische Einflüsse - oder durch den Anwender selber verursacht durch Änderungen an Programmen - oder durch unsachgemäße oder fehlerhafte Einrichtung der Programme beim Setup, z.B. wegen fehlerhafter Parameter kann es zu Datenverlust kommen. Durch unsachgemäße Sicherung und dem Betrieb eines deswegen unsicheren von außen erreichbaren Zugang ins Heimnetzwerk kann sogar das ganze private Netzwerk kompromittiert werden.
Deshalb schließe ich jede Haftung für Schäden an Software oder Hardware oder Vermögensschäden oder für Datenverlust aus, die durch die Benutzung dieses Tutorials enstehen. Die Benutzung dieses Tutorials, die Einrichtung der Services danach und der produktive Einsatz erfolgt auf eigenes Risiko. |
|