Продолжая неустанно трудиться на благо безопасности и удобства администрирования, мы дошли до мысли о том, что sudo — вещь удобная, но небезопасная. Или наоборот, безопасная, но неудобная. Смотря, что написано в sudoers.
Если там что-то, вроде
%wheel ALL=(ALL) NOPASSWD: ALL
то это небезопасно. Любой, кто завладел нужным аккаунтом, получает рута.
А если там
%wheel ALL=(ALL) ALL
то это неудобно. Приходится вбивать пароль каждый раз. И если писать скриптики для групповой порчи серверов
for s in server1 server2 server3; do ssh user@$s "sudo echo 'Превед!' > /etc/motd"; done
то вбивать каждый раз пароль для sudo радости не приносит.
Кроме того, пароли имеют свойство утекать, и, если кто-то завладеет аккаунтом, то ничего ему не мешает сделать alias sudo=…, где будет вороваться пароль. Да и вообще, пароли — не наш выбор. На дворе уже космические корабли бороздят просторы вселенной.
А наш выбор — ssh-ключи. Вообще-то, сильная аутентификация еще лучше, но не в этот раз.
Пускай sudo проверяет аутентичность пользователя по наличию ssh private key, public часть которого лежит в условленном месте.
Недолгий поиск нашел вот этот замечательный проект, который представляет собой pam модуль, проверяющий наличие private ключа в ssh-агенте и его соответствие public ключу в указанном файле. А sudo уже давно умеет использовать pam.
После сборки и установки pam_ssh_agent_auth.so в папку с pam-модулями (/lib/security/ обычно), надо добавить в /etc/pam.d/sudo следующее
auth sufficient pam_ssh_agent_auth.so file=/etc/security/authorized_keys
Потом убедиться, что в /etc/sudoers (используйте visudo, да) в env_keep добавлен SSH_AUTH_SOCK, добавить туда же
%wheel ALL=(ALL) ALL
или аналогичное. Ну и положить свой публичный ключ в /etc/security/authorized_keys (chmod 600 его).
После этого, если зафорварден ssh-agent, sudo не должно спрашивать пароль. И никаких NOPASSWD.
Beware, это будет работать только с sudo >= 1.6.9. В 1.6.8 и ниже pam-модулю не передаются никакие переменные окружения, в том числе и SSH_AUTH_SOCK. Несмотря на любое написанное в sudoers, старый sudo сначала обнуляет практически все переменные окружения, потом запускает pam-модуль, а потом восстанавливает нужное окружение. sudo 1.6.9 убивает только те переменные, которые надо убивать.