Почему с sudo встроенные переменные окружения не читаются правильно без -E на некоторых системах?

Вопрос или проблема

У меня есть bash-скрипт, который выполняет вход в мою Bitwarden-экземпляр с помощью CLI bw следующим образом:

test.sh:

#!/usr/bin/sh
set -e -o pipefail

bw logout --quiet || true

BW_CLIENTID=$(cat ./credentials.json | jq -r '.client_id') \
BW_CLIENTSECRET=$(cat ./credentials.json | jq -r '.client_secret') \
bw login --apikey

Файл ./credentials.json имеет следующие права:

-rw-r--r-- 1 root root 169 Jun 10  2023 credentials.json

Запуск этого скрипта от имени обычного пользователя работает нормально, но иногда мне нужно запускать его от имени root. Я заметил, что на некоторых системах команда bw не читает встроенные переменные окружения правильно при запуске только с sudo, она работает только с sudo -E, так что:

./test.sh         # всегда работает
sudo ./test.sh    # работает на некоторых машинах, но не на всех
sudo -E ./test.sh # всегда работает

Когда работает, я получаю вывод:

You are logged in!

А когда не работает, я получаю:

client_id or client_secret is incorrect. Try again.

Я говорю “правильно”, потому что, похоже, он каким-то образом читает переменные, потому что если я удалю одну из переменных окружения, например:

BW_CLIENTID=$(cat /mnt/keys/vaultwarden.json | jq -r '.client_id') \
bw login --apikey

Меня вместо этого попросят ввести секрет клиента (или client id, если я удалю BW_CLIENTID). Так что по какой-то причине значения в переменных окружения не читаются правильно без опции -E, но они, похоже, там есть.

Я пытался создать тест с помощью общего скрипта следующим образом:

foo.sh:

#!/usr/bin/sh
set -e

FOO=$(cat ./data.json | jq -r '.my_prop') \
BAR=$(cat ./data.json | jq -r '.other_prop') \
./bar.sh

bar.sh:

#!/usr/bin/sh
set -e

echo "foo: '$FOO'"
echo "bar: '$BAR'"

Но запуск любого из них на любой из моих систем работает, все они выдают ожидаемый вывод (содержимое my_prop и other_prop в data.json), и я не вижу разницы между напечатанным значением для любого варианта:

./foo.sh
sudo ./foo.sh
sudo -E ./foo.sh

Я тестировал на нескольких системах, это смесь систем Ubuntu и Arch, пока без -E он не работает на всех системах Ubuntu и некоторых Arch, и работает без -E только на одной Arch системе.

Мои главные вопросы: есть ли способ настроить sudo на всегда запускаться с -E или что-то подобное? И есть ли разница в форматировании при использовании опции -E? (учетные данные могут содержать странные символы, но я не понимаю, почему опция -E должна делать разницу)

Я видел, что файл /etc/sudoers позволяет делать что-то вроде:

Defaults env_keep += "HOME"

Но все такие строки закомментированы во всех файлах /etc/sudoers (на всех системах, включая работающую), и там нет дополнительных файлов в /etc/sudoers.d/. Я также пробовал добавлять BW_CLIENTID и BW_CLIENTSECRET таким образом, но это не имело эффекта:

Defaults env_keep += "BW_CLIENTID"
Defaults env_keep += "BW_CLIENTSECRETS

Но могут быть другие места или настройки?

Примечание: я предполагаю, что это может быть просто какой-то нюанс CLI bw, из-за которого он не может правильно улавливать переменные окружения на некоторых системах без -E, но мне хотелось бы знать, есть ли настройки, которые я мог бы начать исследовать на своих собственных системах. Тем не менее, я был бы заинтересован в любых подсказках по этому поводу.

Ответ или решение

Существует проблема, связанная с управлением переменными окружения при выполнении команд с помощью sudo в Linux-системах, которая может варьироваться от системы к системе. В данном контексте эту проблему можно рассмотреть в три этапа: теоретическое объяснение, практический пример и применение полученных знаний.

Теоретическая часть

Сначала необходимо понять, как работает sudo. Команда sudo используется для выполнения команд от имени другого пользователя, обычно суперпользователя (root). По умолчанию sudo сбрасывает большинство переменных окружения для повышения безопасности, пропуская только минимально необходимые для корректного исполнения команд. Однако, с помощью опции -E можно сохранить текущие переменные окружения и передать их в команду, выполняемую под sudo.

Это различие часто становится причиной проблем в скриптах, где используется передача безопасных данных через переменные окружения. В зависимости от конфигурации системы или специфик исполнения, sudo может не передать некоторые или все переменные в урок-скрипт при отсутствующем -E.

Пример

Рассмотрим предоставленный сценарий. Имеется bash-скрипт, который использует bw CLI для входа в Bitwarden, где переменные окружения BW_CLIENTID и BW_CLIENTSECRET определяются inline. В обычном режиме скрипт выполняется корректно, однако при запуске с sudo без -E на некоторых системах возникают ошибки аутентификации.

Для сравнения, другой набор скриптов, foo.sh и bar.sh, работающие с другими JSON-данными, всегда выполняются корректно. Это различие может быть связано с обработкой bw CLI переменных окружения или с особенностями выполнения sudo на разных системах.

Практическое применение

Для достижения стабильного результата, важно понимать и управлять переменными окружения в контексте sudo. В данном случае, sudo -E ./test.sh всегда срабатывает, так как переменные окружения в неизменном виде передаются скрипту. Чтобы навсегда решить проблему, можно предпринять несколько шагов:

  1. Изменение логики скрипта: Использовать опцию -E в команде sudo всегда, когда требуется передать переменные окружения.

  2. Настройка sudoers: Можно модифицировать файл /etc/sudoers для сохранения определенных переменных окружения при использовании sudo. Добавление строки Defaults env_keep += "BW_CLIENTID BW_CLIENTSECRET" будет полезным шагом для автоматической передачи этих переменных.

  3. Альтернативные методы передачи: Применение конфигурационных файлов или других механизмов передачи чувствительных данных может уменьшить зависимость от переменных окружения.

Важно помнить, что поведение sudo может зависеть от множества настроек и конфигураций, включая отличия между версиями дистрибутивов Linux и особенностями конфигурации конкретных систем. В случаях, аналогичных описанным, рекомендуется тщательно проверять конфигурацию системы и, при необходимости, проконсультироваться с документацией и техническими ресурсами.

Надеюсь, предоставленная информация будет полезной для эффективного решения данной проблемы и позволит избежать лишних проблем в будущем при управлении и передаче переменных окружения в скриптах.

Оцените материал
Добавить комментарий

Капча загружается...