Kitura を SSL に nginx のリバースプロキシ経由で対応させる。

Server Side Swift

Kitura で Server Side Swift を始めてみたものの、Kitura 自体はまだ SSL に対応していない様子でした。

そこで nginx のリバースプロキシ機能を使って SSL に対応させてみることにしました。


先日に こちら で書いたように Kitura を使って Server Side Swift 環境を作ってみました。ただ Kitura 自体は SSL に対応していないように見えたので、ひとまず nginx を使って SSL 対応のリバースプロキシを立ち上げてみることにしました。

nginx をインストールする

まずは Kitura をインストールした Ubuntu 14.04 LTS 環境に nginx をインストールするところから始めます。

Ubuntu 14.04 の標準状態でも apt-get を使って nginx を入れることはできるみたいですけど、それだと 現在では 1.4.6 がインストールされるようなので、今回は最新版の 1.9.12 を入れるようにしてみます。

APT リポジトリを登録する

Ubuntu 14.04 でも nginx 公式の APT リポジトリを登録すると apt-get最新版の nginx をインストールできるらしいので、今回はそうしてみることにします。

PGP キーのインストール

そのために、まずは APT で nginx 公式リポジトリを使えるように nginx リポジトリの PGP キーをインストールします。

wget -O - http://nginx.org/keys/nginx_signing.key | sudo apt-key add -

ちなみにこれを忘れると、いざ apt-get しようとした時に次のようなエラーメッセージが表示される様子でした。

Reading package lists... Done

W: GPG error: http://nginx.org trusty Release: The following signatures couldn't be verified because the public key is not available: NO_PUBKEY ABF5BD827BD9BF62

nginx 公式リポジトリのインストール

そして Ubuntu 14.04 LTS の APT で nginx 公式リポジトリを使えるように、次の2行を /etc/apt/sources.list に追加します。

deb http://nginx.org/packages/mainline/ubuntu/ trusty nginx
deb-src http://nginx.org/packages/mainline/ubuntu/ trusty nginx

これで nginx 公式のリポジトリを使う準備が整いました。

ちなみに Ubuntu 14.04 LTS のコードネームは trusty というそうです。上記の debdeb-src 内の URL にあるその文字がコードネームを表していて、他のバージョンの Ubuntu を使っている場合には、適宜調整する必要があるようです。

バージョン コードネーム
12.04 precise
14.04 trusty
15.04 vivid
15.10 wily

また、上記では最新バージョンが使える Mainline という位置付けのリポジトリをインストールしましたが、安定板までに制限された Stable という位置付けのものもあるようです。

こちらを使う場合は deb や deb-src で指定する URL のところを http://nginx.org/packages/ubuntu/ にすれば良いようです。どちらを使うのが良いか分からなかったのですけど、軽く調べた感じでは nginx では Mainline の使用を推奨しているらしい ので、今回はそれを使ってみることにしました。

公式 nginx サイトの Documentation > Linux Packages のページにもちゃんと /etc/apt/sources.list に上記の2行を追加するようにと書いてあったのですけど、最初それを見逃していて deb コマンド や deb-src コマンドがあるのかと勘違いしてしまいました。よくよく調べてみたらそういうコマンドはないそうで、上記の通り /etc/apt/sources.list 設定ファイルに記載するものになるとのことでした。

nginx のインストール

ここまで出来れば最新版 nginx のインストールは簡単です。

apt-get update
apt-get install nginx

これで 時点で最新の 1.9.12 をインストールすることができました。

ちなみに、既に Ubuntu 14.04 LTS 標準の状態で nginx 1.4.6 をインストールしていたりすると、ここでインストールに失敗することがある様子でした。そんな時は apt-get remove nginx を実行したり apt-get autoremove を実行したりしてみてからインストールしてみると上手くいく様子でした。

パケットフィルタリングの設定

初めて nginx をインストールした環境では、外部から Web サービスにアクセスできないようになっているかもしれません。

上の手順で nginx をインストールすると、Ubuntu の ufw コマンドを使ってファイアーウォールの設定をしている場合は、次のようにして簡単にアクセスできるように設定調整できます。

ufw allow "Nginx HTTPS"

こうすることで、SSL に対応した https アクセスのための標準ポート 443/tcp への外部アクセスが解放されます。http のための標準ポート 80/tcp を解放したい場合には ufw allow "Nginx HTTP" を実行することになります。

Ubuntu 14.04 LTS で ufw を使ってファイアーウォールを設定する方法については、初歩的なところだけですけれど こちら で記しています。

nginx にリバースプロキシを設定する

nginx のインストールが終わったので、いよいよリバースプロキシを設定します。目標としては SSL を有効にした nginx を起動させて、そこへ来たアクセスを全てそのまま Kitura で稼働している Web サーバーへ転送する形をとります。

SSL 証明書の作成

SSL 対応サイトを立ち上げるために、まずは SSL 電子証明書を作成します。

最終的な運用ではちゃんとした証明機関の電子証明書を取得する必要がありますけど、今はそれが本題ではないので、まずは Ubuntu にインストールされている openssl を使って自己署名の電子証明書を作成することにします。

まず、電子証明書を保存するための場所として、今回は /etc/nginx/certs を使うことにします。その場所を作成して、その場所に移動します。

mkdir /etc/nginx/certs
cd /etc/nginx/certs

そうしたら、次のようにして、まずは電子証明書を使うために必要な秘密鍵を作成します。今回はそれを api.ez-net.jp.key に保存しておくことにします。

openssl genrsa 2048 > api.ez-net.jp.key
chmod go-r api.ez-net.jp.key


そうしたら、証明期間に電子証明書を発行してもらう申請書的な証明書要求ファイルを作成します。今回はこれを api.ez-net.jp.csr という名前で作成することにします。

openssl req -new -key api.ez-net.jp.key > api.ez-net.jp.csr

この手順では、国名や地域、証明書を使う URL のドメイン名 (Common Name) などを入力することになるので、適切なものを入力します。今回はたとえば次のように入力しておくことにしました。

Country Name (2 letter code) [AU]:JP
State or Province Name (full name) [Some-State]:Kanagawa
Locality Name (eg, city) []:Yokohama
Organization Name (eg, company) [Internet Widgits Pty Ltd]:EZ-NET
Organizational Unit Name (eg, section) []:
Common Name (e.g. server FQDN or YOUR name) []:api.ez-net.jp
Email Address []:

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


そうしたら、電子証明書を発行します。

本運用であればここで Rapid SSL などの認証機関に発行を依頼することになるのでしょうけど、今回はまだ試運転で私的利用に限られるのもあって、とりあえず Ubuntu の openssl コマンドを使って、このまま次のように電子証明書を発行します。

openssl x509 -days 300 -req -signkey api.ez-net.jp.key < api.ez-net.jp.csr > api.ez-net.jp.crt

これで、作成した秘密鍵に対応した電子証明書 api.ez-net.jp.crt が出来上がりました。有効期間は -days で指定した 300 日です。

nginx を設定するための準備

あとは nginx を設定するだけなのですけど、初回は少し既存の設定ファイルの管理周りを調整する必要があるようでした。

Ubuntu 14.04 LTS の nginx では、設定ファイルを /etc/nginx/sites-available/etc/nginx/sites-enabled の2つで管理して、前者の中に仮想ドメインごとの設定ファイルを用意して、後者のディレクトリ内に実際に使いたい設定ファイルへのシンボリックリンクを作成することになるようです。

そういう風に準備をして、nginx を起動すると後者 /etc/nginx/sites-enabled からリンクされている仮想ドメインが有効になる構造で運用するらしいんですけど、今回の nginx を始めてインストールした状況では、まだ /etc/nginx/sites-enabled の設定が読み込まれるようになっていませんでした。

そこで /etc/nginx/nginx.confhttp { } の中にある include /etc/nginx/conf.d/*.conf 行の次のあたりに、次の1行を追記しておきます。

include /etc/nginx/sites-enabled/*;

あと、このままだと既存の設定と、既定で用意されていた /etc/nginx/sites-enabled/default とで設定が被ってしまうようなので、とりあえず次のようにして sites-enabled からのシンボリックリンクを削除して default の設定を読み込まないようにしておきます。

rm sites-enabled/default

nginx を設定する

このような準備ができたら、仮想ドメインの設定を行います。

今回は /etc/nginx/sites-available/https_api.ez-net.jp というファイルを、次のような内容で作成してみることにしました。Kitura で実装した Web アプリケーションの待ち受け URL は http://127.0.0.1:8090 であるとします。

service nginx reload

server {

        listen                  443;
        server_name             api.ez-net.jp;

        ssl                     on;
        ssl_certificate         /etc/nginx/certs/api.ez-net.jp.crt;
        ssl_certificate_key     /etc/nginx/certs/api.ez-net.jp.key;

        proxy_set_header        Host $http_host;
        proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;

        location / {

                proxy_pass      http://127.0.0.1:8090
                proxy_redirect  http:// https://
        }
}

これができたら、次のようにして /etc/nginx/sites-enabled からのシンボリックリンクを作成して、設定ファイルの準備ができました。

ln -s /etc/nginx/sites-available/https_api.ez-net.jp sites-enabled/

あとは次のように nginx の設定チェックと再読み込みを行えば、これで SSL を使った nginx から Kitura Web アプリケーションへのリバースプロキシが起動してくれます。

service nginx configtest
service nginx reload

Kitura で作った Web アプリケーションを起動させた状態で、今回の設定であれば Web サーバーへ https://api.ez-net.jp/ みたいな URL で接続すると、SSL 対応サイトから Kitura の Web アプリケーションからのレスポンスを得られることが確認できます。