Upgrade-Zeit – Vorsorge durch Fallback-Installationen – I

Vor wenigen Wochen lief bei Opensuse und bei Ubuntu der Supportzeitraum für die jeweils vorletzten Versionen ab. Ein Leser des Blogs hat mich angeschrieben und gebeten, mal für einen Linux-Einsteiger zu beschreiben, wie ich denn bei System-Upgrades “immer wieder auftauchenden Problemen aus dem Weg” ginge.

Erste spontane Antwort: Gar nicht 🙂 ; Probleme tauchen halt auf und sind zu lösen oder zu umgehen. Ich habe die Frage dann aber mal wie folgt interpretiert:

Wie erhält man sich trotz möglicher Upgrade-Probleme die Fähigkeit zum beruflich dringend erforderlichen Weiterarbeiten, wenn es nach dem Upgrade Probleme gibt?

Das ist durchaus ein paar Betrachtungen wert. Gerade Freiberufler können sich Arbeitsausfälle aufgrund “zerschossener” Systeme nicht leisten. Das betrifft bei mobilen Beratern u.a. Laptop-Installationen.

Beim Schreiben fiel mir allerdings auf, dass ich vor Upgrades/Updates alleinstehender Linux-Systeme zu Methoden greife, in die sich ein “Einsteiger” erst mal einarbeiten muss und die selbst auch ein gewisses Gefahrenpotential in sich bergen. Leute, das kann ich euch leider nicht ersparen. Deshalb vorweg:

Bitte seid bei einer Nachahmung der nachfolgenden Vorschläge extrem vorsichtig, macht Backups und testet erstmal in einer risikofreien Umgebung – im Besonderen das Kopieren von Festplatten-Partitionen. Ich hafte nicht bei Schäden.

Ferner benötigt man für meinen Ansatz HDs/SSDs mit 500GB aufwärts; man braucht Plattenplatz. Dennoch hat sich die nachfolgend beschriebene Methodik bewährt; sie hat mir schon des öfteren wertvolle Zeit für Problemlösungen verschafft. Die Vorgehensweise hat aber nur einen Sinn auf Einzelplatz-Systemen; sie ist nicht (!) für Server oder Firmen-Installationen geeignet. Und: Sie ersetzt keineswegs (regelmäßige) Backups auf externe Medien!

Frust nach und mit Upgrades/Updates unter Linux? Ja, das gibt es …

Viele Linux-Einsteiger beschreiben ein gar nicht so seltenes Erlebnis mit ihrem Desktop- oder Laptop-System so: “Dann hab’ ich mein Linux upgedated bzw. upgegradet und dabei wohl was falsch gemacht – und mir das System zerschossen. Musste neu installieren.“. (Siehe u.a. Linux-Foren unter Facebook). Das sollte eigentlich unter Linux nicht so ablaufen … passiert aber dennoch.

Ein Grund ist vermutlich: Für Einsteiger ist schwer zu erkennen, was mögliche Ursachen für das “Zerschießen” sind und wo bzw. wie man die richtigen Maßnahmen zur Korrektur einleitet. Der Wunsch, möglichst schnell wieder arbeiten zu können, führt dann gerade bei Windows-Umsteigern fast reflexartig zu Neuinstallationen.

Was manchmal schon im Zuge komplexer Packet-Updates passiert, gilt erst recht für Linux-System-Upgrades, bei denen womöglich auch noch an Grundfesten des Systems gerüttelt wird (wie etwa bei der Einführung von systemd, neuen KDE-Haupt-Versionrn, etc…). Spätestens nach der ersten schlechten Erfahrung mit einem System-Upgrade stellt man sich beim nächsten Mal Fragen:

Soll ich (nach einer Datensicherung) die neue Linux-Version auf einer neuen oder der bisherigen System-Partition ganz von Null neu installieren? Oder die alte Installation durch komplizierte Schritte auf die neue Version bringen? Mit dem Risiko, dass dabei etwas schiefgeht, das System nicht mehr bootet, man sich nicht mehr einloggen kann oder die graphische Oberfläche nicht mehr läuft? Und man nicht mehr produktiv arbeiten kann?

Das sind alles berechtigte Fragen! Frustrierende Erlebnisse mit System-Komponenten, die nach Updates/Upgrades nicht mehr erwartungsgemäß funktionieren, haben nämlich auch erfahrene Linux-User immer wieder. Glaubt keinem, der etwas anderes behauptet!

Auch unter Linux gilt: Shit happens! Und oft genug liegt die Schuld nicht mal bei einem selbst … Linux
ist halt ein komplexes Konglomerat aus unterschiedlichen Komponenten, die von unterschiedlichen Teams entwickelt werden. Die Zusammenstellung übernehmen Distributoren, die auch nicht jede mögliche Installationsvariante testen können. Hinzu kommen ggf. problematische Treiber, u.a. für Grakas. Ergebnis: Fehler treten häufiger auf, als einem als Linux-Fan lieb wäre ….

Vorsorge und Arbeits-“Continuity”

Erfahrene Linux-Nutzer sorgen vor, indem sie eine funktionierende Arbeitsumgebung vorhalten. Komplette Neuinstallationen sind bei Update-Problemen nur selten der richtige Weg: erstens lernt man durch Neuinstallationen nichts und zweitens besteht die Gefahr, wieder in die gleiche Falle zu tappen. Im Falle von System-Upgrades führt eine Neuinstallation dagegen zum mühsamen Nachziehen von bereits getroffenen Konfigurationsentscheidungen – und ohne Rückgriff auf eine noch funktionierende Installation ist das Arbeiten in dieser Phase ggf. eingeschränkt.

Natürlich denkt man vor Updates/Upgrades an Backups der vorhandenen funktionstüchtigen Installation auf externe Medien. Das setzt voraus, dass man sich mit der Restaurierung ganzer Betriebssysteme und den zugehörigen Linux-Tools befasst. Zu dieser wichtigen Grundübung findet man viele hilfreiche Artikel im Internet. Ich möchte in diesem Artikel aber eine andere, zusätzliche Maßnahme besprechen – und zwar den den Ansatz einer

vorsorgenden Partitionierung – unter Einschluss jederzeit bootbarer “Fallback- und Experimental-Partitionen”.

Das ersetzt (regelmäßige) Backups (u.a. für den Fall vom Plattendefekten) keineswegs, erleichtert aber den Umgang mit komplexen Updates oder System-Upgrades.

Motivation ist die Aufrechterhaltung der Möglichkeit zum schnellen Fortsetzen der produktiven Arbeitfür den Fall, dass beim Updaten/Upgraden etwas schief geht. Man spricht auch von ArbeitsKontinuität oder neudeutsch “Continuity“, die eben die Verfügbarkeit funktionierender Installationen voraussetzt.

Nun höre ich schon die Profis fragen: Schon mal was von Snapshots gehört? Ja, aber der von mir beschriebene Ansatz ist auch dann wirkungsvoll, wenn man sich mit Snapshot-Systemen (wie etwa auf Basis von BtrFS oder LVM2) noch nicht auskennt. Zudem sind Filesystem-Snapshots bei vollständigen System-Upgrades eher in Frage zu stellen.

Voraussetzungen und Zielgruppe

Der Artikel richtet sich an Linux-Ein/Um-Steiger, die schon ein paar Schritte mit dem System gegangen sind und sich bereits ein wenig in Plattenpartitionierung wie den Systemstart über Boot-Manager eingearbeitet haben – oder willens sind, das zu tun. So setze ich voraus,

  • dass man weiß, was Partitionen (oder ggf. LVM-Volumes) und Filesysteme sind, wie man die mit entsprechenden Tools seiner Linux-Distribution oder auf der Kommandozeile erstellt, dimensioniert und in den Hauptverzeichnisbaum einhängt (mounted),
  • dass man bereit ist, sich mit den Befehlen “dd”, “uuidgen” und “tune2fs” auseinanderzusetzen
  • dass man keine Scheu hat, System-Dateien zu editieren.
  • dass man bereit ist, sich ein wenig um Grub2 als Boot-Manager auseinanderzusetzen.
  • dass genügend Festplattenplatz vorhanden ist, um 3 Betriebssystem-Partitionen mit einer Größe von etwa 40 bis 80 GByte aufzunehmen.

Der letzte Punkt mag dem einen oder anderen als Platzverschwendung erscheinen. Ja, das erscheint mir aber in der Abwägung gegenüber dem Punkt “kontinuierliche Arbeitsfähigkeit” und auch gegenüber der Schonung von Nerven zweitrangig.

Übrigens: Bis auf spezielle EFI- und Swap-Partitionen, verwende ich den Begriff “Partition” nachfolgend auch synonym für logische LVM2-Volumes. Das ist technisch natürlich nicht korrekt; der Unterschied tut
hier aber nichts zur Sache. LVM2 ist im besonderen mit dem Grub2-Boot-Manager kompatibel. Wem die Begriffe LVM2 und LVM-Volume nichts sagen, kann deren weitere Erwähnung in Klammern erstmal getrost ignorieren.

Ich erläutere die hier verfolgte Philosophie einer Fallback-Partition für Desktop-Systeme und Laptops anhand von Opensuse. Die Grundprinzipien lassen sich meist aber einfach auf andere Distributionen wie etwa Ubuntu abbilden – auch wenn sich ein paar Bezeichnungen von Dateien oder Programmen leicht unterscheiden. Es geht mir auch nur um alleinstehende Desktop-/Laptop-Systeme, auf denen man weitgehend der Herr des Geschehens ist – nicht aber um Server-Systeme oder server-basierte Installationen; letztere erfordern andere Fallback- und Continuity-Strategien.

Vier Maxime für den Umgang mit Updates/Upgrades

Beim Umgang mit kritischen Updates von Systemkomponenten oder gar Upgrades des Betriebssystems orientiere ich mich an folgenden Leitlinien:

  • Never touch a running system – ohne die Konsequenzen zu kennen oder solide einschätzen zu können.
  • Haupt-Installation und separate Partitionen für Nutz- und Anwendungsdaten: Die Betriebssystem-Installation für den täglichen Gebrauch erfolgt auf einer Festplattenpartition begrenzter Größe. Es wird von vornherein eine getrennte Ablage von OS-System-Dateien einerseits und späteren Projekt-Daten (Applikationsdaten, Nutzerdateien, ggf. Virtualisierungsumgebungen) andererseits auf unterschiedlichen Partitionen (LVM-Volumes) der Systemplatte(n) angestrebt.
  • Fallback-Installation: Im beruflichen Einsatz muss man bei Problemen schnell auf eine noch funktionierende Installation zurückgreifen können – hierzu braucht es eine jederzeit bootbare Fallback-Installation auf einer weiteren, separaten Partition der HD/SSD des Systems.
  • Experimental-Installation: Man braucht eine Spielwiese, um neue Programme, aber auch umfassendere oder kritische Updates/Upgrades gefahrlos ausprobieren zu können. Eine entsprechende dritte Betriebssystem-Installation sollte auf einer weiteren eigenen Partition (Volume) untergebracht werden.

Während die erste Maxime übergreifend gilt, haben die anderen drei offenbar eine Auswirkung auf die Partitionierung (und/oder das LVM-Layout) des Systems. Die “Methodik” zur Erhaltung der Arbeitsproduktivität besteht also darin,

  • dass man eine garantiert funktionsfähige Fallback-Installation in bootfähigem Zustand bereit hält,
  • dass man komplexe Updates/Upgrades erstmal auf einer Experimental-Installation austestet, bevor man die Updates/Upgrades auf der Haupt-Installation nachzieht.
  • dass man zu geeigneten Zeitpunkten sowohl die Fallback-Installation als auch die Experimental-Installation als Kopie eines funktionierenden Zustands der Hauptinstallation erneuert. (Falls in zeitlicher Nähe: zuerst die Experimental-Installation und dann die Fallback-Installation.)

Das ist zunächst mal einfach und hoffentlich auch einleuchtend. Wie man die Partitions-“Kopien” erzeugt und dabei Boot-Probleme vermeidet, besprechen wir später. Zunächst gilt:

“Continuity” erfordert, mehrere funktionierende Betriebssystem-Installationen auf ein und demselben System vorzuhalten. Eine dient als Fallback für das produktive Arbeiten, wenn es mal zu Problemen mit der “Haupt-Installation” kommt. Die Fallback-Installation ist daher bzgl. Updates extrem vorsichtig zu behandeln. Ggf. wird man Updates sogar völlig unterlassen. Die Funktionstüchtigkeit dieser Installation ist wichtiger als ein aktueller Paket-Status!

Alle drei in der Liste angesprochenen Installationen müssen separat bootbar sein – und die Daten, mit denen man kontinuierlich (weiter-) arbeiten will, müssen deshalb unabhängig von den einzelnen OS-Installationen gelagert werden.

Ein Zugriff auf produktive Projekt-Daten muss von jeder der drei Installationen aus durch ein “Mounten” des Filesystems der Datenpartitionen in definierte Knotenpunkte des jeweiligen Verzeichnisbaums in gleichartiger Weise ermöglicht werden (s.u.).

Wir benötigen jedenfalls mehrere Partitionen (oder LVM-Volumes) auf der/den Systemplatte/n. Das kann dann in etwa so aussehen:

Die erste Aufgabe für den Linux-Einsteiger, der der obigen Philosophie folgen will, ist also:

Mache dich mit der Partitionierung einer Festplatte und Tools wie etwa “gdisk“, “gparted” oder unter Opensuse auch mit dem “Yast Partitioner” vertraut. Zur Einrichtung eines reinen Linux-Systems sollte man dabei auch schon mal was von ein GPT-Layout von Festplatten gehört haben – und sich (soweit möglich) von veralteten Dingen wie “erweiterten Partitionen” aus MSDOS- bzw. MBR-Zeiten lösen. Siehe etwa: https://wiki.ubuntuusers.de/Partitionierung/Grundlagen/, http://www.linux-community.de/Internal/Artikel/Print-Artikel/EasyLinux/2016/01/OpenSuse-Leap-42.1, https://kofler.info/opensuse-leap-42-1/.

(Merke nebenbei: MS Windows gehört unter Linux eigentlich ins “Fenster”; genauer in eine virtuelle Maschine; zumindest dann, wenn man Windows nicht für 3D-Games benötigt. Auf sowas wie eine primäre NTFS-Partition in einem MBR-Plattenlayout kann man dann völlig verzichten. Will man eine vorhandene NTFS-Windows-Partition aber aus berechtigten (!) Lizenz-Ängsten und auf UEFI-Systemen aus Ängsten vor Boot-Fehlern nicht zerstören, sollte man sie in jedem Fall verkleinern. Die meisten Linux-Installationsprogramme bieten das an.)

Partitionsgrößen für die Betriebssystem-Installationen relativ klein halten!

Als Einsteiger tendiert man dazu, während der Linux-Erstinstallation ein vom Installer der jeweiligen Distribution vorgeschlagenes Partitionsmuster für die Festplatten zu übernehmen. Die meist vorgeschlagenen 2 oder 3 Linux-Partitionen (neben einer Swap- und ggf. auch einer EFI-Partition) umfassen dann insgesamt oft den gesamten Plattenplatz. Kennt man sich dann aber nicht mit so schönen Dingen wie LVM aus, nimmt einem das erhebliche Flexibilität!

Leuten mit ein wenig Erfahrung rate ich deshalb eher dazu, sich im Vorfeld einer Installation genau zu überlegen, welche Partitionen man tatsächlich für welche Zwecke auf seinem Desktop-System benötigt. Den Platz für die zu hauptsächlich zu nutzende Betriebssystem-Installation sollte man dabei auf das Notwendige (s.u.) begrenzen und den Rest der Platte erstmal frei halten.

Zweite Aufgabe für Umsteiger:

Bei der ersten Installation von Linux sollte man die Partition für das Root-Filesystem in der Größe begrenzen; sinnvolle Werte liegen nach meiner Erfahrung zwischen 40GB und 80GB. Das lässt einem genügend Luft für Programm-Installationen und Experimente. Persönlich nehme ich meist 80 GB. Den Vorschlag für eine Swap-Partition kann man übernehmen. Auf weitere Partitionen (etwa wie oft vorgeschlagene für “/home”) kann und sollte man dagegen erst mal verzichten; sie kann man später bei Bedarf immer noch anlegen.

(Bei Nutzung von LVM sollte man unabhängig von der zugrunde liegenden Partitionierung und Volume-Gruppen das logische Volume für das Root-Filesystem begrenzen). Auf einem reinen Linux-PC-System gibt es in meinem Ansatz daher zunächst nur : ggf. eine EFI-Partition, eine rel. kleine Swap-Partition (< 4GB) und eine Partition für das Root-/-Filesystem (mit 40 bis 80GB; in ext4-Formatierung, s.u). Sonst nix!

Wir nutzen den freigelassenen Plattenplatz für unsere Daten-Partition(en) und für weitere Partitionen (Volumes), die unsere Fallback- bzw. Experimental-Installation aufnehmen. Wir werden die Inhalte der Fallback-Partition und der Experimental-Partition später als Kopien eines bestimmten Zustands der Hauptinstallation erstellen. Wir benötigen also mindestens 2 x die Größe der Partition für die Hauptinstallation (also z.B. 3 x 80GB) als freien Plattenplatz; den Rest können wir für eine oder mehrere Datenpartitionen nutzen. (Hinweis: Will man mit schnellen Virtualisierungssystemen arbeiten, braucht man ggf. auch dafür weitere Partitionen (Volumes).)

Unter Opensuse wird während der Installation der sog. YaST-Partitionmanager angeboten. Er erlaubt eine Reduktion der Partitionsgröße im sog. “Expertenmodus”. Ein weiterer Punkt: Nehmt als Anfänger lieber “ext4” als Filesystem und nicht BtrFS. Ich habe hierfür gute Gründe, die ich aus Platzmangel an dieser Stelle aber nicht erläutern kann.

Hat man aber die Erstinstallation bereits hinter sich und wurden dabei zu große Partitionen angelegt, muss man im Nachhinein Platz schaffen. Hierbei muss man sich mit Hilfe der genannten Partitionierungstools dazu kundig machen, welche Partitionen im aktuellen Zustand noch wie weit verkleinert werden können. Danach kann man die vorhandenen Partitionen mit Hilfe der Partitionstools in der Größe reduzieren. Ggf. muss man dazu vorher ein Live-System oder eine Rettungsinstallation von CD/DVD oder USB-Disk booten.

Einsatz eines Bootmanagers – Grub2

Unsere Strategie läuft auf mehrere bootbare Linux-Installationen hinaus. Linux erlaubt über die Installation von sog. “Boot-Managern” das Booten verschiedener Betriebssystem-Installationen aus unterschiedlichen Partitionen der HDs/SSDs des Systems. Hierzu wird einem beim Systemstart eine Liste verfüg- und bootbarer Installationen angezeigt.

Bootmanager werden von den meisten Linux-Distributionen bereits im Rahmen der Erstinstallation des Systems eingerichtet. Der aktuelle distributionsübergreifende Standard ist hierbei wohl “Grub2“. Eine gute Übersicht über diesen relativ komplexen Bootmanager liefern folgende Artikel:

https://en.wikipedia.org/wiki/Grub2#GRUB_version_2
https://opensource.com/article/17/3/introduction-grub2-configuration-linux
https://wiki.ubuntuusers.de/GRUB_2/ und https://wiki.ubuntuusers.de/GRUB_2/Konfiguration/
Für Details siehe: https://www.gnu.org/software/grub/manual/grub/grub.pdf

Ich kann in diesem Artikel aus Platzgründen nicht auf Details von Grub2 eingehen. Für unsere Zwecke ist es ausreichend zu wissen, dass der Grub2-BootLoader in drei Schritten installiert oder modifiziert wird: Zunächst wird aus Vorgaben in der Definitionsdatei “/etc/default/grub” und weiteren Skript- und Konfigurations-Dateien unter dem Verzeichnis “/etc/grub.d/” eine temporäre Konfigurationsdatei erzeugt. Der notwendige Befehl ist je nach Distribution “grub-mkconfig” (z.B. Ubuntu) oder “grub2-mkconfig” (z.B. Opensuse). Das Ergebnis kann man dann über die Kommandozeile mit dem Kommando “update-grub” in die Datei “/boot/grub/grub.cfg” (Ubuntu) bzw. “/boot/grub2/grub.cfg” (Suse) schreiben lassen. Schließlich
schreibt man dann die notwendigen Informationen und Boot-Programme mittels des CLI-Befehls “grub-install” (Ubuntu) oder “grub2-install” (Suse) in bestimmte Plattenbereiche (die wiederum u.a. vom Platten-Layout, GPT oder MBR abhängen).

Spezialtools der verschiedenen Distributionen führen zumindest Teile oder gar alle dieser Schritte in einem Arbeitsvorgang durch:
Opensuse: Yast2 >> System >> Bootloader”
Ubuntu: z.B. Grub Customizer (https://www.pcwelt.de/ratgeber/Grub-Bootloader_anpassen-10017211.html, https://www.bitblokes.de/den-bootloader-via-gui-im-griff-grub-customizer/, https://wiki.ubuntuusers.de/GRUB_Customizer/)
Diese Tools erlauben es auch, die Systempartitionen nach anderen bootbaren Installationen durchsuchen zu lassen – und binden letztere in die Auswahlliste des Boot-Menüs ein.

In unserem Kontext ist/wird vor allem die Konfigrationsdatei “/boot/grub[2]/grub.cfg” relevant. Man kann diese Datei zur Not auch mit einem Editor modifizieren, wenn man sicher ist, was dabei zu tun ist. Wir werden weiter unten lediglich bestimmte begrenzte Strings der “grub.cfg” (in kopierten Partitionen) durch andere ersetzen.

Dritte Aufgabe für Umsteiger:

Befasst euch mit dem Boot-Vorgang und dem Grub2-Boot-Manager.

Nutzdaten auf separaten Partitionen – und die besondere Rolle des eigenen Home-Verzeichnisses “~”

In meiner “Methodik” ist die Unterscheidung zwischen Partitionen für die Systeminstallation einerseits und für Nutzdaten andererseits essentiell. Die meisten Nutzdaten, die man als Benutzer anlegt, lassen sich in Projekte und eigene Ordnerhierarchien gliedern und schlagen sich in dortigen Dateien nieder (z.B. Text-Dateien, Präsentationen, selbst entwickelte Programme, Bilder, Movies …). Hinzu kommen Daten wie Favoriten aus bestimmten Applikationen, die man meist aber zur Sicherungszwecken in separate Files exportieren und importieren kann. Selbst den Ablageort von Datenbank-Dateien kann man meist selbst festlegen. Für all diese Daten lege ich grundsätzlich eine oder mehrere eigene Partitionen (LVM-Volumes) mit zugehörigen Filesystemen (ext4) an, die auf selbst definierte Knotenpunkte im Dateibaum gemountet werden – etwa in Subverzeichnisse unter “/mnt” (/mnt/MyProjects, /mnt/MySamba, /mnt/MyPics …). Eine von der System-Installation unabhängige Datenhaltung vereinfacht im übrigen Backups erheblich.

Hat man die Nutzdaten erstmal vom OS-“Rest” absepariert, so können die Nutzdaten über Filesystem-Mounts in jede funktionierende und gebootete Betriebssysteminstallation eingebunden werden. Die Vorgaben dazu hinterlegt man in der jeweiligen Datei “/etc/fstab”; s. hierzu die man-Seiten oder https://wiki.ubuntuusers.de/fstab/. Unter Opensuse kann man die Einträge auch mit dem YaST-Partitionmanager vornehmen lassen. Natürlich muss man die Dateien und Mount-Punkte jeweils mit den nutzerbezogenen Rechten versehen.

Es ergibt sich also eine dritte Aufgabe für Ein- und Umsteiger:

Arbeitet euch in das “Mounten” von Filesystemen ein – studiert die Bedeutung der Einträge in der /etc/fstab.

[Ergänzung für Fortgeschrittene: Persönlich halte ich meine Projektdateien zudem weitgehend in SVN- oder Git-Verzeichnissen, die mit einem zentralen SVN-/Git-Server abgeglichen wird. Das gilt auch für Dokument-Dateien. Serverbasierte Versionsmanagement-Systeme erlauben neben der Versionierung seiner Arbeiten zudem schnelle “Backups” durch Replikation der Dateien auf weitere Systeme (Server, PCs, mobile Laptops, …). ]

Ausnahmen von der Lagerung eigener “Daten” in
separaten Partitionen

Neben selbst erzeugten Projekt-Daten in Dateien gibt es auch automatisch generierte Konfigurationsdateien, die Einstellung zur persönlichen grafischen Desktop-Umgebung und persönliche Einstellungen zu bestimmten Applikationen betreffen. Auch diese Dateien werden meist in Unterordnern des eigenen Home-Verzeichnisses “/home/uid” [~] untergebracht – u.a. unter “~/.config”.

Diese “Konfigurations”-Dateien sind im Sinne einer schnellen Restauration der Produktionsfähigkeit wichtig! Sie sind ferner relativ eng mit anderen Bibliotheken einer Distributionsversion verzahnt. Wir wollen später mehrere Partitionen mit funktionstüchtigen Installationen, aber auf unterschiedlichen Versionsständen, durch das Kopieren von Partitionen einrichten. Das spricht dann dafür,

die Inhalte des eigenen Home-Verzeichnisses im Gegensatz zu sonstigen Nutzdaten nicht auf eine separate Partition zu legen.

Warum?
Der eigene grafische Desktop und OS müssen im Verbund funktionieren! Das führt dann beim Starten einer neuen Desktopversion u.U. zu automatischen Updates der Konfigurationsdateien. Diese Modifikationen kann man danach ohne Spezialkenntnisse nicht mehr so einfach zurückdrehen. Hat man also das eigene “~”-Verzeichnis auf eine separate Partition verlagert, die man dann nach einem Systemupgrade unter der neuen Installation mounted, so ist nach einem Start der neuen Desktop-Umgebung die spätere Nutzbarkeit der Konfigurationsdateien unterhalb von “~” in der noch vorhandenen alten Installation in Frage gestellt! Das muss man vermeiden – und deswegen ist es besser, das “/home”-Verzeichnis in unserem Verfahren nicht aus dem Root-Filesystem abzuseparieren.

In den turbulenten KDE4-Anfangszeiten (gerade mit Kontact/Kmail) ist mir schmerzlich bewusst geworden, dass es auf einem Stand-Alone-System kaum Sinn macht, das eigene Home-Verzeichnis mit seinen Konfigurationsdateien in eine separate Partition zu verlagern – auch wenn dass bei vielen Distributionen im Installationsprozess so vorgeschlagen wird. Man muss das alte Home-Verzeichnis dann in jedem Fall sichern, wenn man wieder auf die alte Installation zurück will. Dann kann man es in den unterschiedlichen Installationen gleich mit vorhalten – auch wenn das Platz kostet. (Das sieht auf einer serverbasierten Installation, bei der das Home-Verzeichnis ggf. auf einem zentralen NFS-Server liegt und über Netz auf dem lokalen PC gemountet wird, natürlich anders aus.)

Eine weitere Ausnahme bilden womöglich Mail- und Groupware-Daten, die zumeist ebenfalls in Unter-Ordnerhierarchien des persönlichen Desktops – also unterhalb irgendwelchen Konfigurationsordnern des eigenen Home-Verzeichnisses untergebracht werden. Entsprechende Dateien lassen wir mal außen vor – die Ursprungsdaten zu Mails gehören aus meiner Sicht eh’ immer auf einen (ggf. lokalen und virtualisierten) IMAP-Server. In lokalen Mailsystemen der Desktops sollten davon höchstens Kopien vorgehalten werden.

Zwischenfazit

Genug für heute! Es sollte klar geworden sein, dass ich die Kontinuität meiner Arbeitsfähigkeit gegenüber Update/Upgrade-Probleme neben Backups durch verfügbare Fallback-Installationen und eine Speicherung von Nutzdaten auf separaten Partitionen sicherstelle.

Im nächsten Beitrag

Upgrade-Zeit – Vorsorge durch Fallback-Installationen – II

bespreche ich dann den Einsatz des “dd”-Kommandos zum Anlegen von Partitionskopien – und bespreche, wie ihr ein mögliches Chaos beim Booten, das sich aus duplizierten sog. UUIDs der Filesysteme ergeben würde, vermeidet.

Update zu Opensuse 42.3 – kleine Probleme mit nvidia und libvirt/kvm

Das aktuelle Drama um Meltdown und Spectre verlangt auch von Linux-Usern starke Nerven. Bei Opensuse steht zudem das Auslaufen des Support-Zeitraums für Opensuse Leap 42.2 an. Es lohnt sich also, hier auch noch ein Upgrade betroffener Systeme auf Opensuse Leap 42.3 vorzunehmen. In der Reihenfolge

  1. Anwendung aktueller Kernel-Patches (man suche z.B. unter YaST > Software Management” mit dem Begriff “kernel” nach entsprechenden RPM-Paketen und deren Updates) sowie von Intel- bzw. AMD-Microcode-Patches (Pakete “ucode-intel”, “ucode-intel-blob” bzw. “ucode-amd”) unter Opensuse Leap 42.2.
  2. Bei Einsatz von qemu, kvm, libvirt: Update entsprechender Pakete unter Leap 42.2.
  3. Upgrade auf Opensuse Leap 42.3 (z.B. gem. der Anleitung unter https://kamarada.github.io/en/2017/08/03/how-to-upgrade-from-opensuse-leap-422-to-423/)
  4. Soweit dann noch nötig: Anwendung aktueller Kernel-Patches, von Intel- bzw. AMD-Microcode-Patches und Updates von qemu/kvm/libvirt-Paketen unter Leap 42.3
  5. [Für Mutige (und Sicherheitsbewusste): Upgrade auf ein aktuelles Kernel-Paket zur Version 4.14 aus dem “kernel”-Repository “http://download.opensuse.org/repositories/Kernel:/stable/standard/”.]

Das klappt eigentlich ganz gut. Bei zwei Systemen bin ich dabei im Zuge des Standard-Upgrades aber auf zwei kleinere Problemchen mit “kvm/qemu” und dem proprietären “Nvidia”-Treiber gestoßen.

Nvidia-Problem => Deinstallation des Pakets “drm-kmp-default”

Im Zuge der Installation des proprietären Nvidia-Treibers (z.B. über das Installations-File “NVIDIA-Linux-x86_64-384.98.run”), den man sich von der Nvidia-Web-Site laden kann, klappt zwar die Kompilation des Treibers, nicht aber das Laden des Moduls “nvidia-drm.ko”. Es kommt eine entsprechende Meldung zum Fehlschlag der Nvidia-Installation. Ursache ist ein Paket “drm-kmp-default”, das aus mir nicht nachvollziehbaren Gründen installiert wird, aber in seiner Version nicht zum aktualisierten Default-Kernel (z.Z. 4.4.104-39.1) des Leap 42.3-Systems passt. Hier hilft es, das Paket “drm-kmp-default” zu deinstallieren. Das “drm”-Modul wird dennoch geladen und vom Modul “drm-nvidia” auch korrekt verwendet.

qemu/kvm-Problem: Korrekten Eintrag zu “namespaces” in der Datei qemu.conf vornehmen

Nach dem Upgrade auf Leap 42.3 und Aktualisierung aller Virtualisierungspakete ließen sich leider keine KVM-Gastsysteme mehr starten. Ich erhielt ganz unabhängig von der Art des Gastes und dessen Betriebssystem eine Meldung der Art:

Error starting domain: internal error: child reported: Kernel does not provide mount namespace: Permission denied

Ursache ist ein fehlender Eintrag

#namespaces = [ “mount” ]
namespaces = []

(bzw. ein unwirksamer Default-Eintrag (namespaces = [ “mount” ])) in der Datei “/etc/libvirt/qemu.conf”.
Ich tippe darauf, dass dieses Problem durch Rückportierungen bestimmter neuer Kernel-Features auf die relativ veraltete 4.4-Version von Leap 42.3 verursacht wurde. Im Standard-4.4-Kernel brauchte man den Eintrag in der vorliegenden Form nämlich nicht. Auf die Lösung dieses Problems bin ich nicht selbst gekommen; s. zu diesem Thema die unten angegebenen Links.

Viel Spaß weiterhin mit Opensuse – trotz des aktuellen Security Super-GAUs. Das beste Gegenmittel gegen Spectre ist – neben laufenden System-Updates – maximale Vorsicht beim Öffnen jeglicher externer Quellen, das Verifizieren von Update-Quellen für System- und Anwendungsdateien und das Verifizieren von Web-Sites im Internet über https-Verbindungen, das Kontrollieren der Hash-Summen für alle Updates sowie der Einsatz von “Noscript
“-Plugins in euren Browsern. Soweit ich das verstehe, erfordert ein Ausnutzen der Spectre-Schwachstelle in den aktuellen Prozessoren das Ausführen malignen Codes. Ein Einfangen von Schadcode muss man vermeiden – diese Binsenwahrheit gilt und erfordert nunmehr weiter erhöhte Wachsamkeit – im besonderen beim Browsen im Internet.

Vielleicht denken einige Unternehmen und Webseiten-Programmierer nun auch wieder ein wenig mehr darüber nach, ob und wann Javascript für den Betrieb einer öffentlichen Web-Seite überhaupt erforderlich ist. Auf vielen Seiten erfolgt der Einsatz oftmals weniger aus funktionalen Gründen als vielmehr deshalb, damit das Nutzerverhalten aus kommerziellen Gründen getrackt werden kann …..

Links

https://forums.opensuse.org/showthread.php/527697-Can-t-load-nvidia-drm-ko-after-update
https://forums.opensuse.org/showthread.php/527394-KVM-guest-will-not-start-with-latest-version-of-kernel
https://www.redhat.com/archives/libvirt-users/2017-March/msg00033.html
https://www.redhat.com/archives/libvirt-users/2017-March/msg00035.html

firejail firecfg – Problem mit dem KDE-Login unter Opensuse Leap 42.3 – .ssh-Dateien und ssh-agent als Ursache

Experimentiert man unbedarft mir neuen Dingen, muss man sich nicht wundern, wenn man sich Probleme schafft. Jetzt passierte mir das mit firejail.

Ich muss manchmal Skype benutzen. Zu meinem großen Ärger, da jede Art von Closed Source UDP-Streaming Applikation ein prinzipielles Sicherheitsrisiko darstellt. In einen UDP-Datenstrom können immer Pakete integriert werden, die ganz anderen Zwecken dienen als der Übertragung der eigentlichen Audio- und Videodaten. Und wenn man dann den Code nicht kennt … Neben dem Aufsetzen eines speziell konfigurierten Containers ist die Nutzung von Firejail eine Gegenmaßnahme, solchen Applikationen das Vordringen ins System zu erschweren.

Opensuse 42.3 bietet im Repository “Virtualization
ein RPM-Paket firejail 0.9.5 zum Download an. Das habe ich installiert. nach der Installation war zunächst auch ein kein Problem feststellbar.

Aber dann habe ich ein wenig in der Dokumentation gestöbert. Auf der Seite https://firejail.wordpress.com/documentation-2/ findet man dann unter dem Titel “I’ve just installed Firejail, now what?!” Hinweise zu bestimmten Kommandos, um “pulseaudio” [PA] zu korrigieren (wundert mich nicht) und auch das Kommando “firecfg” auszuführen:

$ firecfg –fix-sound
$ sudo firecfg

Beides hat u.U. aber unangenehme Nebenwirkungen:

1) Pulseaudio zunächst nicht mehr deaktivierbar
Das erste Kommando korrigiert “pulseaudio”-Konfigurationsdateien zwar; es sorgt aber auch dafür, dass man unter Opensuse PA nicht mehr einfach über YaST und die dortige Audio-Konfiguraiton abschalten kann. Bekanntermaßen verwende ich PA nur, wenn nicht umgehbar. So erzwangen etwa frühere Skype Versionen für Linux ( u.a. die Version 4.3) die Nutzung von PA. Das ist beim aktuellen “skypeforlinux” (Beta) nicht der Fall; das kooperiert auch direkt mit Alsa.

Das ist auf meinem Laptop auch gut so, denn PA erzeugt dort ein dauerhaftes unangenehmes Hintergrundsgeräusch (niederfrequenter Pfeifton; keine Rückkopplung) auf meinem eingebauten Mikrophon (unabhängig von Skype). Das ließ sich auch durch Ändern der Empfindlichkeit und der Regelung von Verstärkungsfaktoren unter dem PA-eigenen “pavucontrol” nie beseitigen. Ein solches Geräusch tritt bei mir im reinen Alsa-Betrieb dagegen nicht auf.

Beseitigt habe ich die Aktivierung von PA dann durch Umbenennen/Verschieben der Datei “~/.pulseaudio” und anschließende erneute Deaktivierung von PA über YaST.

2) Kein KDE-Login und kein X11-Start mehr für bestimmte Accounts möglich
Schlimmer ist dagegen eine Auswirkung des zweiten Kommandos: Es erzeugt eine Liste von Links unter dem Verzeichnis von “/usr/local/bin“, die alle auf firejail verweisen. Normalerweise führt das dazu, dass viele Programme/Anwendungen über firejail gestartet und geschützt werden. Leider ist die Liste der Profile für Anwendungen aber keineswegs vollständig. Wird für eine Anwendung nichts gefunden, dann kommt wohl ein “default.profile” zum Einsatz. Letzteres verhindert aber den Zugriff u.a. auf ~/.ssh und ~/.gnupg-Verzeichnisse und dortige Dateien. Das wird aber unter Umständen unter Opensuse zu einem Megaproblem beim Start von KDE aus SDDM oder KDM heraus:

Ich konnte mich unter bestimmten Accounts nach dem Absetzen von firecfg nicht mehr von KDM oder SDDM aus in KDE (Plasma 5) einloggen. X11 wurde nicht gestartet; man landet nach ca. 1 Sekunde wieder auf dem KDM oder SDDM-Login-Schirm.

Die Fehlermeldungen hierzu waren unzureichend. Nach mühsamen Experimenten mit Konfigurationsdateien stieß ich schließlich darauf, dass allein die Existenz eines “~/.ssh“-Verzeichnisses zu Fehlern beim KDE-Start
führte. Entfernte ich das Verzeichnis komplett, ließen sich KDE und X11 wieder regulär starten.

Wer oder was will im Start “~/.ssh” auslesen? Mir fiel dazu zunächst nichts ein. Dann stieß ich auf ssh-agent. Und tatsächlich ergab sich unter Opensuse Leap 42.3 folgendes Bild:

mytux:~ # ps aux | grep ssh
root      1574  0.0  0.0  53492  5816 ?        Ss   13:30   0:00 /usr/sbin/
sshd -D
myself       4065  0.0  0.0  20136  1868 ?        S    13:30   0:00 /usr/bin/dbus-launch --sh-syntax --exit-with-session /usr/bin/ssh-agent /usr/bin/gpg-agent --sh --daemon --keep-display --write-env-file /home/myself/.gnupg/
agent.info-mytux.mydomain.de:0 /etc/X11/xinit/xinitrc
myself       4067  0.0  0.0  13312   332 ?        Ss   13:30   0:00 /usr/bin/ssh-agent /usr/bin/gpg-agent --sh --daemon --keep-display --write-env-file /home/myself/.gnupg/agent.info-mytux.mydomain.de:0 /etc/X11/xinit/xinitrc

Offenbar klappt diese Art des X-Starts nicht mit dem komplett gefüllten “/usr/local/bin” (genauer mit den dortigen Links). Ich sehe die Ursache – wie gesagt – im “default.profile”.

Die Link-Orgie unter “/usr/local/bin” beseitigt man übrigens mit

firecfg –clean

Danach klappt der Login in das X11/KDE-Gespann alles wieder. Meine Strategie ist im Moment, die Profile für verschiedene Anwendungen zu checken und “/usr/local/bin” langsam und systematisch mit Links zu füllen, die nur bestimmte Anwendungen betreffen.

Bei manchen alten Accounts habe ich zudem festgestellt, dass die Anlage der Links unter /usr/local/bin” auch dazu führt, dass jeglicher Netzwerkzugriff unterbunden ist. Hier bin ich noch an der Ursachenforschung.

Merke: Nicht gleich alles machen, was Manuals vorschlagen, wenn man von einer neuen Anwendung noch zu wenig versteht.

Upgrade Laptop to Opensuse 42.3, Probleme mit Bumblebee und VMware WS 12.5, Workarounds

Gestern war ein Upgrade meines nun schon in die Jahre gekommenen Laptops von Opensuse Leap 42.2 auf Leap 42.3 fälllig.
Ich bin dabei gem. der schönen Anleitung in
https://kamarada.github.io/en/2017/08/03/how-to-upgrade-from-opensuse-leap-422-to-423/
vorgegangen. Zu der Anleitung gibt es nichts weiter zu sagen; die ist perfekt. Im Upgrade hatte ich nur die Standardrepositories (inkl. Update-Repository) für Leap 42.3 benutzt.

Mein Laptop hat eine Nvidia-Karte (Optimus-System). Das ursprüngliche Leap 42.2 lief auf dem Laptop deshalb mit einer Bumblebee-Installation; das funktionierte einwandfrei. Zudem nutzte ich auf dem Laptop VMware WS 12.5. Nach dem Leap-Upgrade hatte ich jedoch sowohl mit Bumblebee als auch VMware-Workstation Probleme – obwohl auch Leap 42.3 nur einen Kernel der nun doch schon recht alten Version 4.4 aufweist! nach dem Ugrade war bei mir 4.4.92-31 aktiv; bei der Leap_42.3 war dagegen der Kernel 4.4.76 der Default-Kernel.

Nebenbei: Bzgl. der Kernelversionen hat der SLES-Unterbau von Opensuse Leap plötzlich den unangenehmen Nebeneffekt, dass man an älteren Kernelversionen kleben bleibt … Von SUSEs Seite müssen ggf. Back-Portierungen aus neuen Kernelversionen zu älteren Versionen vorgenommen werden. Das kann Nebeneffekte zeitigen (s.u.). Bin mal gespannt wie Opensuse mit diesem Thema in Zukunft umgehen will …

Wiederholte Modul-Einträge in der Datei “/etc/sysconfig/kernel”

Das erste Problem war, dass die Datei “/etc/sysconfig/kernel” nach dem Neustart mehrfache Einträge zum Laden von nvidia-Modulen enthielt. Woher immer das stammte; vielleicht hatte ich das ja schon früher von Experimenten mit Bumblebee drin. Vielleicht wurden die Einträge aber auch im Upgrade hinzugefügt. Jedenfalls mal checken, dass in dieser Datei nach dem Upgrade kein überflüssiger Unsinn drinsteht.

Bumblebee-Installation wieder zum Laufen bringen

Bumblebee lief nach dem Upgrade nicht mehr. Ok, dachte ich, also die für Leap 42.3 passenden Repositories aktivieren und diverse Bumblebee-Pakete aktualisieren. Es gibt jedoch mehrere Repositories mit Bumblebee-Paketen für Opensuse Leap, u.a.
http://download.opensuse.org/repositories/home:/Bumblebee-Project:/nvidia:/3xx.xx/OpenSUSE_Leap_42.3.
Unter Leap 42.1/42.2 hatte ich etliche Pakete aus diesen Repositories benutzt.

Für Leap 42.3 gilt (nach meiner Erfahrung): Zu nutzen ist
http://download.opensuse.org/repositories/X11:/Bumblebee/openSUSE_Leap_42.3
und sonst gar nichts! Auch nicht das Nvidia-Community-Repository!

Die im “X11:Bumblebee”-Repository vorhandenen Pakete – inklusive der Pakete mit dem proprietären Nvidia-Treiber – kann und sollte man dagegen (bis auf eines) installieren; das Paket “primus” habe ich mir allerdings aus dem 42.3-Update-Repository geholt.

Ergänzung 02.12.2017: Wichtige Ausnahme:
bbswitch sollte man nicht installieren. Es reicht bbswitch-kmp-default! Und nur letzteres hat bei mir funktioniert – und zwar ohne dkms-Service.

Die Installation von bbswitch aktiviert den “dkms”-Service; waren sowohl “bbswitch-kmp-default” und “bbswitch” installiert, so führte dies bei mir anhand von Statusanzeigen erkennbar zu einem wechselseitigen An- und Abschalten der Graka im Bootprozess; sie wird danach von den Treibern nicht mehr erkannt.

(Auf die anderen Repositories zu unterschiedlichen Nvidia-Treibern sollte man wirklich nur im Notfall zurückgreifen, und zwar dann, wenn ihr für eure Graka zwingend einen älteren Nvidia-Treiber benötigt; aber auch dann nur x11-video-nvidia installieren. Nicht dagegen das Paket “dkms-nvidia”!)

Zu beachten ist also auch folgender Hinweis: Falls ihr früher einen laufenden dkms-Service hattet: Unbedingt deaktivieren! Und zwar nach der Installation der Pakete, aber schon vor einem anschließenden Neustart des Systems.

systemctl disable dkms

Das steht im Gegensatz zu den Anweisungen in der Anleitung
https://de.opensuse.org/SDB:NVIDIA_Bumblebee
absolut notwendig! Zumindest auf meinem Laptop … Fragt mich bitte nicht, warum der dkms-Service zu Problemen führt.

Der Bumblebee-Dämon “bumblebeed” dagegen muss über den zuständigen Service aktiviert werden

systemctl enable bumblebeed

Zudem checken, dass der User, unter dem ihr mit einer grafischen Oberfläche arbeitet, Mitglied der Gruppen “video” und “bumblebee” ist. Ggf. mittels “usermod -G video,bumblebee USERNAME” korrigieren.

Dann Neustart des Systems. Die Kommandos

optirun glxspheres
vblank_mode=0 primusrun glxspheres
optirun -b none nvidia-settings -c :8

sollten danach alle einwandfrei funktionieren.

Sollte das nicht der Fall sein und immer noch eine Meldung kommen, dass die Graka nicht vorhanden sei und der “nvidia”-Treiber nicht geladen werden könne:

Alle Pakete aus dem Nvidia-(Community)-Repository (Treiber nvidia-gfx-GL04 und ähnliche), aus dem Nvidia-Bumblebee-Repository und dem oben angegebenen Standard-Bumblebee-Repository löschen. Danach nur die Pakete aus dem oben angegebenen Standard-Repository http://download.opensuse.org/repositories/X11:/Bumblebee/openSUSE_Leap_42.3
mit Ausnahme von bbswitch (!) installieren. Den dkms-Service dann prophylaktisch deaktivieren! Neustart.

Ein probeweiser Start des dkms-Service führt nach einem vorhergehenden Erfolg mit “primusrun” in jedem Fall wieder in die Katastrophe:

Danach kommen in Logfiles Fehlermeldungen, dass es kein passendes Grafik Device gäbe. Am Terminal erscheint: “Cannot access secondary GPU …”. Das ließ sich durch ein anschließendes normales Stoppen des dkms-Service nicht mehr beheben. Bumblebee funktionierte auch nach dem Stoppen des dkms-Service nicht mehr ordnungsgemäß; nvidia Module ließen sich selbst manuell nicht mehr laden. Da half nur ein Reboot – natürlich bei deaktiviertem dkms-Service.

Ich habe leider keine Zeit, der genauen Ursache auf den Grund zu gehen. Bei künftigen Änderungen des Kernels muss man ohne korrekt funktionierendes dkms ggf. halt ein Update für die nvidia- und bbswitch-Module aus dem Bumblebee-Repository erzwingen und damit (zumindest bzgl. nvidia) eine Neukompilation durchführen lassen. Interessant ist, dass für den bei mir nach dem Leap-Upgrade aktiven Kernel 4.4.92-31 ein Link von
/lib/modules/4.4.92-31-default/weak-updates/updatesbbswitch.ko -> /lib/modules/4.4.676-1-default/updates/bbswitch.ko
angelegt wurde. Der funktioniert offenbar. Irgendwas am Kernel 4.4.92 missfällt womöglich dkms beim Versuch, für den neueren Kernel das passende Modul zu definieren. Der 4.4.92-Kernel führt aufgrund von Rückportierungen, die die SuSE-Leute wohl vorgenommen haben, auch noch in anderem Kontext – nämlich bzgl. der VMware WS – zu Schwierigkeiten.

Probleme mit der VMware Workstation 12.5. unter Leap 42.3 beheben

Meine unter Leap 42.2 installierte VM WS 12.5.1 lief nach dem Leap-Upgrade nicht mehr. Auch ein Upgrade der Workstation-SW auf die aktuelle Version 12.5.8 endete beim ersten Startversuch mit Kompilierungsfehlern. Die konnte ich mir im Detail zwar ansehen; wie man aber die problematischen Stellen im Quellcode der VMware-Module beheben hätte müssen, lag jenseits meiner Kenntnisse und Fähigkeiten.

Hier half aber der Beitrag eines offenbar Kernel-Kundigen im VMware Community Forum:
https://communities.vmware.com/message/2693257#2693257
Dort suche man nach dem Beitrag von “hendrikw84“! Herzlichen Dank an diesen Herrn! Seine Vorgaben zur Korrektur diverser Codezeilen funktionieren nämlich einwandfrei. (Ursache der Probleme sind offenbar Rückwärtsportierungen von Features des Kernels 4.10 in den Code des Kernels 4.4. Was immer die SuSE-Leute dabei gedacht haben …)

[ Warum allerdings die eine vorgeschlagene Korrektur-Zeile

retval = retval = get_user_pages((unsigned long)uvAddr, numPages, 0, ppages, NULL);

nicht gleich zu

retval = get_user_pages((unsigned long)uvAddr, numPages, 0, ppages, NULL);

verkürzt werden kann, ist mir etwas schleierhaft. Typo? Die letzte Zeile für retval klappt für den Code von hostif.c unter vmmon-only/linux nämlich auch.]

Nach Durchführung der Korrekturen ließen sich die VMware-Codes jedenfalls anstandslos für Kernel “4.4.9-31-default” kompilieren – und die nötigen Kernelmodule wurden fehlerfrei erzeugt. Meine zwei lokalen (non shared) virtuellen Maschinen für Windows-Installationen liefen damit bislang einwandfrei.

Ob es – wie in der Diskussion im VMware Community Forum angedeutet, Probleme mit “shared VMs” auf Servern gibt, habe ich nicht getestet. Auf Servern verwende ich KVM-Installaionen mit spice oder X2GO.

Viel Spaß denn mit Opensuse 42.3 auf dem Laptop!

Fun with veth-devices, Linux bridges and VLANs in unnamed Linux network namespaces – I

Recently, I started writing some blog posts about my first experiences with LXC-containers and libvirt/virt-manager. Whilst gathering knowledge about LXC basics I stumbled across four hurdles for dummies as me, who would like to experiment with network namespaces, veth devices and bridges on the command line and/or in the context of LXC-containers built with virt-manager:

  • When you use virt-manager/libvirt to set up LXC-containers you are no longer able to use the native LXC commands to deal with these containers. virt-manager/virsh/libvirt directly use the kernel API for cgroups/namespaces and provide their own and specific user interfaces (graphical, virsh, XML configuration files) for the setup of LXC containers and their networks. Not very helpful for quick basic experiments on virtual networking in network namespaces ….
  • LXC-containers created via virt-manager/virsh/libvirt use unnamed namespaces which are identified by unique inode numbers, but not by explicit names. However, almost all articles on the Internet which try to provide a basic understanding of network namespaces and veth devices explicitly use “ip” command options for named namespaces. This raises the question: How to deal with unnamed network namespaces?
  • As a beginner you normally do not know how to get a shell for exploring an existing unnamed namespace. Books offer certain options of the “ip”-command – but these again refer to named network namespaces. You may need such a shell – not only for basic experiments, but also as the administrator of the container’s host: there are many situations in which you would like to enter the (network) namespace of a LXC container directly.
  • When you experiment with complex network structures you may quickly loose the overview over which of the many veth interfaces on your machine is assigned to which (network) namespace.

Objectives and requirements

Unfortunately, even books as “Containerization with LXC” of K. Ivanov did not provide me with the few hints and commands that would have been helpful. I want to close this gap with some blog posts. The simple commands and experiments shown below and in a subsequent article may help others to quickly setup basic network structures for different namespaces – without being dependent on named namespaces, which will not be provided by virt-manager/libvirt. I concentrate on network namespaces here, but some of the things may work for other types of namespace, too.

After a look at some basics, we will create a shell associated with a new unnamed network namespace which will be different from the network namespace of other system processes. Afterwards we will learn how to enter an existing unnamed namespaces by a new shell. A third objective is the attachment of virtual network devices to a network namespace.

In further articles we will use our gathered knowledge to attach veth interfaces of 2 different namespaces to virtual bridges/switches in yet a third namespace, then link the host to the bridge/switch and test communications as well as routing. We shall the extend our virtual networking scenario to isolated groups of namespaces (or containers, if you like) via VLANs. As a side aspect we shall learn how to use a Linux bridge for defining VLANs.

All our experiments will lead to temporary namespaces which can quickly be cretated by scripts and destroyed by killing the basic shell processes associated with them.

Requirements: The kernel should have been compiled with option “CONFIG_NET_NS=y”. We make use of userspace tools that are provided as parts of a RPM or DEB packet named “util-linux” on most Linux distributions.

Namespaces

Some basics first. There are 6 different types of “namespaces” for the isolation of processes or process groups on a Linux system. The different namespace types separate

  • PID-trees,
  • the networks,
  • User-UIDs,
  • mounts,
  • inter process communication,
  • host/domain-names (uts) of process groups

against each each other. Every process on a host is attached to certain namespace (of each type), which it may or may not have in common with another process. Note that the uts-namespace type provides an option to give a certain process an uts-namespace which may get a different hostname than the original host of the process!

“Separation” means: Limitation of the view on the process’ own environment and on the environment of other processes on the system. “Separation” also means a limitation of the control a process can get on processes/environments associated with other namespaces.

Therefore, to isolate LXC containers from other containers and from the host, the container’s processes will typically be assigned to distinct namespaces of most of the 6 types. In addition: The root filesystem of a LXC containers typically resides in a chroot jail.

Three side remarks:

  1. cgroups limit the ressource utilization of process groups on a host. We do not look at cgroups in this article.
  2. Without certain measures the UID namespace of a LXC container will be the same as the namespace of the host. This is e.g. the case for a standard container created with virt-manager. Then root in the container is root on the host. When a container’s basic processes are run with root-privileges of the host we talk of a “privileged container”. Privileged containers pose a potential danger to the host if the container’s environment could be left. There are means to escape chroot jails – and under certain circumstances there are means to cross the borders of a container … and then root is root on the host.
  3. You should be very clear about the fact that a secure isolation of processes and containers on a host depend on other more sophisticated isolation mechanisms beyond namespaces and chroot jails. Typically, SE Linux or Apparmor rules may be required to prevent crossing the line from a namespace attached process to the host environment.

In our network namespace experiments below we normally will not separate the UID namespaces. If you need to do it, you must map a non-privileged UID (> 1000) on UID 0 inside the namespace to be able to perform certain network operations. See the options in the man pages of the commands used below for this mapping.

Network namespaces

The relevant namespace type for the network environment (NICs, bridges etc.) to which a process has access to is the “network namespace”. Below I will sometimes use the abbreviation “net-ns” or simply “netns”.

When you think about it, you will find the above statements on network isolation a bit unclear:

In the real world network packets originate from electronic devices, are transported through cables and are then distributed and redirected by other devices and eventually terminate at yet other electronic devices. So, one may ask: Can a network packet created by a (virtual) network device within a certain namespace cross the namespace border (whatever this may be) at all? Yes, they can:

Network namespaces affect network devices (also virtual ones) and also routing rules coupled to device ports. However, network packets do NOT care about network namespaces on OSI level 2.

To be more precise: Network namespace separation affects network-devices (e.g. Ethernet devices, virtual Linux bridges/switches), IPv4/IPv6 protocol stacks, routing tables, ARP tables, firewalls, /proc/net, /sys/class/net/, QoS policies, ports, port numbers, sockets. But is does not stop an Ethernet packet to reach an Ethernet device in another namespace – as long as the packet can propagate through the virtual network environment at all.

So, now you may ask what virtual means we have available to represent something like cables and Ethernet transport between namespaces? This is one of the purposes veth devices have been invented for! So, we shall study how to bridge different namespaces by the using the 2 Ethernet interfaces of veth devices and by using ports of virtual Linux bridges/switches.

However, regarding container operation you would still want the following to be true for packet filtering:

A fundamental container process, its children and network devices should be confined to devices of a certain “network namespace” because they should not be able to have any direct influence on network devices of other containers or the host.
And: Even if packets move from one network namespace to another you probably want to be able to restrict this traffic in virtual networks as you do in real networks – e.g by packet filter rules (ebtables, iptables) or by VLAN definitions governing ports on virtual bridges/switches.

Many aspects of virtual bridges, filtering, VLANs can be tested already in a simple shell based namespace environment – i.e. without full-fletched containers. See the forthcoming posts for such experiments …

Listing network namespaces on a host

The first thing we need is an overview over active namespaces on a host. For listing namespaces we can use the command “lsns” on a modern Linux system. This command has several options which you may look up in the man pages. Below I show you an excerpt of the output of “lsns” for network namespaces (option “-t net”) on a system where a LXC container was previously started by virt-manager:

mytux:~ # lsns -t net -o NS,TYPE,PATH,NPROCS,PID,PPID,COMMAND,UID,USER 
        NS TYPE PATH              NPROCS   PID  PPID COMMAND                  UID USER  
4026531963 net  /proc/1/ns/net       389     1     0 /usr/lib/systemd/system    0 root   
4026540989 net  /proc/5284/ns/net     21  5284  5282 /sbin/init                 0 root  

Actually, I have omitted some more processes with separate namespaces, which are not relevant in our context. So, do not be surprised if you should find more processes with distinct network namespaces on your system.

The “NS” numbers given in the output are so called “namespace identification numbers”. Actually they are unique inode numbers. (For the reader it may be instructive to let “lsns” run for all namespaces of the host – and compare the outputs.)

Obviously, in our case there is some process with PID “5282”, which has provided a special net-ns for the process with PID “5284”:

mytux:~ # ps aux | grep 5282
root      5282  0.0  0.0 161964  8484 ?        Sl   09:58   0:00 /usr/lib64/libvirt/libvirt_lxc --name lxc1 --console 23 --security=apparmor --handshake 26 --veth vnet1    

This is the process which started the running LXC container from the virt-manager interface. The process with PID “5284” actually is the “init”-Process of this container – which is limited to the network namespace created for it.

Now let us filter or group namespace and process information in different ways:

Overview over all namespaces associated with a process

This is easy – just use the option “-p” :

mytux:~ # lsns -p 5284 -o NS,TYPE,PATH,NPROCS,PID,PPID,COMMAND,UID,USER 
        NS TYPE  PATH              NPROCS   PID  PPID COMMAND                                                            UID USER
4026531837 user  /proc/1/ns/user      416     1     0 /usr/lib/systemd/systemd --switched-root --system --deserialize 24   0 root
4026540984 mnt   /proc/5284/ns/mnt     20  5284  5282 /sbin/init                                                           0 root
4026540985 uts   /proc/5284/ns/uts     20  5284  5282 /sbin/init       
                                                    0 root
4026540986 ipc   /proc/5284/ns/ipc     20  5284  5282 /sbin/init                                                           0 root
4026540987 pid   /proc/5284/ns/pid     20  5284  5282 /sbin/init                                                           0 root
4026540989 net   /proc/5284/ns/net     21  5284  5282 /sbin/init                                                           0 root

Looking up namespaces for a process in the proc-directory

Another approach for looking up namespaces makes use of the “/proc” directory. E.g. on a different system “mylx“, where a process with PID 4634 is associated with a LXC-container:

mylx:/proc # ls -lai /proc/1/ns
total 0
344372 dr-x--x--x 2 root root 0 Oct  7 11:28 .
  1165 dr-xr-xr-x 9 root root 0 Oct  7 09:34 ..
341734 lrwxrwxrwx 1 root root 0 Oct  7 11:28 ipc -> ipc:[4026531839]
341737 lrwxrwxrwx 1 root root 0 Oct  7 11:28 mnt -> mnt:[4026531840]
344373 lrwxrwxrwx 1 root root 0 Oct  7 11:28 net -> net:[4026531963]
341735 lrwxrwxrwx 1 root root 0 Oct  7 11:28 pid -> pid:[4026531836]
341736 lrwxrwxrwx 1 root root 0 Oct  7 11:28 user -> user:[4026531837]
341733 lrwxrwxrwx 1 root root 0 Oct  7 11:28 uts -> uts:[4026531838]

mylx:/proc # ls -lai /proc/4634/ns
total 0
 38887 dr-x--x--x 2 root root 0 Oct  7 09:36 .
 40573 dr-xr-xr-x 9 root root 0 Oct  7 09:36 ..
341763 lrwxrwxrwx 1 root root 0 Oct  7 11:28 ipc -> ipc:[4026540980]
341765 lrwxrwxrwx 1 root root 0 Oct  7 11:28 mnt -> mnt:[4026540978]
345062 lrwxrwxrwx 1 root root 0 Oct  7 11:28 net -> net:[4026540983]
 38888 lrwxrwxrwx 1 root root 0 Oct  7 09:36 pid -> pid:[4026540981]
341764 lrwxrwxrwx 1 root root 0 Oct  7 11:28 user -> user:[4026531837]
341762 lrwxrwxrwx 1 root root 0 Oct  7 11:28 uts -> uts:[4026540979]

What does this output for 2 different processes tell us? Obviously, the host and the LXC container have different namespaces – with one remarkable exception: the “user namespace”! They are identical. Meaning: Root on the container is root on the host. A typical sign of a “privileged” LXC container and of potential security issues.

List all processes related to a given namespace?

“lsns” does not help us here. Note:

“lsns” only shows you the lowest PID associated with a certain (network) namespace.

So, you have to use the “ps” commands with appropriate filters. The following is from a system, where a LXC container is bound to the network namespace with identification number 4026540989:

mytux:~ # lsns -t net -o NS,TYPE,PATH,NPROCS,PID,PPID,COMMAND,UID,USER
        NS TYPE PATH              NPROCS   PID  PPID COMMAND                                               UID USER
4026531963 net  /proc/1/ns/net       401     1     0 /usr/lib/systemd/systemd --switched-root --system --d   0 root
4026540989 net  /proc/6866/ns/net     20  6866  6864 /sbin/init                                              0 root

mytux:~ #  ps -eo netns,pid,ppid,user,args --sort netns | grep 4026540989
4026531963 16077  4715 root     grep --color=auto 4026540989
4026540989  6866  6864 root     /sbin/init
4026540989  6899  6866 root     /usr/lib/systemd/systemd-journald
4026540989  6922  6866 root     /usr/sbin/ModemManager
4026540989  6925  6866 message+ /bin/dbus-daemon --system --address=systemd: --nofork --nopidfile --systemd-activation   
4026540989  6927  6866 tftp     /usr/sbin/nscd
4026540989  6943  6866 root     /usr/lib/wicked/bin/wickedd-dhcp6 --systemd --foreground
4026540989  6945  6866 root     /usr/lib/wicked/bin/wickedd-dhcp4 --systemd --foreground
4026540989  6947  6866 systemd+ avahi-daemon: running [linux.local]
4026540989  6949  6866 root     /usr/lib/wicked/bin/wickedd-auto4 --systemd --foreground
4026540989  6951  6866 avahi-a+ /usr/lib/polkit-1/polkitd --no-debug
n4026540989  6954  6866 root     /usr/lib/systemd/systemd-logind
4026540989  6955  6866 root     login -- root
4026540989  6967  6866 root     /usr/sbin/wickedd --systemd --foreground
4026540989  6975  6866 root     /usr/sbin/wickedd-nanny --systemd --foreground
4026540989  7032  6866 root     /usr/lib/accounts-daemon
4026540989  7353  6866 root     /usr/sbin/cupsd -f
4026540989  7444  6866 root     /usr/lib/postfix/master -w
4026540989  7445  7444 postfix  pickup -l -t fifo -u
4026540989  7446  7444 postfix  qmgr -l -t fifo -u
4026540989  7463  6866 root     /usr/sbin/cron -n
4026540989  7507  6866 root     /usr/lib/systemd/systemd --user
4026540989  7511  7507 root     (sd-pam)
4026540989  7514  6955 root     -bash

If you work a lot with LXC containers it my be worth writing some clever bash or python-script for analyzing the “/proc”-directory with adjustable filters to achieve a customizable overview over processes attached to certain namespaces or containers.

Hint regarding the NS values in the following examples:
The following examples have been performed on different systems or after different start situations of one and the same system. So it makes no sense to compare all NS values between different examples – but only within an example.

Create a shell inside a new network namespace with the “unshare” command …

For some simple experiments it would be helpful if we could create a process (as a shell) with its own network-namespace. For this purpose Linux provides us with the command “unshare” (again with a lot of options, which you should look up).

For starting a new bash with a separate net-ns we use the option “-n“:

mytux:~ # unshare -n /bin/bash 
mytux:~ # lsns -t net
        NS TYPE NPROCS   PID USER  COMMAND
4026531963 net     398     1 root  /usr/lib/systemd/systemd --switched-root --system --deserialize 24   
4026540989 net      21  5284 root  /sbin/init
4026541186 net       2 27970 root  /bin/bash

mytux:~ # ip link
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN mode DEFAULT group default qlen 1
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00

mytux:~ # exit
exit

mytux:~ # ip link
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1   
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: eth0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/ether d7:58:88:ab:cd:ef brd ff:ff:ff:ff:ff:ff
....
....

Obviously, it is not possible to see from the prompt that we have entered a different (network) namespace with the creation of the new shell. We shall take care of this in a moment. For the time being, it may be a good idea to issue commands like

lsns -t net -p 1; lsns -t net -p $$

in the shell opened with “unshare”. However, also our look at the network interfaces proved that the started “bash” was directly associated with a different net-ns than the “parent” bash. In the “unshared” bash only a “lo”-device was provided. When we left the newly created “bash” we at once saw more network devices (namely the devices of the host).

Note: A namespace (of any type) is always associated with at least one process. Whenever we want to create a new namespace for an experiment we have to combine it with a (new) process. During the experiments in this post series we will create new network namespaces together with related simple bash-processes.

And: A namespace lives as long as the associated process (or processes). To keep a specific new network namespace alive for later experiments we put the associated basic bash-process into the background of the host-system.

In real world scenarios the processes related to namespaces are of course more complex than a shell. Examples are containers, browser-processes, etc. This leads us to the question whether we can “enter” an existing namespace somehow (e.g. with a shell) to gather information about it or to manipulate it. We will answer this question in a minute.

Information about host processes from a shell inside a specific network namespace?

You can get information about all processes on a host from any process with a specific network namespace – as long as the PID namespace for this process is not separated from the PID namespace of the host. And as long as we have not separated the UID namespaces: root in a network namespace then is root on the host with all the rights there!

Can a normal unprivileged user use “unshare”, too?

Yes, but his/her UID must be mapped to root inside the new network namespace. For this purpose we can use the option “-r” of the unshare command; see the man pages. Otherwise: Not without certain measures – e.g. on the sudo side. (And think about security when using sudo directives. The links at the end of the article may give you some ideas about some risks.)

You may try the following commands (here executed on a freshly started system):

myself@mytux:~> unshare -n -r /bin/bash 
mytux:~ # lsns -t net -t user
        NS TYPE  NPROCS   PID USER COMMAND
4026540842 user       2  6574 root /bin/bash
4026540846 net        2  6574 root /bin/bash
mytux:~ # 

Note the change of the prompt as the shell starts inside the new network namespace! And “lsns” does not give us any information on the NS numbers for net and user namespaces of normal host processes!

However, on another host terminal the “real” root of the host gets:

mytux:~ # lsns -t net -t user 
        NS TYPE  NPROCS   PID USER   COMMAND
4026531837 user     382     1 root   /usr/lib/systemd/systemd --switched-root --system --deserialize 24   
4026531963 net      380     1 root   /usr/lib/systemd/systemd --switched-root --system --deserialize 24   
4026540842 user       1  6574 myself /bin/bash
4026540846 net        1  6574 myself /bin/bash

There, we see that the user namespaces of the unshared shell and other host processes really are different.

Open a shell for a new named network namespace

The “unshare” command does not care about “named” network namespaces. So, for the sake of completeness: If you like to or must experiment with named network namespaces you may want to use the “ip” command with appropriate options, e.g.:

mytux:~ # ip netns add mynetns1 
mytux:~ # ip netns exec mynetns1 bash   
mytux:~ # lsns -o NS -t net -p $$
        NS
4026541079
mytux:~ # exit 
mytux:~ # lsns -o NS -t net -p $$
        NS
4026531963
mytux:~ # 

“mynetns1” in the example is the name that I gave to my newly created named network namespace.

How to open a shell for an already existing network namespace? Use “nsenter”

Regarding processes with their specific namespaces or LXC containers: How can we open a shell that is assigned to the same network namespace as a specific process? This is what the command “nsenter” is good for. For our purposes the options “-t” and “-n” are relevant (see the man pages). In the following example we first create a bash shell (PID 15150) with a new network namespace and move its process in the background. Then we open a new bash in the foreground (PID 15180) and attach this bash shell to the namespace of the process with PID 15150:

mylx:~ # unshare -n /bin/bash &
[1] 15150
mylx:~ # lsns -t net 
        NS TYPE NPROCS   PID USER  COMMAND
4026531963 net     379     1 root  /usr/lib/systemd/systemd --switched-root --system --deserialize 24   
4026540983 net      23  4634 root  /sbin/init
4026541170 net       1 15150 root  /bin/bash

[1]+  Stopped                 unshare -n /bin/bash
mylx:~ # nsenter -t 15150 -n /bin/bash
mylx:~ # ip link
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN mode DEFAULT group default qlen 1   
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
mylx:~ # echo $$
15180
mylx:~ # lsns -t net -p $$
        NS TYPE NPROCS   PID USER COMMAND
4026541170 net       3 15150 root /bin/bash
mylx:~ # 

Note, again, that “lsns” only gives you the lowest process number that opened a namespace. Actually, we are in a different bash with PID “15180”. If you want to see all process using the same network namespace you may use :

mylx:~ # echo $$
15180
mylx:~ # ps -eo pid,user,netns,args --sort user | grep 4026541170  
15150 root     4026541170 /bin/bash
15180 root     4026541170 /bin/bash
16284 root     4026541170 ps -eo pid,user,netns,
args --sort user
16285 root     4026541170 grep --color=auto 4026541170

Note that the shell created by nsenter is different from the shell-process we created (with unshare) as the bearing process of our namespace.

In the same way you can create a shell with nsenter to explore the network namespace of a running LXC container. Let us try this for an existing LXC container on system “mylx” with PID 4634 (see above: 4026540983 net 23 4634 root /sbin/init).

mylx:~ # nsenter -t 4634 -n /bin/bash
mylx:~ # ip link
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1   
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
13: eth0@if14: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default qlen 1000   
    link/ether 00:16:3e:a3:22:b8 brd ff:ff:ff:ff:ff:ff link-netnsid 0
mylx:~ # exit
exit

Obviously, an ethernet device eth0 exists in this container. Actually, it is an interface of a veth device with a peer interface “if14”; see below.

Change the hostname part of a shell’s prompt in a separate network namespace

We saw that the prompt of a shell in a separate network namespace normally does not indicate anything about the namespace environment. How can we change this? We need 2 steps to achieve this:

  • We open a shell in the background not only for a separate network namespace but also for a different uts namespace. Then any changes to the hostname inside the uts namespace for the running background process will have no impact on the host.
  • The “nsenter” command does not only work for shells but for any reasonable command. Therefore, we can also apply it for the command “hostname”.

Now, before we enter the separate namespaces of the process with yet another shell we can first change the hostname in the newly created uts namespace:

mytux:~ # unshare --net --uts /bin/bash &
[1] 25512
mytux:~ # nsenter -t 25512 -u hostname netns1

[1]+  Stopped                 unshare --net --uts /bin/bash   
mytux:~ # echo $$
20334
mytux:~ # nsenter -t 25512 -u -n /bin/bash 
netns1:~ #
netns1:~ # lsns -t net -t uts -p $$
        NS TYPE NPROCS   PID USER COMMAND
4026540975 uts       3 25512 root /bin/bash
4026540977 net       3 25512 root /bin/bash
netns1:~ # exit
mytux:~ # hostname
mytux

Note the “-u” in the command line where we set the hostname! Note further the change of the hostname in the prompt! In more complex scenarios, this little trick may help you to keep an overview over which namespace we are currently working in.

veth-devices

For container technology “veth” devices are of special importance. A veth device has two associated Ethernet interfaces – so called “peer” interfaces. One can imagine these interfaces like linked by a cable on OSI level 2 – a packet arriving at one interface gets available at the other interface, too. Even if one of the interfaces has no IP address assigned.

This feature is handy when we e.g. need to connect a host or a virtualized guest to an IP-less bridge. Or we can use veth-devices to uplink several bridges to one another. See a former blog post
Fun with veth devices, Linux virtual bridges, KVM, VMware – attach the host and connect bridges via veth
about these possibilities.

As a first trial we will assign the veth device and both its interfaces to one and the same network namespace. Most articles and books show you how to achieve this by the use of the “ip” command with an option for a “named” namespace. In most cases the “ip” command would have been used to create a named net-ns by something like

ip netns add NAME

where NAME is the name we explicitly give to the added network namespace. When such a named net-ns exists we can assign an Ethernet interface named “ethx” to the net-ns by:

ip link set ethx netns NAME

However, in all our previous statements no NAME for a network namespace has been used so far. So, how to achieve something similar for unnamed network namespaces? A look into the man pages helps: The “ip” command allows the introduction of a PID together with the option parameter “netns” at least for the variant “ip link set”. Does this work for veth devices and the command “ip link add”, too? And does it work for both Ethernet interfaces?

In the example discussed above we had a namespace 4026541170 of process with PID 15180. We open a bash shell on our host mylx, where PID 15150 still runs in the background, and :

mylx:~ # echo $$
27977
mylx:~ # lsns -t net
        NS TYPE NPROCS   PID USER  COMMAND   
4026531963 net     393     1 root  /usr/lib/systemd/systemd --switched-root --system --deserialize 24   
4026540983 net      23  4634 root  /sbin/init
4026541170 net       1 15150 root  /bin/bash
mylx:~ # ip link add veth1 netns 15150 type veth peer name veth2 netns 15150
mylx:~ # nsenter -t 15150 -n /bin/bash
mylx:~ # echo $$
28350
mylx:~ # ip link
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN mode DEFAULT group default qlen 1
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: veth2@veth1: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000   
    link/ether 8e:a0:79:28:ae:12 brd ff:ff:ff:ff:ff:ff
3: veth1@veth2: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000   
    link/ether fa:1e:2c:e3:00:8f brd ff:ff:ff:ff:ff:ff
mylx:~ # 

Success! Obviously, we have managed to create a veth device with both its 2 interfaces inside the network namespace associated with our background process of PID 15150.

The Ethernet interfaces are DOWN – but this was to be expected. So far, so good. Of course it would be more interesting to position the first veth interface in one network namespace and the second interface in another network namespace. This would allow network packets from a container to cross the border of the container’s namespace into an external one. Topics for the next articles …

Summary and outlook on further posts

Enough for today. We have seen how we can list (network) namespaces and associated processes. We are able to create shells together with and inside in a new network namespace. And we can open a shell that can be attached to an already existing network namespace. All without using a “NAME” of the network namespace! We have also shown how a veth device can be added to a specific network namespace. We have a set of tools now, which we can use in more complicated virtual network experiments.

In the next post

Fun with veth-devices, Linux bridges and VLANs in unnamed Linux network namespaces – II

I shall present a virtual network environment for several interesting experiments with network namespaces – or containers, if you like. Further articles will discuss such experiments step by setp.

Addendum, 25.03.2024: I have started a new series about virtual networking experiments concerning veths with VLAN-interfaces, namespaces, routes, ARP, ICMP and security aspects. If you are interested in these topics a look at the posts in the new series may give you some more information on specific topics.

Links

Introduction into network namespaces
http://www.linux-magazin.de/ Ausgaben/ 2016/06/ Network-Namespaces

Using unshare without root-privileges
https://unix.stackexchange.com/ questions/ 252714/ is-it-possible-to-run-unshare-n-program-as-an-unprivileged-user
https://bbs.archlinux.org/viewtopic.php?id=205240
https://blog.mister-muffin.de/ 2015/10/25/ unshare-without-superuser-privileges/