Cách thực tế (gần với Linux cổ điển) để sử dụng (tự động hóa) SUDO cho CygWin


11

Có thể sử dụng sudocác lệnh trong CygWin rất hữu ích và nhanh hơn việc mở một lớp vỏ nâng cao:

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.

Như được hiển thị ở trên, bạn cũng có thể chạy các lệnh / tập lệnh của Windows, giống như Linux. Đối với tôi là gọn gàng; hoạt động trên bảng điều khiển từ xa (SSH) và cho phép kết hợp các lệnh Windows / Linux . Vì vậy, có thể thực hiện các nhiệm vụ hành chính là gần như phải.

Nhưng dự án SUDO cho CygWin có một hành vi có thể nguy hiểm : nó hoạt động như một kiến trúc máy chủ / máy khách , trên thực tế, một máy khách (sudo) gửi các yêu cầu lệnh đến một máy chủ (sudoserver.py) ở bên trong (không nghe bên ngoài máy tính cục bộ) cổng 7070TCP, không có người dùng hoặc quyền kiểm tra , vì vậy bất kỳ ai (ngay cả người dùng không có đặc quyền) đăng nhập vào máy tính cũng có thể thực thi các lệnh hoặc tập lệnh shell (CygWin hoặc Windows) (CygWin hoặc Windows).
Vấn đề trở nên tồi tệ hơn nếu bạn giữ phương thức được đề xuất của tác giả: đăng ký "sudoserver.py" làm dịch vụ, vì vậy nó sẽ tiếp tục chạy vĩnh viễn.

Vì vậy, để duy trì mọi thứ an toàn hơn một chút (không hoàn toàn), tôi thực hiện:
1.- Thực thi "sudoserver.py" trên trình quản trị.
2.- Thực thi các lệnh "sudo" của tôi trên một vỏ CygWin khác.
3.- Đóng (Ctrl + C) "sudoserver.py" và trình quản trị.

Một chút khó chịu . Tôi đang giải quyết nó bằng cách sử dụng một .cmdtệp có phím nóng được gán chạy "sudoserver.py" và tôi sẽ đóng (thủ công) nó sau các công việc quản trị của mình, nhưng vẫn còn xa khả năng sử dụng "sudo" cổ điển trên Linux.

Cách tuyệt vời và thiết thực sẽ là một số phương pháp:

  1. ** Tự động mở "sudoserver.py" yêu cầu Nhắc về Độ cao UAC (hoặc người dùng / mật khẩu).
  2. Đóng nó sau một thời gian, vì vậy yêu cầu UAC sẽ không tiếp tục làm phiền trong trường hợp một số sudolệnh được thực hiện tuần tự.

Có cách nào để tự động hóa điều này , ít nhất là một phần?

Câu trả lời:


10

LƯU Ý: Đây chủ yếu là một chương trình (shell script) tôi đã thực hiện và tôi biết diễn đàn này là một trang web trả lời câu hỏi hơn là giới thiệu chương trình. Nhưng tôi không có bất kỳ tài khoản GitHub (hoặc tương tự) nào, tôi cũng không có thời gian để nghiên cứu về phương pháp xuất bản chương trình Nguồn mở ra cộng đồng. Vì vậy, miễn là có một rủi ro là một chương trình hữu ích và hữu ích không được chú ý (thậm chí trong nhiều tháng) cho những người có thể thưởng thức nó, và thật buồn khi không chia sẻ một chương trình đã được thực hiện, tôi sẽ xuất bản nó ở đây cho hiện nay. Không có vấn đề với tôi nếu quản trị viên quyết định loại bỏ chủ đề này, tôi sẽ hiểu. Tôi hy vọng đã diễn đạt vấn đề theo cách trả lời câu hỏi đủ để làm cho nó hữu ích cho diễn đàn này. Nếu có đủNgười dùng quan tâm , tôi sẽ cố gắng hết sức để dành thời gian tiếp tục dự án (sau tất cả các nghiên cứu của tôi, tôi không tìm thấy bất cứ điều gì gần nhất với điều này trên Internet, nhưng, tôi không biết liệu kịch bản của mình có giá trị hay nó đã lãng phí thời gian)

Tôi đã lập trình một tập lệnh shell Linux đơn giản hoạt động (cho đến bây giờ) trên CygWin và giúp (tôi hy vọng) giảm SUDO cho khoảng thời gian tấn công của CygWin. Chương trình được đặt tên là TOUACExt (viết tắt của " TimeOut và UAC Extension ") và hoạt động như một trình bao bọc cho SUDO cho CygWin (được cài đặt bắt buộc) và thực sự được tạo bởi một bộ bốn .shchương trình.

Ví dụ về thực thi TOUACExt

Các tính năng :

  • Sử dụng thoải mái : Bằng cách mô phỏng sudo gốc từ hành vi Linux, lời nhắc yêu cầu xác nhận UAC chỉ xuất hiện một lần (nhiều sudolệnh liên tiếp sẽ chỉ tạo một yêu cầu UAC). Miễn là sudoserver.py tiếp tục chạy (mặc định 15 phút), sẽ không có thêm yêu cầu UAC .
  • Người dùng đặc quyền (Quản trị viên) chỉ nhận được yêu cầu xác nhận UAC ( Có / Không ) trên màn hình.
  • Người dùng không có đặc quyền (không phải Quản trị viên) có được màn hình nhập mật khẩu / tài khoản Quản trị viên .
  • sudoserver.py tiếp tục chạy, sau đó đóng tự động sau thời gian được xác định trước (15 phút) từ lần thực hiện lệnh sudo cuối cùng.
  • sudoserver.py không đóng (tiếp tục chạy và sẽ kiểm tra lại sau 5 phút) trong trường hợp có bất kỳ trường hợp nào chạy sudo .
  • Hoạt động từ xa (được kiểm tra qua SSH):
    • Người dùng không có đặc quyền không thể bắt đầu sudoserver.py từ xa.
  • Tạo một (nhưng đơn giản và không phải là rất có thể đọc được) log vào /var/log/SUDOForCygWin/.

Yêu cầu (bằng CygWin):

  • SUDO cho CygWin .
  • pgrep (tại procpsgói).
  • đàn (theo util-linuxgói).
  • nohup (Tôi nghĩ được cài đặt theo mặc định trên CygWin, nhưng không chắc chắn).

Giả sử : - Hai chương trình của dự án SUDO cho CygWin trên đường dẫn được đề xuất bởi tác giả:

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

TOUACExt đã được thử nghiệm hoạt động trên Windows 7 SP1 và Windows XP SP3, nhưng tôi không biết liệu nó có hợp lý khi sử dụng nó trên cái cuối cùng này không.

Hướng dẫn cài đặt :

  • Đặt tập lệnh này (tên được đề xuất SUDOServer.cmd:) và tạo một lối tắt (bạn có thể cá nhân hóa biểu tượng của nó nếu bạn muốn) với tên được đặt SUDOServer.lnk(bạn phải bật trên phím tắt này Advanced Options --> Execute as Administrator) ở bất kỳ đâu trên đường dẫn Windows của bạn , vì vậy sudoserver.pycó thể được yêu cầu trực tiếp từ Windows:

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

  • Đặt bốn tập lệnh .sh của TOUACExt trên đường dẫn, ví dụ:

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

  • Đổi tên tập lệnh Python gốc từ sudothành sudo.py:

    mv /usr/local/bin/sudo /usr/local/bin/sudo.py
    CẢNH BÁO: Tập lệnh Python "sudo" ban đầu không được giữ ở bất kỳ đâu trong đường dẫn của bạn hoặc thay vào đó có thể được thực thi.

  • Tạo bí danh này (ví dụ: thủ công hoặc bằng cách chỉnh sửa của bạn ~/.bashrc):

    alias sudo='SUDO.sh'

Mã cho 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.

Mã cho 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). 

Mã cho 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 

Mã cho 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 

Kiểm tra chương trình từ trình bao 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

LƯU Ý 2: Các tập lệnh này đang ở phiên bản tiền beta , vì vậy chúng vẫn có lỗi và mã không được sạch sẽ cho lắm. Dù sao, trong các thử nghiệm của tôi với ba máy tính Windows 7 khác nhau, chúng dường như đang hoạt động (chủ yếu) OK.

Giải thích ngắn gọn về chương trình:

  1. Do bí danh, khi thực hiện lệnh sudo, tập lệnh SUDO.sh được gọi.
  2. SUDO.sh gọi SUDOServer.sh , mở (thông qua SUDOServer.lnk) "sudoserver.py" nếu cần.
  3. Lệnh sudo gốc được gọi bởi người dùng được thực thi.
  4. Sau đó SUDO.sh gọi SUDOServerWatchDogScheduler.sh , lên lịch SUDOServerWatchDog.sh để thực thi sau thời gian đã cho (mặc định 15 phút) để đóng sudoserver.py.
  5. Sau thời gian được xác định trước, SUDOServerWatchDog.sh sẽ đóng sudoserver.py . Nếu có bất kỳ trường hợp nào của sudo đang chạy , nó sẽ tự lập trình để thực hiện mới sau 5 phút.

Để làm :

  • Tự cài đặt tự động tạo tất cả các tệp .sh, .cmd và .lnk.
  • Thiết lập tệp khóa cho một số khác (nó ở mức $ TMP / lockfile.lck).
  • Thêm tập lệnh cấu hình hoặc tệp .config (để mặc định trong thời gian chờ, vị trí tệp ... vv).
  • Thêm hành vi tài khoản hệ thống (cảm ơn, @ Wyatt8740).
  • Thay đổi "bầy" (khóa chế độ SUDO bên trong) bằng "bộ nhiệt áp" khi thích hợp?
  • Gợi ý được chấp nhận.

Báo cáo lỗi :

  • Shell bash tiếp tục mở ngay cả sau khi nhập exitnếu sudoserver.pyđang chạy cho đến khi nó đóng. Giải pháp tạm thời được chào đón.

Tôi hy vọng ai đó sẽ sử dụng chương trình dài mà tôi dành riêng cho TOUACExt.
Cải tiến và sửa chữa được chấp nhận.
Gợi ý về nơi tôi nên xuất bản mã để ngừng cằn nhằn diễn đàn này cũng được chấp nhận ;-).

Xin lôi vi bai đăng dai. Tôi không có nhiều thời gian rảnh, và dự án này đã biến mất trong tủ quần áo của tôi (có thể trong nhiều năm, ai biết được?).


2
Nếu bạn muốn phản hồi về mã của mình, hãy đăng nó lên codereview.stackexchange.com. (Các ghi chú sử dụng và ví dụ rất tốt để có ở đây)
Ben Voigt

Cảm ơn, @BenVoigt, tôi không biết. Xin một câu hỏi: nếu tôi làm, tôi nghĩ rằng hầu hết các bài viết nên là một bản sao của câu trả lời này. Điều đó sẽ được coi là đăng chéo?
Sopalajo de Arrierez

1
Hãy chắc chắn để liên kết chúng với nhau. Tác hại của crossposting là mọi người nhân đôi nỗ lực. Nếu chúng được liên kết, đó không phải là vấn đề như vậy
Ben Voigt

Đây là một giải pháp rất tốt. Nếu nó không yêu cầu python, tôi sẽ sử dụng nó. Tôi có một cá nhân, ghê tởm sâu sắc cho python. Đó là một ngôn ngữ tốt, nhưng vì lý do cá nhân hơn bất cứ điều gì, tôi không thích nó. Tuy nhiên, vì hầu như không ai ghét con trăn, và lòng căm thù của tôi là phi lý, tôi đã nêu lên giải pháp của bạn, vì nó gần với vật thật hơn tôi.
Wyatt8740

1
Cảm ơn, @CharlesRobertoCanato. Có lẽ bạn có thể cho tôi các chi tiết tại cuộc trò chuyện, để giải quyết nó? Phòng trò chuyện "TOUACExt - SuDo cho Windows": chat.stackexchange.com/rooms/56716/touacext-sudo-for-windows
Sopalajo de Arrierez

1

SIMPLE sudo.bat (sử dụng nircmd)

Có thể tải xuống Nircmd tại đây:
http://www.nirsoft.net/utils/nircmd.html

Tôi đã tải về NirCmd và đổi tên nircmdc.exeđể nircmd.exethay thế bản gốc nircmd.exe. Sau đó tôi chuyển nó đến C:\windows\system32.

Tôi cũng đã tạo tệp bó sau đây để cho phép các đối số được truyền vào tập lệnh.

Cần phải nói rằng tôi đã tắt UAC trên máy của mình, vì vậy tôi không còn cần tập lệnh này nữa, nhưng nó KHÔNG hoạt động như trên windows 8. Nó cũng hoạt động trong cygwin.

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

Một giải pháp lạ mắt. Ngắn gọn và dễ dàng. Nhưng tại sao nó lại làm tôi thất vọng sudo.bat dir? Một cửa sổ lỗi thông báo "Windows không thể tìm thấy tệp có tên dir". Nó dường như hoạt động với sudo echo Hello, nhưng không có đầu ra giao diện điều khiển.
Sopalajo de Arrierez

Một bất tiện nhỏ với phương pháp này là yêu cầu liên tục cho dấu nhắc UAC trong các lệnh liên tiếp. TOUACExt giải quyết điều này, giống như trong các thực thi sudo Linux cổ điển. Tôi đã chỉnh sửa danh sách các tính năng để hiển thị nó.
Sopalajo de Arrierez

dirkhông hoạt động vì dirvề mặt kỹ thuật không phải là một chương trình, mà là một lệnh DOS tích hợp. trong khi trong linux, lslà một chương trình nhị phân, trong DOS / windows, dirđược xử lý bởi chính trình thông dịch (ví dụ :.COM.COM hoặc cmd.exe). Không có dir.exenơi nào để chương trình của tôi chạy. Nhưng đối với Cygwin, sudo lsnên đủ. Ngay cả khi bạn không, làm sudo cmdhoặc sudo bashhoặc bất cứ điều gì sẽ giúp bạn có được lời nhắc cấp 'Quản trị viên'. Ngay cả 'Quản trị viên' cũng ở dưới 'HỆ THỐNG', mặc dù - đối với 'HỆ THỐNG', hãy sử dụng nircmd.exe elevatecmd runassystem <program.exe>. Ngoài ra, tôi vô hiệu hóa UAC trên máy của mình :)
Wyatt8740

Ngoài ra, tôi không nghĩ echolà một chương trình trong cửa sổ. Đây là một phần của HOL.COM / cmd.exe. Đối với tôi, một người dùng cygwin ls.exeecho.exenó hoạt động tốt. Và tôi thực sự đã sử dụng nó ngày hôm nay lần đầu tiên sau nhiều tháng để quản lý các tệp trên tài khoản của anh tôi mà không đăng nhập như anh ấy (anh ấy đã quản lý để đưa mọi chương trình trên máy tính của mình vào thư mục "khởi động" của menu bắt đầu: P). Chỉ cần đăng nhập vào một trang khác và được sử dụng sudo.bat cmdđể nhận được lời nhắc cấp quản trị viên sẽ cho phép tôi quản lý các tệp của người dùng khác.
Wyatt8740

Ý tưởng của bạn về tài khoản hệ thống là tốt. Tôi sẽ thêm nó vào TOUCExt như một tùy chọn.
Sopalajo de Arrierez

0

Không hài lòng với giải pháp khả dụng, tôi đã sử dụng tập lệnh của nu774 để thêm bảo mật và giúp thiết lập và sử dụng dễ dàng hơn. Dự án có sẵn trên Github

Để sử dụng nó, chỉ cần tải về cygwin-sudo.pyvà chạy nó qua python3 cygwin-sudo.py **yourcommand**.

Bạn có thể thiết lập bí danh để thuận tiện:

alias sudo="python3 /path-to-cygwin-sudo/cygwin-sudo.py"
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.