Файл init в вызовах init.d с использованием sudo в script.sh выдает ошибку sudo: tty отсутствует и не задана программа askpass
Я пытаюсь сделать скрипт, который запускается при загрузке, чтобы подключиться к моей личной VPN.
У меня есть файл инициализации: /etc/init.d/vpnstartup
который вызывает мой скрипт vpnon.sh при загрузке с помощью команд:
case "$1" in
start)
su username -c $VPN_DIR/vpnon.sh
;;
в моем скрипте vpnon.sh есть команды, для выполнения которых необходимы права root:
sudo iptables -A INPUT -i pptp -j ACCEPT
sudo iptables -A OUTPUT -o pptp -j ACCEPT
Я предоставляю разрешения для файла инициализации vpnstartup и сценария vpnon.sh с помощью chmod 775, когда я испытываю файл инициализации, вызывая его с помощью запуска./vpnstartup
Я получаю следующую ошибку, когда вызывается команда sudo iptables
sudo: no tty present and no askpass program specified
sudo: no tty present and no askpass program specified
Я думаю, что происходит: команда sudo требует ввода пароля, но не может его получить.
Единственное решение, которое я нашел, это добавление NOPASSWD :ALL option
в файл sudoers под моим именем пользователя.
Я не хочу делать этот метод по соображениям безопасности, если есть лучшее решение.
Пожалуйста, дайте мне знать, если вы можете помочь мне с этой проблемой; Я потратил много часов на это.
2 ответа
Я думаю, что ключевым фактором здесь является то, что, поскольку скрипт запускается с помощью sudo, он может делать все, что может делать root. Проблема заключается в том, что другие команды sudo в этом скрипте не обязательно наследуют права root, но выполняются как контролирующий пользователь. Это часто может привести к ошибке, которую вы видите в sudo, даже если сам родительский скрипт разрешен через sudo, а подкоманды - нет.
Происходит то, что вложенный вызов sudo в этом скрипте не выполняется, потому что sudo обычно запрашивает пароль, но нет управляющей оболочки, поэтому он не может. Это создает слегка неоднозначный sudo: no tty present and no askpass program specified
ошибка, которую вы видите.
Простой способ проиллюстрировать это, если, как и ваш пример, скрипт init содержит внутренние вызовы с использованием sudo. Бег:
sudo /etc/init.d/startvpn
может произойти сбой, если ваш собственный пользователь не имеет прав sudo на все вызовы sudo внутри, и может выдать вам ошибку sudo tty. Однако, запустив его так:
sudo sh /etc/init.d/startvpn
вероятно, будет работать. В последнем случае, sudo sh
создает командную оболочку от имени пользователя root, поэтому все, что запускается в этой оболочке, действительно выполняется от имени пользователя root. Root обычно имеет неограниченные права sudo, поэтому больше не имеет значения, запускается ли команда с sudo или нет.
Некоторые вещи стоит упомянуть:
- Как отмечали другие, большей части этого беспорядка можно избежать, не используя sudo в скриптах. Часто подкоманды, которые не работают при запуске с sudo, могут нормально работать без него (когда родительский скрипт запускается с sudo).
- Во время работы скрипта с
sudo sh
может решить проблему, опять же есть последствия для безопасности. Учтите, что sudo ведет себя таким образом, как проверка работоспособности, чтобы гарантировать, что содержимое скрипта не делает то, что не должно делать, даже если сам скрипт разрешен. - Если пользователь, которого вы запускаете sudo as, также имеет достаточные общие разрешения, вы можете не увидеть ни одной из этих проблем. Но они могут всплыть позже, скажем, если вы разрабатываете сценарий со своей собственной привилегированной учетной записью, а в рабочей среде он запускается как непривилегированная служебная учетная запись.
- В общем, вы должны избегать предоставления широких разрешений sudo учетным записям пользователей как способ решения этой проблемы. Если это действительно необходимо, ограничьте правила доступа к учетной записи этим пользователем и этой конкретной командой.
Я нашел решение проблемы.
Я удалил все отдельные команды sudo в своем сценарии vpnon.sh и передал sudo извне сценария.
В моем файле /etc/init.d/vpnstartup я изменил su username -c
в sudo $VPN_DIR/vpnon.sh
который сейчас выглядит так:
case "$1" in
start)
sudo $VPN_DIR/vpnon.sh
;;
затем позвонил sudo update-rc.d vpnstartup defaults
и теперь VPN подключается при запуске! :)