読者です 読者をやめる 読者になる 読者になる

HTTPSのWebサーバを設定した (h2o + Let's Encrypt)

最近、ハイパフォーマンスブラウザネットワーキングを読んでいて、HTTPSについてちょっと勉強しています。勉強にあたっては、実際に試せる場所があったら便利そうなので、自分のさくらVPSにHTTPSのWebサーバを設置してみることにしました。この次はHTTP2の実験もしたいので、先進的なHTTP2の機能が実装されていそうなh2oを使ってみることにしました。

環境

今回の作業は以下のような環境でやりました。

$ uname -a
Linux douzemille 4.4.0-36-generic #55-Ubuntu SMP Thu Aug 11 18:01:55 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux
$ cat /etc/lsb-release
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=16.04
DISTRIB_CODENAME=xenial
DISTRIB_DESCRIPTION="Ubuntu 16.04.1 LTS"

準備

このあとの作業のために以下くらいのパッケージをいれておきます。h2oのmruby機能を使わないのであればruby系とbisonは不要。rotatelogsコマンドのためにapach2-utilとかもいれてます。

  • cmake
  • build-essential
  • libyaml-dev
  • ruby
  • ruby-dev
  • bison
  • letsencrypt
  • apache2-utils

h2oのビルドとインストール

オフィシャルのドキュメントが丁寧なのでその通りにやりましょう。この手順で、/usr/local以下にインストールされます。

$ ghq get h2o/h2o
$ ghq look h2o/h2o
$ git checkout -b build v2.0.4
$ cmake -DWITH_BUNDLED_SSL=on .
$ make
$ sudo make install

h2oの基本的な設定の準備

Let's Encrypt でHTTPSの鍵を取得するためにstaticなファイルを配信するためのHTTPサーバが必要なので、そのためのh2oの設定を用意します。/usr/local/etc/h2o/h2o.conf.ymlとか好きなところに置きます。

pid-file: /run/h2o.pid
error-log: "| rotatelogs /var/log/h2o/error.%Y%m%d 86400"
access-log: "| rotatelogs /var/log/h2o/access.%Y%m%d 86400"
listen: 80
hosts:
  "hakobe.douzemille.net:80": # 自分のドメインにする
    paths:
      /:
        file.dir: /home/yohei/web/hakobe # 配信されるファイルのおいてあるパスを指定

h2oをデーモンとして起動するためのsytemdのunit定義を準備

最近のUbuntuはsystemdというやつでデーモンの管理をしているそうです。h2oをsystemdの管理下で動作させるために、/lib/systemd/system/h2o.service に以下のような内容のファイルを置きます。h2o systemd service file作った - うま味がない をめっちゃ参考にしてます、というかだいたいコピペです。

[Unit]
Description=H2O the optimized HTTP/1, HTTP/2 server
After=syslog.target network.target remote-fs.target nss-lookup.target

[Service]
Type=forking
PIDFile=/run/h2o.pid
ExecStartPre=/usr/local/bin/h2o -c /usr/local/etc/h2o/h2o.conf.yml -t
ExecStart=/usr/local/bin/h2o -c /usr/local/etc/h2o/h2o.conf.yml -m daemon
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s QUIT $MAINPID
PrivateTmp=true

[Install]
WantedBy=multi-user.target

ファイルをおいたら以下のようなコマンドで有効化します。

$ sudo systemctl enable h2o.service
$ sudo systemctl start h2o.service
$ sudo systemctl status h2o.service # これでログが見れる

ここまでで80番ポートでHTTPのサーバが起動している状態になっています。設定ファイルに書いたディレクトリ(この手順では/home/yohei/web/hakobeにファイルをおいてうまく配信されているか確認しましょう。

Let's Encrypt からHTTPSの鍵をもらう

決められた手順でLet's Encryptとやりとりすることで、Let's Encryptによって署名されたHTTPSの鍵を取得できます(How It Works - Let's Encrypt - Free SSL/TLS Certificates で詳しい仕組みが紹介されています)。自動化されていているので、コマンドを実行するだけですぐに完了します。

ドメインの所有者であることを証明するために、そのドメインでアクセスできるHTTPサーバから鍵を配信する必要があります(そしてもちろんドメイン名から今設定しているサーバのIPが引けるように設定されている必要があります)。ここまででh2oがstaticファイルを配信できるように設定してあるので、コマンドラインのオプションから -wオプションでファイル配信元のディレクトリを指定します。

$ sudo letsencrypt certonly --webroot -w /home/yohei/web/hakobe -d hakobe.douzemille.net

これで /etc/letsencrypt 以下に鍵や設定が保存されます。よくできてますね。

追記: ちなみにここではletsencrypt というコマンドを使っていますが、最新版では名称が変わってcertbotというコマンドになっています。certbotのほうが高機能なようですが、基本的な動きは変わらないようです。certbotのページから自分の使っているOSを選択するとインストール方法を紹介してくれます。Ubuntuの場合はapt-get install letsencryptせよと言わるのでしたがっています。

Let's Encrypt の鍵を定期更新する

Let's Encrypt の鍵は3ヶ月でexpireします。必要に応じて更新する手順も自動化されているので sudo crontab -eとかして以下のように書いておきます。

0 4 * * * letsencrypt renew

h2oでHTTPSのサーバを起動する設定

はじめに作って、/usr/local/etc/h2o/h2o.conf.ymlとかにおいてあった設定を書き換えてHTTPSで動作するようにします。

pid-file: /run/h2o.pid
error-log: "| rotatelogs /var/log/h2o/error.%Y%m%d 86400"
access-log: "| rotatelogs /var/log/h2o/access.%Y%m%d 86400"
listen:
  port: 443
  ssl:
    certificate-file: /etc/letsencrypt/live/hakobe.douzemille.net/fullchain.pem
    key-file: /etc/letsencrypt/live/hakobe.douzemille.net/privkey.pem
    cipher-suite: "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4"
    cipher-preference: server

hosts:
  "hakobe.douzemille.net:443":
    paths:
      /:
        file.dir: /home/yohei/web/hakobe

あれこれ書いてますが、

ということをしています。省略してますが80番ポートもlistenして、httpsのURLにリダイレクトしたり Strict-Transport-Security ヘッダを付けて返したりすると良いです。

できました

f:id:hakobe932:20160923180015p:plain

とくに何か情報のあるWebサイトではないのですが、とにかくHTTPSで配信できるようになりました。h2oを使っているのでHTTP2も喋れているようです。(HTTP/2 and SPDY indicator - Chrome Web Store で確認しています)

https://hakobe.douzemille.net/

SSL Labs によると A くらいの評価の設定にはなっているようです。がんばればA+になるらしいけどまずはこんなもんで。

f:id:hakobe932:20160923180137p:plain

これでとにかく現代的なインターネット基盤を実験してみる環境が整いました。めでたいですね。

ハイパフォーマンス ブラウザネットワーキング ―ネットワークアプリケーションのためのパフォーマンス最適化

ハイパフォーマンス ブラウザネットワーキング ―ネットワークアプリケーションのためのパフォーマンス最適化

ISUCON6 に参加して無事洗礼をうけてきた

id:hitode909 くんと id:hatz48 さんの三人のチーム「C0-100%」としてISUCON6に参加した。初参加者のみのチームで言語はPerl。普段会社では良い設計考えたり開発フローいい感じにしていこうみたいなのが得意なメンバーで、今回もテスト書いたりCIまわしたりするいつも通りの開発でやっていくぞというテーマで参加した。

結果としては、最高38000点くらいまでいったものの予選敗退。最終スコア計算の時点ではほとんどFAILしてる感じで、300点くらいだった。トホホ。

我がチームの様子はhitodeくんのエントリが詳しい。

blog.sushi.money

担当

自分はサーバオペレーションを担当した。わりとすぐやることがなくなってきたので、アプリケーションコードを書いていた。

チームメンバーはみなアプリケーションエンジニアで、普段からインフラ的な仕事をしている人がチームにいなかった。誰かが特別得意ということもないので、とりあえず担当決めて事前に準備してやるという感じだった。

幸い今回の問題はそんなにサーバオペレーションが効くという雰囲気でもなかったので、過去のISUCONの回答例などを参考にミドルウェア類を整備するという感じでなんとかなった。kazeburoさんの設定をどんどん入れていくという感じ (
ISUCON4 予選でアプリケーションを変更せずに予選通過ラインを突破するの術 - Hateburo: kazeburo hatenablog )

順調な前半

前半は事前の準備の効果があってめちゃくちゃスムーズにすすめることができた。はじめにやることのチェックリストを作ってあったので、あわてず丁寧にすすめることができた。

https://cdn-ak.f.st-hatena.com/images/fotolife/h/hakobe932/20160919/20160919124529.png

↑こういう感じ

  • 初期実装を起動してから最低限のnginxいれて、一度だけベンチをまわしてリクエストの傾向みる
  • CI、プロファイラを用意する
  • アプリケーションコードを呼んで怪しそうなところにあたりをつけておく

みたいなところを分担して一気にすすめて、一時間くらい。さらに一時間くらいデプロイできるようにしたり、コードを読み込むとかをしたところで、具体的な改善に入れそうだなとなった。

お昼頃にはリーダーボードにでてくるくらいのスコアになったので、ハイタッチして昼食休憩にはいったりした。

キャッシュの海に沈んだ後半

昼食をたべながら作戦会議をして、やはりhtmlifyを良くしていくのが良さそうだということで改善をはじめた。リクエストの傾向をみると表示に比べて更新の頻度が比較的低かったので、キャッシュが効くやろとかいって取り組みはじめた。このとき

  • htmlify された結果をキャッシュする
  • 正規表現の構築にRegexp::Assembleをつかう
  • 正規表現をキャッシュする

などを同時進行ですすめてたんだけども、これがあまり良くなかった。これらの変更を全部いれてベンチにかけたところめちゃくちゃFAILしまくる感じになってしまった。FAILの原因を丁寧につぶしていくという作戦にでたけど、2時間くらいはまってしまってだいぶ時間を無駄にしてしまった。

時間的な余裕もなくなったことで、新しいことをはじめる決断もできなくなってしまった。半分自棄になって、競技終了30分前にkeywordの文字数をカラムにいれてsortに使うようにする変更をいれたところ一気に15000点くらい点数があがって元気がでてきたものの、時すでに遅しであった。

反省

一つ一つの施策は方針が決まればすばやく実装できたのだけど、キャッシュまわりでうまくいかなくなり、打つ手がなくなったときにチームの活動がほぼ停止してしまい、うまくパフォーマンスをだせなくなってしまった。

全員が同じ方向を向いているパワーがでるけど、その方向をミスってしまったという感じがする。時間をきめてあきらめるとか、全員キャッシュに向かずに別のことをしてる人をつくるとかすると、もう少し安定感がでたかもしれない。

感想

せめて自分たちの考えたアイディアを全部うまく実施したかったけど、実現パワーが足りなくて、道半ばという感じで終わってしまいかなりくやしい。のらりくらりとコードを書いていてはいけない。来年あったら一矢報いたい。

初参加ということで、はじめてISUCONを体験したけども、これは運営大変だなと感じた。みんな真剣にやってるのでミスするとやばい感がすごい。運営のみなさま、本当にありがとうございました。

以下は会社の反省会の後での感想です。

アマチュア無線の専門店にいってみた

お休みをいただいて大阪で用事を済ませてきたのだけど、帰りに日本橋のアマチュア無線の専門店をのぞいてきた。のぞいたのは中野無線というところで、いかにも初心者ですという感じで店内をながめていたところ、気さくな店員さんがいろんな話を聞かせてくださり、かなり勉強になった。

144MHz帯や430MHz帯のFMはラグチュー中心になりつつあるらしくて、CQだして楽しみたいのであればHF帯がおすすめということのようであった。ただ、144MHz帯や430MHz帯であってもデジタル方式であればレピータ局などを経由して、日本中の人とつながれるので楽しむこともできるので、やりようはあるとのこと。

初級者向けのモービルの無線局+安定化電源+アンテナのセットだとどうしても10万円くらいのコースにはなるらしい。例えば予算が5万円ということであれば、中古品をやりくりすることもできるし、いろんなプランを用意できるので、相談してほしいとのこと。

アマチュア無線ガチ勢のお話なども伺ったがかなりおもしろく、アマチュア無線のために山に小屋をたてたりだとか、島に移住したりだとか、何百万円もするタワーアンテナ建てているだとか、いろんなエピソードがでてきた。だいたい現在進行形の話題なのがすごい。

勢いで10万円支払う勇気がなかったので、その場はお礼をいって帰ってきたのだけど、かなり頼りになるお店という感じで実際リグを買うときには相談したい。が我が家の電波状況はあまりかんばしくないのもわかってきたので、どういう方針でやってくかめっちゃなやむ〜。

RubyKaigi にちょっとだけお邪魔した

用事があって初日の懇親会と最終日の午後しか参加できなかったのだけど、たいへんおもしろかった。YAPCにはよくいってたけど、RubyKaigiに参加するのははじめて。

普段はあまりRuby界隈に顔は出さないので、ぼっちになるかと思いきや、意外と見知った方がたくさんいらっしゃった。大学時代はRuby関西のコミュニティにずいぶんお世話になったのだけれども、その界隈の方とは会うのはかなりひさびさに会えて話せたのも良かった。知り合いつながりで、はじめての方とも会話するのにも成功したので、なんとかなったと言えそう。みなさま、かまっていただきありがとうございました。

発表は数えるほどしか見れなかったものの、Rubyならではの言語の実装や開発の取り組み方の話題も聞けて新鮮だった。めっちゃCの話がでてくるなー。YAPCに比べると海外からの参加者がより多いような気もする。気がするだけかも。

でかい技術カンファレンスが電車一本でいける距離で開催されるのは不思議な感覚になる。これまでは自分の中では、だいたい旅行とセットという認識だった。

あまり積極的にかかわれなかったもの、なんやかんやで参加してよかったなー。

1アマ合格してた

先日、1アマを受験してきた記事を書きましたが無事合格できておりました。自己採点ではだいたい大丈夫そうということがわかってものの、ちゃんと合格って書いてある紙がやってくるとうれしい。

このあと実際に免許されるには、さらに申請が必要で、免許証が届くのは一ヶ月先とからしい。先は長い。

第一級アマチュア無線技士の資格試験を受験した

ちょっと前に電子工学の入門をしたのだけど、理論についてもう少しまとまった知識を身に付けたいと思い、いっちょやってみるかと第一級アマチュア無線技士の資格(いわゆる1アマ)の取得に取り組むことにした。

1アマは、昔は通信術の試験があって、高速なモールス通信を身に付ける必要があり難しかったのが、今は筆記試験だけになりハードルが下がっている。もともと、他の級のアマチュア無線技士の資格はもってなくて前提知識は大してなかったのだけど、きっちり勉強すればなんとかなるやろうと思って一気に一級にチャレンジした。

勉強の仕方

試験は工学と法規の二科目あるので、それぞれ勉強する必要がある。

法規は基本的に暗記なので、比較的ハードルは低い。工学については、基礎的な電気物理やアナログの電子回路、無線機のしくみや電波の性質について理解する必要があって、ある程度体系的に学んでいく必要がある。

勉強の期間はだいたい3ヶ月くらいだった。最初はとにかく試験範囲を知るべきかと思って、試験範囲を網羅的に解説してくれる本を買ってきて読んでみた。

解説・無線工学 2016/2017: 第1級・第2級アマチュア無線技士国家試験用

解説・無線工学 2016/2017: 第1級・第2級アマチュア無線技士国家試験用

この本は400ページくらいあって、読むのに1ヶ月くらいかかった。今思うとちょっと時間をかけすぎてしまったように思う。詳細に解説がのっている本なので、軽く目を通した後で辞書的に使うというのが良さそう。

この本を読んだあとは、評判の良さそうな問題集を買ってきて、繰り返し問いていった。

第一級アマチュア無線技士試験問題集 (合格精選400題)

第一級アマチュア無線技士試験問題集 (合格精選400題)

  • 作者: 吉川忠久
  • 出版社/メーカー: 東京電機大学出版局
  • 発売日: 2012/10/22
  • メディア: 単行本(ソフトカバー)
  • クリック: 1回
  • この商品を含むブログを見る

1周目はざっと問題を問いて、どういう雰囲気の問題がでるのかだけ確認した。2周目は、問題をまちがえた時は問題の解説をじっくり読んで理解するというやり方で問いた。2週目が終ったところでだいたい一度は全範囲を理解しているという状態になったので、記憶に定着するように3週目、4週目と問題を問いていった。範囲が広いので繰り返しやって、頭にすりこんでいく感じになる。はじめは1周やるのに2週間くらいかかってたと思うけど、最後には1週間強くらいで済むようになったので、一応前進している感じはあった。

工学の勉強で特に無線工学を基礎から学ぶ 第1級アマチュア無線技士という有名な解説サイトにお世話になった。過去問に対して、一問一問かなり詳細な説明をしてくれていて非常に助かった。教科書はこのサイトだけでも良いと思う。

法規については、ただ、問題だけみていても条文の前後関係とかが良くわからず難しかったので、教科書として電波法令抄録を購入した。

アマチュア局用 電波法令抄録 2015/2016年版

アマチュア局用 電波法令抄録 2015/2016年版

あと、昼休みと終業時間の二回のタイミングで、ランダムで過去問を一問出題してくれるSlack botを作って活用した。2ヶ月くらいの間、平日は毎日2問は問題を問いていたことになるので、80問くらいになると思う。ちょっとは役に立ったはず。

直前には、過去問を2,3回分くらい問いたりして、やったことのない問題がでてきてもびっくりしないように準備した。

試験当日

緊張していまいちぐっすり寝れなかった上に、会場が電車で一時間くらいの場所で早起きする必要があり、ずっと眠かった。

今回の試験は工学がちょっと簡単だったように思う。過去問の傾向では2,3問は複雑な計算問題がでてくるのだけれど、今回の試験ではそういった複雑な計算問題はほぼなかった。ただ計算問題の総数自体は例年より増えていた印象。

複雑な計算に時間をとられなかった分、じっくり検算する余裕があったので、そこそこ自信をもって試験を終えられた。B問題では、まったくわからない問題を勘で答えてまちがえたり、慌ててしまい "太陽に照らされている" が正解なところを "太陽に照らされていない" って答えてしまった。

法規のほうは、自信満々で満点やろ!とか思いながら試験を終えたものの、意外と覚え間違いがあり、そこそこ間違えた。試験後に問題と法令と照らしあわせて考えてみたんだけど、思い込みがあるのか、未だにどこを間違ってしまったのかがわからない..。

試験会場では、みなさん試験直前もがっつり計算問題の練習とかして勉強されていて、すげーなって感じだった。僕はとにかく集中できなくて、雑にしか勉強できなかった。試験受けるの学生以来なので、試験官のおじさんのことを思わず先生って認識してしまうということもわかった(「先生なかなかこないなー」って考えたりしてたけど冷静に考えると先生ではなかった)。

自己採点

今回の試験の問題と回答が公開されたので自己採点をしてみた。結果としては

  • 法規: 139/150 ( 92.6 % 正解 )
  • 工学: 148/150 ( 98.6 % 正解)

だった。105点が合格ラインなので、たぶんいけるのではないか。めちゃくちゃまちがってマークしてる可能性もあるので、月末の正式な合格発表を待ちたい。

感想

とにかくまとまった電子工学分野の知識を得たい、ということではじめた1アマチャレンジだけども、その目的はそこそこ達成されたと思う。基礎知識が増えて電気のことや回路の話題が出てもだいたい何を言ってるのがわかるようになった。ただ実際自分で回路を考えたり分析したりするとなると、もう少し勉強が必要そうである。先は長い。

もし合格していれば、無線機を運用する免許を得られるので、せっかくなのだから実際の交信も体験してみたい。くわしい人にどのリグを買ったらいいか聞きたい。短波帯にはそのうち出てみたいけど、設備をそろえるのがたいへんだろうからまずはハンディだろうな〜。

こういう資格試験は目標設定としてはわかりやすく、締切や達成度の指標もあるので、真剣に勉強をつづけることができてよかった。ただ、勉強内容が試験に最適化されがちだし、コストも高いので効率はそんなに良くないかもしれない。

ひとまずは一つおもしろチャレンジが完了したのでほっとした。三ヶ月ずっと勉強してた気がするし、なぜか途中で引越ししたりもしたので、妙にたいへんだった。はー、次は何を勉強しようかという感じだ。ソフトウェア開発とかWeb技術にちょっともどりつつ、もうちょっとデータ見れるように確率統計とかを勉強したい気がしてる。

Kyoto.なんか#2 を今週末やります!

(参加登録はもう終わってるんですが)、今週末の8/21(日) にはてなオフィスでKyoto.なんかというイベントをやります。Kyoto.なんかはプログラミングやインターネットに関する発表をしあってみんなでわいわいする勉強会です。

atnd.org

スケジュールも決まりました。開催が14時からになりました! なのでおもしろ発表たくさんあるので、参加登録されているかたは忘れずぜひいらしてくださいね!!

当日とびいりのLTも歓迎です!

スケジュール

13:30 開場
14:00 - 14:10 オープニング
14:10 - 14:25 y_uuki さん サーバ運用スクリプト集がゴミ捨て場みたいになってた話
14:25 - 14:40 kizkoh さん Rust か仕事まわりについてなんか
14:40 - 14:50 休憩
14:50 - 14:55 鹿くん さん なんか
14:55 - 15:00 JPMartha さん なんか
15:00 - 15:05 休憩
15:05 - 15:20 side_tana さん 開発のための開発
15:20 - 15:35 r7kamura さん amakanかwikihubのどちらかについてなんか
15:35 - 15:45 休憩
15:45 - 16:00 moznion さん なんか
16:00 - 16:05 PastaK さん なんか
16:05 - 16:10 yusukebe さん 憂鬱について
16:05 - 16:15 休憩
16:15 - 16:30 とびいり発表のコーナー
16:30 - 16:40 エンディング
16:40 - 17:00 バッファ
17:00 ~ 懇親会

懇親会について

  • イベント開催後、同じ場所でピザなどを頼んで懇親会を開催します
  • 会場入場時に懇親会への参加されるかを伺います
  • 懇親会に参加される方は参加費1000円をおねがいいたします