testian
29.04.14, 23:51
Wie der Titel schon sagt möchte ich Usern erlauben beliebige shell-Befehle auszuführen, sofern diese vorgegeben regulären Ausdrücken entsprechen. Das ist die Spezifikation.
Die Lösung habe ich bereits geschrieben, aber da ich das Gefühl habe sicherheitstechnisch gesehen etwas heikles zu machen, erhoffe ich mir etwas Feedback. Für den folgenden Fall soll angenommen werden, dass sowohl der öffentliche als auch der private Schlüssel von someuser@somehost öffentlich ist, also dem potenziellen Angreifer bekannt ist.
Zunächst habe ich folgendes gemacht:
Für sshd_config ist von defaults auszugehen (z.B. für AcceptEnv)
Eintrag in ~/.ssh/authorized_keys
command="./restrict test",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty ssh-rsa ... someuser@somehost
Dieser Eintrag erzwingt für den Inhaber des "privaten" Schlüssels someuser@somehost den Befehl "./restrict" mit dem Parameter "test". Der Parameter "test" soll der Name einer Art Berechtigungsgruppe oder Rolle sein wie man später sieht. Weitere builtin-Funktionen von SSH (diverse Forwarding-Dienste) sollen abgeschaltet werden.
Die Datei ~/restrict hat folgenden Inhalt und ist ausführbar:
#!/bin/bash
set -e
cd -- "$(dirname -- "$0")"
if [[ $# -ne 1 ]]; then
echo "Usage: $0 <group>" >&2
exit 1
fi
GROUP="$1"
set +e
grep -E -f <(grep -vE '^\s*$' "restrict-groups/$GROUP") <<< "$SSH_ORIGINAL_COMMAND" > /dev/null
EXITCODE=$?
if [[ EXITCODE -ne 0 ]]; then
echo "No permission to execute: $SSH_ORIGINAL_COMMAND" >&2
exit $EXITCODE
fi
bash -c "$SSH_ORIGINAL_COMMAND"
Neben dieser Datei gibt es ein Verzeichnis ~/restrict-groups
Im Verzeichnis ~/restrict-groups gibt es für jede Berechtigsungsgruppe eine Datei mit dem Namen derselben. Diese Datei enthält eine Liste von regulären Ausdrücken.
Entspricht ein SSH mitgegebener Befehl einem der regulären Ausdrücke, dann soll der Befehl ausgeführt werden. Dies wird mit grep -E geprüft. Es kann davon ausgegangen werden, dass die Liste sorgfältig erstellt wurde. Hinweise auf Falltüren sind aber trotzdem willkommen.
Aktuell ist folgendes in der Datei ~/restricted-groups/test zu finden:
^echo fish$
^cat$
Was sagt ihr? Ist das sicher? Gibt es potenzielle Flaws? Erfinde ich das Rad neu?
Meine ersten Sorgen bisher sind, ob das auslesen des EXITCODEs nach "grep -E -f <(grep -vE '^\s*$' "restrict-groups/$GROUP") <<< "$SSH_ORIGINAL_COMMAND" > /dev/null" tatsächlich den Exit-Code des ersten grep erfasst. Ich mag mich erinnern, dass das bei Verwendung der Pipe nicht ganz so einfach ist. Wie ist es in diesem Fall?
Ein weiteres Problem besteht vielleicht dann, wenn die Datei "test" unvollständig kopiert oder während dem Speichervorgang ausgelesen wird und eine Zeile dann dadurch zuviel matcht, weil z.B. kein Match mit dem Zeilenende "$" verlangt wird. Wie sollte ich das auffangen?
Edit: Die entfernte Ausführung gelingt dann nicht interaktiv, sondern einfach so:
ssh exec@remotehost "echo fish"
Die Lösung habe ich bereits geschrieben, aber da ich das Gefühl habe sicherheitstechnisch gesehen etwas heikles zu machen, erhoffe ich mir etwas Feedback. Für den folgenden Fall soll angenommen werden, dass sowohl der öffentliche als auch der private Schlüssel von someuser@somehost öffentlich ist, also dem potenziellen Angreifer bekannt ist.
Zunächst habe ich folgendes gemacht:
Für sshd_config ist von defaults auszugehen (z.B. für AcceptEnv)
Eintrag in ~/.ssh/authorized_keys
command="./restrict test",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty ssh-rsa ... someuser@somehost
Dieser Eintrag erzwingt für den Inhaber des "privaten" Schlüssels someuser@somehost den Befehl "./restrict" mit dem Parameter "test". Der Parameter "test" soll der Name einer Art Berechtigungsgruppe oder Rolle sein wie man später sieht. Weitere builtin-Funktionen von SSH (diverse Forwarding-Dienste) sollen abgeschaltet werden.
Die Datei ~/restrict hat folgenden Inhalt und ist ausführbar:
#!/bin/bash
set -e
cd -- "$(dirname -- "$0")"
if [[ $# -ne 1 ]]; then
echo "Usage: $0 <group>" >&2
exit 1
fi
GROUP="$1"
set +e
grep -E -f <(grep -vE '^\s*$' "restrict-groups/$GROUP") <<< "$SSH_ORIGINAL_COMMAND" > /dev/null
EXITCODE=$?
if [[ EXITCODE -ne 0 ]]; then
echo "No permission to execute: $SSH_ORIGINAL_COMMAND" >&2
exit $EXITCODE
fi
bash -c "$SSH_ORIGINAL_COMMAND"
Neben dieser Datei gibt es ein Verzeichnis ~/restrict-groups
Im Verzeichnis ~/restrict-groups gibt es für jede Berechtigsungsgruppe eine Datei mit dem Namen derselben. Diese Datei enthält eine Liste von regulären Ausdrücken.
Entspricht ein SSH mitgegebener Befehl einem der regulären Ausdrücke, dann soll der Befehl ausgeführt werden. Dies wird mit grep -E geprüft. Es kann davon ausgegangen werden, dass die Liste sorgfältig erstellt wurde. Hinweise auf Falltüren sind aber trotzdem willkommen.
Aktuell ist folgendes in der Datei ~/restricted-groups/test zu finden:
^echo fish$
^cat$
Was sagt ihr? Ist das sicher? Gibt es potenzielle Flaws? Erfinde ich das Rad neu?
Meine ersten Sorgen bisher sind, ob das auslesen des EXITCODEs nach "grep -E -f <(grep -vE '^\s*$' "restrict-groups/$GROUP") <<< "$SSH_ORIGINAL_COMMAND" > /dev/null" tatsächlich den Exit-Code des ersten grep erfasst. Ich mag mich erinnern, dass das bei Verwendung der Pipe nicht ganz so einfach ist. Wie ist es in diesem Fall?
Ein weiteres Problem besteht vielleicht dann, wenn die Datei "test" unvollständig kopiert oder während dem Speichervorgang ausgelesen wird und eine Zeile dann dadurch zuviel matcht, weil z.B. kein Match mit dem Zeilenende "$" verlangt wird. Wie sollte ich das auffangen?
Edit: Die entfernte Ausführung gelingt dann nicht interaktiv, sondern einfach so:
ssh exec@remotehost "echo fish"