ねこテニ

猫とテニス。

プログラミングビギナーNekoteniがあなたに贈る!NginxでSSLの巻

2014年11月05日 | プログラミング
NekoteniがNginxを〜♪嫌いなんじゃない〜♪
NginxがNekoteniを〜♪嫌ってるんだ〜♪

NginxでVirtual Hostを無事表示できたNekoteni。
その先には何があるのか?!
行けばわかるさ!!(特にプロレスのファンではないです)
・・・次は最後の難関、SSLに挑みます。

プログラムビギナーのNekoteniが辿った軌跡が皆様のお役に立てば幸いです。


【前提】
・NekoteniはさくらのVPS上のDebianを使っている(自分のMacではない)。
・Nekoteniはお名前.comでドメインを取った。
・sslはVirtual Hostのサイトに適用した。

ビギナーであるがゆえに気をつけなければいけなかったポイントを【Beginner's Point】(青文字)として記載しています。
わかっている人にとっては当たり前のことなので、青い文字は飛ばして黒い文字赤い文字だけ追って行って下さい。

【自己認証局・自己証明書(通称:オレオレ証明書)を使ったSSL対応サイトを作る】
SSL(Secure Sockets Layer)とは
 インターネットなどのTCP/IPネットワークでデータを暗号化して送受信するプロトコル(通信手順)の一つ。データを送受信する一対の機器間で通信を暗号化し、中継装置などネットワーク上の他の機器による成りすましやデータの盗み見、改竄などを防ぐことができる。by IT用語辞典

【Beginner's Point】
ええと・・・上記のSSLとは、をNEKOTENI、あまり理解できていません(大汗)。
だって専門用語山盛りじゃん?説明って小学生にもわかるような内容にするのが一番大事なことだとNEKOTENIは思うの。

というわけでNEKOTENIのSSLへの理解はこんな感じです。

登場人物
・ジュリエット(手紙の送り主)
・ロミオ(手紙の受取人)
・ロレンス:フランシスコ会の修道僧(SSLクライアント)
・ジョン:フランシスコ会の修道僧(SSLサーバー)

ジュリエットとロミオは敵対する家同士ですが、何故か恋人同士。
手紙のやりとりをちょくちょくしているものの、フランシスコ会のおかげでバレたことはありません。

「ロミオ様に手紙を送りましょう」

ジュリエットは手紙を書きます。でもそのまま送るとお父様にバレバレ。何故なら配達員は買収されているからです。
そこでジュリエットは手紙をロレンス修道僧(SSLクライアント)へ持って行きます。

「ロレンス様、手紙を暗号化して送って下さいな」
「わかりました、ジュリエット」
「あの・・・ロミオ様に手紙を渡して下さるジョンという方は信用できる方なんですか?」
「ジョンからは私と同じフランシスコ会の修道僧であるという証明書が届いています。信用できる人物ですよ」

ロレンスはジョンから届いた証明書と一緒に同封されていた暗号化の鍵(公開鍵)でジュリエットの手紙を暗号化します。
暗号化されたジュリエットの手紙は数字の羅列になっているので、何が書かれているのかわかりません。
また、暗号化の鍵(公開鍵)は暗号化しかできないので、ロレンスから盗んで手に入れても手紙の内容はわかりません。

暗号化されたジュリエットの手紙は、ロレンス → 一般の配送員 → ジョンへ届けられます。

ジュリエットからの暗号化された手紙を受け取ったジョンは、ジョンしか持っていないたった1本の復号化の鍵(秘密鍵)でジュリエットの手紙を元の手紙の内容に直します。
復号化の鍵(秘密鍵)はジョンしか持っていないので、配送員が間違えて隣村のフランシスコ会のジョーに送ってしまっても、復号化の鍵(秘密鍵)が違うので隣村のジョーはジュリエットの手紙を復号化することはできません。

「ロミオ様、ジュリエット様よりお手紙です」
「ああ、ジュリエット。何て素敵な手紙なんだ!」

こうして無事に手紙はロミオへ渡ったのでした。

ポイントは、
・暗号化する鍵と、復号化する鍵は別々のもの。
・暗号化する鍵(公開鍵)はSSLサーバから証明書と一緒にSSLクライアントへ渡される。

SSLのしくみについては、いろんな例えや図解を見ているうちに、何となくわかってきます。
妻に公開鍵暗号を教えてみた
イケメンとラブレターで学ぶSSLの仕組み
Lesson1:アプリ同士のやりとりを暗号化,相手が信頼できるかも確かめる
Lesson2:二つの暗号方式を組み合わせて,安全かつ高速に通信をする
自分で例えを書いてみると嫌でも理解します(T▽T)


本来はSSLの証明書を認証局が発行しますが、発行にはお金がかかります。
証明書のランクによって数千円/年から10万超え/年まであります。
練習にしちゃちょっと金かかりすぎですね・・・。

というわけで今回は証明書は自分で発行します。
いわゆる「オレオレ証明書」です。
何の裏付けもないので、証明書としては全く信憑性のないもの(オレオレ詐欺と同じですね)ですが、オレオレ証明書があればSSLのシステムを使ってSSL対応サイトを作ることができるので、今回はそれで行きます。
あ、もちろん本物の証明書を取ってもいいですよ!!

【オレオレ証明書を作る】
まず、オレオレ証明書を作ります。
NEKOTENIが参考にしたのはこちらのサイトです。

オレオレ証明書を作るには3つのファイルを作成する必要があります。
1)秘密鍵 (Private Key):server.key
2)証明書署名要求 (CSR):server.csr
3)サーバ証明書(CRT):server.crt

ちょっと注意を要するところもありますが、それほど難しくはありません。

1)秘密鍵 (Private Key):server.keyを作成
$ openssl genrsa 2048 > server.key

秘密鍵のファイルが作成されます。

2)証明書署名要求 (CSR):server.csrを作成
$ openssl req -new -key server.key > server.csr

このコマンドを打つと、こんな文章が表示されます(びっくりしないでね!)
落ち着いて、ご自分の内容を入力して行って下さい。
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]: JP ←日本
State or Province Name (full name) [Some-State]: TOKYO ←都道府県名
Locality Name (eg, city) []: CHIYODA-KU ←市区町村名
Organization Name (eg, company) [Internet Widgits Pty Ltd]: NEKOYA ←会社名。Enterで飛ばしてもOK。
Organizational Unit Name (eg, section) []: NEKOBU ←組織名。Enterで飛ばしてもOK。
Common Name (e.g. server FQDN or YOUR name) []: www.nikukyu.club←ここ超重要!必ずVirtual Hostのドメイン名を入れて下さい!!
Email Address []: nekoteni@nekoneko.com ←メールアドレス

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []: ←Enterで飛ばす
An optional company name []: ←Enterで飛ばす

上記の質問&答えに沿った内容で、証明書署名要求ファイルが作成されます。

3)サーバ証明書(CRT):server.crtを作成
$ openssl x509 -days 3650 -req -signkey server.key < server.csr > server.crt

2)で作った証明書署名要求ファイルを使って、サーバ証明書が作成されます。

オレオレ証明書(ファイル3つ)の保存先はこちら。
/ ルートディレクトリ (Windowsで言うとCドライブ、みたいなもの)

├ /bin 一般ユーザー向けの基本コマンド

├ /boot 起動に必要なファイル

├ /dev デバイスファイル

├ /etc 設定ファイル
| ├ /init.d システム (PC)が起動した時に、自動的に実行するプログラムが置いてあるらしい。
|  ├ /nginx ←ここにNginxの実行ファイルがいます。Nginxを起動させる時、/etc/init.d/nginx startしましたね。
|   ├ /sites-available - nikukyu.club ←Virtual Hostの設定を書いたファイル
|   ├ /sites-enable - nikukyu.club ←sites-availableの内容を見にいけよーというシンボリックリンクが貼られたファイル。
|  ├ /ssl - server.key ←秘密鍵
|      - server.csr ←証明書署名要求
|       - server.crt ←サーバ証明書


├ /home ユーザーのホームディレクトリ
| ├ /demo ←Virtual Hostのデータを入れとくディレクトリ(ファイル)
|   ├ /public_html
|    ├ /nikukyu.club ←サブフォルダ
|     ├ /public - index.html ←nikukyu.clubのトップページ
|     ├ /private
|     ├ /log
|     ├ /backup

├ /lib 共有ライブラリ

├ /mnt ファイルシステムの一時的なマウントポイント用ディレクトリ

├ /media CD-ROMなどのリムーバブル媒体(media)のマウントポイント

├ /opt 実行時に書き換えられないアプリケーションソフトウェアパッケージ

├ /proc カーネルやプロセスに関する情報をテキストで表示する仮想ファイルシステム

├ /root root用ホームディレクトリ

├ /sbin システム管理用コマンド

├ /tmp ファイルなどを一時的に保管するディレクトリ

├ /srv システムに提供されたサイト固有のデータ

├ /usr プログラムやカーネルソース
| ├ /share
|  ├ /nginx - index.html ←Welcome to Nginx!が入ってたのはここ!

└ /var システムログなどの動的に変化するファイル

【Beginner's Point】
NEKOTENIは証明書署名要求 (CSR):server.csrを作成する際、Common Nameをドメイン名ではなく、自分の名前を入れてしまいました。
※Common Name (e.g. server FQDN or YOUR name) :ね、Your Nameって書いてあるでそ。
これはイカン!作り直さねば!!とあれこれいじくっているうちに、opensslに必要な大事なopenssl.cnfファイルを消してしまいました。
しかも消したことにも気付いてない。ダメダメです。
これがないと秘密鍵が作成できません。

しょうがない。もう一回opensslをインストールするか。
 ↓
openssl.cnfが作成されない。
 ↓
何度もapt-get install opensslやってみるけど、やっぱりopenssl.cnfは作成されない。
 ↓
職場の人に泣きつく。
 ↓
opensslを一回全部削除(apt-get --purge openssl)してから、もう一回opensslをインストールしてみたら?と助言を受ける。
 ↓
おお!!openssl.cnfが作成されたぁぁ!!
 ↓
今度こそCommon Nameを間違えずにwww.nikukyu.clubで登録し、nginxの再起動もできた!!ブラボー!!

ここまででざっと半日以上使いましたorz
文字にするとこんなに短いのに・・・。

ビギナーならではのどうしようもない問題でしたが、一回こういうことをやると次はどうしたらいいのかわかるようになります。
人生万事塞翁が馬。
でもファイルの削除はものすごーく気を使って下さいね。NEKOTENIの二の轍を踏まないでね。



【オレオレ証明書を使うことを設定ファイルに書く】
オレオレ証明書を作成しただけでは、Nginxはオレオレ証明書を認識してくれません。
この証明書を使うからね!とVirtual Hostの設定ファイルへ書き込む必要があります。

【Beginner's Point】
さてここで問題です。
VIrtual Hostの設定はどこに書いたでしょーかっ?

NEKOTENIはオレオレ証明書を作っている間に、すーっかり頭から抜けてしまっていました。
おかげでとんちんかんなファイルにオレオレ証明書を使うよ!ということを書いてしまい、Virtual Hostのページがhttpsで表示されないよー(泣)とまた半日以上泣きを見たのです。

言われてみれば当たり前なのですが、VIrtual HostのドメインをSSLを使って表示させたければ、Virtual Hostの設定ファイルに設定を書かなければなりません。
もしもNginxのデフォルトindex.html(Welcome to nginx!ですね)をSSLを使って表示させたければ、Nginxの設定ファイルに設定を書く必要があります。

賢明な読者様はもうVirtual Hostの設定をどこに書いたか思い出しましたね!
そうです。ここです。
/etc/nginx/sites-available/nikukyu.club


Virtual Hostの設定ファイルをvimで開きます。
$ sudo vim /etc/nginx/sites-available/nikukyu.club

開くと、ちょっと前に自分が書いたサーバー設定が表示されます。
この下にsslの設定を追記します。

server {
    listen 443 default ssl;
    server_name www.nikukyu.club;
    ssl on;
    ssl_certificate /etc/ssl/server.crt;
    ssl_certificate_key /etc/ssl/server.key;
}

server {
    listen 443 default ssl;
    server_name nikukyu.club;
    ssl on;
    ssl_certificate /etc/ssl/server.crt;
    ssl_certificate_key /etc/ssl/server.key;
}


この中身を日本語っぽく言うと、
・SSLのデフォルトのポート番号は443ですよ。
・サーバーネームは、www.nikukyu.club(もしくはnikukyu.club)ですよ。
・SSLをONにしますよ。
・SSLの証明書は/etc/ssl/server.crtにありますよ。
・SSLの証明書鍵は/etc/ssl/server.keyにありますよ。
です。

「ESC」キーを押して、「:wq」を入力してvimから抜けましょう。

一応、設定ファイルが正しい文法で書けているかどうか、チェックしておきましょう。
$ sudo nginx -t

・syntax is ok
・test is successful
と出たらOKです。

どっか間違っているところがあると、間違っている所が表示されて、「test failed」と出ます。
Nginx設定ファイルチェック

これでSSLの設定は終わりです。
Nginxを再起動して追記した設定を有効にします。

$ sudo /etc/init.d/nginx stop ←Nginx停止
$ sudo /etc/init.d/nginx start ←Nginx起動

【Beginner's Point】
Nginxを再起動したときに ↓ ってDebian君に言われることがあります。
[emerg]: bind() to 0.0.0.0:80 failed (98: Address already in use)

(Virtual Hostに割り当てている)80番ポートはもうすでに使われてるよ!という意味です。
なので、こういう時は強制的に80番ポートを空けます。
$ sudo fuser -k 80/tcp

再度Nginxを起動してみて下さい。ちゃんと起動するはずです。

エラーメッセージが出てもオロオロしなくて大丈夫です(NEKOTENIはさんざんオロオロしましたが・・・)。
エラーメッセージをコピーしてググってみましょう。
大抵のエラーメッセージは他の誰かも絶対困ってて、しかも解決策が載せられていたりします。
NEKOTENIは80番ポートの件はここを見ました。


ブラウザでSSL認証されているかどうか見てみましょう。
ChromeのアドレスバーにVirtual Hostのアドレスを入れます。

https://www.nikukyu.club

http、じゃないですよ。httpsですよ。さぁ、どうでしたか?
ご自分のVirtual Hostのindex.htmlが表示されましたか?


アドレスバーの鍵マークとhttpsに×と取り消し線がついていることに注目して下さい。
鍵マークをクリックしてみると、「ID情報が確認されてない」とか「サーバーの証明書を信頼できません」とか表示されます。
これはオレオレ証明書を使っているために表示されるものです。
ちゃんとした機関で本物の証明書を取得していれば、鍵マークもhttpsも緑の表示になります。

https付きのアドレスではindex.htmlが表示されず、404なんちゃら、と出たらもう一度鍵の作成や設定を見直してみましょう。
どっかどっか違ってたりします(;セミコロンを:コロンで書いてたりとかね)。
正しく鍵を作成し、正しく設定を記載しないとNginxは動いてくれないのです(泣)。

でも、色々な所でつまづくからこそ、つまづいた部分についての理解が深くなります。
NEKOTENIはNginxでSSLに足掛け2日かかりました。
ものすごい勢いでググりましたし、それでもわからなくて先輩方に泣きついたりしました。
泣きつける先があっただけマシだとは思うのですが、それでもかなり苦しい2日間でした。

Nginxに関して3記事書きましたが、書いていてわかったのは「作業中はとにかく視野が狭くなる」ということ。
碁盤の一部しか見えていないんですね。
一歩引いて、碁盤全体を見たらわかるはずの手が見えなくなってしまう。
これからもそういう状態になるとは思いますが、今回の経験をしたからこそ、次回は「おっと、一歩引かねば」と思えるはず。
ものすごく大変でしたが、ものすごくいい経験をしました。

最新の画像もっと見る

コメントを投稿