Ansible 1.5.3とGitをsshエージェント転送で使用しています( https://help.github.com/articles/using-ssh-agent-forwarding )。 Ansibleで管理しているサーバーにログインし、gitへの接続が正しく構成されていることをテストできます。
ubuntu@test:~$ ssh -T [email protected]
Hi gituser! You've successfully authenticated, but GitHub does not provide Shell access.
また、このアカウントを使用してリポジトリの1つを複製および更新して、git設定が適切に見えるようにし、sshを介してサーバーに直接ログインするときにssh転送を使用することもできます。
問題:Ansibleコマンドモジュールを使用して上記と同じテストを試みると。 「Permission denied」で失敗します。 Ansible出力の一部(詳細なログ記録を含む)は次のようになります。
failed: [xxx.xxxxx.com] => {"changed": true, "cmd": ["ssh", "-T", "[email protected]"], "delta": "0:00:00.585481", "end": "2014-06-09 14:11:37.410907", "rc": 255, "start": "2014-06-09 14:11:36.825426"}
stderr: Permission denied (publickey).
このコマンドを実行する簡単なプレイブックを次に示します。
- hosts: webservers
Sudo: yes
remote_user: ubuntu
tasks:
- name: Test that git ssh connection is working.
command: ssh -T [email protected]
質問:sshを使用して手動でログインしてコマンドを実行しても、同じコマンドがAnsibleを介して同じユーザーとして実行されると失敗するのはなぜですか?
誰も私にそれをbeatる人がいなければ、私はすぐに答えを投稿します。私はgitを使用して問題を実証していますが、sshエージェントの転送に依存するモジュールで発生する可能性があります。これはAnsibleに固有のものではありませんが、多くの人がこのシナリオで最初に問題に遭遇すると思われます。
この問題は、プレイブックから次の行を削除することで解決されます。
Sudo: yes
リモートホストでSudoを実行すると、ログイン中にsshによって設定された環境変数は使用できなくなります。特に、「エージェントとの通信に使用されるUNIXドメインソケットのパスを識別する」SSH_AUTH_SOCKは表示されないため、sshエージェントの転送は機能しません。
必要のないときにSudoを回避することは、問題を回避する1つの方法です。もう1つの方法は、sudoersファイルを作成して、Sudoセッション中にSSH_AUTH_SOCKが確実に保持されるようにすることです。
/etc/sudoers:
Defaults env_keep += "SSH_AUTH_SOCK"
ここには非常に役立つ部分的な回答がいくつかありますが、この問題に何度か遭遇した後、概要が役立つと思います。
まず、Ansibleを実行しているクライアントからターゲットマシンに接続するときに、SSHエージェント転送が有効になっていることを確認する必要があります。 transport=smart
を使用しても、クライアントのSSH構成によっては、SSHエージェント転送が自動的に有効にならない場合があります。確実にそうするために、~/.ansible.cfg
を更新してこのセクションを含めることができます。
[ssh_connection]
ssh_args=-o ControlMaster=auto -o ControlPersist=60s -o ControlPath=/tmp/ansible-ssh-%h-%p-%r -o ForwardAgent=yes
次に、become: yes
環境変数がリセットされるため、become_user: root
(およびSSH_AUTH_SOCK
)が一般的にエージェント転送を無効にするという事実に対処する必要があります。 (私は Ansibleが想定しているように見える 人々がrootとしてSSHすることは衝撃的だと思う。なぜならそれはどんな有用な監査も不可能にするからだ。) Ansible 2.2以降、最も簡単なアプローチは、-E
フラグを指定してSudo
を使用するときに(全体)環境を保持することです。
become_flags: "-E"
ただし、これはPATH
などの変数を保持することにより、望ましくない副作用を引き起こす可能性があります。最もクリーンな方法は、SSH_AUTH_SOCK
ファイルのenv_keep
に含めることで、/etc/sudoers
のみを保持することです。
Defaults env_keep += "SSH_AUTH_SOCK"
Ansibleでこれを行うには:
- name: enable SSH forwarding for Sudo
lineinfile:
dest: /etc/sudoers
insertafter: '^#?\s*Defaults\s+env_keep\b'
line: 'Defaults env_keep += "SSH_AUTH_SOCK"'
このプレイブックタスクは、他のデフォルトのenv_keep
設定(または、ファイルが見つからない場合はファイルの最後)の後に既存のenv_keep
設定またはSSH_AUTH_SOCK
が既に存在すると仮定しています。
あなたの質問に対する別の答えは(私がAnsible 1.9を使用していることを除いて)次のようになります
/etc/ansible/ansible.cfg(または構成設定をオーバーライドできる他の3つの潜在的な場所)でtransport=smart
推奨通り ansible docsで 。私のデフォルトはtransport=paramiko
前回のインストール試行中のある時点で、コントロールマシンがOpenSSHを使用できなくなり、エージェントが転送できなくなりました。これはおそらく大規模なEdgeのケースですが、誰が知っていますか?あなたかもしれません!
構成に必要とは思いませんでしたが、他のユーザーが-o ForwardAgent=yes
のように同じファイルのssh_args設定に:
[ssh_connection]
ssh_args=-o ForwardAgent=yes
ここでは完全を期すためにのみ言及します。
@ j.freckleの答えを拡張するために、sudoersファイルを変更するための実用的な方法は次のとおりです。
- name: Add ssh agent line to sudoers
lineinfile:
dest: /etc/sudoers
state: present
regexp: SSH_AUTH_SOCK
line: Defaults env_keep += "SSH_AUTH_SOCK"