Рейтинг:1

Запуск сценария Bash от имени пользователя root с разделом сценария без полномочий root

флаг gh

У меня есть скрипт bash, который нужно запустить от имени пользователя root, чтобы выполнить задачу, в данном случае это заставить валидатор сделать снимок блокчейна Helium.

Я отредактировал файл /etc/sudoers, чтобы запустить этот скрипт от имени пользователя root. Это прекрасно работает.

учетная запись пользователя ALL=(ALL:ALL) NOPASSWD:/home/useraccount/validator_data/snapshotmaker.sh

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

sudo docker exec validator miner snapshot взять /var/data/$dtt

после этого команда генерирует такой файл '30-10-2021T233752.bin'.

Мой следующий шаг — взять этот файл и скопировать его в IPFS, чтобы я мог поделиться им. Команда для этого:

файлы ipfs cp /ipfs/$(ipfs добавить -Q $localfile) $ip

На данный момент я получаю следующую ошибку:

Ошибка: репозиторий IPFS не найден в /root/.ipfs. запустите: 'ipfs init'

Это потому, что он пытается запустить его как root, когда конфигурация находится в моей учетной записи пользователя.

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

Итак, мой вопрос заключается в том, как запустить команду IPFS от имени моего исходного пользователя из корневого сценария.

Мой Баш-скрипт:

#!/бин/баш

dt=$(дата '+%d-%m-%YT%H%M%S');
dtt="${dt}.bin"
а='/вар/данные/'
c="${a}${dt}.bin"

эхо "${с}"

sudo docker exec validator miner snapshot взять /var/data/$dtt


localfile="/home/useraccount/validator_data/${dt}.bin"
echo "Локальный файл: ${localfile}"

ip=" /Helium/Snapshots/2021/${dt}.bin"
echo "Расположение IPFS: ${ip}"

спать 2

если [-f "$localfile"]; тогда
        echo "$localfile существует."
        sudo chown useraccount $localfile
        кто я
        су - учетная запись пользователя
        кто я
        файлы ipfs cp /ipfs/$(ipfs добавить -Q $localfile) $ip
        #ipfs files cp /ipfs/$(ipfs add -Q <локальный-файл>) "/Helium/Snapshots/2021/<имя-назначения>"
еще 
    echo "$localfile не существует."
фи

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

/var/данные/31-10-2021T005728.bin
хорошо
Локальный файл: /home/useraccount/validator_data/31-10-2021T005728.bin
Расположение IPFS: /Helium/Snapshots/2021/31-10-2021T005728.bin
/home/useraccount/validator_data/31-10-2021T005728.bin существует.
корень

А потом умирает. Если я удалю су строка, то я получаю корневую проблему, как указано в верхней части этого поста.

Надеясь, что кто-то может помочь.

sudodus avatar
флаг jp
Вы запускаете этот скрипт вручную или автоматически (например, через cron)? - Не запускайте весь скрипт от имени root. Вместо этого запустите его как обычный пользователь. Затем, когда он доходит до команд, которым нужны повышенные разрешения, вы уже вызываете их с помощью sudo, и вам будет предложено ввести пароль. Но **вы можете сделать возможным выполнение "только" необходимых задач sudo без пароля**: отредактируйте `/etc/sudoers` через `visudo`.
DevilCode avatar
флаг gh
В данный момент я запускаю вручную, но закрою, как только все заработает. Вы говорите, что я должен добавить в sudoers только команду sudo docker, а не скрипт bash?
bac0n avatar
флаг cn
@sudodus Я бы сказал наоборот. например, в этом случае даст пользователю доступ к `chown`, как раздачу ключа. Пока в сценарии есть четко определенные задачи, `sudo` не должно вызывать проблем.
bac0n avatar
флаг cn
В `ip="/Helium..." есть пробел.
bac0n avatar
флаг cn
@DevilCode Я предлагаю вам удалить все sudo из скрипта, запустить скрипт с помощью sudo и использовать su с ipfs: `su -c 'файлы ipfs cp /ipfs/$(ipfs add -Q $1) $2' _ "$localfile" "$ip"`
sudodus avatar
флаг jp
@ bac0n, я согласен, что вы не должны предоставлять общий доступ к chown, а только к определенной командной строке (строкам), используемой скриптом. Если я правильно помню, это возможно и должно сделать это безопасным. - В противном случае, имея доступ ко всему шеллскрипту, вы также должны перехватывать Ctrl C, чтобы снизить риск злоупотреблений. Это тоже будет хорошим решением.
sudodus avatar
флаг jp
@DevilCode, да, это то, что я предложил, **все командные строки** с `sudo docker ...` и `sudo chown useraccount $localfile`
DevilCode avatar
флаг gh
Кто-то должен будет написать это, так как я потерялся сейчас. @ bac0n, как работает эта команда? Я думал, что $1 $2 были аргументами скрипта?
bac0n avatar
флаг cn
`su -c` работает почти так же, как `sh -c`, где `-c` принимает первый аргумент как 'командную строку', а следующие аргументы становятся позиционными параметрами в командной строке, например, `su user -c' echo $0 $1 $2' _ один два`.
DevilCode avatar
флаг gh
К сожалению, не работает. Я попробовал sudo su useraccount -c '/usr/local/bin/ipfs stats repo' не работает с sudo или без него. это нормально как скрипт, но когда он запускается через crontab, он терпит неудачу. crontab должен делать что-то странное. Если я просто вызову команду прямо из репозитория статистики scrip /usr/local/bin/ipfs, это сработает. Если я сделаю это с помощью команды файлов, это не так. Понятия не имею, кроме того, что он работает в каком-то странном месте или что-то в этом роде.
Рейтинг:1
флаг jp

Я провел «пробный прогон» без докер и что бы вы ни делали в нем и без IPFS. Метод должен работать для вас с реальными программами после некоторых настроек.

  • Запустите шелл-скрипт сума как ваш обычный пользователь, а не с судо.

  • Отредактируйте скрипт, чтобы он изменился с «тестер» в моей демонстрации на ваше имя пользователя.

  • Отредактируйте точные командные строки, которые необходимо судо без пароля с зрение,

    $ LANG =C sudo tail -n2 /etc/sudoers
    %tester ALL=NOPASSWD: /usr/sbin/docker exec validator miner snapshot take /var/data/tmpfil
    %tester ALL=NOPASSWD: /usr/bin/chown tester /home/tester/validator_data/tmpfil
    
    • Важно иметь фиксированное имя файла для операций sudo. После этого ему можно дать имя, зависящее от времени.
    • Проверьте расположение исполняемого файла докера (возможно, не в /usr/sbin).

Мой модифицированный скрипт сума:

#!/бин/баш

если [ "$(whoami)" != "тестер" ]
тогда
 echo "запустить как "тестер""
 выход
фи

dt=$(дата '+%d-%m-%YT%H%M%S');
dtt="${dt}.bin"
а='/вар/данные/'
c="${a}${dt}.bin"

эхо "${с}"

sudo /usr/sbin/docker exec validator miner snapshot принять /var/data/tmpfil

если [ -f "/home/tester/validator_data/tmpfil" ]; тогда
        ls -l "/home/tester/validator_data/tmpfil"

        sudo /usr/bin/chown тестер "/home/tester/validator_data/tmpfil"
        mv "/home/tester/validator_data/tmpfil" "/home/tester/validator_data/${dt}.bin"
        localfile="/home/tester/validator_data/${dt}.bin"
        echo "Локальный файл: ${localfile}"
        ls -l "${локальный файл}"

        ip=" /Helium/Snapshots/2021/${dt}.bin"
        echo "Расположение IPFS: ${ip}"

        спать 2

        echo "$localfile существует."
        кто я
        /usr/local/bin/ipfs файлы cp /ipfs/$(/usr/local/bin/ipfs добавить -Q $localfile) $ip
        #ipfs files cp /ipfs/$(ipfs add -Q <локальный-файл>) "/Helium/Snapshots/2021/<имя-назначения>"
еще 
    echo "$localfile не существует."
фи

Скрипт, выдающий себя за докер командная строка:

#!/бин/баш

если [ "$EUID" == "0" ]
тогда
 echo "мир докеров" > "/home/tester/validator_data/tmpfil"
 chown root:root "/home/tester/validator_data/tmpfil"
 эхо "хорошо"
еще
 echo "запустить с помощью sudo"
фи

Демонстрационный запуск:

tester@lenovo-v130:~$ LANG=C ./скрипт 
/var/данные/01-11-2021T051748.bin
хорошо
-rw-r--r-- 1 root root 15 ноя 1 05:17 /home/tester/validator_data/tmpfil
Локальный файл: /home/tester/validator_data/01-11-2021T051748.bin
-rw-r--r-- 1 корень тестера 15 1 ноября 05:17 /home/tester/validator_data/01-11-2021T051748.bin
Расположение IPFS: /Helium/Snapshots/2021/01-11-2021T051748.bin
/home/tester/validator_data/01-11-2021T051748.bin существует.
тестер
./scrip: строка 34: ipfs: команда не найдена
./scrip: строка 34: ipfs: команда не найдена
DevilCode avatar
флаг gh
Хорошо, поэтому я изменил его, чтобы он работал, как вы предложили. При вызове через командную строку работает отлично. При вызове через crontab все работает кроме строки ipfs files cp. По какой-то причине, когда вызывается ipfs, эта строка не запускается, если выполняется через crontab. Я даже добавил полный путь /usr/local/bin/ipfs и не повезло.
DevilCode avatar
флаг gh
Нашел: /usr/local/bin/ipfs files cp /ipfs/$(/usr/local/bin/ipfs add -Q
DevilCode avatar
флаг gh
Спасибо всем !!
sudodus avatar
флаг jp
@DevilCode, у тебя все получилось :-) Я рад, что смог помочь тебе на этом пути.
Рейтинг:0
флаг cn

So my question is how to run the IPFS command as my original user from within the root script.

sudo su - useraccount -c COMMAND
Рейтинг:0
флаг cn

Во-первых, вам нужно создать конфигурацию sudo для вашего скрипта, в этом примере мы поместим его в /etc/sudoers.d с разрешения 440:

Cmnd_Alias ​​CMDS = /opt/bin/docker_example.sh
Псевдоним пользователя CMDUSERS = bac0n
CMDUSERS ALL=(ALL) NOPASSWD: CMDS
По умолчанию!CMDS !требуется

Мы называем сценарий docker_example.sh, как показано в примере sudo:

#!/бин/баш

# Немедленный выход при ненулевом статусе выхода.
установить -е

((EUID != 0)) && {
    echo Этот скрипт должен запускаться от имени пользователя root.
    выход 1
}

[[ ${SUDO_USER+ } ]] && \
user_account=$SUDO_USER || user_account=$(id -nu)

printf -v бинарный_файл \
'%(%d-%m-%YT%H%M%S)T.%s' -1 бин

local_file=$HOME/validator_data/$bin_file
 ipfs_file=/Helium/Снимки/2021/$bin_file

printf '
Бин-файл: %s
Локальный файл: %s
Файл IPFS: %s
' "$bin_file" "$local_file" "$ipfs_file"

docker exec validator miner snapshot take "/var/data/$bin_file"
спать 2

[[ -f $local_file ]] || {
    эхо Файл не существует: "$local_file"
    выход 1
}

chown $user_account "$local_file"

#
# su $user_account -c 'echo whoami: $1, su: $(id -nu)' _ $(id -nu)
#
su $user_account -c 'ipfs files cp "/ipfs/$(ipfs add -Q "$1")" "$2"' _ "$local_file" "$ipfs_file"

Теперь вы сможете добавить этот скрипт с помощью sudo в crontab, и он должен работать с NOPASSWD.

$ sudo crontab -u bac0n -e
# мин час дом месяц команда доу
* * * * * sudo /opt/bin/docker_example.sh > /dev/null 2>&1

Ответить или комментировать

Большинство людей не понимают, что склонность к познанию нового открывает путь к обучению и улучшает межличностные связи. В исследованиях Элисон, например, хотя люди могли точно вспомнить, сколько вопросов было задано в их разговорах, они не чувствовали интуитивно связи между вопросами и симпатиями. В четырех исследованиях, в которых участники сами участвовали в разговорах или читали стенограммы чужих разговоров, люди, как правило, не осознавали, что задаваемый вопрос повлияет — или повлиял — на уровень дружбы между собеседниками.