Timothee Ravier z firmy Red Hat, maintainer projektów Fedora Silverblue i Fedora Kinoite, zaproponował sposób na unikanie korzystania z narzędzia sudo, które używa suid-bitu do podnoszenia uprawnień. Zamiast sudo, do wykonywania poleceń z uprawnieniami roota przez zwykłego użytkownika proponuje się użycie narzędzia ssh z lokalnym połączeniem do tego samego systemu poprzez UNIX-socket i sprawdzaniem uprawnień na podstawie kluczy SSH.
Użycie ssh zamiast sudo pozwala zrezygnować z programów suid w systemie i zorganizować wykonywanie uprzywilejowanych poleceń w środowisku hosta dystrybucji korzystających z izolacji komponentów, takich jak Fedora Silverblue, Fedora Kinoite, Fedora Sericea i Fedora Onyx. Do ograniczenia dostępu można dodatkowo zastosować potwierdzenie uprawnień za pomocą tokena USB (na przykład Yubikey).
Przykład konfiguracji komponentów serwerowych OpenSSH do dostępu przez lokalny Unix-socket (będzie uruchamiana osobna instancja sshd z własnym plikiem konfiguracyjnym):
/etc/systemd/system/sshd-unix.socket: [Unit] Description=OpenSSH Server Unix Socket Documentation=man:sshd(8) man:sshd_config(5) [Socket] ListenStream=/run/sshd.sock Accept=yes [Install] WantedBy=sockets.target
/etc/systemd/system/sshd-unix@.service: [Unit] Description=OpenSSH per-connection server daemon (Unix socket) Documentation=man:sshd(8) man:sshd_config(5) Wants=sshd-keygen.target After=sshd-keygen.target [Service] ExecStart=-/usr/sbin/sshd -i -f /etc/ssh/sshd_config_unix StandardInput=socket
/etc/ssh/sshd_config_unix: # Оставляет только аутентификацию по ключам PermitRootLogin prohibit-password PasswordAuthentication no PermitEmptyPasswords no GSSAPIAuthentication no # ограничиваем доступ выбранным пользователям AllowUsers root adminusername # Оставляем только использование .ssh/authorized_keys (без .ssh/authorized_keys2 AuthorizedKeysFile .ssh/authorized_keys # включаем sftp Subsystem sftp /usr/libexec/openssh/sftp-server
Aktywujemy i uruchamiamy jednostkę systemd: sudo systemctl daemon-reload sudo systemctl enable —now sshd-unix.socket
Dodajemy swój klucz SSH do /root/.ssh/authorized_keys
Konfigurujemy działanie klienta SSH.
Instalujemy narzędzie socat: sudo dnf install socat
Uzupełniamy /.ssh/config, wskazując socat jako proxy do dostępu przez UNIX-socket: Host host.local User root # Używamy /run/host/run zamiast /run do pracy z kontenerów ProxyCommand socat — UNIX-CLIENT:/run/host/run/sshd.sock # Ścieżka do klucza SSH IdentityFile ~/ .ssh/keys/localroot # Włączamy wsparcie dla TTY do interaktywnej powłoki RequestTTY yes # Usuwamy zbędny output LogLevel QUIET
W obecnej formie użytkownik adminusername teraz będzie mógł wykonywać polecenia z uprawnieniami roota bez wprowadzania hasła. Sprawdzamy działanie: $ ssh host.local [root ~]#
Tworzymy w bash alias sudohost w celu uruchomienia «ssh host.local» analogicznie do sudo: sudohost() { if [[ ${#} -eq 0 ]]; then ssh host.local «cd \»${PWD}\»; exec \»${SHELL}\» —login» else ssh host.local «cd \»${PWD}\»; exec \»${@}\»» fi }
Sprawdzamy: $ sudohost id uid=0(root) gid=0(root) groups=0(root)
Dodajemy sprawdzenie uprawnień i włączamy uwierzytelnianie dwuskładnikowe, które pozwala na dostęp do roota tylko po włożeniu tokena USB Yubikey.
Sprawdzamy, które algorytmy wspiera posiadany Yubikey: lsusb -v 2>/dev/null | grep -A2 Yubico | grep «bcdDevice» | awk ‘{print $2}’
Jeśli wyświetlono 5.2.3 lub wyższą wartość, używamy ed25519-sk do generowania kluczy, w przeciwnym razie — ecdsa-sk: ssh-keygen -t ed25519-sk lub ssh-keygen -t ecdsa-sk
Dodaje klucz publiczny do /root/.ssh/authorized_keys
Dodajemy powiązanie typu klucza do konfiguracji sshd: /etc/ssh/sshd_config_unix: PubkeyAcceptedKeyTypes sk-ecdsa-sha2-nistp256@openssh.com,sk-ssh-ed25519@openssh.com
Ograniczamy dostęp do gniazda Unix tylko dla użytkownika, któremu można podnieść uprawnienia (w naszym przykładzie — adminusername). W /etc/systemd/system/sshd-unix.socket dodajemy: [Socket] … SocketUser=adminusername SocketGroup=adminusername SocketMode=0660
Źródło: opennet.ru
