目次

DockerにSSH-AgentをフォワードしてAnsibleを実行する


M1 Mac(Monterey 12.6)で特定バージョンのAnsibleを動かすためのDockerを構築したらSSHで大変に苦労した。

以前にこちらで特定バージョンが稼働するDocker環境を構築したことがあった。以前は作りかけだったが、端末を新調することを機会に整理した結果、思わぬところではまってしまった。

特定versionのAnsibleを実行するためのdocker環境を構築した

何かを入れたタイミングでいろいろな開発環境の依存関係が壊れてしまいansibleが逝ってしまった。これを機にandible専用のDocker

特定のAnsibleが稼働するためのDocker環境

Dockerfile
1
2
3
4
5
FROM alpine:3.9
RUN apk add --no-cache --repository http://dl-cdn.alpinelinux.org/alpine/v3.9/main/ ansible~=2.7.17	

RUN apk --update add --no-cache py3-pip openssh openssh-client	
RUN pip3 install --upgrade pip botocore boto3
docker-compose.yml
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
services:
  ansible-playbook:
    build: .
    entrypoint:
      - ansible-playbook
    volumes:
      - ~/.ssh/:${YOUR_HOME_DIRECTORY}/.ssh/
      - ${SSH_AUTH_SOCK}:/ssh-agent
    environment:
      - SSH_AUTH_SOCK=/ssh-agent
1
docker-compose run --rm ansible-playbook <play-book>

おおよそこのような形となる。(結局、docker-composeである必要がないのはご愛嬌)

ホストマシンではSSHできるのに、Docker環境からSSHできない

AnsibleスクリプトをDockerで実行しようとすると、Playbookの途中でパスワード訊かれることに気がついた。Ansibleの場合、パスワードを正しく打ち込んでも、ループして認証されないため、秘密鍵(鍵認証)の情報をDockerコンテナにフォワードして上げる必要がある。

ところが、この鍵情報がフォワードされているにもかかわらず、DockerからAnsible実行時に認証されないのである。

切り分け

ホストマシンから、(Ansibleで)接続するサーバーにSSHしてみる

1
2
3
$ssh-add ~/.ssh/private.rsa
$ssh user@sever -i ~/.ssh/private.rsa
> OK

Dockerから、SSHしてみる

1
2
3
4
5
6
7
docker exec --rm docker /ash
$ssh-add -l
> xxxxxx

$ssh user@sever -i ~/.ssh/private.rsa
# ~/.ssh/private.rsaのパスワードが聞かれる
# パスワードを打ち込むとログインできる

~/.sshのディレクトリと、~/.ssh/private.rsaのパーミッションの確認

こういう場合、最も問題となりがちなのは、パーミッションである。そこで ~/.sshのディレクトリと、~/.ssh/private.rsaのパーミッションを確認してみる

tree -pguコマンドのホストマシンとDockerコンテナ上の結果は同じであった。

Dockerコンテナ上での再現

コンテナの何かが誤っているかもしれないので、シンプルなUbutuコンテナを構築してSSHできるかを確認する

1
2
3
4
docker run --rm -v ~/.ssh:/root/.ssh -it ubuntu:18.04 /bin/bash
> apt update && apt install -y openssh-client && eval `ssh-agent`
> ssh-add ~/.ssh/private.rsa
> ssh user@sever -i ~/.ssh/private.rsa

結果は・・・ パスワードを聞かれる。つまり、DockerコンテナでSSH-Agentが正しく起動できていないか、パーミッションがやはり間違っている(と考えたところが問題でこれから先かなりの時間悩む羽目になった)

結論

いろいろと切り分けをつづけていった結果、 ssh user@sever -i ~/.ssh/private.rsa -F /dev/null と実行するとパスワード認証されずにSSHできるのに、ssh user@sever -i ~/.ssh/private.rsaと実行するとパスワードの確認が入ることに気がついた。

つまり~/.ssh/configが何かおかしい。SSH時にオプションvを利用して確認していったが、正常時のログとパスワードを聞かれる際のログでエラーやワーニングの差が存在していない。

仕方がないので、sshconfigを1行ずつ消したり書いたり別ファイルを指定していった結果

  • sshconfigのパーミッションを600に
  • IdentitiesOnly yes を削除する

ことで解決した。前者は(ホストマシンであるMacでは)パーミッションがゆるゆるでも動作していたので、見落としていた。後者は若干、理由がわからないが、もしかするとMac側でvirtiofsを一時期ONにしていたことが問題かもしれない)

注:ssh user@sever -i ~/.ssh/private.rsa -F /dev/null -vvvで詳細ログが確認できる