Praktische (näher an der klassischen Linux-Methode) Verwendung von SUDO für CygWin (automatisieren)


11

Die Verwendung von sudoBefehlen in CygWin ist nützlich und schneller als das Öffnen einer erhöhten Shell:

Luis@Kenobi /cygdrive/c/Users/Luis
$ net user /add TestUser
System error 5.
Access denied.

Luis@Kenobi /cygdrive/c/Users/Luis
$ sudo net user /add TestUser
Command completed successfully.

Wie oben gezeigt, können Sie ebenso wie Linux Windows-Befehle / -Skripte ausführen. Für mich ist ordentlich; Funktioniert auf Remote- Konsolen (SSH) und ermöglicht das Kombinieren von Windows / Linux- Befehlen. Die Ausführung von Verwaltungsaufgaben ist daher fast ein Muss.

Das SUDO for CygWin- Projekt weist jedoch ein Verhalten auf, das gefährlich sein kann : Es funktioniert als Server / Client- Architektur. Tatsächlich sendet ein Client (sudo) Befehlsanforderungen an einen Server (sudoserver.py) intern (nicht außerhalb des.) lokaler Computer) Port 7070TCP, mit keinem Benutzer oder Berechtigungen überprüft , so dass jeder (auch nicht privilegierte Benutzer) angemeldet auf die Computer - Administratoren ausführen kann (CygWin oder Windows) Shell - Befehle oder Skripte (CygWin oder Windows, auch).
Das Problem wird schlimmer, wenn Sie die vom Autor vorgeschlagene Methode beibehalten: "sudoserver.py" als Dienst registrieren, damit es dauerhaft ausgeführt wird.

Um die Dinge ein bisschen sicherer (nicht vollständig) zu machen, mache ich:
1.- Führen Sie "sudoserver.py" auf einer Admin-Shell aus.
2.- Führen Sie meine "sudo" -Befehle auf einer anderen CygWin-Shell aus.
3.- Schließen Sie (Strg + C) "sudoserver.py" und die Admin-Shell.

Ein bisschen nervig . Ich arbeite daran, indem ich eine .cmdDatei mit einem zugewiesenen Hotkey verwende , auf der "sudoserver.py" ausgeführt wird, und ich schließe sie (manuell) nach meinen Verwaltungsjobs, aber immer noch weit entfernt von der klassischen "sudo" -Benutzbarkeit unter Linux.

Der großartige und praktische Weg wäre eine Methode, die:

  1. ** Öffnet automatisch "sudoserver.py" und fordert die UAC Elevation Prompt (oder den Benutzer / das Passwort) an.
  2. Schließt es nach einer Weile, damit die UAC-Anforderung bei mehreren sudonacheinander ausgeführten Befehlen nicht weiter stört .

Gibt es eine Möglichkeit, dies zumindest teilweise zu automatisieren ?

Antworten:


10

HINWEIS: Dies ist hauptsächlich ein Programm (Shell-Skript), das ich erstellt habe, und ich weiß, dass dieses Forum eher eine Frage-Antwort-Site als eine Programm-Einführungsseite ist. Aber ich habe weder einen GitHub-Account (oder einen ähnlichen Account) noch die Zeit, nach der Methode zu suchen, ein Open Source-Programm in der Community zu veröffentlichen. Also, solange die Gefahr besteht , dass ein funktionierendes und nützliches Programm unbemerkt bleibt (sogar für Monate) zu denen , die es genießen konnte, und es wäre traurig, nicht ein bereits Programm zu teilen, werde ich es hier veröffentlichen für jetzt. Keine Probleme für mich, wenn die Administratoren beschließen, diesen Thread zu entfernen, werde ich verstehen. Ich hoffe , dass die Angelegenheit in einer haben formulierte Frage-Antwort - Art und Weise genug , um es in dieses Forum nützlich zu machen. Wenn es genug gibtinteressierte Benutzer , ich werde mein Bestes tun, um etwas Zeit für die Fortsetzung des Projekts aufzuwenden (nach all meinen Recherchen habe ich im Internet nichts gefunden, was dem am nächsten kommt, aber ... Ich weiß nicht, ob mein Skript wertvoll ist oder nicht es war Zeitverschwendung).

Ich habe ein einfaches Linux-Shell-Skript programmiert , das (bis jetzt) ​​unter CygWin funktioniert und (ich hoffe) dabei hilft, das Zeitangriffsintervall von SUDO für CygWin zu reduzieren. Das Programm heißt TOUACExt (Abkürzung für " TimeOut and UAC Extension ") und fungiert als Wrapper für SUDO für CygWin (erforderlich installiert). Es besteht aus vier .shProgrammen.

Beispiel für die Ausführung von TOUACExt

Eigenschaften :

  • Komfortable Verwendung : Durch die Simulation des ursprünglichen Sudo-Verhaltens unter Linux wird die Eingabeaufforderung für die UAC-Bestätigungsanforderung nur einmal angezeigt (mehrere aufeinanderfolgende sudoBefehle generieren nur eine UAC-Anforderung). Solange sudoserver.py ausgeführt wird (standardmäßig 15 Minuten), werden keine UAC- Anforderungen mehr ausgeführt.
  • Privilegierte Benutzer (Administratoren) erhalten nur eine UAC-Bestätigungsanforderung ( Ja / Nein ) auf dem Bildschirm.
  • Nicht privilegierte Benutzer ( keine Administratoren ) erhalten einen Bildschirm zur Eingabe eines Administratorkontos / Kennworts .
  • sudoserver.py läuft weiter und wird nach der vordefinierten Zeit (15 Minuten) nach der letzten Ausführung des sudo-Befehls automatisch geschlossen .
  • sudoserver.py wird nicht geschlossen (läuft weiter und wird in 5 Minuten erneut überprüft), falls sudo ausgeführt wird.
  • Funktioniert aus der Ferne (über SSH getestet):
    • Nicht privilegierte Benutzer können sudoserver.py nicht remote starten.
  • Erstellt ein (noch einfaches und nicht sehr lesbares) Protokoll bei /var/log/SUDOForCygWin/.

Anforderungen (in CygWin):

  • SUDO für CygWin .
  • pgrep (am procpsPaket).
  • Herde (am util-linuxPaket).
  • nohup (Ich denke , standardmäßig auf CygWin installiert , aber nicht sicher).

Angenommen : - Die beiden Programme des SUDO for CygWin-Projekts auf dem vom Autor vorgeschlagenen Weg:

/usr/local/bin/sudoserver.py
/usr/local/bin/sudo

TOUACExt wurde unter Windows 7 SP1 und Windows XP SP3 getestet , aber ich weiß nicht, ob es sinnvoll ist, es in diesem letzten zu verwenden.

Installationsanleitung :

  • Fügen Sie dieses Skript (vorgeschlagener Name SUDOServer.cmd:) ein und erstellen Sie eine Verknüpfung (Sie können das Symbol personalisieren, wenn Sie möchten) mit dem Namen SUDOServer.lnk(Sie müssen diese Verknüpfung aktivieren Advanced Options --> Execute as Administrator) an einer beliebigen Stelle in Ihrem Windows-Pfad , sodass Sie sudoserver.pydirekt von Windows angefordert werden können:

    c:\CygWin\bin\python2.7.exe /usr/local/bin/sudoserver.py

  • Fügen Sie die vier .sh- Skripte von TOUACExt in den Pfad ein, zum Beispiel:

    /usr/local/bin/SUDO.sh /usr/local/bin/SUDOServer.sh /usr/local/bin/SUDOServerWatchDog.sh /usr/local/bin/SUDOServerWatchDogScheduler.sh

  • Benennen Sie das ursprüngliche Python-Skript von um sudoin sudo.py:

    mv /usr/local/bin/sudo /usr/local/bin/sudo.py
    WARNUNG: Das ursprüngliche Python-Skript "sudo" darf nirgendwo auf Ihrem Pfad verbleiben, da es sonst ausgeführt werden kann.

  • Erstellen Sie diesen Alias (z. B. manuell oder durch Bearbeiten Ihres ~/.bashrc):

    alias sudo='SUDO.sh'

Code für SUDO.sh :

#!/bin/bash

# ********** SUDO.sh v0.04a **********

# Variables:
# LockFile (will use a temporal one for now):
#lockfile=sudoserver-running.lck
LockFile=lockfile.lck

# Creating LogFile (if it does not exist):
mkdir /var/log/SUDOForCygWin 2>/dev/null
chmod 777 /var/log/SUDOForCygWin 2>/dev/null
LogFile=/var/log/SUDOForCygWin/$(date +%Y%m%d).log
exec 5>>$LogFile    # Redirector 5 will be the log file.
chmod 777 $LogFile >&5 2>&5 # Writable to anyone (for now).

# Start of the program
echo "========== Starting SUDO Server for CygWin ==========" >&5
echo $(date) >&5

# does the lock file exists as locked?
if [ $(flock -n $TMP/$LockFile echo>/dev/null;echo $?) -eq 0 ]
   then
    # The lock file is not locked.
    echo "LockFile not locked. Testing sudo access..." >&5
    if [ $(sudo.py vartemp=0>/dev/null 2>/dev/null;printf $?) -eq 0 ]
       then
        # Wooops. sudoserver.py is running without the lockfile. Better to correct this.
        echo "LockFile not locked, but sudoserver.py seems to be running." >&5
        printf "Killing sudoserver.py...\n" >&5
        sudo.py kill $(sudo.py pgrep.exe -f -l sudoserver.p[y] | grep "pgrep" -v | awk '{print $1}') >&5 2>&5
    fi
    # Starting SUDOServer.sh
    printf "Requesting SUDOServer start...\n" >&5
    nohup SUDOServer.sh >&5 2>&1&
    # Wait some time delay for UAC Prompt to start
    sleep 2
    timeout=$((SECONDS+10))
    # Has sudoserver.py already started?
    while [ $(flock -w 1 $TMP/$LockFile echo>/dev/null;printf $?) -eq 0 ] || [ $(tasklist | grep "consent.exe" -i>/dev/null;printf $?) -eq 0 ]
    do
        # No. We have to wait.
        # Waiting for SUDOServer.py to be running.
        printf "."
        if [ $SECONDS -ge $timeout ]
           then
            # sudoserver.py not responding. Aborting with errorlevel=3.
            printf "sudoserver.py not responding. Aborting.\n"
            exit 3
        fi
    done
    # Yes. sudoserver.py is up and running.
fi

printf "\n"
# Schedule (add) SUDOServer Watch Dog to Task Scheduler:
SUDOServerWatchDogScheduler.sh

# Invoke requested sudo command
sudo.py $@

#printf "ErrorLevel was: "$?


# ErrorLevel Codes:
# 3 --> timeout waiting for sudoserver.py to respond.

Code für SUDOServer.sh :

#!/bin/bash

# ********** SUDOServer.sh v0.04a **********

# Variables:
# LockFile (a temporal one for now):
#lockfile=sudoserver-running.lck
LockFile=lockfile.lck

# Check for other instances of sudoserver.py running
if [ $(flock -n $TMP/$LockFile echo>/dev/null;printf $?) -eq 0 ]
   then
    printf "Creating lockfile: "$TMP/$LockFile"\n"
    flock $TMP/$LockFile -c 'cmd /c SUDOServer'
    # The file has been unlocked. Send error level=2.
    exit 2
   else
    printf "The lockfile: "$TMP/$LockFile" is locked by another process.\n"
    printf "Exiting SUDOServer.sh"
fi

printf "SUDOServer.sh execution finished. Exiting."

# Exiting with no problems.
exit 0

# ErrorLevel Codes:
# 2 --> SUDOServer.lnk (maybe denial of UAC). 

Code für SUDOServerWatchDog.sh :

#!/bin/bash

# ********** SUDOServerWatchDog.sh v0.04a **********

# Variables:
# LockFile (a temporal one for now):
#lockfile=sudoserver-running.lck
LockFile=lockfile.lck

# Redirecting to LogFile:
LogFile=/var/log/SUDOForCygWin/$(date +%Y%m%d).log
exec 5>>$LogFile
if [ $(stat $LogFile -c %a) -ne 777 ]
   then
    echo "Logfile "$LogFile" has incorrect permissions." >&5
    echo "Attemping to change permissions of "$LogFile >&5
    chmod 777 $LogFile >&5 2>&5
fi

# Remove Task Scheduler entry, if exists.
if [ $(schtasks.exe /query | grep "SUDOServerWatchDog" -i>/dev/null 2>&5;printf $?) -eq 0 ]
   then
    sudo.py schtasks.exe /delete /tn "SUDOServerWatchDog" /f >&5 2>&5
fi

# Is sudoserver.py running?
if [ $(flock -n $TMP/$LockFile echo>/dev/null;printf $?) -eq 1 ] || [ $(sudo.py vartemp=0>/dev/null 2>/dev/null;printf $?) -eq 0 ]
   then
    # Yes. sudoserver.py is running. So...
    printf "sudoserver.py detected running...\n" >&5
    # Is any instance of sudo running right now?
    if [ $(sudo.py pgrep -f -l "/usr/local/bin/sudo.py " | grep -v grep>/dev/null 2>&5;printf $?) -eq 0 ]
       then
        # Yes. sudo is running right now. So...
        printf "There are instances of sudo running.\n" >&5
        sudo.py schtasks /create /tn "SUDOServerWatchDog" /tr "SUDOServerWatchDog" /sc minute /mo 5 /sd 10/10/2010 /ru "SYSTEM" >&5 2>&5
        printf "Will check again in 5 minutes. Adding Task.\n" >&5
       else
        # No. sudo is not running right now. So...
        # Kill sudoserver.py.
        printf "Closing sudoserver.py\n" >&5
        sudo.py kill $(sudo.py pgrep.exe -f -l sudoserver.p[y] | grep "pgrep" -v | awk '{print $1}')
    fi
   else
    printf "sudoserver.py not running. Nothing to be done.\n" >&5
fi 

Code für SUDOServerWatchDogScheduler.sh :

#!/bin/bash

# ********** SUDOWatchDogScheduler.sh v0.04a **********

# Check if WatchDog is already scheduled
if [ $(schtasks.exe /query | grep "SUDOServerWatchDog">/dev/null 2>&5;printf $?) -eq 0 ]
   then
    # Yes. Remove it in order to create a new one.
        echo "Task SUDOServerWatchDog already existing." >&5
    echo "Removing task SUDOServerWatchDog..." >&5
    sudo.py schtasks.exe /delete /tn "SUDOServerWatchDog" /f >&5 2>&5
    if [ $? -eq 0 ]
       then
        # Task correctly deleted.
        echo "Task correctly removed." >&5
       else
        # Something failed in task creation. Report.
        echo "ERROR on deleting the SUDOServerWatchDog programmed task." >&5
    fi
fi
# Schedule new task for deletion.
echo "Adding new SUDOServerWatchDog task to trigger in 15 minutes." >&5
sudo.py schtasks /create /tn "SUDOServerWatchDog" /tr "SUDOServerWatchDog" /sc minute /mo 15 /sd 10/10/2010 /ru "SYSTEM" >&5 2>&5
if [ $? -eq 0 ]
   then
    # Task correctly scheduled.
    echo "Task SUDOServerWatchDog correctly scheduled." >&5
   else
    # Something failed in task scheduling. Report.
    echo "ERROR on scheduling programmed task SUDOServerWatchDog." >&5
fi 

Testen Sie das Programm über eine CygWin Bash-Shell:

Luis@Kenobi ~
$ sudo ls -la
<UAC ELEVATION PROMPT APPEARS>
total 49
drwxr-xr-x+ 1 Luis  None     0 abr  7 02:23 .
drwxrwxrwt+ 1 Luis- None     0 abr  4 03:27 ..
-rw-------  1 Luis  None 13798 abr 14 00:31 .bash_history
-rwxr-xr-x  1 Luis  None  1494 mar  3 11:36 .bash_profile
-rwxr-xr-x  1 Luis  None  6260 abr  6 05:19 .bashrc
-rwxr-xr-x  1 Luis  None  1919 mar  3 11:36 .inputrc
-rw-------  1 Luis  None    35 abr  2 01:43 .lesshst
-rwxr-xr-x  1 Luis  None  1236 mar  3 11:36 .profile
drwx------+ 1 Luis  None     0 mar  8 01:49 .ssh
-rw-r--r--  1 Luis  None     7 mar  4 18:01 d:ppp.txt
-rw-r--r--  1 Luis  None    37 abr  7 02:23 my.log

HINWEIS 2: Diese Skripte befinden sich in der Vor-Beta- Version, sind also immer noch fehlerhaft und der Code ist nicht sehr sauber. Wie auch immer, in meinen Tests mit drei verschiedenen Windows 7-Computern scheinen sie (meistens) in Ordnung zu sein.

Kurze Erklärung des Programms:

  1. Aufgrund des Alias ​​wird beim Ausführen eines sudo-Befehls das Skript SUDO.sh aufgerufen.
  2. SUDO.sh ruft SUDOServer.sh auf und öffnet SUDOServer.lnkbei Bedarf (über ) "sudoserver.py".
  3. Der vom Benutzer aufgerufene ursprüngliche sudo-Befehl wird ausgeführt.
  4. Anschließend ruft SUDO.sh SUDOServerWatchDogScheduler.sh auf , das die Ausführung von SUDOServerWatchDog.sh nach der angegebenen Zeit (standardmäßig 15 Minuten) zum Schließen plant sudoserver.py.
  5. Nach der vordefinierten Zeit schließt SUDOServerWatchDog.sh sudoserver.py . Wenn eine sudo-Instanz ausgeführt wird , programmiert sie sich nach 5 Minuten für die neue Ausführung.

Zu tun :

  • Selbstinstallationsprogramm , das alle .sh-, .cmd- und .lnk-Dateien automatisch erstellt.
  • Richten Sie eine Sperrdatei für eine andere Datei ein (diese befindet sich unter $ TMP / lockfile.lck).
  • Fügen Sie ein Konfigurationsskript oder eine .config-Datei hinzu (für Standardeinstellungen bei Zeitüberschreitungen, Dateispeicherorten usw.).
  • Verhalten des Systemkontos hinzufügen (danke, @ Wyatt8740).
  • ¿Gegebenenfalls "Flock" (SUDO-Modus mit interner Verriegelung) mit "Fixiereinheit" ändern?
  • Vorschläge angenommen.

Gemeldete Fehler :

  • Die Bash-Shell bleibt auch nach der Eingabe geöffnet, exitwenn sie ausgeführt sudoserver.pywird, bis sie geschlossen wird. Vorläufige Problemumgehungen sind willkommen.

Ich hoffe, jemand wird die langen Programmierstunden nutzen, die ich TOUACExt gewidmet habe.
Verbesserungen und Korrekturen akzeptiert.
Vorschläge, wo ich den Code veröffentlichen soll, um dieses Forum nicht mehr zu nerven, werden ebenfalls akzeptiert ;-).

Entschuldigung für den langen Beitrag. Ich habe nicht viel Freizeit und dieses Projekt verschwand in meinem Schrank (vielleicht jahrelang, wer weiß?).


2
Wenn Sie Feedback zu Ihrem Code wünschen, veröffentlichen Sie es auf codereview.stackexchange.com. (Die Verwendungshinweise und Beispiele sind hier gut zu haben)
Ben Voigt

Danke, @BenVoigt, ich wusste es nicht. Bitte eine Frage: Wenn ja, sollte der größte Teil des Beitrags ein Duplikat dieser Antwort sein. Wird das als Cross-Posting betrachtet?
Sopalajo de Arrierez

1
Stellen Sie sicher, dass Sie sie miteinander verknüpfen. Der Schaden beim Crossposting besteht darin, dass Menschen doppelte Anstrengungen unternehmen. Wenn sie verbunden sind, ist das kein Problem
Ben Voigt

Dies ist eine sehr gute Lösung. Wenn es kein Python erfordern würde, würde ich es verwenden. Ich habe eine persönliche, tiefe Abneigung gegen Python. Es ist eine schöne Sprache, aber aus persönlichen Gründen mag ich sie vor allem nicht. Da jedoch fast niemand Python hasst und mein Hass irrational ist, habe ich Ihre Lösung positiv bewertet, da sie näher an der Realität liegt als meine.
Wyatt8740

1
Danke, @CharlesRobertoCanato. Vielleicht könntest du mir die Details im Chat geben, um es zu lösen? Chatraum "TOUACExt - SuDo für Windows": chat.stackexchange.com/rooms/56716/touacext-sudo-for-windows
Sopalajo de Arrierez

1

EINFACH sudo.bat (verwendet nircmd)

Nircmd kann hier heruntergeladen werden:
http://www.nirsoft.net/utils/nircmd.html

Ich heruntergeladen NirCmd und umbenannt , nircmdc.exeum nircmd.exedie ursprüngliche ersetzt nircmd.exe. Ich habe es dann verschoben C:\windows\system32.

Ich habe auch die folgende Batch-Datei erstellt, damit Argumente an das Skript übergeben werden können.

Es sollte gesagt werden, dass ich die Benutzerkontensteuerung auf meinem Computer deaktiviert habe, sodass ich dieses Skript nicht mehr benötige, aber es funktioniert ab Windows 8. Es funktioniert genauso gut in Cygwin.

@echo off
if "%*" == "" goto error
nircmd elevate %*
goto thisiseof
:error
echo No arguments were given. Exiting.
:thisiseof

Eine ausgefallene Lösung. Kurz und einfach. Aber warum scheitert es mir einfach sudo.bat dir? Ein Fehlerfenster sagt "Windows kann die Datei mit dem Namen dir nicht finden". Es scheint zu funktionieren sudo echo Hello, aber es gibt keine Konsolenausgabe.
Sopalajo de Arrierez

Eine kleine Unannehmlichkeit bei dieser Methode ist die kontinuierliche Anforderung einer UAC-Eingabeaufforderung in aufeinanderfolgenden Befehlen. TOUACExt löst dieses Problem , ähnlich wie bei klassischen Linux-Sudo-Ausführungen. Ich habe die Funktionsliste bearbeitet, um sie anzuzeigen.
Sopalajo de Arrierez

dirfunktioniert nicht, da dires sich technisch gesehen nicht um ein Programm handelt, sondern um einen eingebauten DOS-Befehl. Unter Linux lswird ein Binärprogramm unter DOS / Windows dirvom Interpreter selbst verwaltet (z. B. COMMAND.COM oder cmd.exe). Es gibt keine dir.exeüberall für mein Programm zu laufen. Aber für Cygwin sudo lssollte das genügen. Selbst wenn Sie dies nicht tun, sollten Sie beim Ausführen sudo cmdoder sudo bashwas auch immer eine Eingabeaufforderung auf Administratorebene erhalten. Sogar 'Administrator' steht unter 'SYSTEM' - für 'SYSTEM' verwenden nircmd.exe elevatecmd runassystem <program.exe>. Außerdem deaktiviere ich die
Benutzerkontensteuerung

Ich glaube auch nicht, dass echoes sich um ein Programm in Windows handelt. Es ist Teil von COMMAND.COM/cmd.exe. Für mich allerdings ein Cygwin-Benutzer mit ls.exeund echo.exees funktioniert gut. Und ich habe es heute zum ersten Mal seit Monaten verwendet, um Dateien auf dem Konto meines Bruders zu verwalten, ohne mich als ihn anzumelden (er hat es geschafft, jedes einzelne Programm auf seinem Computer in das "Start" -Verzeichnis seines Startmenüs zu stellen: P). Einfach bei einem anderen angemeldet und sudo.bat cmdeine Eingabeaufforderung auf Administratorebene erhalten, mit der ich die Dateien anderer Benutzer verwalten kann.
Wyatt8740

Ihre Vorstellung vom Systemkonto ist gut. Ich werde es als Option zu TOUCExt hinzufügen.
Sopalajo de Arrierez

0

Da ich mit der verfügbaren Lösung nicht zufrieden bin, habe ich das Skript von nu774 übernommen , um die Sicherheit zu erhöhen und die Einrichtung und Verwendung zu vereinfachen. Das Projekt ist auf Github verfügbar

Um es zu verwenden, laden cygwin-sudo.pySie es einfach herunter und führen Sie es über aus python3 cygwin-sudo.py **yourcommand**.

Sie können der Einfachheit halber einen Alias ​​einrichten:

alias sudo="python3 /path-to-cygwin-sudo/cygwin-sudo.py"
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.