Как мне отредактировать / etc / sudoers из скрипта?

116

Мне нужно отредактировать /etc/sudoersсценарий, чтобы добавить / удалить что-то из белых списков.

Предполагая, что у меня есть команда, которая будет работать с обычным файлом, как я могу ее применить /etc/sudoers?

Могу ли я скопировать и изменить его, а затем visudoзаменить оригинал измененной копией? Предоставляя свой собственный сценарий $EDITOR?

Или можно просто использовать те же замки и cp?

Вопрос больше в потенциальных проблемах, чем в поиске того, что работает.

н-александр
источник

Ответы:

146

Старая ветка, а как насчет:

echo 'foobar ALL=(ALL:ALL) ALL' | sudo EDITOR='tee -a' visudo
beckerr
источник
10
Это отличный ответ. Вся подоболочка должна выполняться от имени пользователя root, например echo "$USER ALL=NOPASSWD:/usr/bin/rsync" | (sudo su -c 'EDITOR="tee" visudo -f /etc/sudoers.d/rsync').
Саймон
3
Этот ответ отлично работает! Я использую его для скриптов postinst в пакетах debian. Спасибо! Поскольку это всегда root, он становится коротким и удобным:echo "$CONFIGLINE" | (EDITOR="tee -a" visudo)
Boris Däppen 05
3
Я просто хочу указать на важный нюанс в ответе @ BorisDäppen: -aфлаг для EDITOR="tee": он добавит строку в файл, а не только перезапишет первую строку. Сначала я не заметил разницы и не мог понять, как добавить. Я надеюсь, что смогу найти людей, указав на это прямо ;-)
Жан-Филипп Мюррей
3
может кто-нибудь объяснить мне, как эта работа, я имею в виду, не требует точки с запятой после EDITOR = 'tee -a'. Я знаю, что это нарушит команду. EDITOR - это переменная оболочки, а visudo - еще одна команда, поэтому здесь мы передаем EDITOR и visudo в одной командной строке. как это на самом деле работает?
Sagar
1
Я пробовал это x = "something" echo $ x. У меня это не сработало.
Сагар
43

Используйте для этого visudo с настраиваемым редактором. Это решает все условия гонки и проблемы "взлома" с решением Брайана.

#!/bin/sh
if [ -z "$1" ]; then
  echo "Starting up visudo with this script as first parameter"
  export EDITOR=$0 && sudo -E visudo
else
  echo "Changing sudoers"
  echo "# Dummy change to sudoers" >> $1
fi

Этот скрипт добавит строку «# Dummy change to sudoers» в конец sudoers. Никаких взломов и никаких гоночных условий.

Аннотированная версия, объясняющая, как это на самом деле работает:

if [ -z "$1" ]; then

  # When you run the script, you will run this block since $1 is empty.

  echo "Starting up visudo with this script as first parameter"

  # We first set this script as the EDITOR and then starts visudo.
  # Visudo will now start and use THIS SCRIPT as its editor
  export EDITOR=$0 && sudo -E visudo
else

  # When visudo starts this script, it will provide the name of the sudoers 
  # file as the first parameter and $1 will be non-empty. Because of that, 
  # visudo will run this block.

  echo "Changing sudoers"

  # We change the sudoers file and then exit  
  echo "# Dummy change to sudoers" >> $1
fi
sstendal
источник
5
Для этого требуется, чтобы sudo был скомпилирован --enable-env-editor, в противном случае он будет использовать переменную редактора только в том случае, если это одно из небольшого набора известных значений.
Калеб
У меня это работает (Ubuntu 12.04), но я не понимаю, как это работает. Может ли кто-нибудь объяснить, как его правильно использовать и как он на самом деле работает? Спасибо
MountainX
Хотел бы отметить, что это, похоже, не работает для меня ровно 12.04. Я создал сценарий bash, добавил к нему разрешения + x и выполнил файл со следующим выводом: visudo: невозможно запустить / tmp / edit_sudoers: Exec format error visudo: /etc/sudoers.tmp unchanged
Jose Diaz-Gonzalez
Это отлично сработало для меня, хотя я просто вошел в систему как root и удалил sudo -Eиз первой команды.
merlin2011
Мне очень нравится этот ответ, но у меня он не сработал. Я думаю, что мое sudo не было скомпилировано с необходимым флагом.
Mnebuerquo
30

Вы должны внести изменения во временный файл, затем использовать visudo -c -f sudoers.temp, чтобы подтвердить, что изменения действительны, а затем скопировать его поверх / etc / sudoers

#!/bin/sh
if [ -f "/etc/sudoers.tmp" ]; then
    exit 1
fi
touch /etc/sudoers.tmp
edit_sudoers /tmp/sudoers.new
visudo -c -f /tmp/sudoers.new
if [ "$?" -eq "0" ]; then
    cp /tmp/sudoers.new /etc/sudoers
fi
rm /etc/sudoers.tmp
Брайан С. Лейн
источник
Похоже, вы используете sudoers.tmp в качестве файла блокировки, не уверен, как это подтверждает, что изменения действительны. Разве мы не должны проверять статус выхода visudo, чтобы убедиться, что нет ошибок?
converter42
/etc/sudoers.tmp - это файл блокировки, проверенный visudo в интерактивном режиме. visudo -c -f возвращает 1, если произошла ошибка, следовательно, выполняется проверка кода возврата.
Брайан С. Лейн,
Меня беспокоит использование sudoers.tmp, так как он выглядит как использование внутреннего интерфейса visudo, то есть взлома. Является ли он стандартным, что означает, что в качестве блокировки всегда будет использоваться файл sudoers.tmp? Или у них есть свобода изменить это в будущем?
n-alexander
2
необходимо использовать файл блокировки вместо test / touch
n-alexander
2
На странице руководства говорится, что он использует /tmp/sudoers.tmp, так что в настоящее время это стандарт. Конечно, это может измениться в будущем. И да, вы правы, есть состояние гонки.
Брайан С. Лейн
18

В Debian и его производных вы можете вставить собственный сценарий в /etc/sudoers.d/каталог с правами 0440- для получения дополнительной информации см. /Etc/sudoers.d/README .

Это может помочь.

pevik
источник
Разве это не закомментировано?
2
@TomDworzanski: ИМХО, нет. См. Man sudoers (5) и другие комментарии .
pevik
Ты прав! Спасибо за ссылки и отличный ответ.
3
Я также использую этот каталог в centos 7
Александр Бёрд,
Я считаю, что это правильный способ сделать это.
jansohn
11

visudo должен быть человеческим интерфейсом для редактирования /etc/sudoers. Вы можете добиться того же, заменив файл напрямую, но вы должны позаботиться о параллельном редактировании и проверке синтаксиса. Обратите внимание на r--r-----разрешения.

СПП
источник
9

Если вы sudoразрешаете добавлять записи /etc/sudoers.d, вы можете использовать этот ответ от @ dragon788:

https://superuser.com/a/1027257/26022

В основном вы используете visudoдля проверки файла перед его копированием /etc/sudoers.d, так что вы можете быть уверены, что sudoникого не нарушаете .

visudo -c -q -f filename

Это проверяет его и возвращает успех (0) , если это действительно, так что вы можете использовать его с if, &&и другими операциями сценария булевыми. Как только вы подтвердите, просто скопируйте его, /etc/sudoers.dи он должен работать. Убедитесь, что он принадлежит пользователю root и не доступен для записи другим пользователям.

Mnebuerquo
источник
5

Настройте собственный редактор. По сути, это будет сценарий, который принимает имя файла (в данном случае /etc/sudoers.tmp), изменяет и сохраняет его на месте. Так что вы можете просто записать в этот файл. Когда вы закончите, выйдите из скрипта, и visudo позаботится об изменении фактического файла sudoers за вас.

sudo EDITOR=/path/to/my_dummy_editor.sh visudo
Али Афшар
источник
Я прав, что все, что нужно dummy_editor.sh, должно содержать что-то вроде этого? #!/bin/sh; echo "# my changes to sudoers" >> $1; exit 0Мне кажется, это работает.
MountainX
4

Множество ответов, я работал с sudo для yonks, но до сих пор не было необходимости автоматизировать конфигурацию установки. Я использовал сочетание некоторых из приведенных выше ответов, записав свою строку конфигурации в /etc/sudoers.d include location, поэтому мне не нужно изменять основной файл sudoers, а затем проверил этот файл на синтаксис, простой пример ниже:

Напишите свою строку во включаемый файл sudoers:

sudo bash -c 'echo "your_user ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers.d/99_sudo_include_file'

Убедитесь, что ваш включаемый файл sudoers прошел проверку синтаксиса visudo:

sudo visudo -cf /etc/sudoers.d/99_sudo_include_file
Im-Kirk-Dougla-Кас
источник
Просто опустите звездочку, этого там не должно быть ^^
Sonata
он и возвращает успех (0) - получил
Олег
2

Просто чтобы добавить дополнительную опцию к приведенным выше ответам, если состояние гонки не является серьезной проблемой, тогда можно использовать следующую команду, чтобы избежать ручного копирования измененного файла в /etc/sudoers

sudo EDITOR="cp /tmp/sudoers.new" visudo

Это гарантирует, что новый файл будет проверен и правильно установлен с обновлением разрешений.

Обратите внимание, что если в /tmp/sudoers.newфайле есть ошибка, visudoпользователю будет предложено ввести данные, поэтому рекомендуется visudo -c -f /tmp/sudoers.newсначала проверить ее .

zelanix
источник
1

Я думаю, что самое простое решение - это:

Создайте скрипт addudoers.sh

#!/bin/sh

while [ -n "$1" ]; do
    echo "$1    ALL=(ALL:ALL) ALL" >> /etc/sudoers;
    shift # shift all parameters
done

и вызовите его с пользователями, которых хотите добавить, как:

root prompt> ./addsudoers.sh user1 user2

Для полного объяснения см. Этот ответ: Добавление пользователей в sudoers через сценарий оболочки

С уважением!

Альберт Вонпупп
источник
0

Попробуйте повторить это. Однако вы должны запустить его в подоболочке. Пример:

sudo sh -c "echo \"group ALL=(user) NOPASSWD: ALL\" >> /etc/sudoers"

Аполлон
источник
-2

Это сработало для меня, основываясь на том, что другие разместили здесь. Когда я использовал скрипт других людей, он открывал для меня visudo, но не вносил изменения. Это внесло необходимые изменения, чтобы разрешить всем пользователям, включая обычных пользователей, устанавливать java 7u17 для safari / firefox.

#!/usr/bin/env bash
rm /etc/sudoers.new
cp /etc/sudoers /etc/sudoers.new
echo "%everyone   ALL = NOPASSWD: /usr/sbin/installer -pkg /Volumes/Java 7 Update 17/Java 7 Update 17.pkg -target /" >> /etc/sudoers.new
cp /etc/sudoers.new /etc/sudoers

В конец файла sudoers добавлен% every blah blah blah. Мне пришлось запустить сценарий вот так.

sudo sh sudoersedit.sh

Удачи: D

Камаль
источник