Von Michael Gisbers 1. August 2022
tar
- Archiv zu packen, dieses im Netz abzulegen, den Rechner
zu bereinigen und über das Archiv wiederherzustellen.
Dabei werden viele Tools wie fdisk
/gdisk
, mkfs
, mount
, tar
und
grub-install
benötigt um den Datenträger vorzubereiten, die Partitionen zu
formatieren und die Dateisysteme wieder richtig einzuhängen um dort das Archiv
zu entpacken. Nach der Installation des GRUB läuft dann in der Regel das System
wieder und kann getestet werden.
Leider kommt es immer mal wieder dazu, daß der Versuch als Benutzer einen ping
in dem neu aufgebauten System einen Fehler meldet.
user@linux $ ping gisbers.de
ping: socket: Operation not permitted
Woher kommt der Fehler? Das System ist korrekt hochgefahren und auch die Netzwerkumgebung läuft einwandfrei, aber es kommt - egal ob über eine IP - Adresse oder einen DNS-Namen aufgerufen - immer die gleiche Fehlermeldung.
Bei einem genauen Blick auf die Fehlermeldung wird klar, daß ping
versucht
eine Verbindung aufzubauen, die er nicht aufbauen darf. Dazu muss man hinter
die Aufgabe des Befehls schauen: Er soll einem per IP - Netzwerk erreichbaren
Gerät eine Nachricht des Typs 8 (Echo Request) über das Internet Control
Message
Protocol
(ICMP) und auf die Antwort des anderen Gerätes warten. Dieses schickt - solange ihm das
nicht verboten ist oder eine Firewall blockt - eine Antwort mit einer Nachricht
Typ 0 ICMP (Echo Reply) zurück.
Um die Nachrichten versenden und Antworten zu empfangen muss ping
in der Lage
sein einen passenden Socket für das Senden und einen für den Empfang der
Antwort zu öffnen.
Und genau hier wird die Fehlermeldung generiert. Dem Befehl ping
fehlt
das Recht diese Sockets zu öffnen. Wird der Befehl als Benutzer root
aufgerufen funktioniert er wie gewohnt.
Was dem Benutzer fehlt ist das Recht Sockets für ICMP zu erstellen. Für die Protokolle TCP und UDP - bei Ports größer 1023 - darf er das und damit auch eigene Programme starten, die sie benutzen.
Sehr lange Zeit haben die Distributionen den Befehl ping
über ein SetUID zu
einem Befehl gemacht, der als Benutzer root
läuft. Dazu muss der Besitzer des
Befehls der Benutzer root
und das s
(SetUID) - Flag für den Benutzer
gesetzt sein. Zu sehen an dem kleinen s
in den Zugriffsrechten.
user@linux $ ls -l /bin/ping
-rwsr-xr-x 1 root root 76568 22 Dez. 2021 /bin/ping
Mit den durch diese Einstellung vergebenen Rechten läuft der Befehl ping
beim
Aufruf mit den effektiven Rechten des Benutzer root
. Bedeutet, daß es möglich
ist durch Fehler innerhalb des Befehls z. B. andere Programme zu starten, die
dann auch direkt mit uneingeschränkten root
Rechten laufen.
Das schöne an diesen Rechten ist, daß sie in einen tar
Archiv
transportierbar sind und nach dem entpacken als Benutzer root
wieder
vorhanden sind.
Allerdings wäre es sehr viel sinnvoller dem Befehl nur die benötigten Rechte
zum Erstellen der Sockets zu geben und nicht die vollen root
Rechte.
Die root
- Rechte sind
capabilities
(Fähigkeiten), die dem Benutzer root
in einem Linux basierten System
zugewiesen sind. Im Gegensatz zu normalen Benutzern erhält root
alle
capabilities, der Benutzer keine.
Schaut man durch die Liste der capabilities, dann findet man eine mit dem Namen CAP_NET_RAW.
CAP_NET_RAW
* Use RAW and PACKET sockets;
* bind to any address for transparent proxying.
Die Beschreibung verspricht, daß ein Zugriff auf RAW und Packet Sockets erlaubt ist. Zusätzlich erlaubt es auf beliebige Adressen zu binden.
Der neue Trick der Distributionen ist also dem Befehl ping
die capability
CAP_NET_RAW zu geben und darüber nur ein eingeschränktes Recht zu
erhalten. Vorteil dieser Vorgehensweise: Bei einem Fehler im Befehl können
von ihm aufgerufene Programme davon nicht profitieren.
user@linux $ ls -l /bin/ping
-rwsr-xr-x 1 root root 76568 22 Dez. 2021 /bin/ping
user@linux $ getcap /bin/ping
/bin/ping cap_net_raw+p
Wie im Listing zu sehen ist gibt es über den Befehl ls
keinen Hinweis darauf,
daß der Befehl mit zusätzlichen capabilities versehen ist. Erst mit dem Tool
getcap
lassen sich die capabilities von Befehlen anzeigen.
Da diese in den erweiterten Attributen der Dateien gepeichert sind lassen sie
sich auch mit dem Befehl getfattr
auslesen.
user@linux $ getfattr -n security.capability /bin/ping
# file: bin/ping
security.capability=0sAQAAAgAEAAAAAAAAAAAAAAAAAAA=
Genau diese erweiterten Attribute gehen bei einem normalen Backup per tar
verloren. tar
kann sie also auch nach dem Entpacken nicht wiederherstellen.
Sollen diese Attribute mit in das Archiv, dann muss explizit --xattrs
als
Parameter beim Erzeugen vorhanden sein. Aus Sicherheitsgründen stellt tar
die
security.capability
- Attribute nur wieder her, wenn dies explizit über den
Parameter --xattrs-include='security.capability'
oder allgemeiner
--xattrs-include='*'
für alle Attribute beim Entpacken angefordert ist.
Beispiel für das Packen und Entpacken des Befehls tar
mit erweiterten
Attributen.
Bitte das Beispiel nicht in Live/Produktiv - Systemen ausprobieren
user@linux $ tar --xattrs -cvf /tmp/ping.tar /bin/ping
tar: Entferne führende „/“ von Elementnamen
/bin/ping
user@linux $ sudo tar --xattrs-include='*' -C / -xvf /tmp/ping.tar
bin/ping
Durch die beiden Befehle wird zunächst ein Archiv mit dem Befehl /bin/ping
und dessen erweiterten Attributen erzeugt und danach auf die gleiche Datei
zurückgeschrieben.
Allerdings überraschen immer mehr Distributionen und zeigen, daß es auch komplett anders geht.
Es kommen weder ein SetUID
noch capabilities zum Einsatz. Trotzdem
funktioniert der Befehl ping
für den normalen Benutzer.
Hier hilft der Kernel mit. Über den Parameter
/proc/sys/net/ipv4/ping_group_range
bekommt der Kernel die Information
welcher Bereich an Gruppen IDs die Erlaubnis haben den Befehl ping
ohne
weitere capabilities oder SetUID
zu benutzen.
Obwohl der Parameter schon seit der Kernel Version 2.6.39 existiert findet er erst jetzt häufiger seinen Einsatz. Genaue Informationen dazu sind in der ICMP Manual Page zu finden.
ping_group_range (two integers; default: see below; since Linux
2.6.39)
Range of the group IDs (minimum and maximum group IDs,
inclusive) that are allowed to create ICMP Echo sockets.
The default is "1 0", which means no group is allowed to
create ICMP Echo sockets.
Bei Archlinux ist dieser Parameter so eingestellt, daß er für alle möglichen Gruppen IDs gilt.
user@linux $ cat /proc/sys/net/ipv4/ping_group_range
0 2147483647
Am sinnvollsten lässt sich der Eintrag über den Befehl sysctl
verändern.
user@linux $ sudo sysctl -w net.ipv4.ping_group_range='0 2147483647'
net.ipv4.ping_group_range = 0 2147483647
Dies ist allerdings nicht persistent. Um es persistent und damit auch nach
einem Neustart direkt neu einzutragen wird die Zeile mit dem Parameter und Wert
in eine Datei unter /etc/sysctl.d/
abgelegt. Genauere Infos hierzu sind in
der sysctl Manual Page
zu finden.
Mit den nun bekannten Informationen im Hinterkopf lässt sich die Aufgabe für die Linux Administratoren neu gestalten und führt wieder zu einem Erfolgserlebnis.