Puncte:1

Rularea Bash Script ca root cu secțiune de script non root

drapel gh

Am un script bash care trebuie să ruleze ca root pentru a îndeplini o sarcină, în acest caz, este de a face validatorul să ia un instantaneu al blockchain-ului Helium.

Am editat fișierul /etc/sudoers pentru a-mi permite să rulez acest script ca root. Acest lucru funcționează bine.

useraccount ALL=(ALL:ALL) NOPASSWD:/home/useraccount/validator_data/snapshotmaker.sh

Comanda din script este următoarea:

sudo docker exec validator miner snapshot take /var/data/$dtt

după aceasta, comanda generează un fișier ca acesta '30-10-2021T233752.bin'.

Următorul meu pas este să iau acest fișier și să-l copiez în IPFS, astfel încât să îl pot partaja. Comanda pentru a face acest lucru este:

fisiere ipfs cp /ipfs/$(ipfs adauga -Q $fisier local) $ip

Momentan imi apare urmatoarea eroare:

Eroare: nu a fost găsit niciun repo IPFS în /root/.ipfs. rulați: „ipfs init”

Acest lucru se datorează faptului că încearcă să-l ruleze ca root atunci când configurația este în contul meu de utilizator.

Am încercat să schimb conturile în mijlocul scriptului, dar se pare că îl omoara.

Deci întrebarea mea este cum să rulez comanda IPFS ca utilizator inițial din scriptul rădăcină.

My Bash Script:

#!/bin/bash

dt=$(data '+%d-%m-%YT%H%M%S');
dtt="${dt}.bin"
a='/var/data/'
c="${a}${dt}.bin"

ecou „${c}”

sudo docker exec validator miner snapshot take /var/data/$dtt


localfile="/home/useraccount/validator_data/${dt}.bin"
echo „LocalFile: ${localfile}”

ip=" /Helium/Snapshots/2021/${dt}.bin"
echo „Locație IPFS: ${ip}”

somn 2

if [ -f "$localfile" ]; atunci
        echo "$localfile există."
        sudo chown useraccount $localfile
        cine sunt
        su - useraccount
        cine sunt
        fisiere ipfs cp /ipfs/$(ipfs adauga -Q $fisier local) $ip
        #ipfs fișiere cp /ipfs/$(ipfs add -Q <local-file>) „/Helium/Snapshots/2021/<dest-name>”
altfel 
    echo "$localfile nu există."
fi

Ieșirea este după cum urmează:

/var/data/31-10-2021T005728.bin
Bine
LocalFile: /home/useraccount/validator_data/31-10-2021T005728.bin
Locație IPFS: /Helium/Snapshots/2021/31-10-2021T005728.bin
/home/useraccount/validator_data/31-10-2021T005728.bin există.
rădăcină

Și apoi moare. Dacă scot su atunci primesc problema rădăcină așa cum este menționat în partea de sus a acestei postări.

În speranța că cineva poate ajuta.

sudodus avatar
drapel jp
Executați acest script manual sau automat (de exemplu prin `cron`)? - Nu rulați întregul script ca root. În schimb, rulați-l ca utilizator obișnuit. Apoi, când ajunge la comenzile care au nevoie de permisiuni ridicate, le apelați deja cu sudo și vi se va solicita să introduceți parola. Dar **puteți face ca „doar” sarcinile sudo necesare să fie rulate fără parolă**: editați `/etc/sudoers` prin `visudo`.
DevilCode avatar
drapel gh
Momentan rulez manual, dar îl voi crona odată ce toate lucrurile funcționează. Vrei să spui că ar trebui să adaug doar comanda sudo docker la sudoers, mai degrabă decât scriptul bash?
bac0n avatar
drapel cn
@sudodus aș spune contrariul. de exemplu, în acest caz, ar oferi utilizatorului acces la `chown`, cum ar fi oferirea cheii. Atâta timp cât scriptul are sarcini bine definite, `sudo` nu ar trebui să pună o problemă.
bac0n avatar
drapel cn
Există un spațiu pe `ip=" /Helium..."`
bac0n avatar
drapel cn
@DevilCode Vă sugerez să eliminați toate sudo din script și să rulați scriptul cu sudo și să utilizați su cu ipfs: `su -c 'fișiere ipfs cp /ipfs/$(ipfs adaugă -Q $1) $2' _ "$localfile" "$ip"`
sudodus avatar
drapel jp
@bac0n, sunt de acord că nu ar trebui să acordați acces general la chown, ci doar la linia (liniile) de comandă specifice, utilizată de script. Dacă îmi amintesc corect, acest lucru este posibil și ar trebui să fie sigur. - În caz contrar, cu acces la întregul shellscript, ar trebui să prindeți și ctrl C pentru a reduce riscul de abuz. Aceasta ar fi, de asemenea, o soluție bună.
sudodus avatar
drapel jp
@DevilCode, Da, asta am sugerat, **toate liniile de comandă** cu `sudo docker ...` și `sudo chown useraccount $localfile`
DevilCode avatar
drapel gh
Cineva va trebui să scrie asta, deoarece sunt pierdut acum. @bac0n cum funcționează această comandă? Am crezut că $1 $2 sunt argumente pentru un script?
bac0n avatar
drapel cn
`su -c` funcționează în același mod ca `sh -c`, unde `-c` ia primul argument ca 'șir de comandă' și următoarele argumente devin parametri de poziție în șirul de comandă, de exemplu, `su user -c ' echo $0 $1 $2' _ unu doi`.
DevilCode avatar
drapel gh
Nu funcționează din păcate. Am încercat sudo su useraccount -c '/usr/local/bin/ipfs stats repo' nu funcționează cu sau fără sudo. este ok ca script, dar când este rulat prin crontab, eșuează. crontab trebuie să facă ceva ciudat. Dacă apelez comanda direct din scrip /usr/local/bin/ipfs stats repo, aceasta funcționează. Dacă o fac cu comanda fișiere, nu o face. Nicio idee în afară de faptul că rulează într-o locație ciudată sau așa ceva.
Puncte:1
drapel jp

Am făcut un test de „funcție uscată” fără docher și orice faci în ea și fără ipfs. Metoda ar trebui să lucrează pentru tine cu programele reale după câteva ajustări.

  • Rulați shellscript-ul scrip ca utilizator normal, nu cu sudo.

  • Editați scriptul pentru a schimba de la „tester” din demonstrația mea la numele dvs. de utilizator.

  • Editați liniile de comandă exacte de care aveți nevoie sudo fara parola cu visudo,

    $ 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
    
    • Este important să aveți un nume fix al fișierului pentru operațiunile sudo. După aceea i se poate da un nume care depinde de timp.
    • Verificați locația executabilului docker (poate nu în /usr/sbin).

Scriptul meu modificat scrip:

#!/bin/bash

if [ "$(whoami)" != "tester" ]
atunci
 ecou „rulați ca „tester””
 Ieșire
fi

dt=$(data '+%d-%m-%YT%H%M%S');
dtt="${dt}.bin"
a='/var/data/'
c="${a}${dt}.bin"

ecou „${c}”

sudo /usr/sbin/docker exec validator miner snapshot take /var/data/tmpfil

if [ -f "/home/tester/validator_data/tmpfil" ]; atunci
        ls -l "/home/tester/validator_data/tmpfil"

        sudo /usr/bin/chown tester "/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: ${localfile}”
        ls -l „${localfile}”

        ip=" /Helium/Snapshots/2021/${dt}.bin"
        echo „Locație IPFS: ${ip}”

        dormi 2

        echo "$localfile există."
        cine sunt
        /usr/local/bin/ipfs fișiere cp /ipfs/$(/usr/local/bin/ipfs add -Q $localfile) $ip
        #ipfs fișiere cp /ipfs/$(ipfs add -Q <local-file>) „/Helium/Snapshots/2021/<dest-name>”
altfel 
    echo "$localfile nu există."
fi

Un scenariu care se pretinde a fi docher Linie de comanda:

#!/bin/bash

dacă [ "$EUID" == "0" ]
atunci
 echo „lumea docker” > „/home/tester/validator_data/tmpfil”
 chown root:root "/home/tester/validator_data/tmpfil"
 ecou "ok"
altfel
 echo "a alerga cu sudo"
fi

Executare demonstrativă:

tester@lenovo-v130:~$ LANG=C ./scrip 
/var/data/01-11-2021T051748.bin
Bine
-rw-r--r-- 1 root root 15 nov 1 05:17 /home/tester/validator_data/tmpfil
LocalFile: /home/tester/validator_data/01-11-2021T051748.bin
-rw-r--r-- 1 tester root 15 nov 1 05:17 /home/tester/validator_data/01-11-2021T051748.bin
Locație IPFS: /Helium/Snapshots/2021/01-11-2021T051748.bin
/home/tester/validator_data/01-11-2021T051748.bin există.
tester
./scrip: linia 34: ipfs: comanda nu a fost găsită
./scrip: linia 34: ipfs: comanda nu a fost găsită
DevilCode avatar
drapel gh
Ok, așa că l-am schimbat pentru a rula așa cum ai sugerat. Când este apelat prin linia de comandă, funcționează perfect. Când este apelat prin crontab, totul funcționează, cu excepția liniei ipfs files cp. Pentru unele reson atunci când ipfs este numit, acea linie nu va rula atunci când se face prin crontab. Am adăugat chiar și calea completă /usr/local/bin/ipfs și nu am avut noroc.
DevilCode avatar
drapel gh
S-a găsit: /usr/local/bin/ipfs fișiere cp /ipfs/$(/usr/local/bin/ipfs add -Q
DevilCode avatar
drapel gh
Vă mulțumesc tuturor !!
sudodus avatar
drapel jp
@DevilCode, L-ai făcut să funcționeze :-) Mă bucur că te-am putut ajuta pe parcurs.
Puncte:0
drapel cn

Deci întrebarea mea este cum să rulez comanda IPFS ca utilizator inițial din scriptul rădăcină.

sudo su - useraccount -c COMANDĂ
Puncte:0
drapel cn

Mai întâi, trebuie să creați o configurație sudo pentru scriptul dvs., în acest exemplu, o plasăm /etc/sudoers.d cu permisiunea 440:

Cmnd_Alias ​​CMDS = /opt/bin/docker_example.sh
User_Alias ​​CMDUSERS = bac0n
CMDUSERS ALL=(TOȚI) NOPASSWD: CMDS
Implicit!CErință!CMDS

Numim scenariul docker_example.sh, așa cum se arată în exemplul sudo:

#!/bin/bash

# Ieșiți imediat în starea de ieșire diferită de zero.
set -e

((EUID != 0)) && {
    echo Acest script ar trebui să ruleze ca root.
    iesirea 1
}

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

printf -v fișier_bin \
„%(%d-%m-%YT%H%M%S)T.%s” -1 bin

local_file=$HOME/validator_data/$bin_file
 ipfs_file=/Helium/Snapshots/2021/$bin_file

printf '
Fișier Bin: %s
Fisiere locale
Fișier IPFS: %s
' "$bin_file" "$local_file" "$ipfs_file"

docker exec validator miner snapshot take "/var/data/$bin_file"
somn 2

[[ -f $fișier_local ]] || {
    Fișierul echo nu există: „$local_file”
    iesirea 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"

Acum ar trebui să puteți adăuga acest script cu sudo la crontab și ar trebui să ruleze cu NOPASSWD.

$ sudo crontab -u bac0n -e
# min oră dom luna comanda dow
* * * * * sudo /opt/bin/docker_example.sh > /dev/null 2>&1

Postează un răspuns

Majoritatea oamenilor nu înțeleg că a pune multe întrebări deblochează învățarea și îmbunătățește legătura interpersonală. În studiile lui Alison, de exemplu, deși oamenii își puteau aminti cu exactitate câte întrebări au fost puse în conversațiile lor, ei nu au intuit legătura dintre întrebări și apreciere. În patru studii, în care participanții au fost implicați în conversații ei înșiși sau au citit transcrieri ale conversațiilor altora, oamenii au avut tendința să nu realizeze că întrebarea ar influența – sau ar fi influențat – nivelul de prietenie dintre conversatori.