caddyで簡単にhttpsサイト

この記事はMicroAd Advent Calendar 2017の5日目の記事です。

# はじめに
昨今セキュリティが騒がれているせいかhttps化しているサイトが増えてきてますね。またLet's Encryptの登場で個人サイトでも比較的簡単にhttps化ができるのでますます増えていくかと思います。
比較的簡単とはいえapacheとかnginxとか入れてLet's Encrypt設定して〜、って作業も結構手間かかります。
そこでcaddyの登場です。

# caddyとは
caddyはGo言語で実装されたwebサーバで特徴としては下記があります。

- Caddyfileによる簡単な設定
- HTTP/2がデフォルト
- 自動HTTPSはデフォルトでオン（Let's Encrypt経由）
- 複数のサイトが機能するようなバーチャルホスティング
- 実験的なQUICサポート！
などなど。

起動時にLet's Encrypt経由で証明書関連を処理してくれるので、簡単にhttps化したサイトが作成できます。

# インストール

テスト環境：Ubuntu 16.04

## Goのインストール

さっそくダウンロードして使ってみようと思いますが、本家で提供されているFreeのバイナリは非商用利用に制限されてるので、ソースを取ってきてコンパイルして使ってみます。そしてGoが必要なのでそこから。

1.8以上が必要なのでレポジトリ追加してからインストール。

```shell-session
$ sudo add-apt-repository ppa:longsleep/golang-backports
$ sudo apt-get update
$ sudo apt-get install golang-go
```

.bashrcに適当にGOPATHを設定しておく

```shell-session:~/.bashrc
export GOPATH=$HOME/.go
```

書いたら反映

```shell-session
$ . .bashrc
```

## caddyのインストール
https://github.com/mholt/caddy
こちらにBuild方法が書いてあるのでその通りにインストールします。

ソースの入手とコンパイル

```shell-session
$ go get github.com/mholt/caddy/caddy
$ go get github.com/caddyserver/builds
$ cd $GOPATH/src/github.com/mholt/caddy/caddy
$ go run build.go
```

これでバイナリができるのでPATH通っている適当な場所にコピー

```shell-session
$ sudo cp caddy /usr/local/bin
```

ユーザで実行するならケーパビリティ設定しておく

```shell-session
$ sudo setcap cap_net_bind_service=+ep /usr/local/bin/caddy
```

これでcaddyと叩けばサーバ起動するし、ドメイン持っているのであれば指定すると初回起動時にLet's Encryptでhttps設定してくれる

```shell-session
$ caddy -host example.com
Activating privacy features...
Your sites will be served over HTTPS automatically using Let's Encrypt.
By continuing, you agree to the Let's Encrypt Subscriber Agreement at:
  https://acme-v01.api.letsencrypt.org/terms
Please enter your email address so you can recover your account if needed.
You can leave it blank, but you'll lose the ability to recover your account.
Email address: メールアドレス入力
 done.
https://example.com
http://example.com
```
ブラウザで証明書確認するとこんな感じ。
![2017-12-04 19.27.28.png](https://qiita-image-store.s3.amazonaws.com/0/21170/c07eed1f-ffc8-bf67-344a-51c4c6ffca44.png)
本当にさくっとhttpsサイトのできあがり。

とは言えこれだと初期表示のままなのであれですが、基本的な設定はCaddyfileを作って起動。
[ここ](https://github.com/caddyserver/examples)にサンプルが結構あって、例えばwordpressであればこんな感じですね。

```shell-session:Caddyfile
example.com

root /path/to/wordpress/
gzip
fastcgi / 127.0.0.1:9000 php
rewrite {
	if {path} not_match ^\/wp-admin
	to {path} {path}/ /index.php?{query}
}
```

```shell-session
$ caddy -conf Caddyfile -host example.com
```
通信はhttp/2ですね。
![2017-12-05 15.24.13.png](https://qiita-image-store.s3.amazonaws.com/0/21170/6927ed35-1761-2c01-313f-b24d83a0c843.png)

みなさんも簡単にhttpsサイトができるcaddyを使ってみてはいかがでしょうか！

# 追伸
と、本当はQUICの挙動確認をしたかったんですが、chromeからQUIC接続できず断念しました。。
起動時に-quicをつけるとQUIC対応になってudpの80,443のlistenができます。

```shell-session
udp6       0      0 :::443                  :::*                               
udp6       0      0 :::80                   :::* 
```

## QUICって？
[wiki](https://ja.wikipedia.org/wiki/QUIC)を参照下さい。
ざっくりとですが、HTTP/HTTPS通信ではTCP接続を使用してるんですが、QUICはUDPをベースに開発されたWeb向けのプロトコルです。
TCPだと3ウェイハンドシェイクで接続をしてからHTTPで会話を始めます。
例えばAからBへ接続したいとき、
A:「突然すいません、Bさんと接続したいのですがこの贈り物受け取ってもらえますか？」
B:「贈り物受領しました。こちらからの返礼品も受けとってもらえますか？」
A:「ありがとうございます。返礼品受領しました。」
雑だけどこんな感じで接続が行われてます。
HTTPSであればさらにTLSのネゴシエーションが必要になり、より多くのラウンドトリップが発生します。会話し始めるまでに結構時間がかかってますね。このことを会話と表現するのがインフラおっさん臭いですがご了承下さい。
そしてその遅さはWebの表示、ダウンロード速度に響いてきます。

QUICはこのTCP+TLSをUDP上で実装した感じになってて、3ウェイハンドシェイクを行わずにデータの取得を可能にしてます。

で、実際に使われているのかというとブラウザはchromeが対応していて、サーバはgoogleが対応してます。まあGoogleが開発してるので当然ですが。
chromeの検証でProtocolが確認できますし、
![スクリーンショット 2017-12-05 10.08.55.png](https://qiita-image-store.s3.amazonaws.com/0/21170/80539ba1-7c0f-0093-8159-42b20375f8ab.png)

**chrome://net-internals/#quic**を開くとQUICの使用状況を確認できます。
![chrome_quic.png](https://qiita-image-store.s3.amazonaws.com/0/21170/1e71cefe-8050-38d2-80aa-c0a9a8e3adb1.png)

そしてQUICが使用できるサーバが今のところcaddyしかないみたいなので試してみた感じでございます。
うまく挙動確認できたら次のAdvent Calendarで。