Praktis (lebih dekat ke Linux klasik) cara untuk menggunakan (mengotomatisasi) SUDO untuk CygWin

11

Mampu menggunakan sudoperintah di CygWin berguna, dan lebih cepat daripada membuka shell yang ditinggikan:

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.

Seperti yang ditunjukkan di atas, Anda juga dapat menjalankan perintah / skrip Windows, seperti halnya Linux. Bagi saya rapi; bekerja pada konsol jarak jauh (SSH) dan memungkinkan untuk menggabungkan perintah Windows / Linux . Jadi dapat melakukan tugas-tugas administrasi hampir merupakan keharusan.

Tetapi proyek SUDO untuk CygWin memiliki perilaku yang bisa berbahaya : ini berfungsi sebagai arsitektur server / klien , pada kenyataannya, klien (sudo) mengirim permintaan perintah ke server (sudoserver.py) di internal (tidak mendengarkan di luar komputer lokal) port 7070TCP, tanpa pengguna atau izin memeriksa , sehingga siapa pun (bahkan pengguna yang tidak terjangkau) yang masuk ke komputer dapat menjalankan perintah atau skrip admin (CygWin atau Windows) shell (CygWin atau Windows, juga).
Masalahnya semakin buruk jika Anda tetap menggunakan metode yang disarankan penulis: mendaftarkan "sudoserver.py" sebagai layanan, sehingga itu akan tetap berjalan secara permanen.

Jadi, untuk menjaga hal-hal sedikit lebih aman (tidak sepenuhnya), saya lakukan:
1.- Jalankan "sudoserver.py" pada shell admin.
2.- Jalankan perintah "sudo" saya di shell CygWin lain.
3.- Tutup (Ctrl + C) "sudoserver.py" dan shell admin.

Agak menyebalkan . Saya mengatasinya dengan menggunakan .cmdfile dengan hotkey yang ditetapkan yang menjalankan "sudoserver.py", dan saya menutupnya (secara manual) setelah pekerjaan administratif saya, tetapi masih jauh dari kegunaan "sudo" klasik di Linux.

Cara yang hebat dan praktis adalah beberapa metode yang:

  1. ** Buka otomatis "sudoserver.py" yang meminta UAC Elevation Prompt (atau pengguna / kata sandi).
  2. Menutupnya setelah beberapa saat, sehingga permintaan UAC tidak akan terus mengganggu jika ada beberapa sudoperintah yang dieksekusi secara berurutan.

Apakah ada cara untuk mengotomatisasi ini , setidaknya sebagian?

Sopalajo de Arrierez
sumber

Jawaban:

10

CATATAN: Ini sebagian besar adalah program (skrip shell) yang saya buat, dan saya tahu forum ini lebih merupakan situs tanya jawab daripada pengantar program. Tetapi saya tidak memiliki akun GitHub (atau sejenisnya), saya juga tidak punya waktu untuk meneliti tentang metode penerbitan program Open Source kepada komunitas. Jadi, selama ada risiko bahwa program yang berfungsi dan bermanfaat tetap tidak diperhatikan (bahkan selama berbulan-bulan) bagi mereka yang bisa menikmatinya, dan akan menyedihkan untuk tidak berbagi program yang sudah dibuat, saya akan menerbitkannya di sini untuk sekarang. Tidak masalah bagi saya jika admin memutuskan untuk menghapus utas ini, saya akan mengerti. Saya berharap telah mengatakan hal ini dengan cara tanya-jawab yang cukup untuk membuatnya bermanfaat bagi forum ini. Jika ada cukuppengguna yang tertarik , saya akan melakukan yang terbaik untuk meluangkan waktu untuk melanjutkan proyek (setelah semua penelitian saya, saya belum menemukan sesuatu yang paling dekat dengan ini di Internet, tapi, yah ... Saya tidak tahu apakah skrip saya berharga atau sudah buang-buang waktu).

Saya telah memprogram skrip shell Linux sederhana yang berfungsi (sampai sekarang) di CygWin dan membantu (saya harap) mengurangi SUDO untuk interval waktu-serangan CygWin. Program ini dinamai TOUACExt (akronim dari " TimeOut dan UAC Extension ") dan bertindak sebagai pembungkus untuk SUDO untuk CygWin (wajib dipasang), dan benar-benar disusun oleh seperangkat empat .shprogram.

Contoh eksekusi TOUACExt

Fitur :

  • Penggunaan yang nyaman : Dengan mensimulasikan sudo asli dari perilaku Linux, prompt permintaan konfirmasi UAC hanya muncul sekali (beberapa sudoperintah berurutan hanya akan menghasilkan satu permintaan UAC). Selama sudoserver.py terus berjalan (standar 15 menit), tidak akan ada lagi permintaan UAC .
  • Pengguna istimewa (Admin) hanya mendapatkan permintaan konfirmasi UAC ( Ya / Tidak ) di layar.
  • Pengguna yang tidak memiliki hak istimewa (non-Admin) mendapatkan layar input akun Administrator / kata sandi .
  • sudoserver.py terus berjalan, lalu menutup secara otomatis setelah waktu yang ditentukan sebelumnya (15 menit) dari eksekusi perintah sudo terakhir.
  • sudoserver.py tidak menutup (terus berjalan dan akan memeriksa lagi dalam 5 menit) jika ada kejadian sudo berjalan.
  • Bekerja jarak jauh (diuji melalui SSH):
    • Pengguna yang tidak memiliki hak tidak dapat memulai sudoserver.py dari jarak jauh.
  • Membuat log (namun sederhana dan tidak terlalu dapat dibaca) di /var/log/SUDOForCygWin/.

Persyaratan (dalam CygWin):

  • SUDO untuk CygWin .
  • pgrep (pada procpspaket).
  • flock (pada util-linuxpaket).
  • nohup (saya pikir diinstal secara default di CygWin, tetapi tidak yakin).

Dengan asumsi : - Dua program dari SUDO untuk proyek CygWin di jalan yang disarankan oleh penulis:

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

TOUACExt telah diuji bekerja pada Windows 7 SP1 dan Windows XP SP3, tapi saya tidak tahu apakah masuk akal untuk menggunakannya pada yang terakhir ini.

Petunjuk Instalasi :

  • Letakkan skrip ini (nama yang disarankan SUDOServer.cmd:) dan buat pintasan (Anda dapat mempersonalisasikan ikonnya jika Anda mau) dengan nama itu SUDOServer.lnk(Anda harus mengaktifkan pintasan ini Advanced Options --> Execute as Administrator) di mana saja di jalur Windows Anda , jadi sudoserver.pydapat langsung diminta dari Windows:

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

  • Letakkan empat skrip .sh dari TOUACExt di jalur, misalnya:

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

  • Ganti nama skrip Python asli dari sudomenjadi sudo.py:

    mv /usr/local/bin/sudo /usr/local/bin/sudo.py
    PERINGATAN: Skrip Python "sudo" yang asli tidak boleh berada di mana pun di jalur Anda, atau sebaliknya dapat dijalankan.

  • Buat alias ini (misalnya, secara manual atau dengan mengedit Anda ~/.bashrc):

    alias sudo='SUDO.sh'

Kode untuk 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.

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

Kode untuk 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 

Kode untuk 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 

Uji program dari shell Bash CygWin:

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

CATATAN2: Skrip-skrip ini dalam rilis pra-beta , sehingga masih bermasalah dan kodenya tidak terlalu bersih. Bagaimanapun, dalam pengujian saya dengan tiga komputer Windows 7 yang berbeda mereka tampaknya berfungsi (kebanyakan) OK.

Penjelasan singkat tentang program:

  1. Karena alias, saat melakukan perintah sudo skrip SUDO.sh dipanggil.
  2. SUDO.sh memanggil SUDOServer.sh , membuka (via SUDOServer.lnk) "sudoserver.py" jika perlu.
  3. The perintah sudo asli dipanggil oleh pengguna dijalankan.
  4. Kemudian SUDO.sh memanggil SUDOServerWatchDogScheduler.sh , yang menjadwalkan SUDOServerWatchDog.sh untuk dieksekusi setelah waktu yang diberikan (standar 15 menit) untuk ditutup sudoserver.py.
  5. Setelah waktu yang ditentukan, SUDOServerWatchDog.sh menutup sudoserver.py . Jika ada contoh sudo yang berjalan , program itu sendiri untuk eksekusi baru setelah 5 menit.

Yang Harus Dilakukan :

  • Pemasang mandiri yang membuat semua file .sh, .cmd, dan .lnk secara otomatis.
  • Buat file kunci ke yang lain (ini di $ TMP / lockfile.lck).
  • Tambahkan skrip konfigurasi atau file .config (untuk default dalam timeout, lokasi file ... dll).
  • Tambahkan perilaku akun Sistem (terima kasih, @ Wyatt8740).
  • ¿Ubah "flock" (mode SUDO mengunci internal) dengan "fuser" di mana yang sesuai?
  • Saran diterima.

Bug yang Dilaporkan :

  • Bash shell tetap terbuka bahkan setelah memasukkan exitjika sudoserver.pysedang berjalan sampai ditutup. Penanganan sementara dipersilakan.

Saya harap seseorang akan menggunakan pemrograman berjam-jam yang saya dedikasikan untuk TOUACExt.
Penyempurnaan dan koreksi diterima.
Saran tentang di mana saya harus menerbitkan kode untuk berhenti mengomel forum ini juga diterima ;-).

Maaf untuk posting lama. Saya tidak punya banyak waktu luang, dan proyek ini hampir hilang di lemari saya (mungkin selama bertahun-tahun, siapa tahu?).

Sopalajo de Arrierez
sumber
2
Jika Anda ingin umpan balik pada kode Anda, kirimkan di codereview.stackexchange.com. (Catatan penggunaan dan contohnya bagus untuk dimiliki di sini)
Ben Voigt
Terima kasih, @BenVoigt, saya tidak tahu. Tolong sebuah pertanyaan: jika saya lakukan, saya pikir sebagian besar posting harus merupakan duplikat dari jawaban ini. Apakah itu akan dianggap sebagai lintas posting?
Sopalajo de Arrierez
1
Pastikan untuk menghubungkan mereka satu sama lain. Kerugian dalam crossposting adalah bahwa orang menduplikasi usaha. Jika mereka ditautkan, itu bukan masalah
Ben Voigt
Ini solusi yang sangat bagus. Jika tidak memerlukan python, saya akan menggunakannya. Saya memiliki kebencian yang mendalam terhadap python. Ini adalah bahasa yang baik, tetapi karena alasan pribadi lebih dari apa pun, saya tidak menyukainya. Namun, karena hampir tidak ada orang yang membenci python, dan kebencian saya tidak rasional, saya meningkatkan solusi Anda, karena itu lebih dekat ke hal yang nyata daripada milik saya.
Wyatt8740
1
Terima kasih, @CharlesRobertoCanato. Mungkin Anda bisa memberi saya detail di obrolan, untuk menyelesaikannya? Ruang Obrolan "TOUACExt - SuDo for Windows": chat.stackexchange.com/rooms/56716/touacext-sudo-for-windows
Sopalajo de Arrierez
1

SEDERHANA sudo.bat (menggunakan nircmd)

Nircmd dapat diunduh di sini:
http://www.nirsoft.net/utils/nircmd.html

Saya mengunduh nircmd dan mengganti namanya nircmdc.exemenjadi nircmd.exe, menggantikan yang asli nircmd.exe. Saya kemudian memindahkannya ke C:\windows\system32.

Saya juga membuat file batch berikut untuk memungkinkan argumen diteruskan ke skrip.

Seharusnya dikatakan bahwa saya telah menonaktifkan UAC pada mesin saya, jadi saya tidak lagi memerlukan skrip ini, tetapi ia TIDAK berfungsi pada windows 8. Ia juga berfungsi di cygwin.

@echo off
if "%*" == "" goto error
nircmd elevate %*
goto thisiseof
:error
echo No arguments were given. Exiting.
:thisiseof
Wyatt8740
sumber
Solusi mewah. Pendek dan mudah. Tapi mengapa itu gagal saya secara sederhana sudo.bat dir? Jendela kesalahan memberi tahu "Windows tidak dapat menemukan file bernama dir". Tampaknya bekerja dengan baik sudo echo Hello, tetapi tidak ada output konsol.
Sopalajo de Arrierez
Sebuah ketidaknyamanan kecil dengan metode ini adalah permintaan terus menerus untuk UAC prompt dalam perintah berturut-turut. TOUACExt memecahkan ini, mirip dengan eksekusi sudo Linux klasik. Saya telah mengedit daftar fitur untuk menunjukkannya.
Sopalajo de Arrierez
dirtidak berfungsi karena dirsecara teknis bukan program, tetapi perintah DOS bawaan. sedangkan di linux, lsadalah program biner, di DOS / windows, dirditangani oleh penerjemah itu sendiri (yaitu COMMAND.COM atau cmd.exe). Tidak ada dir.exetempat untuk menjalankan program saya. Tapi untuk cygwin, sudo lssudah cukup. Bahkan jika Anda tidak melakukannya, melakukan sudo cmdatau sudo bashatau apa pun akan membuat Anda meminta tingkat 'Administrator'. Bahkan 'Administrator' di bawah 'SYSTEM', meskipun - untuk 'SYSTEM', gunakan nircmd.exe elevatecmd runassystem <program.exe>. Juga, saya menonaktifkan UAC di komputer saya :)
Wyatt8740
Juga, saya pikir echoini bukan program di windows. Itu bagian dari COMMAND.COM/cmd.exe. Bagi saya, pengguna cygwin dengan ls.exedan echo.exeitu berfungsi dengan baik. Dan saya benar-benar menggunakannya hari ini untuk pertama kalinya dalam beberapa bulan untuk mengelola file di akun saudara saya tanpa login sebagai dia (dia berhasil menempatkan setiap program di komputernya di direktori "startup" menu start-nya: P). Baru saja masuk ke yang lain dan digunakan sudo.bat cmduntuk mendapatkan prompt tingkat administrator yang memungkinkan saya mengelola file pengguna lain.
Wyatt8740
Gagasan Anda tentang akun Sistem bagus. Saya akan menambahkannya ke TOUCExt sebagai opsi.
Sopalajo de Arrierez
0

Karena tidak puas dengan solusi yang tersedia, saya mengadopsi skrip nu774 untuk menambah keamanan dan membuatnya lebih mudah untuk diatur dan digunakan. Proyek ini tersedia di Github

Untuk menggunakannya, cukup unduh cygwin-sudo.pydan jalankan melalui python3 cygwin-sudo.py **yourcommand**.

Anda dapat mengatur alias untuk kenyamanan:

alias sudo="python3 /path-to-cygwin-sudo/cygwin-sudo.py"
Kronologis
sumber