Wie erzwinge ich immer ein Sudo-Passwort für einen bestimmten Befehl?

12

Neulich habe ich einige Wartungsarbeiten auf meinem Webserver durchgeführt. Ich hatte es eilig und war müde, also habe ich alles mit sudoKommando gemacht.

Und dann habe ich versehentlich Ctrl+ gedrückt Vund diesen Befehl an meinen Webserver gesendet:

sudo rm -rf /*

Für diejenigen, die sich fragen, was der obige Befehl bewirkt: Dies löschte meinen gesamten Webserver

Zum Glück hatte ich Backups und leider musste ich noch zwei Stunden wach sein, um diesen großartigen Fehler zu beheben. Aber seitdem habe ich mich gefragt:

Gibt es eine Möglichkeit, das sudo-Kennwort immer für einen bestimmten Befehl zu erzwingen?

Wenn der Server mich nach einem Passwort fragen würde, würde ich mir viele Probleme ersparen. Es tat nicht, weil ich ungefähr 5 sudoBefehle vor diesem majestätischen Fehler ausgeführt habe.

Gibt es einen Weg, dies zu tun? Ich brauche nur das Passwort mit dem rmBefehl, um immer durchgesetzt zu werden. Andere Befehle, die ich benutze, sind normalerweise nanooder cpbeide (in gewissem Maße) rückgängig zu machen.

Pavel Janicek
quelle
1
Siehe auch: So wird sudo jedes Mal zur
Eingabe
2
@solsTiCe /*wird erweitert, bevor es an den Befehl rm übergeben wird. Der Befehl sieht also kein einziges Argument, sondern eine Liste von Argumenten ( /bin /boot /cdrom /dev /etc /home...)
Dan
3
Eine wichtige Lehre, die Sie daraus ziehen sollten, ist, dass Sie keine Dinge mit sudo ausführen sollten, es sei denn, Sie müssen dies wirklich tun. Ich weiß, das beantwortet nicht, was Sie hier gefragt haben, aber die übergeordnete Frage ist, wie Sie (hoffentlich) verhindern können, dass Sie Ihren Server wieder löschen, und Sudo zu vermeiden, sollte Ihre erste Verteidigungslinie dagegen sein.
David Z
2
Mögliches Duplikat von Wie kann ich ein Kennwort für den Befehl 'rm' einrichten?
WinEunuuchs2Unix
2
@ WinEunuuchs2Unix Das ist überhaupt keine doppelte Frage, der op hier möchte nicht, dass der rmBefehl ein Passwort hat. Sie möchten nur sudojedes Mal, wenn der Befehl rm verwendet wird, eine Eingabeaufforderung eingeben. Die Lösung für die Frage, die Sie verknüpft haben, würde bei Ihrem ersten Befehl etwas ärgerlich werden sudo rm. Da es Sie nach zwei Passwörtern fragt, eins für sudoeins für rm.
Dan

Antworten:

17

Sie können die festgelegt timestamp_timeoutauf 0für bestimmte Befehle in /etc/sudoers. Erstellen Sie eine Datei visudo -f /etc/sudoers.d/pduckmit folgendem Inhalt:

Cmnd_Alias DANGEROUS = /bin/rm

Defaults!DANGEROUS timestamp_timeout=0

pduck ALL = (ALL:ALL) DANGEROUS

Jetzt wird der Benutzer pduckbeim Ausführen immer nach einem Kennwort gefragt sudo rm(unabhängig davon, welche zusätzlichen Parameter angegeben sind), obwohl der Benutzer Mitglied der sudoGruppe ist und sudosich sein Kennwort für andere Befehle merkt.

Der Nachteil ist, dass Sie der /bin/rmZeile in der Datei nicht einfach Parameter hinzufügen können, um dies weiter einzuschränken. Nun ... Sie können, wie:

Cmnd_Alias DANGEROUS = /bin/rm -f

Aber dann werden Sie nur genau sudo rm -fund nicht (erneut) sudo rm -rfzum Beispiel dazu aufgefordert .

PerlDuck
quelle
9

Eine Methode wäre die Verwendung von safe-rm . Dies wird NUR die Verwendung von "rm" ansprechen und verhindern, dass bestimmte Versionen von "rm" ausgeführt werden. Dies schließt das Entfernen Ihres Root-Systems ein, kann aber auch dazu verwendet werden, das Entfernen systembezogener Verzeichnisse wie "/ usr /" oder "/ var /" zu verhindern. Über den Link:

Das versehentliche Löschen wichtiger Dateien rückgängig machen

Safe-rm ist ein Sicherheitstool, das das versehentliche Löschen wichtiger Dateien verhindern soll, indem es /bin/rmdurch einen Wrapper ersetzt wird, der die angegebenen Argumente mit einer konfigurierbaren schwarzen Liste von Dateien und Verzeichnissen vergleicht, die niemals entfernt werden sollten.

Benutzer, die versuchen, eine dieser geschützten Dateien oder Verzeichnisse zu löschen, können dies nicht und erhalten stattdessen eine Warnmeldung:

$ rm -rf /usr   
Skipping /usr

(Geschützte Pfade können sowohl auf Site- als auch auf Benutzerebene festgelegt werden.)

Das Wiederherstellen wichtiger Dateien, die Sie versehentlich gelöscht haben, kann sehr schwierig sein. Schützen Sie sich noch heute durch die Installation von safe-rm und verringern Sie die Wahrscheinlichkeit, dass Sie sich an einen Datenrettungsdienst wenden müssen!

Bildbeschreibung hier eingeben

Rinzwind
quelle
Upvoted for the safecow
Michael Fulton
3

sudobietet eine Option -k, --reset-timestamp, siehe man sudo:

Wenn diese Option in Verbindung mit einem Befehl oder einer Option verwendet wird, für die möglicherweise ein Kennwort erforderlich ist, ignoriert sudo die zwischengespeicherten Anmeldeinformationen des Benutzers. Infolgedessen fordert sudo zur Eingabe eines Kennworts auf (sofern dies für die Sicherheitsrichtlinie erforderlich ist) und aktualisiert die zwischengespeicherten Anmeldeinformationen des Benutzers nicht.

Sie könnten einen einfachen Wrapper zum sudoTesten schreibenrm -rf /* und Ausführen

sudo -k rm -rf /*

stattdessen zB so:

sudo ()                                                                                                                                                 
{ 
    [[ "$*" == "rm -rf /*" ]] && opt="-k";
    /usr/bin/sudo $opt "$@"
}

Anwendungsbeispiel

Testen mit echo ahier.

$ sudo echo
[sudo] password for dessert: 

$ sudo echo

$ sudo echo a
[sudo] password for dessert: 
a
$ sudo echo a
[sudo] password for dessert: 
a

Wenn Sie bei jeder Ausführung rmim Allgemeinen gefragt werden möchten , können Sie die obige Funktion wie folgt anpassen:

sudo () 
{ 
    [[ "$1" == "rm" ]] && opt="-k";
    /usr/bin/sudo $opt "$@"
}

Wenn Sie sowohl allgemeine Befehlsaufrufe als auch bestimmte Befehlszeilen kombinieren möchten, empfehle ich die Verwendung von casez. B .:

sudo () 
{ 
    case "$*" in 
        rm*)            opt="-k" ;;
        "mv /home"*)    opt="-k" ;;
        "ln -s /usr/bin/fish /bin/sh") opt="-k" && echo "Don't you dare!" ;;
        *)              opt="" ;;
    esac;
    /usr/bin/sudo $opt "$@"
}

Beachten Sie, dass diese Ansätze nicht funktionieren, wenn Sie sudomit Optionen arbeiten. Mögliche Lösungen sind [[ "$*" =~ " rm " ]], nach der Zeichenfolge "rm" zu suchen, die von Leerzeichen umgeben ist, oder *" rm "*)mit case, um eine Befehlszeile mit "rm" abzufangen.

Dessert
quelle
[[ "$1" == "rm" ]] && opt="-k";und wie wäre es /bin/rm?
Rinzwind
@Rinzwind Ich denke, die Funktion ist leicht an spezifische Bedürfnisse anpassbar, insbesondere den caseAnsatz.
Dessert
1

Diese Antwort bezieht sich nicht auf den sudoTeil Ihrer Frage, sondern auf eine Möglichkeit, die Gefahr von versehentlichen rmAufrufen für einen Benutzer zu verringern .

Sie können einen Alias rmfür rm -Iwelche erstellen

  • bittet um Bestätigung, sobald ein Verzeichnis oder mehr als 3 Dateien gelöscht werden
  • solange Sie weglassen,-f welche der vorherigen -IOptionen überschreibt .

--one-file-system ist ein weiterer möglicher Schutz gegen unbeabsichtigtes Löschen, den ich in meinem rm Alias ​​verwende.

Installieren

Verwenden Sie den folgenden Befehl, um einen solchen Alias ​​zu erstellen:

alias rm='rm -I --one-file-system'

Sie können es in Ihre ~/.bashrcoder sogar setzen/etc/bash.bashrc .

Verwendung

$ sudo rm -r /etc/apt/sources.list.d /*
rm: remove all arguments?

Um die Eingabe yesoder die Übersetzung in Ihr Gebietsschema oder den ersten Buchstaben eines Wortes zu bestätigen, drücken Sie Enter. Jede andere Eingabe, einschließlich keiner, bricht den Vorgang ab.

David Foerster
quelle