【翻訳記事】Protect the Docker daemon socket

# はじめに

このページは、[Protect the Docker daemon socket | Docker Documentation](https://docs.docker.com/engine/security/https/)　(閲覧 : 2018/08/16 20:00) の翻訳記事です。

##  Protect the Docker daemon socket

> By default, Docker runs via a non-networked Unix socket. It can also optionally communicate using an HTTP socket.
> 
> If you need Docker to be reachable via the network in a safe manner, you can enable TLS by specifying the `tlsverify` flag and pointing Docker’s `tlscacert` flag to a trusted CA certificate.
> 
> In the daemon mode, it only allows connections from clients authenticated by a certificate signed by that CA. In the client mode, it only connects to servers with a certificate signed by that CA.

デフォルトでは、Dockerはネットワーク化されていないUnixソケットを通して実行されます。若しくはHTTPソケットを通して実行することも出来ます。もしDockerをネットワーク経由で安全に接続したければ、`tlsverify`フラグを指定し、Dockerの`tlscacert`フラグを信頼できるCA証明書に指定することでTLSを有効にできます。デーモンモードでは、CAによって署名された証明書で認証されたクライアントからの接続のみが許可されます。 クライアントモードでは、CAによって署名された証明書を使用してサーバーに接続するだけです。

---

### Create a CA, server and client keys with OpenSSL

> > Note: replace all instances of `$HOST` in the following example with the DNS name of your Docker daemon’s host.

注意：以下の記述で`$HOST`となっている部分はあなた自身のDocker daemonのホスト名に置き換えてください！

---

> First, on the **Docker daemon’s host machine**, generate CA private and public keys:

まずはじめに、Docker daemonがあるホストマシン上でCA(Certification Authority)の秘密鍵と公開鍵を生成します。

> ```bash:bash
$ openssl genrsa -aes256 -out ca-key.pem 4096
Generating RSA private key, 4096 bit long modulus
............................................................................................................................................................................................++
........++
e is 65537 (0x10001)
Enter pass phrase for ca-key.pem:
Verifying - Enter pass phrase for ca-key.pem:

> $ openssl req -new -x509 -days 365 -key ca-key.pem -sha256 -out ca.pem
Enter pass phrase for ca-key.pem:
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:
State or Province Name (full name) [Some-State]:Queensland
Locality Name (eg, city) []:Brisbane
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Docker Inc
Organizational Unit Name (eg, section) []:Sales
Common Name (e.g. server FQDN or YOUR name) []:$HOST
Email Address []:Sven@home.org.au
> ```

---

> Now that you have a CA, you can create a server key and certificate signing request (CSR). Make sure that “`Common Name`” matches the hostname you use to connect to Docker:

> ```bash:bash
$ openssl genrsa -out server-key.pem 4096
Generating RSA private key, 4096 bit long modulus
.....................................................................++
.................................................................................................++
e is 65537 (0x10001)
--- 
$ openssl req -subj "/CN=$HOST" -sha256 -new -key server-key.pem -out server.csr
```

CAがあれば、サーバーキーと証明書署名要求（CSR）を作成できます。 「`Common Name`」がDockerへの接続に使用するホスト名と一致することを確認しましょう。
　
> Next, we’re going to sign the public key with our CA:
> 
> Since TLS connections can be made via IP address as well as DNS name, the IP addresses need to be specified when creating the certificate. For example, to allow connections using `10.10.10.20` and `127.0.0.1`:
>
> ```bash
$ echo subjectAltName = DNS:$HOST,IP:10.10.10.20,IP:127.0.0.1 >> extfile.cnf
```

次に、CAで公開鍵に署名します。TLS接続はDNS名と同じようにIPアドレスを通してつなぐことができるため、証明書を作成するときにIPアドレスを指定する必要があります。 たとえば、`10.10.10.20` と `127.0.0.1`を使用して接続を許可するには、上記のようにします;

---

> Set the Docker daemon key’s extended usage attributes to be used only for server authentication:

> ```bash
$ echo extendedKeyUsage = serverAuth >> extfile.cnf
```


Dockerデーモン・キーの拡張使用属性がサーバー認証にのみ使用されるように設定しましょう。

---

> Now, generate the signed certificate:

> ```bash
$ openssl x509 -req -days 365 -sha256 -in server.csr -CA ca.pem -CAkey ca-key.pem \
  -CAcreateserial -out server-cert.pem -extfile extfile.cnf
> 
> Signature ok
subject=/CN=your.host.com
Getting CA Private Key
Enter pass phrase for ca-key.pem:
```

そうしたら、署名された証明書を生成しましょう。

> [Authorization plugins](https://docs.docker.com/engine/extend/plugins_authorization/) offer more fine-grained control to supplement authentication from mutual TLS. In addition to other information described in the above document, authorization plugins running on a Docker daemon receive the certificate information for connecting Docker clients.

[認証プラグイン](https://docs.docker.com/engine/extend/plugins_authorization/)は、相互TLSからの認証を補完するために、よりきめ細かな制御を提供します。 上記のドキュメントに記載されている他の情報に加えて、Dockerデーモン上で動作する認証プラグインは、Dockerクライアントを接続するための証明書情報を受け取ります。

> For client authentication, create a client key and certificate signing request:

> > Note: for simplicity of the next couple of steps, you may perform this step on the Docker daemon’s host machine as well.

> ```bash
> $ openssl genrsa -out key.pem 4096
Generating RSA private key, 4096 bit long modulus
.........................................................++
................++
e is 65537 (0x10001)
> 
> $ openssl req -subj '/CN=client' -new -key key.pem -out client.csr
```

クライアント認証の場合は、クライアント鍵と証明書署名リクエストを作成します。（注：次のステップを簡単にするために、Dockerデーモンのホストマシンでもこの手順を実行することができます）

> To make the key suitable for client authentication, create an extensions config file:

> ```bash
$ echo extendedKeyUsage = clientAuth >> extfile.cnf
```

クライアント認証に適切な鍵を作成するには、拡張設定ファイルを作成します。

> Now, generate the signed certificate:

> ```bash
$ openssl x509 -req -days 365 -sha256 -in client.csr -CA ca.pem -CAkey ca-key.pem \
  -CAcreateserial -out cert.pem -extfile extfile.cnf

> Signature ok
subject=/CN=client
Getting CA Private Key
Enter pass phrase for ca-key.pem:
```

そうしたら、署名された証明書を生成しましょう。

> After generating cert.pem and server-cert.pem you can safely remove the two certificate signing requests:

> ```bash
$ rm -v client.csr server.csr
```

cert.pemとserver-cert.pemを生成すると、2つの証明書署名リクエストを安全に削除できます。

> With a default `umask` of 022, your secret keys are world-readable and writable for you and your group.

> To protect your keys from accidental damage, remove their write permissions. To make them only readable by you, change file modes as follows:

> ```bash
$ chmod -v 0400 ca-key.pem key.pem server-key.pem
```

デフォルトの`umask`が022の場合、あなたとあなたのグループの秘密鍵は世界中で読み取りと書き込みが可能です。キーが偶発的な損傷から保護されるように、書き込み権限を削除してください。 それらをあなただけが読めるようにするには、ファイルモードを変更してください。

> Certificates can be world-readable, but you might want to remove write access to prevent accidental damage:

> ```bash
$ chmod -v 0444 ca.pem server-cert.pem cert.pem
```

証明書は世界共通ですが、偶発的な被害を防ぐために書込みアクセスを削除したい場合があります。

> Now you can make the Docker daemon only accept connections from clients providing a certificate trusted by your CA:

> ```bash
$ dockerd --tlsverify --tlscacert=ca.pem --tlscert=server-cert.pem --tlskey=server-key.pem \
 -H=0.0.0.0:2376
```

Dockerデーモンは、CAから信頼された証明書を提供するクライアントからの接続のみを受け入れることができます。

> To connect to Docker and validate its certificate, provide your client keys, certificates and trusted CA:
> >  Run it on the client machine
> > This step should be run on your Docker client machine. As such, you need to copy your CA certificate, your server certificate, and your client certificate to that machine.
> 
> > Note: replace all instances of `$HOST` in the following example with the DNS name of your Docker daemon’s host.

> ```bash
$ docker --tlsverify --tlscacert=ca.pem --tlscert=cert.pem --tlskey=key.pem \
  -H=$HOST:2376 version
```

Dockerに接続してその証明書を検証するには、クライアント鍵、証明書、および信頼できるCAを提供してください。（※Dockerクライアント側で実行してください。この手順は、Dockerクライアントマシンで実行する必要があります。 そのため、CA証明書、サーバー証明書、およびクライアント証明書をそのマシンにコピーする必要があります。

（注意：`$HOST`となっている部分はあなた自身のDocker daemonの**DNS名**に置き換えてください！）

> > Note: Docker over TLS should run on TCP port 2376.

実行時のポート番号は2376が推奨されています。

> > ❗ **Warning** ❗ : As shown in the example above, you don’t need to run the docker client with `sudo` or the docker group when you use certificate authentication. That means anyone with the keys can give any instructions to your Docker daemon, giving them root access to the machine hosting the daemon. Guard these keys as you would a `root` password!

上記の例に示すように、証明書認証を使用する場合は、Docker clientをsudoまたはDockerグループで実行する必要はありません。 これは、キーを持つ誰もがDockerデーモンに指示を与えることができ、デーモンをホストしているマシンにrootアクセスできることを意味します。 rootのパスワードと同じように、これらのキーを守ってください！

---

### Secure by default

> If you want to secure your Docker client connections by default, you can move the files to the `.docker` directory in your home directory -- and set the `DOCKER_HOST` and `DOCKER_TLS_VERIFY` variables as well (instead of passing `-H=tcp://$HOST:2376` and `--tlsverify` on every call).

> ```bash
$ mkdir -pv ~/.docker
$ cp -v {ca,cert,key}.pem ~/.docker
>
$ export DOCKER_HOST=tcp://$HOST:2376 DOCKER_TLS_VERIFY=1
```

デフォルトでDockerクライアント接続をSecureにしたい場合は、

１．ホームディレクトリ直下に.dockerディレクトリを作成
２．`.docker`ディレクトリへ `ca.pem`, `cert.pem`, `key.pem` を移動
３．DOCKER_HOSTとDOCKER_TLS_VERIFY変数を設定

上記３つのステップを遂行しましょう。
（オプション引数として `-H=tcp://$HOST:2376` や `--tlsverify`を渡す代わりになります）

> Docker now connects securely by default:

> ```bash
$ docker ps   # Confirm Docker process
```

これでようやく、DockerはデフォルトでSecureに接続出来たことになります。

---

### Other modes

> If you don’t want to have complete two-way authentication, you can run Docker in various other modes by mixing the flags.

完全な双方向認証を必要としない場合は、Dockerをフラグを混在させてさまざまなモードで実行できます。

#### Daemon modes

- `tlsverify`, `tlscacert`, `tlscert`, `tlskey` set: Authenticate clients
- `tls`, `tlscert`, `tlskey`: Do not authenticate clients

> ※デーモンモードでは、CAによって署名された証明書で認証されたクライアントからの接続のみが許可されます。

#### Client modes

- `tls`: Authenticate server based on public/default CA pool
    - 公開/既定のCA poolに基づいてサーバーを認証する
- `tlsverify`, `tlscacert`: Authenticate server based on given CA
    - 指定されたCAに基づいてサーバーを認証する
- `tls`, `tlscert`, `tlskey`: Authenticate with client certificate, do not authenticate server based on given CA
    - クライアント証明書で認証するが、指定されたCAに基づいてサーバーを認証しない
- `tlsverify`, `tlscacert`, `tlscert`, `tlskey`: Authenticate with client certificate and authenticate server based on given CA
    - 指定されたCAに基づいてクライアント証明書で認証し、サーバを認証する

> ※クライアントモードでは、CAによって署名された証明書を使用したサーバーへの接続のみ行なえます。

---

> If found, the client sends its client certificate, so you just need to drop your keys into `~/.docker/{ca,cert,key}.pem`. Alternatively, if you want to store your keys in another location, you can specify that location using the environment variable `DOCKER_CERT_PATH`.

> ```bash
$ export DOCKER_CERT_PATH=~/.docker/zone1/
$ docker --tlsverify ps
```

もしクライアント証明書が見つかった場合、クライアントはそれを送信するので、あなたは `〜/ .docker / {ca、cert、key} .pem`にkey(s)を移動させるだけです。 あるいは、別の場所にキーを格納したい場合は、環境変数 `DOCKER_CERT_PATH`を使ってその場所を指定することができます。

---

### Connecting to the secure Docker port using `curl`

> To use curl to make test API requests, you need to use three extra command line flags:

> ```bash
$ curl https://$HOST:2376/images/json \
  --cert ~/.docker/cert.pem \
  --key ~/.docker/key.pem \
  --cacert ~/.docker/ca.pem
```

`curl`を使用してテストAPIリクエストを行うには、3つほど追加してコマンドラインフラグを使用する必要があります

---

### Related information

- [Using certificates for repository client verification](https://docs.docker.com/engine/security/certificates/)
    - リポジトリにおけるクライアントの検証に証明書を使用する場合の説明
- [Use trusted images](https://docs.docker.com/engine/security/trust/)
    - 信頼性の高いDocker Imagesをつかう方法の説明