На днях я выполнял некоторые задачи по обслуживанию своего веб-сервера. Я спешил и спал, поэтому я все делал, используя команду sudo
.
А потом я случайно нажал Ctrl kbd> + V kbd>, отправив эту команду на мой веб-сервер:
sudo rm -rf /*
Для тех, кому интересно что делает вышеприведенная команда: Это удалило мой весь веб-сервер
К счастью, у меня были резервные копии, и, к сожалению, мне пришлось потратить еще два часа на то, чтобы не допустить исправления этой удивительной ошибки. Но с тех пор мне стало интересно:
Есть ли способ всегда применять пароль sudo для конкретной команды?
Если сервер запросил у меня пароль, я спас бы себя от многих неприятностей. Это не так, потому что я выполнил около 5 sudo
команд до этой величественной ошибки.
rm
, чтобы он всегда применялся. Другие команды, которые я использую, обычно nano
или cp
, которые обе (в некоторой степени) обратимы.
Можно установить timestamp_timeout
кому: 0
для конкретных команд в /etc/sudoers
. Создайте файл visudo -f /etc/sudoers.d/pduck
со следующим содержанием:
Cmnd_Alias DANGEROUS = /bin/rm
Defaults!DANGEROUS timestamp_timeout=0
pduck ALL = (ALL:ALL) DANGEROUS
Теперь пользователь pduck
всегда просится относительно пароля при выполнении sudo rm
(какие дополнительные параметры даны) даже при том, что пользователь является членом sudo
группа и sudo
помнит его пароль за другие команды.
Оборотная сторона - то, что Вы не можете легко добавить параметры к /bin/rm
строка в файле для дальнейшего ограничения этого. Хорошо … Вы может, как:
Cmnd_Alias DANGEROUS = /bin/rm -f
но затем Вас просто предлагают точно sudo rm -f
и не (снова) для sudo rm -rf
, например.
Один метод должен был бы использовать безопасную комнату. Это ТОЛЬКО адресует использование "комнаты" и предотвращение определенных версий "комнаты", которая будет выполнена. Это включает удаление Вашей корневой системы, но может также использоваться для предотвращения удаления связанных с системой каталогов как "/usr /" или "/var /". Из ссылки:
Перевентиляция случайного удаления важных файлов
Безопасная комната является инструментом безопасности, предназначенным для предотвращения случайного удаления важных файлов путем замены
/bin/rm
с оберткой, которая проверяет данные аргументы по настраиваемому черному списку файлов и каталогов, которые никогда не должны удаляться.Пользователи, которые пытаются удалить один из этих защищенных файлов или каталогов, не смогут сделать так и будут показаны предупреждающее сообщение вместо этого:
$ rm -rf /usr Skipping /usr
(Резервируемые тракты могут быть установлены и на сайте и на уровнях пользователя.)
Восстановление важных файлов, которые Вы удалили по ошибке, может быть довольно трудным. Защитите себя сегодня путем установки безопасной комнаты и уменьшите вероятность, что необходимо будет связаться с сервисом восстановления данных!
sudo
предоставляет возможность -k, --reset-timestamp
, посмотрите man sudo
:
При использовании в сочетании с командой или опцией, которая может потребовать пароля, эта опция заставит sudo игнорировать кэшируемые учетные данные пользователя. В результате sudo запросит пароль (если Вы будете требоваться политикой безопасности), и не обновит кэшируемые учетные данные пользователя.
Вы могли записать простую обертку для sudo
тестирование на rm -rf /*
и выполнение
sudo -k rm -rf /*
вместо этого, например, как это:
sudo ()
{
[[ "$*" == "rm -rf /*" ]] && opt="-k";
/usr/bin/sudo $opt "$@"
}
Тестирование с echo a
здесь.
$ sudo echo
[sudo] password for dessert:
$ sudo echo
$ sudo echo a
[sudo] password for dessert:
a
$ sudo echo a
[sudo] password for dessert:
a
Если Вы хотите быть спрошенными каждый раз, когда Вы работаете rm
в целом можно адаптировать вышеупомянутую функцию следующим образом:
sudo ()
{
[[ "$1" == "rm" ]] && opt="-k";
/usr/bin/sudo $opt "$@"
}
Если Вы хотите объединить и общекомандные вызовы и определенные командные строки, я рекомендую использовать case
, например:
sudo ()
{
case "$*" in
rm*) opt="-k" ;;
"mv /home"*) opt="-k" ;;
"ln -s /usr/bin/fish /bin/sh") opt="-k" && echo "Don't you dare!" ;;
*) opt="" ;;
esac;
/usr/bin/sudo $opt "$@"
}
Обратите внимание, что эти подходы не будут работать, если Вы будете работать sudo
с опциями – возможные решения [[ "$*" =~ " rm " ]]
проверять на строку “комнату” окружило пробелами или *" rm "*)
с case
поймать любую командную строку, содержащую “комнату”.
Этот ответ не обращается sudo
часть Вашего вопроса, но с другой стороны это обращается к способу смягчить опасность случайного элемента rm
вызовы для любого пользователя.
Можно исказить rm
кому: rm -I
который
-f
который переопределяет предыдущий -I
опции.--one-file-system
другая возможная гарантия против непреднамеренного удаления, которое я использую в моем rm
псевдоним.
Для создания такого псевдонима используют команду:
alias rm='rm -I --one-file-system'
Можно поместить его в Ваш ~/.bashrc
или даже /etc/bash.bashrc
.
$ sudo rm -r /etc/apt/sources.list.d /*
rm: remove all arguments?
Подтвердить тип yes
или его перевод в Вашу локаль или первую букву любого слова и нажимает Enter. Любой другой вход включая ни один прерывает операцию.