在CygWin中使用(自动化)SUDO的实用(接近经典Linux的)方式


11

能够sudoCygWin中使用命令是有用的,并且比打开提升的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.

如上所示,您也可以像Linux一样运行Windows命令/脚本。对我来说是整洁的;在远程(SSH)控制台上工作,并允许组合Windows / Linux命令。因此,能够执行管理任务几乎是必须的。

但是SUDO for CygWin项目的行为可能很危险:它用作服务器/客户端体系结构,实际上,客户端(sudo)在内部(而不是在外部监听)向服务器(sudoserver.py)发送命令请求。本地计算机)端口7070TCP,无需进行用户或权限检查,因此登录到计算机上的任何人(甚至是非特权用户)都可以执行admin(CygWin或Windows)外壳命令或脚本(CygWin或Windows)。如果保留建议的作者方法,则
问题会变得更糟:将“ sudoserver.py”注册为服务,因此它将永久运行。

因此,为了使事情更安全(并非完全),我这样做:
1.-在管理外壳上执行“ sudoserver.py”。
2.-在另一个CygWin shell上执行我的“ sudo”命令。
3.-关闭(Ctrl + C)“ sudoserver.py”和admin shell。

有点讨厌。我正在使用.cmd带有分配的热键的文件来解决该问题,该文件运行“ sudoserver.py”,在我完成管理工作后将其关闭(手动),但仍远未达到 Linux上经典的“ sudo”可用性。

伟大而实用的方法是:

  1. **自动打开“ sudoserver.py”,请求输入UAC高程提示(或用户/密码)。
  2. 一段时间后将其关闭,因此在sudo顺序执行多个命令的情况下,UAC请求不会继续受到干扰。

有什么办法可以自动化,至少是部分自动化

Answers:


10

注意:这主要是我编写的一个程序(shell脚本),而且我知道这个论坛更像是一个问答站点,而不是一个程序介绍站点。但是我没有任何GitHub(或类似的)帐户,也没有时间研究向社区发布开源程序的方法。所以,只要有一个风险,即一个工作和有用的程序一直被忽视(甚至几个月)那些谁可以享受它,那将是可悲的不是共享一个已经作出计划,我将在这里发布的现在。如果管理员决定删除此线程,对我来说没有问题,我会理解的。我希望以一种问答方式表达此问题, 以使其对本论坛有用。如果有足够感兴趣的用户,我将竭尽全力继续该项目(经过所有研究,我没有在Internet上找到与此项目最接近的东西,但是,嗯...我不知道我的脚本是否有价值或浪费时间)。

我编写了一个简单的Linux Shell脚本,该脚本可以在CygWin上运行(直到现在),并且可以(希望)减少CygWin时间攻击间隔的SUDO。该程序名为TOUACExt(“ 超时和UAC扩展名 ”的缩写),并充当CygWin的SUDO包装(必需安装),实际上由四个.sh程序组成。

TOUACExt执行的例子

特点

  • 舒适的用法:通过模拟Linux行为中的原始sudo,UAC确认请求提示仅出现一次(多个连续sudo命令将仅生成一个UAC请求)。只要sudoserver.py保持运行(默认15分钟),就不会再有UAC请求。
  • 特权(Admin)用户仅在屏幕上收到UAC确认请求(是/否)。
  • 非特权(非管理员)用户将获得管理员帐户/密码输入屏幕。
  • sudoserver.py保持运行,然后在自上次执行sudo命令起的预定义时间(15分钟)后自动关闭
  • 如果有任何sudo运行实例, sudoserver.py不会关闭(保持运行状态,并会在5分钟内再次检查)。
  • 远程工作(通过SSH测试):
    • 没有特权的用户不能远程启动sudoserver.py。
  • 创建(但简单的,不是很可读)日志/var/log/SUDOForCygWin/

要求(在CygWin中):

  • SUDO for CygWin
  • pgrep(procps打包)。
  • 羊群(util-linux包装)。
  • nohup(我认为默认安装在CygWin上,但不确定)。

假设:-SUDO for CygWin的两个程序按照作者建议的路径进行:

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

TOUACExt已测试工作在Windows 7 SP1和Windows XP SP3,但我不知道它在使用它的这最后一个是有道理的。

安装说明

  • 将这个脚本(建议的名称:)放在Windows路径中的任何位置,SUDOServer.cmd并为其命名SUDOServer.lnk(必须启用此快捷方式Advanced Options --> Execute as Administrator)以创建一个快捷方式(如果需要,可以个性化其图标),因此可以直接从Windows请求:sudoserver.py

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

  • TOUACExt的四个.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 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

注意2:这些脚本处于beta版本之前,因此它们仍然存在错误,并且代码不是很干净。无论如何,在我对三台不同的Windows 7计算机的测试中,它们似乎都可以正常工作(大部分情况下)。

该程序的简要说明

  1. 由于存在别名,执行sudo命令时会调用SUDO.sh脚本
  2. SUDO.sh 调用SUDOServer.shSUDOServer.lnk如果需要,通过(打开)“ sudoserver.py”。
  3. 执行由用户调用的原始sudo命令
  4. 然后SUDO.sh 调用SUDOServerWatchDogScheduler.sh,它安排SUDOServerWatchDog.sh在给定时间(默认15分钟)关闭后执行sudoserver.py
  5. 在预定义的时间之后,SUDOServerWatchDog.sh 关闭sudoserver.py。如果有任何sudo实例正在运行,它将在5分钟后自行编程以执行新的执行。

要做

  • 自行安装程序,可自动创建所有.sh,.cmd和.lnk文件。
  • 建立其他锁定文件(位于$ TMP / lockfile.lck)。
  • 添加配置脚本或.config文件(用于超时,文件位置等的默认设置)。
  • 添加系统帐户行为(感谢@ Wyatt8740)。
  • 在适当的地方用“ fuser”更改“ flock”(内部锁定SUDO模式)吗?
  • 接受建议

错误报告:

  • bash shell中输入查询,即使以后基本保持开放exit,如果sudoserver.py正在运行,直至关闭。欢迎临时解决方法。

我希望有人会使用我专门致力于TOUACExt的长时间编程。接受
增强和更正
关于我应该在哪里发布代码以停止na这个论坛的建议,也被接受;-)。

抱歉,很长的帖子。我没有太多的空闲时间,这个项目正要在我的壁橱里消失(也许多年了,谁知道?)。


2
如果您希望获得有关代码的反馈,请将其发布在codereview.stackexchange.com上。(此处使用用法说明和示例很好)
Ben Voigt 2014年

谢谢,@ BenVoigt,我不知道。请问一个问题:如果我愿意,我认为大部分帖子应该是该答案的重复。那会被认为是交叉发布吗?
Sopalajo de Arrierez 2014年

1
确保将它们彼此链接。交叉发布的危害在于人们重复努力。如果他们被链接了,那就不是问题了
Ben Voigt 2014年

这是一个很好的解决方案。如果它不需要python,我会用它。我个人非常讨厌python。这是一门好语言,但出于个人原因,我不喜欢它。不过,由于几乎没有人讨厌python,而且我的仇恨是非理性的,所以我赞成您的解决方案,因为它比我的更接近真实。
Wyatt8740 2014年

1
谢谢@CharlesRobertoCanato。也许您可以在聊天中给我详细信息,以便解决它?聊天室“ TOUACExt-Windows的SuDo”:chat.stackexchange.com/rooms/56716/touacext-sudo-for-windows
Sopalajo de Arrierez,

1

简单的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出现错误,提示“ Windows找不到名为dir的文件”。似乎可以使用sudo echo Hello,但是没有控制台输出。
Sopalajo de Arrierez 2014年

这种方法的一个小麻烦是连续命令中连续请求UAC提示。TOUACExt解决了这个问题,就像在传统的Linux sudo执行中一样。我已经编辑了功能列表以显示它。
Sopalajo de Arrierez 2014年

dir不起作用,因为dir从技术上讲它不是程序,而是内置的DOS命令。在Linux中,ls是一个二进制程序,在DOS / Windows中,dir由解释器本身(即COMMAND.COM或cmd.exe)处理。没有一个dir.exe我的程序运行的任何地方。但是对于cygwin,sudo ls应该足够了。即使您不这样做sudo cmdsudo bash也应该通过“操作”或“其他操作”获得“管理员”级别的提示。即使“管理员”也位于“系统”下方,但对于“系统”而言,请使用nircmd.exe elevatecmd runassystem <program.exe>。另外,我在机器上禁用了UAC :)
Wyatt8740

另外,我也不认为这echo是Windows中的程序。它是COMMAND.COM/cmd.exe的一部分。但是对我来说,使用cygwin的用户ls.exeecho.exe能正常工作。实际上,今天我已经几个月来第一次使用它来管理我哥哥的帐户中的文件,而无需以他的身份登录(他设法将每个程序都放在他的计算机的开始菜单的“启动”目录:P中)。刚刚登录到另一个帐户并用来sudo.bat cmd获取管理员级别的提示,该提示使我可以管理其他用户的文件。
Wyatt8740 2014年

您对系统帐户的想法很好。我将其作为选项添加到TOUCExt。
Sopalajo de Arrierez 2014年

0

对于可用的解决方案不满意,我采用了nu774的脚本来增加安全性,并使其更易于设置和使用。该项目在Github上可用

要使用它,只需cygwin-sudo.py通过下载并运行它python3 cygwin-sudo.py **yourcommand**

为了方便起见,您可以设置别名:

alias sudo="python3 /path-to-cygwin-sudo/cygwin-sudo.py"
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.