So geben Sie das Passwort in einem Bash-Skript, das sudo benötigt, nur einmal ein

21

Daten

  • Ich möchte, dass Operator-Benutzer auf diesem Computer ihre eigenen CIF-Freigaben bereitstellen
  • Die sudoersDatei enthält bereits den /bin/mount -t cifs //*/* /media/* -o username=*Befehl für alle Operatoren
  • Ich möchte, dass die Benutzer eine cifsFreigabe über ein Skript bereitstellen, das das Kennwort nur einmal und nicht zweimal eingibt.
  • Das sudo-Passwort und das cifs-Passwort sind identisch.

Was ich schon habe

Dieses Skript funktioniert:

#!/bin/bash
sudo 'mount -t cifs //192.168.1.1/home /media/$USER/home -o username=$USER'

... aber die Benutzer müssen dasselbe Passwort zweimal eingeben!

  • Einmal für sudo
  • Einmal für die Montierung selbst

Das würde auch funktionieren:

#!/bin/bash
echo -n Password: 
read -s szPassword
echo $szPassword | sudo -S sh -c 'echo $szPassword | mount -t cifs //192.168.1.1/home /media/$USER/home -o username=$USER'

... aber dafür müsste ich allen Betreibern die Möglichkeit gebensudo sh (schwerwiegendes Sicherheitsproblem)

Frage

Wie mounte ich eine CIF-Freigabe in bash¹, ohne shdie sudoersDatei einzufügen oder eine permanente / temporäre Datei zu erstellen?

Anmerkung 1: Kein Python, Perl, C, Go, ... bitte?
Hinweis 2: Ich weiß, dass ich das Passwort einfach durch die sudoersDatei entfernen kann , aber ich versuche, die Sicherheit zu erhöhen, nicht zu lockern, ohne auf Bequemlichkeit zu verzichten ...

Fabby
quelle
2
Wie wäre es printf "%s\n" "$szPassword" "$szPassword" | sudo -S mount -t cifs / ...?
muru
Versuchen Sie das jetzt! @Muru
Fabby

Antworten:

24

Sie sollten stattdessen den Benutzer veranlassen, sudo als zu verwenden sudo script. Überprüfen Sie einfach, ob das Skript als root ausgeführt wird, wenn Sie nicht danach fragen

if [[ $EUID -ne 0 ]]; then
   echo "This script must be run as root, use sudo "$0" instead" 1>&2
   exit 1
fi

Versuchen Sie nicht, das Passwort Ihrer Benutzer zu erfassen.

Braiam
quelle
1
Vielleicht fehlt mir etwas, aber können Sie erklären, wie sich die Anzahl der Passwortabfragen von zwei auf eins verringert? Ansonsten sehe ich nicht, wie dies die Frage beantwortet.
Oliphaunt - wieder Monica
@Oliphaunt Ich sehe keine zwei Passwortabfragen. Können Sie das erklären? Auch diese Antwort ist nicht das, was OP will, sondern was es braucht. Ist eine saubere und richtige Lösung, wenn Sie Befehle als root ausführen müssen und wie andere Dienstprogramme (überprüfen Sie, ob root, sonst Bail-out)
Braiam
1
Das Problem des OP (so wie ich es verstehe) ist, dass der Benutzer nach seinem Passwort gefragt wird sudound dann (nach erfolgreicher Authentifizierung) wieder von mount. In ihrem Anwendungsfall sind diese Passwörter identisch, so dass ich sehen kann, warum das OP möchte, dass der Benutzer dieses Passwort nur einmal eingeben muss. Ich glaube nicht, dass Ihre Lösung dabei hilft. Ich bin damit einverstanden, dass man keine Passwörter erfassen sollte.
Oliphaunt - wieder Monica
Danke, aber ich hätte die Frage vielleicht ein wenig vereinfacht: Es ist bereits ein Skript, enthält bereits diesen Test (mit Ausnahme des 1>&2), befindet sich im Autostart und war früher nur eine CIF-Freigabe, aber jetzt sind es drei, also wirklich ein Passwort wird gebraucht. (Dieser Test ist bereits enthalten, falls jemand anderes, der nicht Mitglied der Operatorengruppe ist, versucht, ihn auszuführen.)
Fabby
@ Fabby Ich denke immer noch, dass Sie das Problem falsch angehen. In diesen Fällen gibt es ~/.smbcredentialsHilfsprogramme, mit denen Sie das Kennwort einer CIFS / SMB-Freigabe sicher "merken" können ( z. B. beim Bearbeiten ), und zwar auch ohne sudo (wenn Sie gvfs, umount oder polkit verwenden).
Braiam
7

Ich bin dumm!

Das folgende Skript:

#!/bin/bash
read -p "Password: " -s szPassword
printf "%s\n" "$szPassword" | sudo --stdin mount -t cifs //192.168.1.1/home /media/$USER/home -o username=$USER,password="$szPassword"

funktioniert einfach und:

  1. Erstellt keine Dateien mit Passwörtern
  2. Ermöglicht dem Benutzer, nur ein Kennwort für mehrere Freigaben (einschließlich Windows-Freigaben) einzugeben.
  3. Es müssen keine zusätzlichen Berechtigungen erteilt werden. :-)
Fabby
quelle
1
1 Frage: Gibt das den Befehl in die Prozessliste zurück?
Rinzwind,
3
@Rinzwind als eingebautes sollte es nicht in bash oder zsh geben. Der Befehl mount könnte jedoch.
muru
<<<könnte auch anstelle von verwendet werden printf , aber ein besserer Ansatz wäre es, auf alles zu readverzichten und einfach sudo --stdinalles alleine zu verwenden. So etwas wie $ printf "Type out your password\n" && sudo --stdin apt-get update Benutzer kann immer noch das sudo-Passwort eingeben. und das wird es nicht in die Prozessliste setzen. Aber natürlich gibt es unendlich viele andere mögliche Sicherheitsprobleme, wie Keylogger, potenzielle Sicherheitslücken in sudound bla und bla und bla ins Unendliche
Sergiy Kolodyazhnyy
@SergiyKolodyazhnyy: Fühlen Sie sich frei zu bearbeiten , Mann!
Fabby
3

sudoFür die Ausführung dieses Befehls ist kein Kennwort erforderlich. Die Passwortabfrage für mountbleibt bestehen.

In sudoers, schließen Sie etwas wie ein

ALL        ALL = NOPASSWD: /bin/mount -t cifs //*/* /media/* -o username=*

Nachdem Sie dies eingegeben haben, sudowerden Sie nicht mehr nach einem Kennwort für diesen bestimmten Befehl gefragt. Der Benutzer muss weiterhin ein Kennwort für den mountBefehl angeben.

Hinweis : Ich habe den Befehl wörtlich von dem übernommen, was Sie in der Frage angegeben haben. Ich habe nicht geprüft, ob die Platzhalter den Benutzern erlauben würden, etwas Böses zu tun. In der sudoersManpage finden Sie Beispiele für üble Dinge. Beachten Sie insbesondere, dass sudoersder Benutzer in dieser Zeile beliebig viele -oSchalter oder andere Argumente hinzufügen kann mount. Möglicherweise möchten Sie Ihren Ansatz überdenken, indem Sie z. B. ein Skript wie das von @Braiam vorgeschlagene hinzufügen und die Ausführung sudoohne zusätzliche Authentifizierung zulassen . Das Skript stellt dann sicher, dass Benutzer nur die bestimmte Form ausführen können mount, die sie ausführen möchten.

Anstatt dies für alle Benutzer zuzulassen, können Sie dies auch auf Mitglieder einer bestimmten Gruppe beschränken, z. B. eine Gruppe erstellen cifsmountund dann haben

%cifsmount ALL = NOPASSWD: /bin/mount -t cifs //*/* /media/* -o username=*
In Oliphaunt stellst du Monica wieder her
quelle
@ Fabby Sorry, aber was ist daran so gefährlich? Auch ich kann einen Anflug von Sarkasmus feststellen, nicht sicher.
Oliphaunt
Nun, auch wenn für sudo kein Kennwort erforderlich ist, ist für mount möglicherweise noch ein Kennwort erforderlich. Die Datei / etc / sudoers kann verwendet werden, um sudo dazu zu bringen, kein Passwort zu benötigen. Das würde nicht beeinflussen, ob mount nach einem Passwort fragt. Wenn eine Person nicht einbinden konnte, würde sudo am Ende nur einen Befehl ausführen, der fehlschlägt, was wahrscheinlich kein Problem ist.
TOOGAM
@TOOGAM Das war meine Absicht. Ein Passwort statt zwei.
Oliphaunt
Ich beabsichtige, eine "Operator" -Gruppe in der sudoers-Datei zu belassen. Wenn also ein Operator versucht, seine eigenen Inhalte zu mounten, muss er noch ein Passwort eingeben, aber um die "Standard" -Operator-Mounts zu mounten, muss er nur das Passwort eingeben einmal statt 5 mal ... Aber Ihre Lösung könnte für andere arbeiten, also upvoted ... (und ursprüngliche Kommentare entfernt)
Fabby
1

Eine allgemeine Lösung für diese Probleme besteht darin, die folgende Präambel an die Spitze Ihres Sudo zu setzen, für das Skripte erforderlich sind:

#!/bin/bash
case $EUID in
   0) : cool we are already root - fall through ;;
   *) # not root, become root for the rest of this session
      # (and ask for the sudo password only once)
      sudo $0 "$@" ;;
esac
# now the present process is effective-UID  (root)
# so there's no need to put sudo in front of commands

any more commands here will run as superuser ...

Dies hat natürlich den Nachteil, dass bei einigen Befehlen im Skript keine sudounnötige Erhöhung der Berechtigungen erforderlich ist.

Jedenfalls dachte ich, ich würde diesen kleinen Tipp teilen. Das Schönste daran ist, dass, wenn Sie bereits eine effektive UID-Wurzel haben (z. B. wenn Sie sie bereits unter sudo aufgerufen haben), sie anmutig das Richtige tut. Außerdem ist es weniger benutzerfreundlich, einen Fehler zu melden und Sie (mit sudo) zur erneuten Eingabe / Ausführung zu zwingen.

Möglicherweise möchten Sie auch die timestamp_timeoutVariable auschecken, in man 5 sudoersder angegeben wird sudo, dass Benutzeranmeldeinformationen für eine begrenzte Anzahl von Minuten gespeichert werden sollen (dies kann auch ein Bruchteil sein).

Arielf
quelle
Ich habe das Skript zu stark vereinfacht, um eine einfache Antwort zu erhalten: Das Skript enthält bereits: #test if root: if not: bail out if [[ $EUID -ne 0 ]]; then echo "This script must be run as root, use sudo "$0" instead" 1>&2 exit 1 fi Der Punkt ist, dass es auch mehrere Bereitstellungen mit demselben Kennwort enthält (erneut: entfernt), aber trotzdem danke ...
Fabby
1
Der Punkt ist, dass die obige Lösung nur eine Eingabe des Passworts erfordern würde (für sudo). Es sollte keinen anderen erfordern. Außerdem ist es ein allgemeiner Ansatz (und eleganter, als einen Fehler zu melden und den Befehl mit sudo erneut einzugeben) für alle ähnlichen Probleme, selbst wenn mehrere (mehr als zwei) privilegierte Befehle erforderlich sind.
Arielf
Das sollte es aber nicht ! ;-) Das liegt daran, dass für jedes cifs share mount auch ein Passwort erforderlich ist. (wie es kann unterschiedlich sein von dem Ubuntu - Passwort, aber in diesem Fall nicht , da die Betreiber behalten ihre Windows- und Ubuntu Passwörter synchronisiert)
Fabby