cfsslとrakeで似たようなCSRをサクッと作る

ずっとSSL証明書面倒くさいなーと思ってたんですよ。まぁ今だと Let' Encrypt とか Heroku もそうだけど無料で自動更新みたいなのはあるにはあるんだけど、伝統的なやつをもうちょっと効率化できないかなとずっと思っていたわけです。1

ありました。

cfsslを知る

cloudflare/cfssl: CFSSL: Cloudflare's PKI and TLS toolkit

本当は openssl + expect ? とか openssl -config <template> ? みたいなことを考えていたんだけど、swiss army knife が見つかっちゃいました。

cfsslの使い方

とっても簡単。

Creating a new CSR &#183; cloudflare/cfssl Wiki

にあるように JSON で

{
  "CN": <CommonName>,
  "key": {
    ...
  },
  "names": [
    {
      "C": "JP",
      ...
    }
  ]
}

のように定義を準備しておいて、

cfssl genkey <json>

てやると

  • パスフレーズなしのprivate key
  • CSR

が JSON で出力されます。

このね、 names に当たる部分て基本的に同じ組織なら同じになっちゃうわけですよ。違うのは CN くらいなわけです。これを openssl で interactive にいくつも作るのは超だるいわけです。これが cfssl ならラクショー、いや、いくつも JSON 作るのもダルいので、そこはあとで工夫します。

cfssljsonでファイルを作る

cfssl の出力はあくまで JSON なんだけど、欲しいのは秘密鍵のファイルと CSR のファイルなわけです。

そこで登場するのは cfssljson です。使い方は上の続きで

cfssl genkey <json> | cfssljson -bare <prefix>

ってやると以下の2つのファイルが生成されます。

  • <prefix>.csr
  • <prefix>-key.pem

そうそう、これが欲しかった。

あとは CSR を出して、戻ってきた cert / intermediate cert と private key をサーバにインストールすればオッケー。

定義をYAMLで書いてrakeで叩く

JSON で定義を書ける、まぁイマドキなわけですが、もっと楽したい。具体的には上の names に当たる部分が共通の SSL 証明書が複数必要、という場合は

YAML で定義を作ってやればアンカーとエイリアスで楽できます

アンカーとエイリアスってのは

Rubyist Magazine - プログラマーのための YAML 入門 (初級編)

こういうやつです。で、例えば Ruby だとこんな感じに

hosts = YAML.load_file(<yaml>)

で定義を取得できるので、この key なんかをもとに

hosts.keys.each {|host|
  desc host
  task host do
    generate_json(host)
    sh "cfssl genkey #{jsonfile} | cfssljson -bare #{prefix(host)}"
  end
}

みたいなことをやってあげると host ごとに private key と csr を作成する rake task がズラッと揃います。(main のレベルで書かない場合は適宜 Rake::DSL を include / extend してください)

こいつをリポジトリに突っ込んであげれば少なくとも CSR 準備作業はきれいに忘れてしまってもオッケーだと思います。

証明書のインストールとかその辺はまた今度

まずはくそ面倒だった openssl + interactive な key / csr 作成とさよならできたのでよしとします。

  1. ACMはメール + Webでacceptの操作が要るので全自動ではないですね 

More