Ansible에 sudo 비밀번호를 지정하십시오.


224

비 대화식으로 Ansible에 대한 sudo 비밀번호를 지정하려면 어떻게해야합니까?

다음과 같이 Ansible 플레이 북을 실행하고 있습니다.

$ ansible-playbook playbook.yml -i inventory.ini \
    --user=username --ask-sudo-pass

그러나 나는 이것을 다음과 같이 실행하고 싶다 :

$ ansible-playbook playbook.yml -i inventory.ini \
    --user=username` **--sudo-pass=12345**

방법이 있습니까? 프로젝트 배포를 최대한 자동화하고 싶습니다.


답변:


169

를 통해 명령 행에서 변수를 전달할 수 있습니다 --extra-vars "name=value". Sudo 비밀번호 변수는 ansible_sudo_pass입니다. 따라서 명령은 다음과 같습니다.

ansible-playbook playbook.yml -i inventory.ini --user=username \
                              --extra-vars "ansible_sudo_pass=yourPassword"

2017 업데이트 : Ansible 2.2.1.0은 이제 var를 사용합니다 ansible_become_pass. 작동하는 것 같습니다.


7
보안 관점에서 다음을 추가하면 가장 좋은 대답 history -c입니다. yml을 실행 한 후.
kiltek

12
@kiltek : 또는 것이다 (bash는) 줄의 시작 부분에 여분의 공간을 추가 * *하지 에 라인을 쓰기 .bash_history.
ccpizza

44
명령 행에서 비밀번호를 전달하는 것은 좋지 않습니다. 명령이 실행되는 동안 누구나 프로세스 목록에서 암호를 볼 수 있습니다.
Pavel Chernikov

22
그래도하지 마십시오. --ask-sudo-pass
JasonG

2
@scrutari 다음과 같은 상황에서는 완벽하게 유효합니다 : 예 : 사용자의 공개 ssh 키를 주입하기 위해 세계적으로 알려진 기본 초기 암호를 변경하십시오 ... 새로 새롭게 이미지화 된 시스템의 초기 구성을 생각하십시오.
Ceredig

236

워드 프로세서는 강력하게 사용하는 대신 일반 텍스트에 sudo는 암호를 설정하고에 추천 --ask-sudo-pass실행할 때 명령 행에ansible-playbook


2016 년 업데이트 :

--ask-sudo-pass사용되지 않는 것으로 표시된 Ansible 2.0 (100 %가 아님) 문서는 이제 --ask-become-pass대신 사용 하는 것이 좋으며 sudo플레이 북 전체 의 사용을로 바 꾸었습니다 become.


16
예, 이것이 권장되는 이유를 알 수 있습니다. 그러나 배포 프로세스의 일부로 Ansible을 사용할 때이를 자동화하는 더 좋은 방법은 무엇입니까? 배포 프로세스 도중 중지하고 sudo 암호를 입력하도록 사용자에게 요청하는 것은 그리 편리하지 않습니다.
Slava Fomin II

9
참고 --ask-sudo-pass는 -K로 축약 될 수 있지만, 아는 한, 다른 암호를 가진 여러 서버에서 실행되는 플레이 북을 처리 할 수있는 방법은 없습니다 (한 번만 묻습니다). sudo는 갈 길입니다.
William Turrell

1
작동하지 않는 것 같습니다. 그러나 다음 제안 ( "some-host ansible_sudo_pass = 'foobar'")
nadavkav

--ask-sudo는 패스가 1.9에서, 이전에 사용되지 않습니다
크리스 Betti이를

답변이 있으면 소스 링크로 답변을 업데이트하고 싶습니다.
deefour

106

scottod가 제공하는 NOPASSWD 솔루션을 사용할 수 없다고 가정하면이 작업을 수행하는 가장 좋은 방법은 Mircea Vutcovici의 솔루션을 Ansible Vault 와 함께 사용하는 것 입니다.

예를 들어 다음과 같은 플레이 북이있을 수 있습니다.

- hosts: all

  vars_files:
    - secret

  tasks:
    - name: Do something as sudo
      service: name=nginx state=restarted
      sudo: yes

여기에 secretsudo 비밀번호를 포함하는 파일 이 포함되어 있습니다.

ansible-vault를 사용하여이 파일의 암호화 된 버전을 만듭니다.

ansible-vault create secret

암호를 묻는 메시지가 표시되면 기본 편집기를 열어 파일을 편집하십시오. 당신은 ansible_sudo_pass여기에 넣을 수 있습니다.

예 : secret:

ansible_sudo_pass: mysudopassword

저장하고 종료합니다. 이제 secretPlaybook을 실행할 때 Ansible에서 해독 할 수 있는 암호화 된 파일이 있습니다. 참고 : 파일을 사용하여 파일을 편집 할 수 있습니다 ansible-vault edit secret( 파일을 만들 때 사용한 암호를 입력하십시오)

퍼즐의 마지막 부분은 파일 --vault-password-file을 해독하는 데 사용할 Ansible을 제공 하는 것입니다 secret.

라는 파일을 작성하고 파일을 vault.txt작성할 때 사용한 비밀번호를 입력 secret하십시오. 비밀번호는 파일에서 한 줄로 저장된 문자열이어야합니다.

Ansible Docs에서 :

.. 다른 사용자가 키에 액세스 할 수없고 소스 제어에 키를 추가하지 않도록 파일에 대한 권한을 확보하십시오.

마지막으로 다음과 같은 방법으로 플레이 북을 실행할 수 있습니다.

ansible-playbook playbook.yml -u someuser -i hosts --sudo --vault-password-file=vault.txt 

위의 디렉토리 레이아웃은 다음과 같습니다.

.
|_ playbook.yml
|_ secret
|_ hosts
|_ vault.txt

Ansible Vault에 대한 자세한 내용은 https://docs.ansible.com/playbooks_vault.html을 참조 하십시오.


5
참고 : ansible 1.9로, 당신이 더 이상 ansible_sudo_pass (또는 ansible_become_pass) 변수를 사용할 수 없음을 나타납니다 : "치명적인 : [...] =>가 암호를 누락"
toast38coza

6
이 솔루션을 프로덕션 환경에서 사용하고 있는데, jenkins는 볼트 암호를 난독 화 된 환경 변수로 저장하고 런타임시 임시 파일에 기록한 후 ansible을 호출합니다.
simone cittadini

6
또는 더 간단하게 : 거기에 ansible-vault create group_vars/all/ansible.yml추가하십시오 ansible_sudo_pass: yourpassword. 변경 플레이 북 또는 재고 할 필요가 없습니다
Bouke Versteegh

1
이것을 시도했지만이 오류가 발생했습니다 :fatal: [localhost]: FAILED! => {"changed": false, "failed": true, "module_stderr": "sudo: a password is required\n", "module_stdout": "", "msg": "MODULE FAILURE", "parsed": false}
JohnnyQ

8
볼트 바로 옆에 일반 텍스트로 볼트를 저장하면 볼트의 장점은 무엇입니까?
Erik

44

코드 ( runner/__init__.py)를 보면 인벤토리 파일에서 코드를 설정할 수 있다고 생각합니다.

[whatever]
some-host ansible_sudo_pass='foobar'

ansible.cfg구성 파일에도 일부 조항이 있지만 현재 구현되지 않았습니다 ( constants.py).


7
이것을 안전하게 구성하는 좋은 방법은 이것을 host_varsor group_vars디렉토리 에 저장 한 다음 ansible-vault
Kyle

44

ansible을 사용하면 원하는대로 플래그에 암호를 지정할 수 있다고 생각하지 않습니다. 설정에 어딘가에있을 수 있지만 설정하면 전반적으로 보안 성이 떨어 지므로 권장하지 않습니다.

대상 시스템에서 사용자를 작성하고 모든 명령 또는 제한된 명령 목록에 비밀번호없는 sudo 권한을 부여하는 것이 가능합니다.

다음 sudo visudo과 같은 줄 을 실행 하고 입력하면 'privilegedUser'사용자는 다음과 같이 실행할 때 비밀번호를 입력하지 않아도됩니다 sudo service xxxx start.

%privilegedUser ALL= NOPASSWD: /usr/bin/service

7
@bschlueter 그래서 나쁜 연습을지지하고 있습니까?
stephen

1
나는 이것이 좋은 생각이라고 생각하지 않습니다. --ask-sudo-pass를 사용하는 것이 좋습니다.
kgpdeveloper

@ simone cittadini 나는 그것이 내가 줄 것이라고 대답 한 것에 완전히 동의합니다. 이것은 보안 위험입니다.
einarc

암호가없는 sudo를 사용하여 준비 / 제품에 배포하지만이 답변을 사용하여 매일 15 분마다 로컬 호스트에 배포 할 때 로컬 랩톱 로그인 암호를 입력하지 않아도되는 경우 보안 위험이 줄어 듭니다.
Jonathan Hartley

Ansible을 사용하여이 줄을 어떻게 추가합니까?
Matthias

21

sudo는 암호 라는 변수로 저장됩니다 ansible_sudo_pass. 이 변수를 몇 가지 방법으로 설정할 수 있습니다.

호스트 당 인벤토리 호스트 파일 ( inventory/<inventoryname>/hosts)

[server]
10.0.0.0 ansible_sudo_pass=foobar

인벤토리 그룹 파일에서 그룹 별 ( inventory/<inventoryname>/groups)

[server:vars]
ansible_sudo_pass=foobar

그룹 별, 그룹 변수 ( group_vars/<groupname>/ansible.yml)

ansible_sudo_pass: "foobar"

그룹당 암호화 ( ansible-vault create group_vars/<groupname>/ansible.yml)

ansible_sudo_pass: "foobar"

18

그룹 또는 모든 서버의 비밀번호를 한 번에 설정할 수 있습니다.

[all:vars]
ansible_sudo_pass=default_sudo_password_for_all_hosts

[group1:vars]
ansible_sudo_pass=default_sudo_password_for_group1

14

나는이 머리카락 위로 머리카락을 찢고 있었고, 이제 내가 원하는 것을하는 해결책을 찾았습니다.

sudo 비밀번호를 포함하는 호스트 당 1 개의 암호화 된 파일

/ etc / ansible / hosts :

[all:vars]
ansible_ssh_connection=ssh ansible_ssh_user=myuser ansible_ssh_private_key_file=~/.ssh/id_rsa

[some_service_group]
node-0
node-1

그런 다음 각 호스트에 대해 다음과 같이 암호화 된 var 파일을 만듭니다.

ansible-vault create /etc/ansible/host_vars/node-0

내용으로

ansible_sudo_pass: "my_sudo_pass_for_host_node-0"

볼트 암호를 구성하는 방법 (--ask-vault-pass를 통해 입력) 또는 cfg에 의한 방법은 귀하에게 달려 있습니다

이를 기반으로 전체 호스트 파일을 암호화 할 수 있다고 생각합니다 ...


Vault를 사용하여 암호화하는 것이 나에게 가장 의미가 있지만 ansible-playback. 나는 전화로 -e @vault/filename.ext볼트를 사용해야했습니다 ansible-playbook.
Alex

9

이 작업을 수행하는 더 정통한 방법은 sudo비밀번호를 LastPass 또는 KeePass 와 같은 안전한 저장소에 저장 한 다음이를 ansible-playbook사용하여 전달 -e@하지만 실제 파일의 내용을 하드 코딩하는 대신 구문 -e@<(...)을 사용하여 명령을 실행할 수 있습니다 . 서브 쉘을 만들고, 출력 (STDOUT)을 익명 파일 디스크립터로 경로 재지 정하여 효과적으로 암호를에 제공하십시오 -e@<(..).

$ ansible-playbook -i /tmp/hosts pb.yml \
   -e@<(echo "ansible_sudo_pass: $(lpass show folder1/item1 --password)")

위는 몇 가지 일을하고 있습니다.

  • ansible-playbook -i /tmp/hosts pb.yml -명백한 플레이 북을 통해 플레이 북을 분명히 실행
  • $(lpass show folder1/item1 --password)"-LastPass CLI를 실행하고 lpass사용할 비밀번호를 검색합니다
  • echo "ansible_sudo_pass: ...password..." -문자열 'ansible_sudo_pass :'를 가져 와서 제공 한 비밀번호와 결합합니다. lpass
  • -e@<(..)-위의 내용을 정리하고 서브 쉘을 <(...)파일 설명 자로 연결하여 ansible-playbook사용합니다.

추가 개선

매번 입력하지 않으려면 단순히 그렇게 할 수 있습니다. 먼저 다음 .bashrc과 같이 별칭을 만드십시오 .

$ cat ~/.bashrc
alias asp='echo "ansible_sudo_pass: $(lpass show folder1/item1 --password)"'

이제 다음과 같이 플레이 북을 실행할 수 있습니다.

$ ansible-playbook -i /tmp/hosts pb.yml -e@<(asp)

참고 문헌


1
서브 쉘을 사용하는 것은 매우 현명한 아이디어입니다! 궁금한 분들을 위해 1Password의 CLI를 사용하여 다음과 같이 표시합니다.--extra-vars @<(echo ansible_become_pass: $(op get item <item name> | jq --raw-output '.details.sections[0].fields[] | select(.t=="password").v'))
Diti

1
나는 바흐 기록을 확인할 때 암호가 일반 텍스트로 노출되지 않았기 때문에 이것을 좋아합니다. 시스템 감사가 활성화 된 경우 명령이 파일을 읽는 것으로 기록됩니다. 예를 들어 /dev/fd/63임시 파일 디스크립터에있는 비밀번호로 인해 명령이 공개되지 않습니다.
JPvRiel


5

다음과 같이 호스트 파일에 플레이 북에 대한 sudo 비밀번호를 쓸 수 있습니다.

[host-group-name]
host-name:port ansible_sudo_pass='*your-sudo-password*'

5

여기에서 Ansible Vault가 두 번 제안되었지만 내 플레이 북에서 중요한 파일을 암호화하기 위해 git-crypt를 선호합니다. 사용 가능한 플레이 북을 유지하기 위해 git을 사용하고 있다면 간단합니다. 필자가 보관소에서 발견 한 문제는 필자가 작업하려는 파일의 암호화 된 사본을 필연적으로 끝내고 작업을 시작하기 전에 해독해야한다는 것입니다. git-crypt더 나은 워크 플로우 IMO를 제공합니다.

이를 사용하여 플레이 북의 var에 비밀번호를 입력하고 다음과 같이 플레이 북을 암호화 된 파일로 표시 할 수 있습니다 .gitattributes.

 my_playbook.yml filter=git-crypt diff=git-crypt

플레이 북은 Github에서 투명하게 암호화됩니다. 그런 다음 ansible을 실행하는 데 사용하는 호스트에 암호화 키를 설치하거나 설명서의 지침에 따라로 설정하십시오 gpg.

전달에 좋은 Q & A 있어요 gpg당신처럼 키 ssh-agent: 앞으로 여기에 키를 SSH를 /superuser/161973/how-can-i-forward-a-gpg-key-via-ssh-agent .


3

sshpass아래와 같이 유틸리티를 사용할 수 있습니다 .

$ sshpass -p "your pass" ansible pattern -m module -a args \
   -i inventory --ask-sudo-pass

3

2.4.1.0을 사용 하면 다음이 작동합니다.

[all]
17.26.131.10
17.26.131.11
17.26.131.12
17.26.131.13
17.26.131.14

[all:vars]
ansible_connection=ssh
ansible_user=per
ansible_ssh_pass=per
ansible_sudo_pass=per

이 인벤토리로 다음과 같이 플레이 북 을 실행하십시오 .

ansible-playbook -i inventory copyTest.yml

3

이것을 자동화하는 내 해킹은 환경 변수를 사용하고를 통해 액세스하는 것이 었습니다 --extra-vars="ansible_become_pass='{{ lookup('env', 'ANSIBLE_BECOME_PASS') }}'".

env var를 내보내 지지만 bash / shell 히스토리는 피하십시오 (공백 또는 기타 메소드 앞에 추가). 예 :

     export ANSIBLE_BECOME_PASS='<your password>'

추가 ansible_become_pass변수를에 전달하는 동안 env var를 조회하십시오 ( ansible-playbook예 :

ansible-playbook playbook.yml -i inventories/dev/hosts.yml -u user --extra-vars="ansible_become_pass='{{ lookup('env', 'ANSIBLE_BECOME_PASS') }}'"

좋은 대체 답변 :


2

암호를 암호화 된 저장소에 코딩 하는 안전한 저장소 를 사용할 수 있습니다 . 그런 다음 플레이 북에서 볼트의 변수를 사용할 수 있습니다.

Ansible Vault에 대한 일부 문서 :
http://docs.ansible.com/playbooks_vault.html

우리는이를 환경 당 저장소로 사용하고 있습니다. 볼트를 편집하려면 다음과 같은 명령이 있습니다.
ansible-vault edit inventories/production/group_vars/all/vault

볼트 변수를 호출하려면 다음과 같은 매개 변수와 함께 플레이 북을 사용해야합니다.
ansible-playbook -s --vault-password-file=~/.ansible_vault.password

예, 우리는 볼트 텍스트를 로컬 디렉토리에 일반 텍스트로 저장하고 있지만 모든 시스템의 루트 암호를 저장하는 것만 큼 위험하지는 않습니다. 루트 암호는 볼트 파일 내에 있거나 사용자 / 그룹의 sudoers 파일과 같이 가질 수 있습니다.

서버에서 sudoers 파일을 사용하는 것이 좋습니다. 다음은 그룹 관리자의 예입니다.
%admin ALL=(ALL) NOPASSWD:ALL



1

5 년이 지난 지금도 여전히 관련성이 높은 주제입니다. 어쨌든 도구를 사용하여 중앙 집중식 인증, 토큰 등을 사용하지 않는 경우가 가장 좋았습니다. 이것은 모든 서버에서 동일한 사용자 이름과 동일한 공개 키를 가지고 있다고 가정합니다. 그렇지 않은 경우, 더 구체적이어야하고 호스트 옆에 해당 변수를 추가해야합니다.

[all:vars]
ansible_ssh_user=ansible
ansible_ssh_private_key_file=home/user/.ssh/mykey
[group]
192.168.0.50 ansible_sudo_pass='{{ myserver_sudo }}'

ansible-vault create mypasswd.yml
ansible-vault edit mypasswd.yml

더하다:

myserver_sudo: mysecretpassword

그때:

ansible-playbook -i inv.ini my_role.yml --ask-vault --extra-vars '@passwd.yml'

적어도이 방법으로 암호를 가리키는 변수를 더 많이 쓸 필요는 없습니다.


1

@ toast38coza의 위 솔루션은 저에게 효과적이었습니다. 그 sudo : 예 는 Ansible에서 더 이상 사용되지 않습니다. 사용 하게 하고 become_user 대신.

tasks:
 - name: Restart apache service
   service: name=apache2 state=restarted
   become: yes
   become_user: root

0

또한 EXPECT BLOCK을 사용하여 bash를 생성하고 필요에 따라 사용자 정의 할 수 있습니다.

- name: Run expect to INSTALL TA
  shell: |
    set timeout 100
    spawn /bin/sh -i

    expect -re "$ "
    send "sudo yum remove -y xyz\n"

    expect "$ "
    send "sudo yum localinstall -y {{ rpm_remotehost_path_for_xyz }}\n"

    expect "~]$ "
    send "\n"

    exit 0
  args:
  executable: /usr/bin/expect

0

매우 간단하며 변수 파일에만 추가하십시오.

예:

$ vim group_vars/all

그리고 이것을 추가하십시오 :

Ansible_connection: ssh
Ansible_ssh_user: rafael
Ansible_ssh_pass: password123
Ansible_become_pass: password123

고맙지 만 Ansible_become_pass 대신 ansible_become_pass를 의미한다고 생각합니다.
Krishnom

0

부록에 불과하므로 최근에 내가 한 성가신 사람은 없습니다.

AFAIK, 최고의 솔루션은 위의 toast38coza의 일반적인 라인을 따르는 솔루션입니다. 암호 파일과 플레이 북을 정적으로 묶는 것이 합리적이라면 vars_files(또는 include_vars)로 템플릿을 따릅니다 . 별도로 보관하려면 다음과 같이 명령 행에 저장소 내용을 제공하십시오.

ansible-playbook --ask-vault-pass -e@<PATH_TO_VAULT_FILE> <PLAYBOOK_FILE>

돌이켜 보면 분명하지만 다음과 같은 문제점이 있습니다.

  1. 그 피 묻은 @ 표시. 그대로두면 구문 분석이 자동으로 실패 하며 처음에는 파일을 지정하지 않은 것처럼 플레이 북이 진행됩니다.

  2. 명령 줄 --extra-vars / -e 또는 YAML 코드 내에서 볼트의 내용을 명시 적으로 가져와야합니다. --ask-vault-pass플래그 (또는 그 이후 사용되지 않을 수있는 값에 대한 프롬프트 외에 당신이) 그 자체로 아무것도하지 않습니다.

"@"를 포함 시켜서 한 시간을 절약하십시오.


-3

이것은 나를 위해 일했다 ... NOPASSWD로 파일 /etc/sudoers.d/90-init-users 파일을 생성

echo "user ALL=(ALL)       NOPASSWD:ALL" > 90-init-users

여기서 "user"는 사용자 ID입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.