fragen stichworte

Warum gibt 'ansible -a "env"' eine andere Umgebung PATH als mein Benutzer zurück?

Wenn ich ssh auf einen Remote-Server starte und env starte, erhalte ich den folgenden PFAD zurück:

PATH=/usr/lib64/qt-3.3/bin:/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin:/home/myusername/bin

Im Gegensatz dazu erhalte ich beim Ausführen des Antwortbefehls ansible -a "env" den folgenden PFAD:

PATH=/usr/lib64/qt-3.3/bin:/usr/local/bin:/bin:/usr/bin

Wie man sich vorstellen kann, verursacht dies Probleme beim Laufversuch sbin -Befehle wie service, ntpdate usw., da der vollständige Pfad zum Befehl sbin eingegeben werden muss. (Ja, ich weiß, dass es anpassbare Module gibt, die dies tun können, aber ich versuche zu lösen, warum der PFAD gekürzt/verkürzt wird.)

Weiß jemand, warum das passiert?

EDIT: Der Grund, warum ich danach frage, ist, dass ich die Beispiele im Buch Ansible for DevOps befolge und einige der Beispiele funktionieren aus diesem Grund nicht.

Das Beispiel, das ich zur Arbeit bringen möchte, ist auf Seite 28 des Buches:

$ ansible multi -s -a "service ntpd stop"
$ ansible multi -s -a "ntpdate -q 0.rhel.pool.ntp.org"
$ ansible multi -s -a "service ntpd start"

Diese Befehle lösen immer einen Fehler aus. Wenn ich sie jedoch so verändere, dass sie den vollständigen Pfad einschließen, funktionieren sie.

$ ansible multi -s -a "/sbin/service ntpd stop"
$ ansible multi -s -a "/usr/sbin/ntpdate -q 0.rhel.pool.ntp.org"
$ ansible multi -s -a "/sbin/service ntpd start"

Natürlich muss ich nicht für jeden Ad-hoc-Befehl, den ich ausgeben, den vollständigen Pfad eingeben müssen. (Ich kenne nicht die Pfade jedes Befehls.)

Gibt es eine Möglichkeit, den normalen Pfad, der in meiner Shell enthalten ist, mit ansible zu versehen? Gibt es eine Pfadvariable, die ich der Inventardatei oder der Datei ansible.cfg hinzufügen kann, um dies zu ermöglichen?

antworten

ansible -a verwendet das Befehlsmodul, und dies verwendet keine Shell, um den Befehl auszuführen.

http://docs.ansible.com/ansible/intro_adhoc.html
Normally commands also take a -m for module name, but the default module name is ‘command’.

Die Komponenten des Pfads, z. B. /usr/sbin, werden von der Shell, die die /etc/profile -Datei bezieht, zum Pfad hinzugefügt. Das Befehlsmodul erstellt keine login -Shell. Lesen Sie diese Datei nicht.

http://linux.die.net/man/1/bash
When bash is invoked as an interactive login shell, or as a non-interactive shell with the --login option, it first reads and executes commands from the file/etc/profile, if that file exists. After reading that file, it looks for ~/.bash_profile, ~/.bash_login, and ~/.profile, in that order, and reads and executes commands from the first one that exists and is readable. The --noprofile option may be used when the shell is started to inhibit this behavior.

Die anzeigbaren Dokumente sagen, wenn Sie eine Shell wünschen, verwenden Sie das -Shell. Es scheint jedoch nicht, dass es eine Option gibt, eine Login-Shell vom Shell-Modul aus zu starten (durch Übergeben der Option --login).

Tatsächlich wird an verschiedenen Stellen erwähnt, dass es die ansible-Richtlinie ist, der Umgebung nicht zu vertrauen und jegliche VARS explizit festzulegen, wenn die Aufgabe definiert wird.

Es ist jedoch möglich, den Pfad festzulegen, wenn ansible im Ad-hoc-Modus verwendet wird. Dies ist der nächste Schritt, um den PFAD zu replizieren, den Sie in einer interaktiven /bin/bash -Shell sehen.

$ ansible raspberrypi -m shell \
-a 'PATH=$PATH:/usr/local/sbin:/usr/sbin:$HOME/bin  env' \
 | grep PATH

PATH=/usr/local/bin:/usr/bin:/bin:/usr/games:/usr/local/sbin:
/usr/sbin:/home/pi/bin

oder alternativ können Sie die Datei /etc/profile als Quelle verwenden;

$ ansible raspberrypi -m shell \
 -a 'executable=/bin/bash source/etc/profile ; env | grep PATH'

 PATH=/opt/consul/bin:/usr/local/sbin:/usr/local/bin:
/usr/sbin:/usr/bin:/sbin:/bin

das scheint auch zu funktionieren;

$ ansible raspberrypi -a '/bin/bash -l -c "env"'

 PATH=/opt/consul/bin:/usr/local/sbin:/usr/local/bin:
/usr/sbin:/usr/bin:/sbin:/bin

Da Ihre Frage letztlich die Ausführung von Befehlen unter sudo mit ansible betrifft, habe ich mir noch einmal angeschaut, wie der PFAD bei der Verwendung von ansible -s -a env eingestellt wird. Ich denke, es ist wichtig zu wissen, dass der $ PATH bei Verwendung des sudo-Flag -s in ansible durch einen anderen Mechanismus festgelegt wird als bei der Verwendung von ansible -a env.

Bei Verwendung von sudo command oder ansible -s wird die Benutzerumgebung zurückgesetzt, und $ PATH wird durch die Einstellung Default secure_path in /etc/sudoers gesteuert. Dies wird in der Dokumentation man sudoers erläutert.

By default, the env_reset option is enabled. This causes commands to be executed with a new, minimal environment. The new environment contains the TERM, PATH, HOME, MAIL, SHELL, LOGNAME, USER, USERNAME and SUDO_* variables in addition to variables from the invoking process permitted by the env_check and env_keep options.

Wenn Sie keinen Wert für Default secure_path festlegen, werden diese Werte in der Binärdatei sshd hartcodiert. Weitere Informationen finden Sie in dieser Antwort.

Der Wert für $ PATH wird jedoch bei fedora/centros/ubuntu standardmäßig aus dem in /etc/sudoers gesetzten sicheren Pfad übernommen.

secure_path - Path used for every command run from sudo.

Zum Beispiel hat mein lokaler Fedora-Eintrag die folgende Zeile in /etc/sudoers

Defaults    secure_path =/sbin:/bin:/usr/sbin:/usr/bin

und wenn ich den Befehl env remote von ssh und sudo ausführe, bekomme ich genau diesen Pfad zurück;

$ ssh localhost "sudo env" | grep PATH
PATH=/sbin:/bin:/usr/sbin:/usr/bin

und ich bekomme dasselbe mit ansible;

$ ansible localhost -s -a 'env' | grep PATH
PATH=/sbin:/bin:/usr/sbin:/usr/bin

und ich habe dasselbe an einer Raspbian (debian) -Instanz versucht, und ich bekomme ein ähnliches Verhalten;

$ ansible raspberrypi -s -a 'cat/etc/sudoers' | grep secure
Defaults        secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"

und dies ist der Pfad, den ansible mit den -s -a -Optionen sieht;

$ ansible raspberrypi -s -a env | grep PATH
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

In Bezug auf Ihre ursprüngliche Frage möchte ich mir die Datei /etc/sudoers ansehen und den Wert von Defaults secure_path="/some/path/here" überprüfen.

Wenn Sie dort keinen Wert haben, der das entsprechende sbin/ -Verzeichnis enthält, funktioniert der folgende Befehl in ansible nicht ohne einen vollständigen angegebenen Pfad.

ansible multi -s -a "service ntpd stop"

Jedes Mal wenn ich Ansible benutzte, lief es als ein anderer Benutzer unter einer anderen Shell. sollte in der Lage sein zu sehen, welcher Benutzer, indem Sie tun:

ansible -a "id"

Sie können dann die Benutzer-Shell sehen, die definiert ist in:   cat/etc/passwd

Die beste Vorgehensweise zum Hinzufügen zum Pfad wäre das Hinzufügen einer Zeile in:  /home/<username>/.profile oder ~/.bash_profile