Poniżej przedstawiono przypadek, w którym chcesz uruchomić polecenie bez hasła tylko wtedy, gdy ma on określony zestaw opcji, w których część opcji jest zmienna . AFAIK nie jest możliwe stosowanie zmiennych lub zakresów wartości w deklaracjach sudoers, tzn. Możesz wyraźnie zezwolić na dostęp, command option1ale nie command option2używając:
user_name ALL=(root) /usr/bin/command option1
ale jeśli struktura jest command option1 value1, gdzie value1może się różnić, musisz mieć wyraźne wiersze sudoers dla każdej możliwej wartości value1. Skrypt powłoki umożliwia obejście tego.
Ta odpowiedź została zainspirowana odpowiedzią M. Ahmada Zafara i naprawia tam problem bezpieczeństwa.
- Utwórz skrypt powłoki, bez którego wywołasz komendę
sudo.
- Zapisz skrypt w folderze uprzywilejowanym do rootowania (np.
/usr/local/bin/), Ustaw plik jako root (np. chown root:wheel /usr/local/bin/script_name) Bez dostępu do zapisu dla innych (np chmod 755 /usr/local/bin/script_name.).
Dodaj wyjątek do sudoers za pomocą visudo:
user_name ALL=(root) NOPASSWD: /usr/local/bin/script_name.
Uruchom skrypt sudo script_name.
Na przykład chcę zmienić limit czasu uśpienia wyświetlacza w systemie macOS. Odbywa się to za pomocą:
sudo pmset displaysleep time_in_minutes
Uważam, że zmiana limitu czasu snu jest niewinną czynnością, która nie usprawiedliwia kłopotów z wpisywaniem hasła, ale pmsetmoże robić wiele rzeczy i chciałbym, aby te inne rzeczy pozostały za hasłem sudo.
Mam więc następujący skrypt /usr/local/bin/ds:
#!/bin/bash
if [ $# -eq 0 ]; then
echo 'To set displaysleep time, run "sudo ds [sleep_time_in_minutes]"'
else
if [[ $1 =~ ^([0-9]|[1-9][0-9]|1[0-7][0-9]|180)$ ]]; then
pmset displaysleep $1
else
echo 'Time must be 0..180, where 0 = never, 1..180 = number of minutes'
fi
fi
Na końcu sudoerspliku mam następujący wiersz:
user_name ALL=(root) NOPASSWD: /usr/local/bin/ds
Aby ustawić limit czasu na 3 minuty, uruchamiam skrypt ze zwykłego konta użytkownika user_name:
sudo ds 3
PS Większość mojego skryptu to sprawdzanie poprawności danych wejściowych, co nie jest obowiązkowe, więc działałyby również:
#!/bin/bash
pmset displaysleep $1
/path/to/my/programbył skryptem w języku Python?