CygWinでSUDOを使用する(自動化する)実用的な(従来のLinuxに近い)方法


11

CygWinでsudoコマンドを使用できると便利であり、昇格したシェルを開くより高速です。

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.

上記のように、Windowsコマンド/スクリプトもLinuxと同様に実行できます。私にとってはきれいです。リモート(SSH)コンソールで動作、Windows / Linuxコマンドを組み合わせることができます。したがって、管理タスクを実行できることはほぼ必須です。

ただし、SUDO for CygWinプロジェクトには危険な動作があります。サーバー/クライアントアーキテクチャとして動作します。実際、クライアント(sudo)はコマンドのリクエストをサーバー(sudoserver.py)に送信します(外部でリッスンしません)ローカルコンピューター)ポート7070TCP、ユーザーまたはアクセス許可のチェックなし、コンピューターにログインしている(特権のないユーザーも)誰でも管理者(CygWinまたはWindows)のシェルコマンドまたはスクリプト(CygWinまたはWindows)も実行できます。
作成者の提案した方法を維持すると、問題は悪化します。「sudoserver.py」をサービスとして登録すると、永続的に実行され続けます。

したがって、物事をもう少し安全に(完全
にではなく)維持するために、次のことを行います。1.-管理シェルで "sudoserver.py"を実行します。
2.-別のCygWinシェルで「sudo」コマンドを実行します。
3.-「sudoserver.py」と管理シェルを閉じます(Ctrl + C)。

少し迷惑です。「sudoserver.py」を実行するホットキー.cmd割り当てられたファイルを使用して回避し、管理ジョブの後に(手動で)閉じますが、Linuxでの古典的な「sudo」の使いやすさからはほど遠いです。

素晴らしい実用的な方法は、次のような方法です。

  1. ** UAC昇格プロンプト(またはユーザー/パスワード)を要求する「sudoserver.py」を自動的に開きます。
  2. しばらくしから閉じるため、UAC要求は、複数のsudoコマンドが連続して実行された場合に邪魔をし続けません。

これを少なくとも部分的に自動化する方法はありますか?

回答:


10

注:これは主に私が作成したプログラム(シェルスクリプト)であり、このフォーラムはプログラムの紹介サイトというよりも質問応答サイトであることを知っています。しかし、私はGitHub(または同様の)アカウントを持っていませんし、オープンソースプログラムをコミュニティに公開する方法について研究する時間もありませんでした。そのため、実用的で有用なプログラムが、それを楽しむことができる人に(数か月間でも)気付かれないリスクがあり、すでに作成されたプログラムを共有しないのが悲しい場合は、ここ公開します。今。管理者がこのスレッドを削除することを決定した場合、私にとって問題はありません、私は理解します。このフォーラムで役立つように、質問と回答の方法で問題を表現したいと思ってい ます。十分ある場合興味のあるユーザー、私はプロジェクト継続するためにいくらかの時間を捧げるために最善を尽くします(すべての研究の後、私はインターネットでこれに最も近いものを見つけていませんが、まあ...私のスクリプトが貴重であるかどうかわかりません時間の無駄でした)。

CygWinで動作する(今まで)簡単なLinuxシェルスクリプトをプログラムし、CygWinの時間攻撃間隔のSUDOを減らすのに役立ちます(願っています)。このプログラムの名前はTOUACExt(「TimeOut and UAC Extension」の頭字語)であり、CygWinのSUDOのラッパーとして機能し(インストールが必要)、実際には4つの.shプログラムのセットで構成されています。

TOUACExtの実行例

特徴

  • 快適な使用法:Linuxの動作からの元のsudoをシミュレートすることにより、UAC確認要求プロンプトは1回だけ表示されます(複数の連続したsudoコマンドは1つのUAC要求のみを生成します)。sudoserver.pyが実行されている限り(デフォルトでは15分)、UAC要求はこれ以上ありません
  • 特権(管理)ユーザーは、画面でUAC確認要求(Yes / No)のみを取得します。
  • 特権のない(非管理者)ユーザーは、管理者アカウント/パスワード入力画面を取得します。
  • sudoserver.pyは実行を継続し、最後のsudoコマンドの実行から事前定義された時間(15分)後に自動的閉じます
  • sudoのインスタンスが実行されている場合、sudoserver.pyは閉じません(実行を続け、5分後に再度チェックします)。
  • リモートで動作します(SSHでテスト済み):
    • 権限のないユーザーは、sudoserver.pyをリモートで起動できません。
  • で(まだシンプルで読みにくい)ログを作成します/var/log/SUDOForCygWin/

要件(CygWin):

  • CygWinのSUDO
  • pgrep(procpsパッケージで)。
  • flock(util-linuxパッケージで)。
  • nohup(CygWinにデフォルトインストールされると思いますが、わかりません)。

想定:-著者によって提案されたパス上のCygWinプロジェクトのSUDOの2つのプログラム:

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

TOUACExtは、Windows 7 SP1およびWindows XP SP3で動作することがテストれていますが、この最後の1つで使用することに意味があるかどうかはわかりません。

インストール手順

  • このスクリプト(推奨される名前:)を入れて、名前付きSUDOServer.cmdのショートカット(必要に応じてアイコンをカスタマイズできます)を作成しますSUDOServer.lnk(このショートカットで有効にする必要があります)Advanced Options --> Execute as AdministratorWindowsのパス上のどこでも、そのsudoserver.py直接のWindowsから要求することができます。

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

  • TOUACExtの 4つの.sh スクリプトをパスに配置します。次に例を示します。

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

  • 元の Pythonスクリプトの名前をからに変更sudosudo.pyます。

    mv /usr/local/bin/sudo /usr/local/bin/sudo.py
    警告:オリジナルの「sudo」Pythonスクリプトはパスのどこにも残してはなりません。そうしないと、代わりに実行される可能性があります。

  • このエイリアスを作成します(たとえば、手動で、または~/.bashrc)。

    alias sudo='SUDO.sh'

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.

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). 

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 

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 

CygWin Bashシェルからプログラムをテストします。

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

注2:これらのスクリプトは ベータ版より前のリリースにあるため、まだバグが多く、コードはあまりきれいではありません。とにかく、3つの異なるWindows 7コンピューターを使用したテストでは、(ほとんど)正常に動作しているようです。

簡単な プログラムの説明

  1. エイリアスのため、sudoコマンドを実行するとき 、SUDO.shスクリプトが呼び出されます。
  2. SUDO.sh は呼び出しSUDOServer.lnk必要に応じて「sudoserver.py」を(経由で)開きます。
  3. オリジナルsudoコマンドユーザによって呼び出さが実行されます。
  4. 次に、SUDO.sh SUDOServerWatchDogScheduler.shを呼び出します、指定された時間(デフォルトでは15分)が終了した後、SUDOServerWatchDog.shの実行をスケジュールしますsudoserver.py
  5. 事前定義された時間が経過すると、SUDOServerWatchDog.shはsudoserver.pyを閉じます実行中のsudoのインスタンスがある場合中、5分後に新しい実行のためにプログラム自体をプログラムします。

やること

  • セルフインストーラーすべての.sh、.cmd、および.lnkファイルを自動的に作成する。
  • 確立する ロックファイルを他の場所にます($ TMP / lockfile.lckにあります)。
  • を追加 構成スクリプトまたは.configファイルます(タイムアウトのデフォルト、ファイルの場所など)。
  • システムアカウントの動作を追加します(ありがとう、@ Wyatt8740)。
  • ¿必要に応じて、「flock」(内部ロックSUDOモード)を「fuser」に変更しますか?
  • 提案受け入れられました。

報告されたバグ

  • bashシェルは、以下を入力した後でも開いたままexitです。sudoserver.py、閉じるまで実行されているなります。暫定的な回避策は大歓迎です。

TOUACExt専用の長時間のプログラミングを誰かが使用しくれることを願っています
拡張および修正が受け入れられました。
についての提案このフォーラムのしつこいをやめるためにコードをどこに公開すべきかも受け入れられました;-)。

長い投稿でごめんなさい。暇がないので、このプロジェクトはクローゼットから消えてしまいました(長年、誰が知っているのでしょうか?)。


2
コードに関するフィードバックが必要な場合は、codereview.stackexchange.comに投稿してください。(使用上の注意と例はここにあるとよいでしょう)
ベンフォイグ

ありがとう、@ BenVoigt、知りませんでした。質問してください:もしそうなら、ほとんどの投稿はこの答えの複製であると思います。それはクロスポストと見なされますか?
ソパラホデアリエレス

1
必ず互いにリンクしてください。クロスポストの害は、人々が努力を繰り返すことです。それらがリンクされている場合は、このような問題ではありません
ベンフォークト

これは非常に良い解決策です。Pythonを必要としない場合は、使用します。私は、Pythonに対して個人的な深い嫌悪感を抱いています。それは素晴らしい言語ですが、個人的な理由で何よりも嫌いです。それでも、Pythonを嫌う人はほとんどいないので、私の憎しみは非合理的です。私よりも本物に近いので、私はあなたの解決策を支持しました。
ワイアット8740 14

1
ありがとう、@ CharlesRobertoCanato。たぶんそれを解決するために、チャットで詳細を教えてもらえますか?チャットルーム「TOUACExt-Windows用SuDo」:chat.stackexchange.com/rooms/56716/touacext-sudo-for-windows
ソパラジョデアリエレス

1

SIMPLE sudo.bat(nircmdを使用)

Nircmdはここからダウンロードできます:http ://www.nirsoft.net/utils/nircmd.html

私はnircmdをダウンロードし、名前を変更nircmdc.exenircmd.exeて、元のnircmd.exe。それからに移動しましたC:\windows\system32

また、引数をスクリプトに渡すことができるように、次のバッチファイルを作成しました。

マシンでUACを無効にしているため、このスクリプトはもう必要ありませんが、windows 8では動作します。cygwinでも動作します。

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

派手なソリューション。短くて簡単。しかし、なぜ単純に失敗するのsudo.bat dirですか?エラーウィンドウは、「Windowsはdirという名前のファイルを見つけることができません」と伝えます。で動作するようですsudo echo Helloが、コンソール出力はありません。
ソパラホデアリエレス

小さな不都合この方法では、連続するコマンドでUACプロンプトの連続要求です。TOUACExtは、これを古典的なLinuxのsudo実行のように解決します。機能リストを編集して表示しました。
ソパラホデアリエレス14

dirdir技術的にはプログラムではなく、組み込みのDOSコマンドであるため機能しません。LinuxではlsDOS / windowsのバイナリプログラムでありdir、インタープリター自体(COMMAND.COMまたはcmd.exe)によって処理されます。dir.exeプログラムを実行する場所はありません。しかし、cygwinについてsudo lsは、十分なはずです。していなくても、やっていることsudo cmdsudo bashまたは何であれ、「管理者」レベルのプロンプトが表示されます。「管理者」でさえ「システム」の下にありますが、「システム」の場合はを使用しますnircmd.exe elevatecmd runassystem <program.exe>。また、マシンでUACを無効にします:)
Wyatt8740 14

また、echoWindowsでもプログラムだとは思いません。COMMAND.COM/cmd.exeの一部です。しかし、私にとっては、cygwinユーザーはls.exeそれecho.exeでうまく動作します。そして、私は実際に数ヶ月ぶりに今日それを使用して、兄としてログインせずに兄のアカウントのファイルを管理しました(彼はコンピューターのすべてのプログラムをスタートメニューの "startup"ディレクトリーに入れました:P)。別のユーザーにログインしsudo.bat cmd、他のユーザーのファイルを管理できる管理者レベルのプロンプトを取得するために使用しました。
Wyatt8740 14

システムアカウントについてのあなたの考えは良いです。オプションとしてTOUCExtに追加します。
ソパラホデアリエレス14

0

利用可能なソリューションに不満があるため、セキュリティを追加し、セットアップと使用を簡単にするために、nu774のスクリプトを採用しました。プロジェクトが利用可能です Github

それを使用するには、単にダウンロードcygwin-sudo.pyして実行してくださいpython3 cygwin-sudo.py **yourcommand**です。

便宜上、エイリアスを設定できます。

alias sudo="python3 /path-to-cygwin-sudo/cygwin-sudo.py"
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.