WebGISの構築7−SSL化

前回までの作業で、TileServerから地図タイル配信は可能となりました。このまま運用しても問題ないのですが、SSL化して通信内容を暗号化することで安心して利用してもらうこができます。
今回は、下図赤枠部分に示すSSL化を行います。

今回の作業範囲
  • ブラウザからの”https://”形式のURLを受付け通信内容を暗号化します。
  • NGINXをSSL化するとプロキシを経由するTileServerを含む全てのサービスの通信が暗号化されます。
  • SSL化は無償のSSL証明書(Let’s Encrypt)を使います。

SSLの概要

SSLとは”Secure Socket Layer”の略で、クライアントとサーバー間の通信内容を暗号化する仕組みです。
第三者機関から発行されるサイトの証明書と公開鍵、秘密鍵を使って通信内容を暗号化します。詳しい説明は、以下のサイトがわかりやすいと思います。

https://ssl.sakura.ad.jp/column/ssl/

今回構築する仕組みは、無償でSSL証明書を発行するサービス”Let’s Encrypt”(レッツ エンクリプト)と、そこからSSL証明書を取得するオープンソースソフトウェア”Certbot”(サートボット)を使用します。

Let’s Encryptの利用イメージ

Let’s Encryptは証明書発行サービスですので、Certbotを使ってサーバ証明書と秘密鍵の発行を要求・取得し、NGINXに組み込んで使用します。

Let’s Encryptの概要

Let’s Encryptは、無償でSSL証明書を発行している非営利団体です。無償とはいえ、Facebookやシスコ、IBMなどがスポンサーとして名を連ねており安心感のあるサービスです。
Let’s Encryptの特徴を以下に示します。

  • サイト証明書を自動で発行する仕組みがあり短時間で入手できる
  • 証明書の有効期限は90日(更新可能)
  • 2億件以上の証明書を発行済み
Let’s Encryptサイトのトップ画面(https://letsencrypt.org)

Let’s Encryptの概要は、以下のサイトがわかりやすいと思います。

https://ssl.sakura.ad.jp/column/letsencrypt/

Certbotの概要

Certbotは、Let’s Encryptサービスからサイト証明書、秘密鍵を取得するオープンソースソフトウェアです。CertbotはEEF(Electric Frontier Foundation:電子フロンティア財団)と呼ばれるデジタル社会での言論の自由を守ることを目的とする非営利組織により開発されています。
EFFサイト内にあるCertbotのWebページを以下に示します。

Certbotのトップページ(https://certbot.eff.org)

上記WebページにWebサーバーとOSを指定すると、”certbot”の導入手順が表示されます。
Certbotの概要を以下に示します。

  • コマンドラインツール”cerbot”として提供され、メジャーなOS、Webサーバーが網羅されている
  • ”cerbot”は、Python3系で開発されている
  • 環境に応じた”certbot”を選択してインストールするシェルスクリプト”certbot-auto”も提供される

SSL化の手順

SSL化は以下の手順で行います。
 1.certbotの導入
 3.nginxのコンフィグ変更
 4.証明書取得
 5.nginxのコンフィグ変更
 6.証明書の更新設定

構築環境は以下の通りです。
 ・OS:CentOS8(CentOS Linux release 8.1.1911)
 ・Webサーバー:NGINX 1.14.1

certbotの導入

今回は、”certbot”導入用のシェルスクリプト”certbot-auto”を使ってcertbotを導入します。
以下のように”certbot-auto”を、ダウンロードし実行権限を付与します。curlコマンドのオプション”-o”で指定するダウンロード先は任意ですが、90日後の証明書更新でも使用するので、パスの通ったディレクトリ(下記の例では”/usr/bin/”)がよいでしょう。

$ sudo curl https://dl.eff.org/certbot-auto -o /usr/bin/certbot-auto
$ sudo chmod 700 /usr/bin/certbot-auto

次に、certbot-autoを起動しcertbotの環境を構築します。

$ sudo certbot-auto

上記により、OSとWebサーバー、Pythonのバージョンが確認され、certbotモジュールや(必要な場合)Python3系がインストールされます。なお、”certbot”のインストール先は、”/opt/eff.org/certbot/venv/bin”です。

サイト確認用のロケーション追加

Let’s Encryptサービスは、証明書を発行する際にサイトの存在を確認します。その存在確認を受け入れるためのロケーション”/.well-known/acme-challenge/”を追加します。このロケーションは、URL”http://サイト名/.well-known/acme-challenge/”にて外部アクセス可能となります。
まず、以下のように外部公開するディレクトリ(任意のディレクトリ)を作成します。

$ sudo mkdir /etc/nginx/letsencrypt

次に、作成したディレクトリを公開するためにnginxのコンフィグファイルに黄色網掛け部分を追記します。
ポート80をListenしているサーバー(下記の例では”labo.takamoto.biz”)に対してロケーションを追加します。

server {
listen 80;
server_name labo.takamoto.biz;
    location /.well-known/acme-challenge/ {
        root /etc/nginx/letsencrypt;
    }
}

なお、nginxのコンフィグファイルは”/etc/nginx/nginx.conf”ですが、”/etc/nginx/conf.d”配下の拡張子”.conf”ファイルを編集することも可能です。
コンフィグファイルの編集が終了したら、設定を有効化するためにnginxを再起動します。

$ sudo systemctl restart nginx

証明書取得

以下のコマンドを発行して証明書をLet’s Encryptに要求します。

$ certbot-auto certonly –webroot -w /etc/nginx/letsencrypt/ -d labo.takamoto.biz

黄色網掛けの部分は証明書の取得要求を意味し、ピンク網掛け(webrootプラグイン)は証明書の取得先、ブルー網掛けは証明が必要なサイト名を指定しています。
証明書の取得が成功すると、以下のようなメッセージが表示されます。

IMPORTANT NOTES:
– Congratulations! Your certificate and chain have been saved at:
/etc/letsencrypt/live/labo.takamoto.biz/fullchain.pem
Your key file has been saved at:
/etc/letsencrypt/live/labo.takamoto.biz/privkey.pem
Your cert will expire on 2020-08-30. To obtain a new or tweaked
version of this certificate in the future, simply run certbot-auto
again. To non-interactively renew all of your certificates, run
“certbot-auto renew”
– If you like Certbot, please consider supporting our work by:
Donating to ISRG / Let’s Encrypt: https://letsencrypt.org/donate
Donating to EFF: https://eff.org/donate-le

上記は、証明書ファイル秘密鍵ファイルが作成されたこと、証明書の有効期限が2020年8月30日までであることが示されています。

nginxのコンフィグ変更

証明書の取得に成功したら、以下のようにnginxのコンフィグファイルを編集します。

server {
listen 80;
server_name labo.takamoto.biz;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
server_name labo.takamoto.biz;
ssl_certificate “/etc/letsencrypt/live/labo.takamoto.biz/fullchain.pem”;
ssl_certificate_key “/etc/letsencrypt/live/labo.takamoto.biz/privkey.pem”;

    location /.well-known/acme-challenge/ {
        root /etc/nginx/letsencrypt;
    }

黄色網掛けの部分は、ポート80へのリクエストがあった場合にレスポンスコード301を返却して”https”への再リクエストを促す設定です。
次の”server”ディレクティブは新規追加で、ピンク網掛けの部分は取得した証明書と秘密鍵のファイルを指定します。また、証明書の更新時にLet’s Encryptから”/.well-known/acme-challenge/”へのアクセスがありますので、ブルー網掛けのようにロケーションごとhttps側に移動しておきます。

コンフィグファイルの編集が終了したら、設定を有効化するためにnginxを再起動します。

$ sudo systemctl restart nginx

TileServerのコンテナ再作成

次に、Docker上のTileServerコンテナをSSL対応とするためにコンテナを再作成します。
コマンドは以下のようになります。

$ docker container stop tile-osaka
$ docker container rm tile-osaka
$ docker run -d -it –name tile-osaka -v /home/takamoto/tiledata/osaka:/data -p 20002:80 klokantech/tileserver-gl –public_url https://labo.takamoto.biz/osaka/

最初のコマンドでコンテナ(tile-osaka)を停止し、次に削除、最後のコマンドで公開URL(–public_url)を””https”化してコンテナ作成・起動しています。

ここまでで、TileServerのSSL化(httpsによるアクセス)が完了しました。

証明書の更新設定

前述のように、証明書は90日で期限を迎えます。
よって、以下のようにcronに証明書の更新コマンド(certbot-auto renew)登録し、証明書の期限切れを防ぎます。

$ sudo crontab -e
10 4 * * 0 root /usr/bin/certbot-auto renew –post-hook “systemctl reload nginx”

上記は、毎週日曜日の朝4:10証明書を更新します。証明書の期限30日以内なら更新され、nginxの再起動されます。

まとめ

今回は、TileServerのSSL化を行いました。
GISというよりは、インフラ系のお話でしたので、これまでとは少し方向性の違うお話でした。

次回は、作成した地図タイル(ベクトルXYZタイル)を表示するためのスクリプト”MapboxGL-JS”について説明します。