はじめに
初めまして!MIS.W53代プログラミング研究会のTsuzuです。 先日サークル内でプロ研発表会がありました。 その際、私はmodokiという自作PaaSを発表したのですが、それを製作する中で得た知見の一部を共有させていただこうと思い、この記事を書くに至りました。
最近Let's Encryptはワイルドカード証明書の取得に対応しました。1
普通Let's Encryptで証明書を取得する際にはcertbot
を利用しますが、Traefikを使う事で更新も自動化でき、複数のWebサイトを運用するのも楽にできるので紹介したいと思います。
必要なもの
用語解説
Let's Encrypt
普段Webブラウザを使っていると左上が緑色になっていたり、保護された通信と表示されているのを見かける事があると思います。それは(認証された証明書を利用して)HTTPSを使っているという意味です。HTTPSを利用すると通信が暗号化され、他人に傍受される事が無くなります。また、Google Chromeは2018年7月までにHTTPを利用しているサイトを「安全でないサイト」と警告するようにすると表明しています。2
HTTPSを利用するためには証明書というものを取得する必要があります。証明書の取得には本来年間数万円が必要です。しかし、Let's Encryptを利用するとタダで証明書を取得する事ができます。
Traefik
Go言語で書かれている多機能リバースプロキシ&ロードバランサです。モダンなnginxです、めっちゃ強いです。HTTP/2、gRPC等にも対応しています。また、キーバリューストアに設定を保存しておき、(一部を除き)再起動する事なく設定をロードする事ができます。
Cloudflare
タダでも使えるいい感じのCDNです。最近1.1.1.1というDNSの運用を始めたと話題にもなりました。とても便利ですが今回はCDNとして利用するわけではないため詳しい説明は割愛します。
(今回はドメインのネームサーバをCloudflareに設定し、CloudflareのAPIを利用してTXTレコードを更新する事でLet's EncryptのDNS Challengeを行うために利用します。)
なぜCloudflareが必要か
Let's Encryptでは、ドメインが申請者のものであることを確認するための方法として、HTTPチャレンジ、SNIチャレンジ、DNSチャレンジの三種類の方法を用意されています。ですが、ワイルドカード証明書の取得には現状DNSチャレンジしか対応していません。 3
DNSチャレンジを利用するためにはドメインのTXTレコードを設定する必要がありますがこれを証明書更新のたびに手動でやるのは面倒です。そこでCloudflareのAPI経由で更新することで自動で行おうというわけです。(certbot
ではcertbot-dns-cloudflare
というプラグインを利用して実現できます。4)
手順
Cloudflareの設定をする
- https://cloudflare.comにアクセスしてアカウントを作成。
- Cloudflareに自身のドメインを登録する。
上の2つは他の記事等でも紹介されているため割愛します。
比較的新しめで画像があるところとかがわかりやすくていいと思います。(こことか。「SSLの設定を変える」の前までやればOKです。)
- Cloudflareの右上の人型のマークのボタンをクリックし、My Profileを開く。
パスワードとreCAPTCHAが求められるので入力してキーを取得し、どこかに控えておく。
Traefikをインストールする。
Traefikはバイナリ単体で動作します。素晴らしいですね。
もちろんバイナリを持ってきて用いても良いですがDockerを使うと気楽でオススメです。
バイナリでインストールする
- https://github.com/containous/traefik/releasesからバイナリをダウンロードする。
$ mv traefik_*-* traefik && chmod +x traefik
(UNIXのみ)$ ./traefik --help
(UNIXのみ, 動作確認)- 任意の場所に移動
Dockerでインストールする
$ docker pull traefik
(後述のdocker runで自動取得するのでしなくてもOKです)
Traefikのtraefik.tomlを用意する
traefik.toml
を作成し、以下のように書き込みましょう。
Your Email Addressのところには自身のメールアドレスを入力します。[[acme.domains]]
内には証明書を取得したいドメインを入力します。
defaultEntryPoints = ["http", "https"] [entryPoints] [entryPoints.http] address = ":80" [entryPoints.http.redirect] entryPoint = "https" [entryPoints.https] address = ":443" [entryPoints.https.tls] [acme] email = "Your Email Address" acmeLogging = true # たまに失敗したりするのであったほうがいいと思います storage = "acme.json" # storage = "traefik/acme/account" # キーバリューストア利用時 entryPoint = "https" [acme.dnsChallenge] provider = "cloudflare" delayBeforeCheck = 0 [[acme.domains]] main="*.example.com" sans = ["example.com"] [file] # これはfileで設定しない場合は無くて構いません。 filename = "rules.toml" watch = true
上のファイル内で[file]
を利用した場合、さらにrules.toml
を作成します。
以下にrules.toml
のサンプルを置いておきます。(サンプルではhttps://test.example.comに繋ぐととlocalhost:8080に接続されます。)
公式リファレンスに詳しいオプションが載っています。
[frontends] [frontends.frontend1] backend = "backend1" [frontends.frontend1.routes] [frontends.frontend1.routes.route0] rule = "Host:test.example.com" [backends] [backends.backend1] [backends.backend1.servers] [backends.backend1.servers.server0] url = "http://localhost:8080"
Traefikを起動する
$ export CLOUDFLARE_EMAIL=Your email address
$ export CLOUDFLARE_API_KEY =Your API Key
(「Cloudflareの設定をする」で取得したやつです)
バイナリを利用する
./traefik --configFile /path/to/traefik.toml
Dockerを利用する
$ docker run -v $PWD:/etc/traefik -e CLOUDFLARE_EMAIL=${CLOUDFLARE_EMAIL} -e CLOUDFLARE_API_KEY=${CLOUDFLARE_API_KEY} -d traefik
無事起動すれば完了です。
もしTXTレコードが一致しないと書かれていた場合は、traefik.toml
のdelayBeforeCheckを30等に変更してTraeefikを再起動してみてください。
終わりに
この記事の主な目的はLet's EncryptとTraefikの布教でした。特にTraefik、知名度が全然ありませんがめっちゃ便利なので是非使ってみてください。
今後もmodokiの開発は続けたいと考えています。Issue/Contributionお待ちしています!