Restriktive SSH-Shell

Als alter Kommandozeilen-Junkie möchte man SSH für administrative Arbeiten aus der Ferne nicht missen. Windows Remote Desktop oder VNC dauern für viele Arbeiten einfach zu lange.

Muss man jetzt einige administrative Arbeiten aus der Hand geben oder will man einem Benutzer die Kommandozeile so idiotensicher wie möglich machen, dann zerbricht man sich sehr schnell den Kopf darüber wie.

Natürlich kann man einen Webserver installieren, schauen ob man irgendetwas im Netz findet, was ungefähr dem entspricht, was man möchte. Vielleicht muss man sogar noch selber entsprechende Skripte zusammenbauen oder Bestehendes anpassen.

Sinnvoller erscheint da eine restriktive SSH-Shell. Das SSH-Einfallstor gibt es schon und wird sowieso sicherheitstechnisch gepflegt. In der Hinsicht also von Vorteil. Die Skripte existieren in der Regel auch schon und müssen vielleicht mal kurz nach eventuellen Sicherheitslücken durchgeschaut werden, falls man sich hier noch nie Gedanken gemacht hatte. Ergo keine zusätzlichen Dienste und am Ende kein PHP-Skript, was man irgendwo aufgeschnappt hat und von dem man nicht weiß, was so alles damit möglich ist.

Um eine restriktive Shell zu verwirklichen gibt es mehrere Möglichkeiten. Eine wäre, ein Chroot zu verwirklichen. Sehr aufwendig und schwer zu pflegen, besonders bei selbstentwickelten Skripten, welche sich vielleicht auch im Laufe der Zeit ändern. Nicht nur das. Vielleicht braucht der Benutzer Zugriff auf einen bestimmten Bereich des Systems und dann wird es richtig kompliziert.

Einfacher und flexibler, allerdings sicherheitstechnisch nicht ganz mit Chroot auf einer Höhe, wäre der Einsatz der Bash in ihrem restriktiven Modus. Aufzurufen per -r Parameter oder mit dem Kommando rbash.

Trägt man also /bin/rbash als Shell für den Benutzer ein, dann landet er in einer restriktiven Umgebung. Er kann nur Programme starten, welche in seinem Ausführungspfad stehen. Direktaufrufe von Programmen über einen absoluten Pfad sind nicht möglich. Umleitungen, Pipes und ein paar andere Feinheiten ebenfalls nicht.

Allerdings stößt man dann über den ersten Haken. Wer SSH kann, der kann auch in der Regel SCP und SFTP. Und hat somit ein Mittel, trotzdem auf dem Server in Bereiche zu kommen, wo er vielleicht nicht hin soll. Der Benutzer sollte also nur SSH machen und nichts anders. Interessanterweise ist das bei Administratoren normalerweise andersherum. Die möchten eigentlich nur SCP oder SFTP zulassen, aber keine SSH.

Die Lösung zu dem Problem ist simple. Bei einer SSH-Verbindung wird der Login-Shell als Parameter übergeben, was gemacht werden soll. Ist es eine normale SSH-Verbindung, also auch ohne Aufruf eines Programms, werden keine Parameter übergeben. Bei SCP oder SFTP werden als Parameter die gewünschten Programme auf dem Server übergeben.

Mit folgenden kleine Shellskript, welches man dann als Shell für den Benutzer einträgt, testet man, ob Parameter übergeben werden und falls nicht, wird die Restriktive Bash als Login-Shell aufgerufen:


#!/bin/bash

test $# -ne 0 && exit 1
exec rbash -l

Das Ganze kann man noch um eventuelle Fehlermeldungen über Stdout erweiteren, damit der Benutzer am anderen Ende mitbekommt, warum das Ganze denn nicht funktioniert.

Als nächstes möchte man vielleicht noch die Restriktive Bash restriktiver machen, zum Beispiel alle Builtin-Kommandos deaktivieren, damit der Benutzer wirklich nur das machen kann, was man will.

Es empfiehlt sich auch, den Ausführungspfad explizit zu setzen, dass der Benutzer nicht einfach alle Standard-Programme auf dem Server ausführen kann. Sinnvoll ist es hier, der Übersicht halber den Ausführungspfad auf ein Verzeichnis im Benutzerverzeichnis zu setzen, zum Beispiel /home/user/bin und dort alle Sachen unterzubringen, welche er benutzen darf.

Da die Restriktive Bash als Login-Shell aufgerufen wird, hat man die Möglichkeit über die Datei .bash_profile im Benutzerverzeichnis die Umgebung des Benutzers zu beeinflussen, ohne das er dies rückgängig machen könnte. Dies könnte beispielsweise so aussehen:


str=$(enable | sed -e 's/\(exit\|logout\)//g' )

export PS1=$
export PATH=$HOME/bin

enable -n $str

Die einzigen Builtins, welche hier erlaubt bleiben, sind exit und logout zum Abmelden. Ansonsten funktioniert nur noch, was unter /home/user/bin zu finden ist. Für dort aufgerufene Programme und Skripte gelten diese Restriktionen übrigens nicht mehr, da die Restriktionen alleine durch die Restriktive Bash forciert werden.

Jetzt kombiniert man das Ganze noch damit, dass der Benutzer sich nur per Schlüssel anmelden darf und erreicht so dann insgesamt eine Sicherheit, die über der einer Weblösung liegen dürfte.

Einen Kommentar schreiben