Docker Remote APIのためにnginxでSSLクライアント認証


Docker Remote API

HTTP経由でDockerを利用できるようにするAPIです。
そもそもDockerのコマンドはこれを利用して動いてるみたいです。

思いつきだけでこれを外部から使えるようにします。
ただし、管理者権限で動作してるので安全に気を配る必要があります。

SSL クライアント認証

というわけでセキュリティ面を担保するのにSSLのクライアント認証を利用して行きます。
証明書を持っていないクライアントからの接続は出来なくなるので安心!

環境

Ubuntu 14.04.2 LTS
Docker 1.6.2
nginx 1.8.0

手順

概要

  • (各種インストール)
  • CA証明/サーバー認証鍵/クライアント認証鍵の生成
  • nginxの設定
  • グループ設定(要らないかも?)

認証鍵・証明書の作成


# openssl コマンドきっとこんな感じ
# genrsa: 秘密鍵の生成
# req -x509: 自己証明書の生成(?)
# req -key: 証明要求の生成
# x509: CAを使い証明書を生成

# 証明書を生成するさいの入力項目で要求されるCommon NameはFQDNの入力が必要です。
# ここで違うと最終的に認証エラーになってしまうので注意

# CAの証明書を作ります(鍵→証明書)
openssl genrsa -aes256 -out ca.key 4096
openssl req -new -x509 -days 3650 -key ca.key -out ca.crt

# サーバーの鍵・証明書を作ります
# またサーバーの鍵はパスフレーズを解除しておきます(nginxで読み込むたびに入力する手間を省くために)
openssl genrsa -aes256 -out server.key 4096
openssl rsa -in server.key -out server_nopass.key
openssl req -new -key server_nopass.key -out server.csr
openssl x509 -req -days 3650 -in server.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out servre.crt

# クライアントの鍵・証明書を作ります
# サーバーの証明書とは別のシリアルを割り当てます(同じだとだめなようです)
# また、クライアント側の証明書にCAの証明書を含めます
openssl genrsa -aes256 -out client.key 4096
openssl req -new -key client.key -out client.csr
openssl x509 -req -days 3650 -in client.csr -CA ca.crt -CAkey ca.key -set_serial 02 -out client.crt
cat client.key client.crt ca.crt | openssl pkcs12 -export -clcerts -out client_bundle.p12

nginx 設定ファイルの編集


upstream docker_api {
  server unix:/var/run/docker.sock;
}

server {

  # SSL接続なのでPort:443 のSSL指定
  listen 443 ssl;
  ssl on;

  # サーバー側の鍵と証明書を設定
  ssl_certificate server.crt;
  ssl_certificate_key server.key;

  # クライアント認証の設定
  ssl_client_certificate ca.crt;
  ssl_verify_client on;
  ssl_verify_depth 2; # よくわかってない

  location / {
    proxy_pass http://docker_api;
  }
}

nginxユーザーをdockerグループに追加


gpasswd -a nginx docker