Практичный (ближе к классическому Linux) способ использования (автоматизации) SUDO для CygWin


11

Возможность использовать sudoкоманды в CygWin полезна и быстрее, чем открытие оболочки с повышенными правами :

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. Выполните мои команды "sudo" на другой оболочке CygWin.
3.- Закройте (Ctrl + C) "sudoserver.py" и оболочку администратора.

Немного раздражает . Я обхожу его, используя .cmdфайл с назначенной горячей клавишей, который запускает «sudoserver.py», и закрываю (вручную) его после выполнения моих административных заданий, но все еще далек от классического удобства использования «sudo» в Linux.

Отличным и практичным способом был бы такой метод, который:

  1. ** Автоматически открывается файл «sudoserver.py», запрашивающий запрос на повышение уровня UAC (или пользователя / пароль).
  2. Закрывает его через некоторое время, поэтому запрос UAC не будет беспокоить в случае sudoпоследовательного выполнения нескольких команд.

Есть ли способ автоматизировать это , хотя бы частично?

Ответы:


10

ПРИМЕЧАНИЕ. Это в основном программа (сценарий оболочки), которую я создал, и я знаю, что этот форум - скорее сайт с вопросами и ответами, чем сайт, посвященный ознакомлению с программами. Но у меня нет ни одной учетной записи GitHub (или аналогичной), и у меня не было времени исследовать метод публикации программы с открытым исходным кодом для сообщества. Таким образом, до тех пор, пока существует риск, что работающая и полезная программа останется незамеченной (даже в течение нескольких месяцев) для тех, кто может ею пользоваться, и было бы грустно не делиться уже созданной программой, я собираюсь опубликовать ее здесь для сейчас. Для меня не проблема, если администраторы решат удалить эту ветку, я пойму. Я надеюсь изложить вопрос в форме вопроса-ответа , чтобы сделать его полезным для этого форума. Если достаточноЗаинтересованные пользователи , я сделаю все возможное, чтобы посвятить некоторое время продолжению проекта (после всех моих исследований я не нашел ничего похожего на это в Интернете, но, ну ... я не знаю, ценен ли мой сценарий или это была пустая трата времени).

Я запрограммировал простой скрипт оболочки Linux, который работает (до сих пор) в CygWin и помогает (я надеюсь) сократить интервал атаки SUDO для CygWin. Программа называется TOUACExt (аббревиатура от « TimeOut и расширение UAC ») и действует как оболочка для SUDO для CygWin (обязательно установлена) и действительно состоит из набора из четырех .shпрограмм.

Пример выполнения TOUACExt

Особенности :

  • Удобное использование : имитируя исходное sudo из поведения Linux, запрос запроса подтверждения UAC появляется только один раз (несколько последовательных sudoкоманд будут генерировать только один запрос UAC). Пока sudoserver.py продолжает работать (по умолчанию 15 минут), запросов UAC больше не будет .
  • Привилегированные (Admin) пользователи получают только запрос подтверждения UAC ( Да / Нет ) на экране.
  • Непривилегированные (не администраторы) пользователи получают экран ввода учетной записи администратора / пароля .
  • Файл sudoserver.py продолжает работать, а затем автоматически закрывается через предварительно определенное время (15 минут) с момента последнего выполнения команды sudo.
  • sudoserver.py не закрывается (продолжает работать и проверит снова через 5 минут) в случае запуска sudo .
  • Работает удаленно (проверено через SSH):
    • Непривилегированные пользователи не могут запускать sudoserver.py удаленно.
  • Создает (но простой и не очень читаемый) журнал в /var/log/SUDOForCygWin/.

Требования (в CygWin):

  • SUDO для 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, но я не знаю, имеет ли смысл использовать его на последнем.

Инструкция по установке :

  • Поместите этот скрипт (предлагаемое имя:) SUDOServer.cmdи создайте ярлык (вы можете персонализировать его значок, если хотите) с именем SUDOServer.lnk(вы должны включить этот ярлык Advanced Options --> Execute as Administrator) в любом месте вашего пути Windows , поэтому sudoserver.pyего можно напрямую запросить из Windows:

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

  • Поместите четыре .sh скрипта TOUACExt в путь, например:

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

  • Переименуйте исходный сценарий Python от sudoдо sudo.py:

    mv /usr/local/bin/sudo /usr/local/bin/sudo.py
    ВНИМАНИЕ: Оригинальный сценарий Python "sudo" не должен оставаться нигде в вашем пути, или он может быть выполнен вместо этого.

  • Создайте этот псевдоним (например, вручную или путем редактирования ~/.bashrc):

    alias sudo='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. Эти сценарии находятся в предварительной бета- версии, поэтому они все еще содержат ошибки и код не очень чистый. Во всяком случае, в моих тестах на трех разных компьютерах с Windows 7 они работали (в основном) нормально.

Краткое описание программы:

  1. В связи с псевдонимом, при выполнении команды SUDO SUDO.sh скрипт вызывается.
  2. SUDO.sh вызывает SUDOServer.sh , открывая (через SUDOServer.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).
  • ¿Заменить «flock» (режим внутренней блокировки SUDO) на «fuser», где это уместно?
  • Предложения принимаются.

Сообщенные ошибки :

  • Оболочка bash остается открытой даже после ввода, exitесли sudoserver.pyработает, пока не закроется. Предварительные обходные пути приветствуются.

Я надеюсь, что кто-то использует многочасовое программирование, которое я посвятил TOUACExt.
Улучшения и исправления приняты.
Предложения о том, куда я должен публиковать код, чтобы перестать мучить этот форум, тоже принимаются ;-).

Извините, за длинную статью. У меня не так много свободного времени, и этот проект вот-вот исчезнет у меня в шкафу (может, на годы, кто знает?).


2
Если вы хотите оставить отзыв о вашем коде, опубликуйте его на codereview.stackexchange.com. (Замечания по использованию и примеры полезны здесь)
Бен Фойгт

Спасибо @BenVoigt, я не знал. Пожалуйста, вопрос: если я это сделаю, я думаю, что большая часть поста должна быть дубликатом этого ответа. Будет ли это рассматриваться как кросс-постинг?
Сопалахо де Арриерес

1
Убедитесь, что связали их друг с другом. Вред в кросспостинге состоит в том, что люди дублируют усилия. Если они связаны, это не такая проблема
Бен Фойгт

Это очень хорошее решение. Если бы это не требовало Python, я бы использовал его. У меня есть личная, глубокая ненависть к питону. Это хороший язык, но по личным причинам мне больше всего не нравится. Тем не менее, так как почти никто больше не ненавидит питона, а моя ненависть иррациональна, я проголосовал за ваше решение, так как оно ближе к реальному, чем мое.
Wyatt8740

1
Спасибо, @CharlesRobertoCanato. Может быть, вы могли бы дать мне детали в чате, чтобы решить это? Комната чата "TOUACExt - SuDo для Windows": chat.stackexchange.com/rooms/56716/touacext-sudo-for-windows
Сопалахо де Арриерес

1

ПРОСТО sudo.bat (использует nircmd)

Nircmd можно скачать здесь:
http://www.nirsoft.net/utils/nircmd.html

Я скачал nircmd и переименовал nircmdc.exeв nircmd.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. Я отредактировал список возможностей, чтобы показать его.
Сопалахо де Арриерес

dirне работает, потому что dirтехнически это не программа, а встроенная команда DOS. в то время как в linux lsэто двоичная программа, в DOS / windows dirона обрабатывается самим интерпретатором (т.е. COMMAND.COM или cmd.exe). Существует не dir.exeгде - нибудь для моей программы для запуска. Но для Cygwin sudo lsдолжно хватить. Даже если вы этого не сделаете, делать sudo cmdили sudo bashили что - то вы должны получить уровень «Администратор» оперативно. Даже «Администратор» ниже «СИСТЕМЫ», хотя - для «СИСТЕМЫ» используйте nircmd.exe elevatecmd runassystem <program.exe>. Кроме того, я отключаю UAC на своих машинах :)
Wyatt8740

Кроме того, я не думаю, что echoэто программа в Windows. Это часть COMMAND.COM/cmd.exe. Для меня, хотя, пользователь Cygwin с, ls.exeи echo.exeон работает нормально. И сегодня я впервые использовал его сегодня за последние месяцы, чтобы управлять файлами в учетной записи моего брата, не входя в систему под своим именем (ему удалось поместить каждую отдельную программу на своем компьютере в папку «Пуск» своего меню «Пуск»: P). Просто вошел в другой и использовал sudo.bat cmdдля получения приглашения уровня администратора, который позволил бы мне управлять файлами другого пользователя.
Wyatt8740

Ваша идея системного аккаунта хорошая. Я добавлю его в TOUCExt в качестве опции.
Сопалахо де Арриерес

0

Будучи недовольным доступным решением, я принял скрипт nu774, чтобы повысить безопасность и упростить его настройку и использование. Проект доступен на Github

Чтобы использовать его, просто скачайте cygwin-sudo.pyи запустите его через python3 cygwin-sudo.py **yourcommand**.

Вы можете настроить псевдоним для удобства:

alias sudo="python3 /path-to-cygwin-sudo/cygwin-sudo.py"
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.