本ガイドでは、Python Flask 開発サーバーで HTTPS を有効化するために SSL 証明書をインストールする手順について説明します。例では Linux、Python 3.6、Flask 2.0.3 を使用します。
前提条件
開始する前に、以下の条件を満たしていることを確認してください。
信頼された認証局(CA)が発行した SSL 証明書を取得済みであること。証明書の有効期限が切れている場合は、あらかじめ更新を行ってください。
保護したいすべてのドメイン名をカバーする証明書です。次のカバレッジルールが適用されます。ドメイン名を追加するには、公式証明書の購入またはドメイン名の追加と置き換えを行います。
完全一致ドメイン:
example.comはexample.comのみを保護します。www.example.comはwww.example.comのみを保護します。ワイルドカードドメイン:
*.example.comはwww.example.comやa.example.comなどの 1 段階のサブドメインをカバーしますが、ルートドメインexample.comやa.b.example.comなどの多段階サブドメインはカバーしません。注: 多段階サブドメインを保護するには、バインド済みドメイン フィールドに正確なドメイン(例:a.b.example.com)または一致するワイルドカード(例:*.b.example.com)を追加してください。
サーバー上で
rootアカウント、またはsudo権限を持つアカウントを保有していること。ドメインの DNS レコードがサーバーのパブリック IP アドレスを指すように設定されていること。
ドメイン名の名前解決:ドメインの DNS レコードが正しく設定され、サーバーのパブリック IP アドレスに解決されること。
サーバーに Python および Flask がインストール済みであること。
ステップ 1:SSL 証明書の準備
SSL 証明書管理 ページに移動します。証明書を検索し、証明書のダウンロード をクリックします(操作 列)。ダウンロード タブで、サーバータイプ として その他 を選択し、パッケージをダウンロードします。
ダウンロードしたパッケージを展開します。
パッケージに証明書ファイル(
.pem)と秘密鍵ファイル(.key)が含まれている場合、両方のファイルを保存してください(デプロイメントに必要です)。パッケージに証明書ファイル(
.pem)のみが含まれており、秘密鍵ファイル(.key)が含まれていない場合、ローカルマシンに保存されている秘密鍵ファイルとともに証明書をデプロイします。
証明書の申請時に、OpenSSL や keytool などのツールを使用して証明書署名要求 (CSR) を生成した場合、秘密鍵はお客様のローカルマシン上にのみ保存され、ダウンロードしたパッケージには含まれません。秘密鍵を紛失すると、証明書は使用できなくなります。新しい証明書を購入する必要があり、新しい CSR と秘密鍵を生成する必要があります。
ステップ 2:システムおよびネットワーク環境の構成
サーバーのセキュリティグループおよびシステムファイアウォールが、TCP ポート 443(HTTPS)へのインバウンドトラフィックを許可していることを確認してください。
ポート 443 が開放されているか確認する
以下のコマンドを実行して、ポート 443 の状態を確認します。<your_server_public_ip> をサーバーのパブリック IP アドレスに置き換えてください。
RHEL/CentOS
command -v nc > /dev/null 2>&1 || sudo yum install -y nc
# <your_server_public_ip> をサーバーのパブリック IP アドレスに置き換えます。
sudo ss -tlnp | grep -q ':443 ' || sudo nc -l 443 & sleep 1; nc -w 3 -vz <your_server_public_ip> 443ポート 443 が開放されている場合、出力は次のようになります。
Ncat: Connected to <your_server_public_ip>:443Debian/Ubuntu
command -v nc > /dev/null 2>&1 || sudo apt-get install -y netcat
# <your_server_public_ip> をサーバーのパブリック IP アドレスに置き換えます。
sudo ss -tlnp | grep -q ':443 ' || sudo nc -l -p 443 & sleep 1; nc -w 3 -vz <your_server_public_ip> 443ポート 443 が開放されている場合、出力は次のいずれかになります。
Connection to <your_server_public_ip> port [tcp/https] succeeded!または
[<your_server_public_ip>] 443 (https) openポート 443 が開放されていない場合は、次の 2 つの手順を実行して開放してください。
セキュリティグループでポート 443 を開放する
サーバーがクラウドプラットフォーム上で実行されている場合、そのセキュリティグループは TCP ポート 443 へのインバウンドトラフィックを許可する必要があります。そうでないと、サービスに到達できません。以下の手順では Alibaba Cloud Elastic Compute Service (ECS) を例として示します。他のクラウドプラットフォームについては、各社のドキュメントをご参照ください。
ECS インスタンス ページに移動し、ターゲットインスタンスをクリックしてその詳細ページを開きます。[セキュリティグループの詳細] セクションで、次の設定で セキュリティグループルールを追加します。
| フィールド | 値 |
|---|---|
| 操作 | 許可 |
| プロトコル | カスタム TCP |
| 送信先(現在のインスタンス) | HTTPS(443) |
| 送信元 | 0.0.0.0/0(任意の場所) |
ファイアウォールでポート 443 を開放する
アクティブなファイアウォールサービスを特定するため、以下のコマンドを実行します。
if command -v systemctl >/dev/null 2>&1 && systemctl is-active --quiet firewalld; then
echo "firewalld"
elif command -v ufw >/dev/null 2>&1 && sudo ufw status | grep -qw active; then
echo "ufw"
elif command -v nft >/dev/null 2>&1 && sudo nft list ruleset 2>/dev/null | grep -q 'table'; then
echo "nftables"
elif command -v systemctl >/dev/null 2>&1 && systemctl is-active --quiet iptables; then
echo "iptables"
elif command -v iptables >/dev/null 2>&1 && sudo iptables -L 2>/dev/null | grep -qE 'REJECT|DROP|ACCEPT'; then
echo "iptables"
else
echo "none"
fi出力が none の場合、追加の操作は不要です。それ以外の場合、以下の対応するコマンドを実行してポート 443 を開放します。
firewalld
sudo firewall-cmd --permanent --add-port=443/tcp && sudo firewall-cmd --reloadufw
sudo ufw allow 443/tcpnftables
sudo nft add table inet filter 2>/dev/null
sudo nft add chain inet filter input '{ type filter hook input priority 0; }' 2>/dev/null
sudo nft add rule inet filter input tcp dport 443 counter accept 2>/dev/nulliptables
sudo iptables -A INPUT -p tcp --dport 443 -j ACCEPTiptables ルールを再起動後も維持するには:
RHEL/CentOS:
sudo yum install -y iptables-services sudo service iptables saveDebian/Ubuntu:
sudo apt-get install -y iptables-persistent sudo iptables-save | sudo tee /etc/iptables/rules.v4 >/dev/null
ステップ 3:Flask アプリケーションへの証明書のインストール
証明書ファイルを格納するディレクトリを作成します。
mkdir /ssl証明書ファイル(
.pem)および秘密鍵ファイル(.key)を/sslにアップロードします。リモートログインツールのファイルアップロード機能を使用してファイルを転送します。一般的なツールには、PuTTY、Xshell、および WinSCP が含まれます。Alibaba Cloud ECS インスタンスを使用している場合は、「ファイルのアップロードまたはダウンロード」をご参照ください。
Flask アプリケーションファイルを開き、
ssl_contextを使用して SSL を構成します。以下は完全な例です。この例をコピーし、証明書のパスを更新してtest.pyとして保存し、簡易テストを実行してください。# Flask ウェブフレームワークをインポート from flask import Flask app = Flask(__name__) @app.route("/") def main(): return "<p>Hello, World!</p>" # SSL 証明書を構成します。 # デフォルトの HTTPS ポートは 443 です。 # '/ssl/cert.pem' を証明書ファイルの絶対パスに置き換えます。 # '/ssl/cert.key' を秘密鍵ファイルの絶対パスに置き換えます。 context = (r'/ssl/cert.pem', r'/ssl/cert.key') app.run(host="0.0.0.0", port=443, ssl_context=context)test.pyを含むディレクトリに移動し、Flask サービスを起動します。# test.py を実際のファイル名に置き換えます。 python test.pyFlask が正常に起動した場合、出力は次のようになります。
* Serving Flask app 'test' * Running on all addresses (0.0.0.0) * Running on https://127.0.0.1:443 * Running on https://<your_server_public_ip>:443
インストールの確認
ブラウザで証明書を確認する
ブラウザで https://yourdomain を開きます(yourdomain を実際のドメイン名に置き換えます)。アドレスバーに鍵アイコンが表示されれば、証明書が正しくデプロイされたことを確認できます。

Chrome バージョン 117 以降では、
アイコンが
に変更されています。このアイコンをクリックすると、証明書の詳細を確認できます。
鍵アイコンが表示されない場合やアクセスエラーが発生した場合は、ブラウザのキャッシュをクリアするか、シークレットモードで再度試してください。
問題が解決しない場合は、「ブラウザのエラーメッセージに基づいて証明書のデプロイメントに関する問題を解決する」および「SSL 証明書デプロイメントのトラブルシューティングガイド」をご参照ください。
本番環境への適用
本番環境へ移行する際には、セキュリティおよび安定性を向上させるために、以下のベストプラクティスを適用してください。
非 root ユーザーとして実行:アプリケーション専用の特権の低いシステムユーザーを作成します。アプリケーションを root ユーザーまたは管理者権限で実行しないでください。
本番環境向けのデプロイメントでは、SSL 終端処理を Flask 内ではなくゲートウェイ層で構成することを推奨します。証明書を Server Load Balancer (SLB) や Nginx などのリバースプロキシにデプロイします。ゲートウェイが HTTPS を処理し、復号された HTTP トラフィックを Flask アプリケーションに転送します。
資格情報のコード内保管を避ける:パスワードおよび機密情報を環境変数、Vault、またはクラウドキー管理サービスに格納します。ソースファイルや構成ファイルにハードコードしないでください。
HTTP から HTTPS へのリダイレクト:サーバーを構成して、すべての HTTP トラフィックを HTTPS にリダイレクトするようにします。これにより、中間者攻撃を防止できます。
レガシープロトコルの無効化:サーバー構成で SSLv3、TLS 1.0、TLS 1.1 を無効化します。TLS 1.2 および TLS 1.3 のみを有効化します。
証明書の有効期限の監視: デプロイメント後、Certificate Management Service でドメイン監視を有効化します。Alibaba Cloud が証明書の有効期間を確認し、有効期限が切れる前に更新のリマインダーを送信します。詳細については、「パブリックドメイン名のモニタリングの購入および有効化」をご参照ください。
よくある質問
証明書のインストールまたは更新後に HTTPS にアクセスできないのはなぜですか?
これは通常、以下のいずれかの原因によって発生します。順に確認してください。
ポート 443 がブロックされている:セキュリティグループまたはファイアウォールがポート 443 のトラフィックを許可していません。「ステップ 2:システムおよびネットワーク環境の構成」をご参照ください。
ドメイン名の不一致:アクセスしようとしているドメイン名が証明書の バインド済みドメイン にリストされていません。ドメイン名の一致ルールについては、「前提条件」をご参照ください。
Flask の再起動が行われていない:アプリケーションファイルを変更した後は、Flask を再起動してください。
証明書パスの誤り:
.pemおよび.keyファイルのパスがssl_contextで正しく指定されているか、最新かつ有効な証明書ファイルが使用されているかを確認してください。他のサービスに証明書がない場合:ドメインでコンテンツデリバリーネットワーク (CDN)、Server Load Balancer (SLB)、または Web Application Firewall (WAF) を使用している場合は、これらのサービスにも証明書をインストールしてください。詳細については、「トラフィックが複数の Alibaba Cloud サービスを経由する場合の証明書のデプロイ先」をご参照ください。
複数サーバーへの部分的なデプロイメント:ドメインの DNS が複数のサーバーを指す場合、すべてのサーバーに証明書をインストールする必要があります。
インストール済みの証明書を更新または置き換えるにはどうすればよいですか?
サーバー上の既存の
.pemおよび.keyファイルをバックアップします。Certificate Management Service コンソールから新しい証明書および秘密鍵ファイルをダウンロードします。
新しいファイルをサーバーにアップロードし、古いファイルを上書きします。Flask 構成で指定されたファイルパスおよびファイル名はそのまま保持します。
新しい証明書を適用するために Flask を再起動します。
Flask が起動時に FileNotFoundError をスローする
このエラーは、ssl_context 内のファイルパスが誤っていることを意味します。ssl_context で指定された証明書および秘密鍵ファイルのパスが正しいか確認してください。パスは python <your-app-file>.py コマンドを実行するディレクトリを基準とした相対パスであるか、絶対パスを使用してください。
ブラウザに ERR_SSL_PROTOCOL_ERROR が表示される、または接続がリセットされる
以下の点を確認してください。
証明書ファイルと秘密鍵ファイルは互いに一致します。
証明書ファイルは、完全な証明書チェーン (通常は
.pemファイル) です。Alibaba Cloud からダウンロードした証明書ファイルには、すでに完全なチェーンが含まれています。セキュリティグループとファイアウォールは、ポート 443 上のインバウンドトラフィックを許可します。