it-swarm.com.de

Wie kann man SSH-Benutzer nach der Anmeldung auf einen vordefinierten Befehlssatz beschränken?

Dies ist eine Idee für eine Sicherheit. Unsere Mitarbeiter sollen Zugriff auf einige Befehle auf einem Linux-Server haben, aber nicht auf alle. Sie sollen z.B. die Möglichkeit haben, auf eine Protokolldatei zuzugreifen (less logfile) oder starten Sie verschiedene Befehle (shutdown.sh/run.sh).

Hintergrundinformation:

Alle Mitarbeiter greifen mit demselben Benutzernamen auf den Server zu: Unser Produkt wird mit "normalen" Benutzerberechtigungen ausgeführt, es ist keine "Installation" erforderlich. Entpacke es einfach in dein Benutzerverzeichnis und starte es. Wir verwalten mehrere Server, auf denen unsere Anwendung "installiert" ist. Auf jeder Maschine gibt es einen Benutzer johndoe. Unsere Mitarbeiter benötigen manchmal Zugriff auf die Anwendung über die Befehlszeile, um auf Protokolldateien zuzugreifen und diese zu überprüfen oder die Anwendung manuell neu zu starten. Nur einige Personen haben vollen Zugriff auf die Befehlszeile.

Wir verwenden die PPK-Authentifizierung auf dem Server.

Es wäre großartig, wenn employee1 nur auf die Logdatei zugreifen könnte und employee2 auch X usw. ausführen könnte.

Lösung: Als Lösung verwende ich die Option command, wie in der Antwort akzeptiert angegeben . Ich werde mein eigenes kleines Shell-Skript erstellen, das die einzige Datei ist, die für manche Mitarbeiter ausgeführt werden kann. Das Skript bietet mehrere Befehle, die ausgeführt werden können, aber keine anderen. Ich verwende die folgenden Parameter in authorized_keys von wie angegeben hier :

command="/bin/myscript.sh",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty
ssh-dss AAAAB3....o9M9qz4xqGCqGXoJw= [email protected]

Das ist genug Sicherheit für uns. Danke, Gemeinschaft!

78
Marcel

Sie können Schlüssel auch auf zulässige Befehle beschränken (in der Datei authorized_keys).

Das heißt Der Benutzer würde sich nicht über ssh anmelden und hätte dann einen eingeschränkten Befehlssatz, sondern könnte diese Befehle nur über ssh ausführen (z. B. "ssh somehost bin/showlogfile").

63
HD.

ssh folgt der Tradition von rsh, indem das Shell-Programm des Benutzers aus der Kennwortdatei zum Ausführen von Befehlen verwendet wird.

Dies bedeutet, dass wir dieses Problem lösen können, ohne die Konfiguration von ssh in irgendeiner Weise zu berücksichtigen.

Wenn der Benutzer keinen Shell-Zugriff haben soll, ersetzen Sie einfach die Shell dieses Benutzers durch ein Skript. Wenn Sie in /etc/passwd Nachsehen, werden Sie feststellen, dass es ein Feld gibt, das jedem Benutzer einen Shell-Befehlsinterpreter zuweist. Das Skript wird als Shell sowohl für die interaktive Anmeldung ssh [email protected] Als auch für Befehle ssh [email protected] command arg ... Verwendet.

Hier ist ein Beispiel. Ich habe einen Benutzer foo erstellt, dessen Shell ein Skript ist. Das Skript gibt die Nachricht my arguments are: Gefolgt von den Argumenten aus (jeweils in einer separaten Zeile und in spitzen Klammern) und endet. Im Login-Fall gibt es keine Argumente. Folgendes passiert:

webserver:~# ssh [email protected]
[email protected]'s password:
Linux webserver [ snip ]
[ snip ]
my arguments are:
Connection to localhost closed.

Wenn der Benutzer versucht, einen Befehl auszuführen, sieht dieser folgendermaßen aus:

webserver:~# ssh [email protected] cat /etc/passwd
[email protected]'s password:
my arguments are:
<-c>
<cat /etc/passwd>

Unsere "Shell" erhält einen Aufruf im -c - Stil mit dem gesamten Befehl als einem Argument, genauso wie /bin/sh Ihn erhalten würde.

Wie Sie sehen, können wir das Skript jetzt so weiterentwickeln, dass es den Fall erkennt, wenn es mit einem -c - Argument aufgerufen wurde, und dann den String analysiert (etwa durch Mustervergleich). Die erlaubten Zeichenketten können durch rekursives Aufrufen von /bin/bash -c <string> An die echte Shell übergeben werden. Der Ablehnungsfall kann eine Fehlermeldung ausgeben und beendet werden (einschließlich des Falls, wenn -c Fehlt).

Sie müssen vorsichtig sein, wie Sie dies schreiben. Ich empfehle, nur positive Übereinstimmungen zu schreiben, die nur ganz bestimmte Dinge zulassen, und alles andere zu verbieten.

Hinweis: Wenn Sie root sind, können Sie sich dennoch in diesem Konto anmelden, indem Sie die Shell im Befehl su wie folgt überschreiben su -s /bin/bash foo. (Ersetzen Sie die Shell Ihrer Wahl.) Nicht-Root kann dies nicht tun.

Hier ist ein Beispielskript: Beschränken Sie den Benutzer darauf, nur ssh für git den Zugriff auf Repositorys unter /git Zu verwenden.

#!/bin/sh

if [ $# -ne 2 ] || [ "$1" != "-c" ] ; then
  printf "interactive login not permitted\n"
  exit 1
fi

set -- $2

if [ $# != 2 ] ; then
  printf "wrong number of arguments\n"
  exit 1
fi

case "$1" in
  ( git-upload-pack | git-receive-pack )
    ;; # continue execution
  ( * )
    printf "command not allowed\n"
    exit 1
    ;;
esac

# Canonicalize the path name: we don't want escape out of
# git via ../ path components.

gitpath=$(readlink -f "$2")  # GNU Coreutils specific

case "$gitpath" in
  ( /git/* )
     ;; # continue execution
  ( * )
    printf "access denied outside of /git\n"
    exit 1
    ;;
esac

if ! [ -e "$gitpath" ] ; then
   printf "that git repo doesn't exist\n"
   exit 1
fi

"$1" "$gitpath"

Natürlich vertrauen wir darauf, dass diese Git-Programme git-upload-pack Und git-receive-pack Keine Löcher oder Escape-Schraffuren haben, die den Benutzern den Zugriff auf das System ermöglichen.

Dies ist mit dieser Art von Beschränkungsschema verbunden. Der Benutzer ist authentifiziert, um Code in einer bestimmten Sicherheitsdomäne auszuführen, und wir begrenzen diese Domäne auf eine Unterdomäne. Wenn Sie beispielsweise einem Benutzer erlauben, den Befehl vim für eine bestimmte Datei auszuführen, um diese zu bearbeiten, kann der Benutzer einfach eine Shell mit :!sh[Enter] Abrufen.

29
Kaz

Was Sie suchen, heißt Restricted Shell . Bash bietet einen solchen Modus, in dem Benutzer nur Befehle ausführen können, die in ihren Basisverzeichnissen vorhanden sind (und nicht in andere Verzeichnisse verschoben werden können), was für Sie möglicherweise ausreichend ist.

Ich habe festgestellt, dass dieser Thread sehr anschaulich ist, wenn auch etwas veraltet.

14
Vinko Vrsalovic

Sie sollten "rssh" erwerben, die eingeschränkte Shell

Sie können die oben genannten Einschränkungen befolgen. Sie sind alle selbsterklärend und einfach zu befolgen. Verstehe die Begriffe "chroot jail" und wie man effektiv sshd/terminal-Konfigurationen implementiert und so weiter.

Da die meisten Benutzer über sshd auf Ihre Terminals zugreifen, sollten Sie wahrscheinlich auch sshd_conifg, die Konfigurationsdatei des SSH-Dämons, überprüfen, um bestimmte Einschränkungen über SSH anzuwenden. Sei jedoch vorsichtig. Verstehe richtig, was du zu implementieren versuchst, denn die Folgen falscher Konfigurationen sind wahrscheinlich ziemlich schlimm.

4
Chuah

Warum schreibst du nicht deine eigene Login-Shell? Es wäre recht einfach, Bash dafür zu verwenden, aber Sie können eine beliebige Sprache verwenden.

Beispiel in Bash

Erstellen Sie die Datei mit Ihrem bevorzugten Editor /root/rbash.sh (Dies kann ein beliebiger Name oder Pfad sein, sollte aber chown root:root Und chmod 700 Sein):

#!/bin/bash

commands=("man" "pwd" "ls" "whoami")
timestamp(){ date +'%Y-%m-%s %H:%M:%S'; }
log(){ echo -e "$(timestamp)\t$1\t$(whoami)\t$2" > /var/log/rbash.log; }
trycmd()
{
    # Provide an option to exit the Shell
    if [[ "$ln" == "exit" ]] || [[ "$ln" == "q" ]]
    then
        exit

    # You can do exact string matching for some alias:
    Elif [[ "$ln" == "help" ]]
    then
        echo "Type exit or q to quit."
        echo "Commands you can use:"
        echo "  help"
        echo "  echo"
        echo "${commands[@]}" | tr ' ' '\n' | awk '{print "  " $0}'

    # You can use custom regular expression matching:
    Elif [[ "$ln" =~ ^echo\ .*$ ]]
    then
        ln="${ln:5}"
        echo "$ln" # Beware, these double quotes are important to prevent malicious injection

        # For example, optionally you can log this command
        log COMMAND "echo $ln"

    # Or you could even check an array of commands:
    else
        ok=false
        for cmd in "${commands[@]}"
        do
            if [[ "$cmd" == "$ln" ]]
            then
                ok=true
            fi
        done
        if $ok
        then
            $ln
        else
            log DENIED "$cmd"
        fi
    fi
}

# Optionally show a friendly welcome-message with instructions since it is a custom Shell
echo "$(timestamp) Welcome, $(whoami). Type 'help' for information."

# Optionally log the login
log LOGIN "[email protected]"

# Optionally log the logout
trap "trap=\"\";log LOGOUT;exit" EXIT

# Optionally check for '-c custom_command' arguments passed directly to Shell
# Then you can also use ssh [email protected] custom_command, which will execute /root/rbash.sh
if [[ "$1" == "-c" ]]
then
    shift
    trycmd "[email protected]"
else
    while echo -n "> " && read ln
    do
        trycmd "$ln"
    done
fi

Sie müssen diese ausführbare Datei lediglich als Anmeldeshell festlegen. Bearbeiten Sie beispielsweise Ihre /etc/passwd - Datei und ersetzen Sie die aktuelle Anmeldeshell dieses Benutzers /bin/bash Durch /root/rbash.sh.

Dies ist nur ein einfaches Beispiel, aber Sie können es so weiterentwickeln, wie Sie möchten. Die Idee ist da. Achten Sie darauf, dass Sie sich nicht aussperren, indem Sie die Login-Shell Ihres eigenen und einzigen Benutzers ändern. Und testen Sie immer seltsame Symbole und Befehle, um festzustellen, ob sie tatsächlich sicher sind.

Sie können es testen mit: su -s /root/rbash.sh.

Vorsicht, stelle sicher, dass der gesamte Befehl übereinstimmt und sei vorsichtig mit Platzhaltern! Besser Bash-Symbole wie ;, &, &&, ||, $ Und Backticks ausschließen, um sicherzugehen.

Abhängig von der Freiheit, die Sie dem Benutzer einräumen, wird es nicht viel sicherer. Ich habe festgestellt, dass ich oft nur einen Benutzer erstellen musste, der Zugriff auf nur einige relevante Befehle hat, und in diesem Fall ist dies wirklich die bessere Lösung. Möchten Sie jedoch mehr Freiheit gewähren, sind ein Gefängnis und Berechtigungen möglicherweise angemessener. Fehler werden leicht gemacht und erst bemerkt, wenn es schon zu spät ist.

3
Yeti

Vielleicht möchten Sie ein Gefängnis einrichten.

1
tmeisenh

[Offenlegung: Ich schrieb sshdo, die unten beschrieben wird]

Wenn Sie möchten, dass die Anmeldung interaktiv ist, ist das Einrichten einer eingeschränkten Shell wahrscheinlich die richtige Antwort. Wenn es jedoch eine Reihe von Befehlen gibt, die Sie zulassen möchten (und sonst nichts), und diese Befehle einzeln über ssh ausgeführt werden können (z. B. ssh user @ Host cmd arg bla bla), dann ein generisches Steuerelement für das Whitelisting von Befehlen für ssh könnte das sein, was du brauchst. Dies ist nützlich, wenn die Befehle auf Client-Seite in einem Skript geschrieben sind und der Benutzer den Befehl ssh nicht tatsächlich eingeben muss.

Dafür gibt es ein Programm namens sshdo. Es steuert, welche Befehle über eingehende SSH-Verbindungen ausgeführt werden dürfen. Es steht zum Download zur Verfügung unter:

http://raf.org/sshdo/ (Manpages hier lesen) https://github.com/raforg/sshdo/

Es verfügt über einen Trainingsmodus, in dem alle versuchten Befehle zugelassen werden, und die Option --learn, um die Konfiguration zu erstellen, die erforderlich ist, um gelernte Befehle dauerhaft zuzulassen. Dann kann der Trainingsmodus ausgeschaltet werden und alle anderen Befehle werden nicht ausgeführt.

Es gibt auch die Option --unlearn, um zu verhindern, dass Befehle, die nicht mehr verwendet werden, zugelassen werden, um die geringsten Berechtigungen beizubehalten, wenn sich die Anforderungen im Laufe der Zeit ändern.

Es ist sehr pingelig, was es erlaubt. Ein Befehl mit Argumenten wird nicht zugelassen. Es können nur vollständige Shell-Befehle zugelassen werden.

Es werden jedoch einfache Muster unterstützt, um ähnliche Befehle darzustellen, die sich nur in den Ziffern unterscheiden, die in der Befehlszeile angezeigt werden (z. B. Folgenummern oder Datums-/Zeitstempel).

Es ist wie eine Firewall oder ein Whitelisting-Steuerelement für ssh-Befehle.

Außerdem werden verschiedene Befehle unterstützt, die für verschiedene Benutzer zulässig sind.

0
raf

Eine andere Sichtweise ist die Verwendung von POSIX-ACLs. Sie muss von Ihrem Dateisystem unterstützt werden. Sie können jedoch alle Befehle unter Linux genau abstimmen, so wie Sie unter Windows die gleiche Steuerung haben (nur ohne die schönere Benutzeroberfläche) ). Link

Eine andere Sache, in die man schauen sollte, ist PolicyKit .

Sie müssen ziemlich viel googeln, um alles zum Laufen zu bringen, da dies im Moment definitiv keine Stärke von Linux ist.

0
Bryan Rehbein