StreamlitのWebサービスをLet's EncryptでHTTPS化する手順の解説

2023年5月16日掲載

StreamlitのWebサービスをLet's EncryptでHTTPS化する手順の解説

仮想コンピューティングのUbuntu22.04にLet's Encryptという無料のSSL/TLS証明書を導入し、StreamlitによるWebサービスをHTTPS化してみたので、その手法を記事にてまとめます。

目次

  • Let's Encryptという無料のSSL/TLS証明書を導入し、StreamlitによるWebサービスをHTTPS化する手順をステップバイステップで解説します。
  • 初心者向けの記事です。

はじめに

著者は最近クラウドサービス上にてStreamlitによるWebサービスを開発・展開しました。そのWebサービスを一般ユーザーが安心かつセキュアに利用してもらうためには、SSL/TLS証明書を導入する必要があります。今回、Ubuntu22.04にLet's Encryptという無料のSSL/TLS証明書を導入し、StreamlitによるWebサービスをHTTPS化してみたので、その手順を記事にします。

なお、著者はAlibaba Cloudの仮想コンピューティングのECS(Elastic Compute Service)を使用していますが、この手法はAWS EC2やAzure VM(Virtual Machines)、Google Cloud Compute Engineにも通じます。
※文中にPublic IPアドレスがありますが、こちらはblog作成用のIPアドレスとなります(現在は削除済)
※この作業をするにあたり、前提として事前にドメインを持っていることが必須です。

1. Streamlitとは

Streamlit (streamlit-extras gallery) はPythonで構築できるオープンソースのWebサービスフレームワークです。StreamlitはPythonを使ってUIコンポーネントを直観的に記述しながらデータを素早く可視化することができます。Streamlitはテンプレートもあり、またライブラリのウィジェットを併用することで、スライダー、テキスト入力、チェックボックス、ラジオボタン、Chart、Mapなどのウィジェットを使いながら、Webサービスを自由自在にカスタマイズすることもできます。

著者はReactやDenoなどJSXによるWebサービス開発が好きですが、今回の仕様・要件からWebサービス構築にあまり工数をかけたくなかったため、Streamlitを使ってWebサービスを構築しています。

Streamlitは通常、Webサイト公開コマンド `streamlit hello` を実行すると、通常はHTTPベース、Port8501でのURLを提供してくれます。

Streamlitの操作画面

今回、StreamlitによるWebサービスを外部公開するために、公開Portを一般ユーザーが使うPortへ変更しながらHTTPS化を実施します。HTTPS化にはSSL証明書が必須です。その場合、Nginxを併用してStreamlitによるWebサービスをHTTP(Port80)へルーティングしたうえで、Nginxを使ってSSL/TLS証明書によるHTTPSへリダイレクトするように設定する必要があります。

そのための作業を細分化したところ、流れとしては次の通りになります。
Step1. Streamlitの導入
Step2. Nginxの導入
Step3. StreamlitによるWebサービスをNginxでルーティングしながら、HTTPへリダイレクト設定
Step4. NginxでLet's Encryptという無料のSSL/TLS証明書を使ってHTTPS化

<作業全体の流れ>

Streamlitの作業全体

2. Nginxのインストール

WebサーバにNginxをインストールします。このWebサーバは先述通り、著者はAlibaba Cloudの仮想コンピューティングのECS(Elastic Compute Service)を使用しています。

sudo apt update && sudo apt install nginx
Streamlit_コード

インストール処理の途中、入力ボタンが問われる場面もありますが、ここでは「Y」を選定します。

Streamlit_コード_1

途中背景ピンク色の画面も出てきますが、ここでは「Enter」キーを押します。

Streamlit_Nginxのインストール_2

Nginxインストールが無事完了したら、Nginxのステータスを確認します。

systemctl status nginx
Streamlit_コード_2

※解除する場合は、ctrl + cをクリックします。

Nginxのステータスが「active(running)」になっているので、次のステップへ進めます。もしactive状態でなければ、「systemctl restart nginx」でリスタート等対処をしてください。

Nginxのステータスが「active(running)」であれば、今度はそのWebサーバ(Alibaba Cloud ECS)のPublic IP アドレスを使って、ブラウザを入力しながらNginxが見れるか確認します。注意として、その仮想コンピューティングにはPort 80と443を事前に解放しておく必要があります。

Streamlitのページ画面

3. StreamlitによるWebサービス立ち上げ

NginxのインストールおよびブラウザにてWebサイトが閲覧できたので、今度はStreamlitによるWebサービスをNginxでルーティングします。

3-1. まずはStreamlitによるWebサービスを確認します。ターミナルにてstreamlitコマンドを実行します。

streamlit hello
Streamlit_コード_3

ここで出力されるhttp://47.91.18.116:8501のうち、http://47.91.18.116はWebサーバのパブリックIPアドレス、8501はStreamlitによるデフォルトのPortを指します。このPort 8501を使って通信することで、ブラウザからStreamlitによるWebサービスを見ることが出来ます。
このグローバルIPアドレスはご自身の環境に置き換えてください。

Streamlitの操作画面_IPアドレス
Streamlitの操作画面_2

一方、このURLのPort 8501を外したらどうなるでしょうか?その結果としては、先述通りNginxによるページが表示されます。

Streamlitの操作画面_4

なので、StreamlitによるページとしてPort8051でなく、Port80、すなわちHTTPページとして閲覧するために、StreamlitによるWebサービスをNginxでルーティングしながら、HTTPへリダイレクト設定します。

なお、Streamlitによるコマンドの引数 `--server.port` で80を指定して Port80で StreamlitによるWebサービスを閲覧することもできますが、それでは最終的にやりたいこと・HTTPS化したStreamlitによるWebサービスが実現できなくなります。そのため、Nginxを使ってルーティングしながらHTTPS化したStreamlitによるWebサービスを表示するというのが今回のシナリオになります。

4. Nginxによるルーティング

まずはNginxで正常ルーティングができるかどうかを確認します。先述の手順でhttp://47.91.18.116:8501 でアクセスすることが確認できたので、次はポート指定なしの http://47.91.18.116 でも接続できるように設定します。Nginxのsites-availableとsites-enabledフォルダを開き、中身を確認します。
このグローバルIPアドレスはご自身の環境に置き換えてください。

cd /etc/nginx/
Streamlit_コード_4

ここで注目したいのは、nginxのパスです。ドメイン設定ファイル用のフォルダと、ドメイン設定ファイルのリンク用のフォルダがあるので、これを使ってルーティングするように設定します。注意として、この作業は途中で止めたらNginx設定から最悪Webサーバ(ECSインスタンス)を再購入せざるを得ない状況になるので、一気呵成で作業を終わらせる必要があります。

/etc/nginx/sites-available  #ドメイン設定ファイル用のフォルダ
/etc/nginx/sites-enabled #ドメイン設定ファイルのリンク用のフォルダ
Streamlit_コード_5

nginx.confを下記のように設定します

vi /etc/nginx/nginx.conf

server {
    listen       80;
    listen       [::]:80;
    server_name  _;
    root         /usr/share/nginx/html;

    # Load configuration files for the default server block.
    include /etc/nginx/default.d/*.conf;
    location / {
    }
    error_page 404 /404.html;
        location = /40x.html {
    }
}
Streamlit_コード_6

続いて、下記のコマンドでsites-availableとsites-enabledフォルダ書き込む権限を付与します。

sudo chmod 777 /etc/nginx/sites-available
sudo chmod 777 /etc/nginx/sites-enabled 
Streamlit_コード_7

sites-availableとsites-enabledフォルダの権限を変更したら、HTTP Port80からStreamlit Port 8501にルーティングするよう、nginxのルーティング設定を追加します。

下記のパスに nginxのルーティング設定用の「streamlit-webservice」ファイルを作成します。(ファイル名は何でも良いです)streamlit-webserviceファイルの中身は次の設定を入れます。
中身としては、ブラウザとしてserver_name および listenのportへアクセスしたら、ルーティング情報として proxu_passへリダイレクトするように設定します。

vi /etc/nginx/sites-available/streamlit-webservice

server {
    listen       80;
    server_name  47.74.21.181; #ドメイン名またはIPアドレス
    location / {
        proxy_pass http://0.0.0.0:8501/; # HTTP Port80からStreamlit Port 8501にルーティングさせます
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_redirect off;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }
}
Streamlit_コード_7

streamlit-webserviceファイルの設定ができたら、シンボリックリンクを作成します。シンボリックリンクはファイルシステム上でアクセスがあれば、ターゲットとなるファイルやディレクトリへ参照する機能です。Unix系オペレーションだと、`ln` コマンドの `-s` オプションなどが該当します。

ln -s /etc/nginx/sites-available/streamlit-webservice  /etc/nginx/sites-enabled/streamlit-webservice
Streamlit_コード_8

上記設定が終われば、Nginxを再起動します。

sudo service nginx restart
sudo service nginx status 
Streamlit_コード_8

Nginxの設定ファイルの設定が終われば、テストとしてStreamlitを起動してみます。

streamlit hello 
Streamlit_コード_9

Nginxのルーティングを確認します。まずはPort 8501付きのブラウザから。

Streamlit_コード_9

こちらはStreamlitによるWebサービスが無事表示されています。
今度はPort 8501無し、すなわちPort80として通常アクセスしたときの結果を確認します。

Streamlit_コード_10

これも、Port 80による StreamlitによるWebサービスが無事表示されています。これでNginxによるルーティング設定は完了です。

5. NginxでSSL証明書を利用

SSL証明書を利用するために、certbot(Let's encrypt)をインストールします。

sudo apt install certbot python3-certbot-nginx

次のコマンドで、ドメインに対してSSL証明書を発行します。今回の例では、search.xxxxxx.coomというドメインに対しSSL証明書を発行します。

sudo certbot --nginx -d <ドメイン>

この作業の途中にて、メールアドレス入力が問われますので、登録者のメールアドレスを入力します。

Streamlit_コード_10

SSL設定が完了したら、Nginxの設定ファイルで、Public IPアドレスをドメイン名に変更します。先ほどはブラウザとしてURLにWebサーバのPublic IP へアクセスしたら、ルーティング情報として StreamlitによるWebサービスへリダイレクトするように設定に対し、今度はブラウザからドメインによるURLアクセスをした際StreamlitによるWebサービスへリダイレクトするよう設定となります。

vi /etc/nginx/sites-available/streamlit-webservice

server {
    listen       80;
    server_name  search.xxxxxx.com; #ドメイン名またはIPアドレス
    location / {
        proxy_pass http://0.0.0.0:8501/; # HTTP Port80からStreamlit Port 8501にルーティングさせます
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_redirect off;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }
}

引き続き、同じ設定内容にて、HTTPリクエストがあった場合、SSL証明書を通じてHTTPSへリダイレクトするよう設定します。そのためには、以下設定情報を追記更新します。

server {
    listen       80;
    server_name  search.xxxxxx.com; #ドメイン名またはIPアドレス
    location / {
        proxy_pass http://0.0.0.0:8501/; # HTTP Port80からStreamlit Port 8501にルーティング
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_redirect off;
        proxy_http_version 1.1; # upgradeしないと、ずっとローディングして動かない
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }

    listen 443 ssl;
    ssl_certificate /etc/letsencrypt/live/search.xxxxxx.com/fullchain.pem; # Certbotによる証明書で認証
    ssl_certificate_key /etc/letsencrypt/live/search.xxxxxx.com/privkey.pem; # Certbotによる証明書で認証
    include /etc/letsencrypt/options-ssl-nginx.conf;
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
}
server {
        listen 80;
        server_name  search.xxxxxx.com;
        return 301 https://$server_name$request_uri; # httpリクエストをhttpsにリダイレクト
}
Streamlit_コード_11

この設定が終われば、StreamlitによるデフォルトのPort8501は使わないので、WebサーバのネットワークルールとしてPort8501の疎通を解除(削除)します。

Streamlitの操作画面_5

続いて、必要に応じてnginx.conf のSSLプロトコルを設定します。SSL/TLS通信において、2023年4月現在、TLS1.0、1.1はサポート終了しており(TLS1.0、TLS1.1サポート終了のお知らせ)脆弱性の問題があるため、もしWebサイトを外部向け公開する際にはnginx.conf設定でSSLプロトコルを変更する必要があります。

nginx.confを下記のように設定します

vi /etc/nginx/nginx.conf
~略~
#ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; # Dropping SSLv3, ref: POODLE #コメントアウト
ssl_protocols  TLSv1.2 TLSv1.3; # Dropping SSLv3 TLSv1 TLSv1.1 , ref: POODLE
ssl_prefer_server_ciphers on;

~略~
Streamlit_コード_11

上記諸々の設定編集が終われば、Nginx をリスタートさせます。

sudo service nginx restart

これで、StreamlitによるWebサービスがHTTPSでみれるようになります。

Streamlit_コード_12
Streamlit_操作画面_4
Streamlit_コード_13

6. SSL証明書の自動更新

Let’s EncryptのSSL証明書は無料の代わりに、有効期間は90日間という制限があります。そのため、Certbotのパッケージにてsystemdタイマーを追加することで、有効期限が切れそうな場合でも自動更新をすることができます。1日に2回このスクリプトが実行され、有効期限の30日以内にある証明書を自動更新しています。
systemctlを使用してタイマーのステータスを確認します。

sudo systemctl status certbot.timer
Streamlit_コード_14

自動更新が正しく設定できているか、確認します。下記のコマンドで実行すると、自動更新が正しく設定されているなら結果がSucceedと返却されます。

sudo certbot renew --dry-run
Streamlit_コード_15

7. さいごに

本記事では、Let's Encryptという無料のSSL/TLS証明書を使って、StreamlitによるWebサービスをHTTPSで公開する手順を記載しました。
SSL証明書はWebサービスやアプリケーションでセキュリティを強化するために使用する重要なツールです。

SSL証明書を使うことで、Webサイトやアプリケーションとユーザ間の通信が暗号化されるので、第三者がデータを盗み見たり、改ざんすることが困難になります。例えば、ログイン情報や住所など個人情報、クレジットカード情報など機密データを保護するためには堅牢な暗号化された通信技術が必須です。同時に、SSL証明書は証明書発行機関(CA)によってSSL証明書を発行するため、所有者の身元を確認し、ユーザーにそのWebサイトが信頼できることを示せるので、フィッシング攻撃や、詐欺サイトなどからユーザーを守ることもできます。更にSSL証明書を使用して信頼できるWebサイトであれば、GoogleやYahooなどのSEO(検索エンジン最適化)において、検索結果のランキングで上位へ有利に動けるよう貢献するメリットもあります。 

Webサイトやアプリケーションで利用するサーバ証明書にはドメイン認証(DV:Domain Validation)、組織認証(OV:Organization Validation)、拡張組織認証(EV:Extended Validation)の3種類が存在します。これはWebサイト自体の信頼度によって用途が変わります。今回の記事で使用したLet's Encryptはドメイン認証(DV)なので取得難易度が低く、無料で調整しやすいです。一方、会社や財団とか法人によるWebサイトであれば、一般的には組織認証(OV)が推奨となります。日本の場合、法人登記や帝国データバンクなどを参照しながらSSL証明書を発行してくれるため、導入ハードルが上がりますが、一般ユーザーによるサイトとの違いを明確化するのに役立ってくれます。この組織認証(OV)の上位である拡張組織認証(EV)があり、これは銀行口座の利用状況や証券会社などお金を使うWebサイトでは必須となっています。

SSL/TLS証明書はWebサイトに対するセキュリティ向上や脆弱性対策、リスク回避などにも使われる技術なので、是非参考にしてみてください。

関連サービス

Amazon Web Services (AWS)

ソフトバンクはAWS アドバンストティアサービスパートナーです。「はじめてのAWS導入」から大規模なサービス基盤や基幹システムの構築まで、お客さまのご要望にあわせて最適なAWS環境の導入を支援します。

Microsoft Azure

Microsoft Azureは、Microsoftが提供するパブリッククラウドプラットフォームです。コンピューティングからデータ保存、アプリケーションなどのリソースを、必要な時に必要な量だけ従量課金で利用することができます。

Google Cloud

Google サービスを支える、信頼性に富んだクラウドサービスです。お客さまのニーズにあわせて利用可能なコンピューティングサービスに始まり、データから価値を導き出す情報分析や、最先端の機械学習技術が搭載されています。

Alibaba Cloud

Alibaba Cloudは中国国内でのクラウド利用はもちろん、日本-中国間のネットワークの不安定さの解消、中国サイバーセキュリティ法への対策など、中国進出に際する課題を解消できるパブリッククラウドサービスです。

MSPサービス

MSP(Managed Service Provider)サービスは、お客さまのパブリッククラウドの導入から運用までをトータルでご提供するマネージドサービスです。

おすすめの記事

条件に該当するページがございません