[Nginx]PythonサービスをSSL化

コマンド

通信が暗号化されていない「http://(常時非暗号化)」のままです。これではセキュリティ的にも、ブラウザに「保護されていない通信」と表示されてしまう点でも、本番運用には適していません。

そこで今回は、続編として完全無料でSSL証明書を発行してくれる「Let’s Encrypt(レッツ・エンクリプト)」と、設定を自動化してくれるツール「Certbot(サートボット)」を使い、一瞬でサイトを「https://」に変える手順をステップ・バイ・ステップで解説します!

導入前のチェックリスト(事前準備)

作業を始める前に、以下の3点が揃っているか確認してください。

  1. 独自ドメインを持っていること
    Let’s EncryptはIPアドレス(例: 192.168.x.x)に対してはSSL証明書を発行できません。必ず example.com のようなドメインが必要です。
  2. DNSの設定が完了していること
    お使いのドメイン管理会社でお使いのサーバーのパブリックIPアドレスに「Aレコード」が紐付けられており、ドメイン名でアクセスすると前回のFlaskアプリが表示される状態にしてください。
  3. Nginxの server_name にドメインが設定されていること
    設定ファイルの server_name your_domain_or_IP; の部分に、取得したドメイン(例: example.com)が正しく記述されている必要があります。

ステップ1:Certbotのインストール

今回は、UbuntuなどのLinux環境で最も推奨されているパッケージ管理ツール「snap」を使って、常に最新版のCertbotをインストールします。

# 1. 念のため既存の古いcertbotパッケージがあれば削除
sudo apt-get remove certbot

# 2. snapdが最新であることを確認
sudo snap install core; sudo snap refresh core

# 3. Certbotのインストール
sudo snap install --classic certbot

# 4. コマンドとしてどこからでも呼び出せるようにシンボリックリンクを作成
sudo ln -s /snap/bin/certbot /usr/bin/certbot

ステップ2:ファイアウォール(UFW)の確認

SSL化を行うと、通信ポートが「80番(HTTP)」から「443番(HTTPS)」に変わります。サーバーのファイアウォールで443番ポートが閉じられているとアクセスできなくなってしまうため、許可を出しておきます。

# Nginxの全通信(80番と443番の両方)を許可する設定を適用
sudo ufw allow 'Nginx Full'

# 現在のステータスを確認(Nginx FullがALLOWになっていればOK)
sudo ufw status

※AWS(EC2)やGCP、ConoHa VPSなどをお使いの場合は、それぞれの管理画面(セキュリティグループ等)でも「HTTPS(443番)」のインバウンドルールを必ず許可しておいてください。

ステップ3:SSL証明書の取得とNginxの自動設定

ここがCertbotの最も素晴らしいところです。次のコマンドを1行実行するだけで、「SSL証明書の取得」から「Nginxの設定ファイルの書き換え」、「Nginxの再起動」までをすべて全自動で行ってくれます。

sudo certbot --nginx

コマンドを実行すると、ターミナル上でいくつか質問をされますので、以下のように回答していけば大丈夫です。

  1. メールアドレスの入力Enter email address (used for urgent renewal and security notices)→ 自身のメールアドレスを入力してEnter(証明書の期限切れ間近などの通知用です)。
  2. 利用規約への同意Please read the Terms of Service... (Y)es/(N)o:Y と入力してEnter。
  3. メールマガジンの登録(任意)Would you be willing, to share your email address... (Y)es/(N)o:→ どちらでも良いので Y または N を入力してEnter。
  4. ドメインの選択Which names would you like to activate HTTPS for?→ Nginxの設定ファイルから自動検出されたドメインの一覧が表示されます。SSL化したいドメインの番号を入力するか、すべて対象にする場合はそのまま空欄でEnterを押します。

しばらく待つと、画面に Congratulations! という文字が表示されます。これでSSL化の作業は完了です!

ステップ4:自動書き換えされた設定を確認してみよう

CertbotがNginxの設定ファイルをどう書き換えたのか、気になりますよね。先ほどの設定ファイル(例: /etc/nginx/sites-available/default)を覗いてみると、自動的に以下のような記述が追加されています。

server {
    server_name example.com;

    location / {
        proxy_pass http://127.0.0.1:8000;
        proxy_set_header Host $host;
        # ...(中略)
    }

    # ---- ここから下がCertbotによって自動追加された設定 ----
    listen 443 ssl; # 443番ポートでSSLを有効化
    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; # 証明書のパス
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; # 秘密鍵のパス
    include /etc/letsencrypt/options-ssl-nginx.conf;
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
}

# HTTP(80番)で来たら、自動的にHTTPS(443番)へリダイレクトする設定も追加されます
server {
    if ($host = example.com) {
        return 301 https://$host$request_uri;
    }
    listen 80;
    server_name example.com;
    return 404;
}

手動でやると面倒な「HTTPからHTTPSへのリダイレクト設定」まで完璧に組んでくれています。

ステップ5:ブラウザから確認

実際にブラウザを開き、自分のドメイン( http://example.com )にアクセスしてみてください。自動的に https://example.com にリダイレクトされ、URLの左側に「鍵マーク(南京錠)」が表示されていれば大成功です!

ステップ6:忘れてはいけない「自動更新」の確認

Let’s Encryptが発行する無料のSSL証明書は、有効期限が90日間しかありません。

しかし、今回インストールしたCertbotは、システム(systemd)に「1日2回、証明書の期限をチェックして、残り30日未満になっていたら自動更新する」というタスクを自動で登録してくれています。

本当に自動更新が機能するか、以下のコマンドで「更新のシミュレーション(ドライラン)」を行っておきましょう。

sudo certbot renew --dry-run

実行した結果、エラーが出ずに最後まで完了すれば、今後あなたが手動で更新作業をする必要はありません。サーバーが動いている限り、永久に無料でSSL化が維持されます。

まとめ

このわずか3つのステップで、Nginxの裏側にあるPythonアプリを完全に保護し、セキュアなWebアプリケーションへと進化させることができました。暗号化された安全な通信環境の上で、さらに素晴らしいPython開発を楽しんでください!

  1. Certbotをインストールする
  2. 443番ポートを開放する
  3. sudo certbot --nginx を実行して質問に答える

コメント

タイトルとURLをコピーしました