Jak wykonać sudo polecenia w skrypcie bez pytania o hasło?

107

Chcę codziennie włączać system automatycznie. Używam więc poniższego kodu w skrypcie Python, ale sudoza każdym razem pytam o hasło:

os.system('sudo sh -c "echo date \'+%s\' -d \'+ \
       24 hours\' > /sys/class/rtc/rtc0/wakealarm"')

Jak mogę uruchomić ten skrypt sudoza każdym razem bez pytania o hasło?

Viswa
źródło
4
Powinieneś zajrzeć do instrukcji płyty głównej lub systemu BIOS, aby sprawdzić, czy obsługuje to zachowanie. Wiem, że to unika pytania! =] Ale może to być wystarczające rozwiązanie.
Alex Hirzel

Odpowiedzi:

149

Uwaga: Jakakolwiek metoda polegająca na wpisaniu hasła logowania w postaci zwykłego tekstu, polecenia lub pliku, jest niepewna i NIE powinna być używana!

Poprawny sposób to zrobić, aby ustawić sudotak, że tylko właściwa komenda jeden trzeba, to znaczy echo date... > rtc..., może pracować bez konieczności hasło.

Krok 1. Utwórz skrypt powłoki za pomocą tego polecenia

  • Otwórz gedit(lub swój ulubiony edytor) i utwórz skrypt nppydatertc.sh
  • Wstaw tylko ten wiersz i zapisz go np. W swoim katalogu domowym:
    data echa \ '+% s \' -d \ '+ 24 godziny \'> / sys / class / rtc / rtc0 / wakealarm
  • Zamknij edytor i z poziomu terminalu uruchom skrypt i zmień jego własność na root , w przeciwnym razie inny użytkownik z dostępem do twojego systemu może go edytować i wykonywać dowolne polecenia jako root bez potrzeby podawania hasła:
    sudo chown root:root /home/username/pydatertc.sh
    sudo chmod 700 /home/username/pydatertc.sh
    

Krok 2. Skonfiguruj sudo, aby umożliwić pydatertc.shwykonywanie bez wymagania hasła

  • Wpisz sudo visudow terminalu, aby otworzyć sudoersplik uprawnień sudo ( )
  • Wokół linii 25 zobaczysz tę linię: %sudo ALL=(ALL:ALL) ALL
  • Pod tym wierszem wstaw następujący wiersz, w którym usernameznajduje się nazwa użytkownika:
    nazwa użytkownika ALL = (ALL) NOPASSWD: /home/username/pydatertc.sh
  • Wyjdź z edytora ( Ctrl+ Xjeśli nano )

Krok 3. Zmodyfikuj skrypt Pythona, aby zadzwonił pydatertc.sh

  • Zmień linię na:
    os.system ('sudo /home/username/pydatertc.sh')

Teraz twój skrypt powinien działać bez konieczności podawania hasła ORAZ bez narażania bezpieczeństwa konta, danych lub systemu!


Alternatywa tylko dla wakealarm(nie do ogólnego użytku!):

W tym konkretnym przypadku tylko , ponieważ /sys/class/rtc/rtc0/wakealarmplik kontroluje tylko alarm budzenia dla systemu i jest inaczej nieszkodliwe, inną alternatywą, aby uniknąć hasło jest albo przejąć na własność tego pliku z chown(jeśli jesteś tylko ustawienie alarmu przez użytkownika) lub uczyń go światowym do pisania chmod +666; w takim przypadku po prostu usuń sudoz wywołania Python, pozostawiając sh -c "...."nienaruszone.

ish
źródło
1
Wspaniale, to jest właściwy sposób, aby to zrobić.
roadmr
1
Tak szczegółowa, pomocna odpowiedź i dokładnie, jak należy to zrobić.
ArtOfCode
@RobertRosati, wielkie dzięki za sugerowaną edycję - nie powinienem o tym zapomnieć!
ish
1
@ m-ric Czy przeczytałeś polecenie powyżej tych wierszy? „w przeciwnym razie inny użytkownik z dostępem do twojego systemu mógłby go edytować i wykonywać dowolne polecenia jako root bez potrzeby podawania hasła”
Tobias Kienzler,
2
Zdaję sobie sprawę, że ta odpowiedź jest stara - ale nadal występuje tutaj problem: jeśli plik znajduje się w / home / nazwa użytkownika , wtedy system może zostać naruszony, jeśli ten katalog jest zapisywalny przez złośliwego użytkownika (lub login inny niż root, który jest zagrożone) . Mogą usunąć lub zmienić nazwę pliku, umieścić inny skrypt na swoim miejscu i uruchomić ten skrypt za pośrednictwem sudo- bez hasła. Dlatego bezpieczniej jest umieścić skrypt w katalogu, który może zmienić tylko root, np .: / usr / sbin lub / root . W przeciwnym razie LGTM.
NVRAM,
30

Ostrzeżenie!

Umieszczenie hasła logowania w postaci zwykłego tekstu, polecenia lub pliku, jest wyjątkowo niepewne i może narazić na szwank twoje prywatne dane i system. Jest wysoce zalecane nigdy tego robić, nawet jeśli uważasz, że Twój system jest „osobisty” lub w „bezpiecznym miejscu”!

Jeśli skrypt jest przeznaczony wyłącznie do użytku osobistego, a Ty umieściłeś go w bezpiecznym miejscu i nie boisz się, że twoje konto zostanie skradzione, oto proste rozwiązanie:

echo LOGINPASSWD | sudo -S COMMAND HERE

gdzie LOGINPASSWD to hasło logowania (przykład: iloveponies), a POLECENIE TUTAJ to polecenie pojawiające się po sudo, takie jak sh -c "echo da .. itd.

hytromo
źródło
13
@Viswa, Uwaga: ujawnienie hasła w postaci zwykłego tekstu jest bardzo niebezpieczne. Zaleca się, aby tego nie robić
Anwar,
3
-1 Jeśli wydaje się to dobrym pomysłem, lepiej byłoby po prostu ustawić hasło do konta root i skorzystać z rozwiązania z7sg; to równie proste i nie stwarza tego bardzo niebezpiecznego problemu bezpieczeństwa.
Bryce
4
Hah! Na mojej odpowiedzi miałem 6 głosów pozytywnych i 4 negatywne :) Ale dlaczego nie wyczyściłem „Użytku osobistego”, „bezpiecznego miejsca” itp.? Nie ma problemu z bezpieczeństwem, chyba że podasz ten plik i masz uruchomiony serwer ssh! Gdzie widzisz problem bezpieczeństwa, pod warunkiem, że skrypt jest do użytku osobistego i znajduje się w bezpiecznym miejscu?
hytromo
5
Z góry oceniona, jest to Droga do ciemnej strony i nie jest potrzebna w metodzie sudo.
Floyd
4
Ok, powiedz mi, nawet jeśli haker zalogował się jako prosty użytkownik do twojego konta, jak do cholery znajdzie skrypt z twoim hasłem w / usr / share / help / lv / ubuntu-help ??
hytromo
21

Jeśli nie przeszkadza ci skrypt działający o określonej godzinie w ciągu godziny (lub w ciągu dnia), włóż go do katalogu głównego roota ( /root) i uruchom skrypt z systemowego crontab ( /etc/crontab) jako root. Wtedy nie będziesz musiał narażać bezpieczeństwa.

Zobacz https://help.ubuntu.com/community/CronHowto, aby dowiedzieć się, jak dodać skrypt do crontab.

z7sg
źródło
4
Prawdopodobnie możesz chcieć użyć, anacronjeśli jest to komputer stacjonarny / laptop, który nie działa 24x7
balki
Jest to przydatna odpowiedź, na przykład, jeśli piszesz skrypt, aby sprawdzić dostępność aktualizacji, zrób coś z tymi informacjami i prześlij administratorowi e-mail o niezbędnych aktualizacjach. Osobiście wiele moich skryptów jest używanych do automatyzacji serwerów, więc po prostu korzystam z sudo crontab -e. +1
Rab
11

Inną pokrewną fajną cechą sudo, o której nie wspomniano w doskonałych odpowiedziach powyżej, jest zmienna „timestamp_timeout”. Jest to zmienna sudo, którą możesz zwiększyć, aby zaoszczędzić na interaktywnym wpisywaniu hasła.

Przykład: w / etc / sudoers (lub jednym z zawartych w nim plików) możesz zmodyfikować wartość domyślną:

# only require a password once every 60 minutes
Defaults timestamp_timeout=60

Pełny opis z „man sudoers”:

timestamp_timeout

        Number of minutes that can elapse before sudo will ask for
        a passwd again.  The default is 5, set this to 0 to always
        prompt for a password.

Oczywiście nie może to pomóc w konkretnym przypadku uruchomienia polecenia z crona. Ale dobrze jest być tego świadomym.

arielf
źródło
0
export MY_SUDO_PASS="user_password_here"

Aby sprawdzić, czy działa, należy:

echo $MY_SUDO_PASS
> user_password_here

Aby uruchomić „sudo apt-get update” i zaakceptować hasło ze zmiennych środowiskowych, które wcześniej utworzyliśmy:

echo $MY_SUDO_PASS | sudo -S apt-get update

Uruchom z python (przykład zmieniając rekurencyjnie własność katalogu na username_here):

python
>> import subprocess
>> subprocess.call('echo $MY_SUDO_PASS | sudo -S chown -R username_here /home/username_here/folder_to_change_ownership_recursivley', shell=True)

echo $ MY_SUDO_PASS pobierz hasło -S przełącznik łapie go i przekazuje hasło do sudo

jturi
źródło
Nie jestem pewien, co to dodaje do istniejących odpowiedzi, najbardziej aktualne wsparcie BIOS-u budzi się po alarmie ...
Starszy Geek