Wygodne uruchamianie i zatrzymywanie usług systemd bez podawania hasła

Kategoria: Oprogramowanie Data publikacji:

Czasami podczas codziennej pracy z komputerem zdarza mi się potrzeba uruchomienia lub za­trzymania usługi systemowej, na przykład daemona bazy MySQL. Ta czynność jest na tyle silną ingerencją w system, że domyślnie trzeba ją potwierdzić hasłem. Istnieje jednak możliwość zmiany konfiguracji w taki sposób, aby uruchamianie lub zatrzymywanie konkretnych usług było możliwe bez potwierdzania hasłem! W dzisiejszym wpisie pokażę, jak za pomocą jednego pliku konfiguracyjnego podnieść komfort pracy z linuksową stacją roboczą. :-)

Oczywiście taka zmiana zmniejsza bezpieczeństwo systemu operacyjnego. Warto podejść do tego typu konfiguracji z rozwagą i ostrożnością, aby nie pozwolić na zbyt wiele. W tym wpisie posłużę się jako przykładem jednostką mariadb.service. (Fedora, z której obecnie korzystam, dostarcza właśnie tę implementację bazy MySQL.) Oczywiście możesz posłużyć się inną nazwą.

Każdy użytkownik dystrybucji Linuksa opartej o daemon systemd zna na pewno polecenia do zatrzymywania i startowania usług:

sudo systemctl start mariadb.service
sudo systemctl stop mariadb.service

Polecenie systemctl wymaga uprawnień roota do wykonania swojego zadania. Z tym, że wywoływanie sudo do tablicy nie jest tutaj konieczne. Co się stanie, jeśli spróbujemy inaczej?

systemctl start mariadb.service
systemctl stop mariadb.service

Jeżeli nie użyjemy sudo, program systemctl sam spróbuje podnieść sobie uprawnienia za pomocą usługi Polkit, a ta zaś zadanie zapytania użytkownika o hasło oddeleguje do środowiska graficznego. W Fedorze i środowisku GNOME może to wyglądać następująco:

Za pomocą własnych reguł usługi Polkit możemy skonfigurować uwierzytelnienie tak, aby użytkownik o danej nazwie lub należący do danej grupy mógł uruchomić lub zatrzymać wskazaną usługę bez podawania hasła, tj. bez powyższego monitu. Reguły Polkit definiuje się jako niewielkie skrypty w języku JavaScript.

Pliki reguł Polkit należy umieścić w folderze /etc/polkit-1/rules.d. Według przyjętej konwencji nazwa pliku powinna zaczynać się dwiema cyframi określającymi priorytet (większa liczba sprawia, że plik ma wyższą ważność) i kończyć się ciągiem .rules. W przykładach poniżej zaproponowałem nazwę 90-no-password-systemctl.rules. W dystrybucjach takich jak Ubuntu i Fedora plik o takiej nazwie szybko przygotujesz za pomocą tych poleceń:

sudo touch /etc/polkit-1/rules.d/90-no-password-systemctl.rules
gedit admin:///etc/polkit-1/rules.d/90-no-password-systemctl.rules

Więcej na ten temat tutaj: „Linux: jak graficznie edytować plik tekstowy jako root?”.

Poniżej umieszczam kilka przykładów takiego pliku konfiguracyjnego, z którymi możesz od razu poeksperymentować na swojej linuksowej stacji roboczej. Nie ma potrzeby restartowania komputera lub jakiejkolwiek usługi — po wciśnięciu Ctrl+S zmiany są wprowadzane od razu!

Zachęcam cię też do zapoznania się z dokumentacją API daemona Polkit, w szczególności z działem „Authorization rules”, w którym możesz zgłębić możliwości przekazywanych obiektów:

  • action — szczegóły operacji Polkit wywołanej przez aplikację (w kontekście programu systemctl nosi ona nazwę org.freedesktop.systemd1.manage-units);
  • subject— informacje o użytkowniku próbującym wykonać operację.

W przypadku zarządzania usługami warto pamiętać, że systemd ustawia też dwie dodatkowe zmienne możliwe do odczytania przez metodę action.lookup():

  • verb — nazwa operacji (np. start, stop);
  • unit — nazwa jednostki systemd wraz z rozszerzeniem (np. mariadb.service).

Brak hasła dla wszystkich użytkowników w grupie wheel

W dystrybucjach, z którymi pracuję na co dzień, przyjęto traktowanie użytkowników w grupie wheel jako administratorów, tj. osób, którym ufamy, więc mogą więcej niż inni: mogą swobodnie używać polecenia sudo czy wykonywać graficzne czynności administracyjne.

polkit.addRule(function(action, subject) {
    if (
        subject.isInGroup('wheel')
        && 'org.freedesktop.systemd1.manage-units' === action.id
        && 'mariadb.service' === action.lookup('unit')
    ) {
        return polkit.Result.YES;
    }
});

Brak hasła dla konkretnego użytkownika

Jeśli zamiast grupy wolisz wskazać konto użytkownika wprost.

polkit.addRule(function(action, subject) {
    if (
        'tomasz' === subject.user
        && 'org.freedesktop.systemd1.manage-units' === action.id
        && 'mariadb.service' === action.lookup('unit')
    ) {
        return polkit.Result.YES;
    }
});

Brak hasła jedynie dla operacji zatrzymania usługi

W przypadku tej reguły jedynie zatrzymanie usługi możliwe będzie bez hasła. Wszystkie inne operacje spowodują wyświetlenie monitu o hasło, bez litości. Oczywiście możesz zmienić słowo stop na inną operację.

polkit.addRule(function(action, subject) {
    if (
        subject.isInGroup('wheel')
        && 'org.freedesktop.systemd1.manage-units' === action.id
        && 'mariadb.service' === action.lookup('unit')
        && 'stop' === action.lookup('verb')
    ) {
        return polkit.Result.YES;
    }
});

Brak hasła dla wielu usług w jednej konfiguracji

Można skonfigurować kilka jednostek systemd w jednym pliku konfiguracyjnym, dla wygody. Jako przykład drugiej usługi podałem tutaj i8kmon — program umożliwiający kontrolę wentylatorów w laptopach firmy Dell, który sporadycznie zdarza mi się uruchamiać.

polkit.addRule(function(action, subject) {
    var unitsWithoutPassword = [
        'mariadb.service',
        'i8kmon.service',
    ];

    if (
        subject.isInGroup('wheel')
        && 'org.freedesktop.systemd1.manage-units' === action.id
        && unitsWithoutPassword.indexOf(action.lookup('unit')) !== -1
    ) {
        return polkit.Result.YES;
    }
});

Uważni czytelnicy mogą zauważyć, że powyższy kod trochę trąci myszką i można by wykorzystać tutaj nowoczesne konstrukcje języka JavaScript takie jak let czy Array.includes(). Teoretycznie jak najbardziej jest to możliwe, ponieważ użyty interpreter je wspiera, jednakże dokumentacja usługi Polkit określa, że kod skryptów reguł powinien być zgodny z ECMAScript 5. Innymi słowy, używana przez Polkit wersja interpretera JavaScript jest traktowana jako szczegół implementacyjny i nie należy się od niej uzależniać.

Dodaj komentarz