docker上でsshの秘密鍵を使ってsshしたいときのハードル

まず、ContainerImageに埋め込むのは除き、実行時に動的に渡す方法として、以下。

  • volumesでホストのファイルを共有する
  • secretsでホストのファイルを共有する

共有した場合の問題点としてはハードルになる。

  • 共有したファイルパーミッションが755になりsshクライアントでエラーとなる
1
2
3
4
5
6
7
8
Warning: Permanently added 'XXXXXXXXXXXXXXXXXXXXX' (RSA) to the list of known hosts.
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ WARNING: UNPROTECTED PRIVATE KEY FILE! @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
Permissions 0755 for '/root/.ssh/id_rsa' are too open.
It is required that your private key files are NOT accessible by others.
This private key will be ignored.
Load key "/root/.ssh/id_rsa": bad permissions

そして、Immutableであることによるハードルとして、以下がある。

  • UserKnownHostsファイルの追記のための対話型操作
1
Are you sure you want to continue connecting (yes/no)?

docker-composeでsecretsを使って秘密鍵を渡す

versionは3.1以降とする必要がある。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
version: '3.1'
services:
xxxxx:
image: python:3-slim
tty: true
volumes:
- ./entrypoint.sh:/work/entrypoint.sh:ro
working_dir: /work/
entrypoint: ./entrypoint.sh
command: /bin/bash
environment:
PYTHONDONTWRITEBYTECODE: 1
GIT_SSH_COMMAND: 'ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no'
secrets:
- host_ssh_key

secrets:
host_ssh_key:
file: ${SSH_KEY_PATH}

entrypoint.shでコピーしてパーミッションを修正する

secretsによって共有された内容は/run/secrets/でReadOnlyアクセスが可能だが、パーミッションは755のため、sshコマンドでエラーになってしまう。そのため、ENTRYPOINTで、コピーしてパーミッションを設定している。

1
2
3
4
5
6
7
8
9
#!/bin/bash

mkdir -p ~/.ssh
chown -R root:root ~/.ssh
chmod -R 0700 ~/.ssh
cp -ip /run/secrets/host_ssh_key ~/.ssh/id_rsa
chmod -R 0600 ~/.ssh

exec "$@"

GIT_SSH_COMMANDでGitが実行するsshコマンドオプションを設定する

環境変数GIT_SSH_COMMANDはGitが実行するsshコマンドを指定することができる。
UserKnownHostsFile=/dev/nullでKnownHostsファイルを生成しないようにし、StrictHostKeyChecking=noで対話型の要求を抑制する。

docker-composeのsecret対応状況

version: '3'で実行した場合

ERROR: The Compose file ‘.\docker-compose.yml’ is invalid because:
Invalid top-level property “secrets”. Valid top-level sections for this Compose file are: version, services, networks, volumes, and extensions starting with “x-“.

You might be seeing this error because you’re using the wrong Compose file version. Either specify a supported version (e.g “2.2” or “3.3”) and place your service definitions under the services key, or omit the version key and place your service definitions at the root of the file to use version 1.
For more on the Compose file format versions, see https://docs.docker.com/compose/compose-file/

secretsでパーミッションを指定できない

パーミッション指定に対応しているように見えるが、docker-compose version 1.25.4, build 8d51620aでは利用できなかった。

mode: サービスのタスクコンテナーにおいて /run/secrets/ にマウントされるファイルのパーミッション。 8 進数表記。 たとえば 0444 であればすべて読み込み可。 Docker 1.13.1 におけるデフォルトは 0000 でしたが、それ以降では 0444 となりました。 secrets はテンポラリなファイルシステム上にマウントされるため、書き込み可能にはできません。 したがって書き込みビットを設定しても無視されます。 実行ビットは設定できます。

1
2
3
4
5
6
secrets:
- source: host_ssh_key
target: host_ssh_key
uid: '103'
gid: '103'
mode: 0600

実行するとサポート対象外のメッセージ。

1
WARNING: Service "xxxxx" uses secret "host_ssh_key" with uid, gid, or mode. These fields are not supported by this implementation of the Compose file

docker-composeの定義ファイルのバージョン

version '3.8の記述がみられるが、docker-compose version 1.25.4, build 8d51620aでは3.3までしか対応していない。

1
2
ERROR: Version in ".\docker-compose.yml" is unsupported. You might be seeing this error because you're using the wrong Compose file version. Either specify a supported version (e.g "2.2" or "3.3") and place your service definitions under the `services` key, or omit the `version` key and place your service definitions at the root of the file to use version 1.
For more on the Compose file format versions, see https://docs.docker.com/compose/compose-file/