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


116

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

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

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

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

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

Ответы:


146

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

echo 'foobar ALL=(ALL:ALL) ALL' | sudo EDITOR='tee -a' visudo

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

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 .

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


Разве это не закомментировано?

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 и не доступен для записи другим пользователям.


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

Просто опустите звездочку, этого там не должно быть ^^
— Sonata

он и возвращает успех (0) - получил
— Олег

2

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

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

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

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


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

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.