🗝

FlaskでHTTPS化をしてAndroid Chromeでエラーが出ないローカルIPのSSL証明書の作り方

2021/10/17に公開

概要

  • 通常のオレオレ証明書(自己署名証明書)だとChromeで警告が出る
  • Androidからアクセスできることが目標

HTTPS通信でないと動作しないAPIを使う時にローカル環境にHTTPSサーバが必要になる時がありました。証明書の生成に時間を要したので作り方についてまとめます。

環境

今回はラズパイにHTTPS化したFlaskを立てます。

  • RaspberryPi 3B (buster)
    • Flaskを起動
    • IPアドレスは192.168.0.12とします
  • MacBookPro 13 2020(big sur)
    • ラズパイにsshするだけに使います
  • Pixel 3a (Android 11)

サーバ証明書の生成

Flaskを起動させるマシンの任意のディレクトリで証明書や鍵を生成。以下のコマンドを実行して生成をしてきます。

  • 秘密鍵の生成

openssl genrsa 2048 > server.key

  • 秘密鍵から署名要求の生成

openssl req -new -key server.key -subj “/C=JP/ST=Some-State/O=Some-Org/CN=192.168.0.12” > server.csr

  • SAN(subject alternative names)の設定ファイルを生成
subjectnames.txt
subjectAltName = IP:192.168.0.12
basicConstraints=CA:TRUE
  • 署名要求を秘密鍵で署名しサーバ証明書を生成

openssl x509 -days 825 -req -sha256 -in server.csr -signkey server.key -extfile subjectnames.txt -extensions SAN -out server.crt

証明書の内容を確認する

openssl x509 -in server.crt -text -noout

SANの設定ファイルと同じ内容の証明書になっていることを確認します。

Androidに証明書をインストール

ラズパイからなんとかしてserver.crtをスマホに転送します。今回はscpでPCに移してからスマホに転送しました。
スマホでファイルアプリから証明書をタップするとインストールができます。

設定 > セキュリティ > 証明書のインストール > CA証明書

Flaskのコードを書く

  • Hello Worldを返すコードを書いてみます。

今までの工程をしてきたディレクトリは以下のとおりになっているものとします。

- app.py
- /openssl
  - server.crt
  - server.csr
  - server.key
  - subjectnames.txt
app.py
from flask import Flask
  app = Flask(__name__)
 	 
  @app.route('/')
  def main():
    return 'Hello world"
 	 
  if __name__ == "__main__":
    app.run(host="0.0.0.0", debug=True, ssl_context=('openssl/server.crt', 'openssl/server.key'))

コードの実行にはroot権限が必要です。

sudo python3 app.py

スマホからラズパイのipアドレスにアクセスしてSSL対応しているサイトが表示されることを確認します。

スマホに証明書を追加したので閲覧が可能になっています。証明書を追加していないPCからではアクセスできないです。

この集団はあくまでも開発環境のみに使用しましょう。

この記事を書いていて見つけたのですが、ローカル環境でSSL環境をつくるときはmkcertというのも使えそうですね。

https://github.com/FiloSottile/mkcert

参考

https://piko2.net/blog/?p=256

https://qiita.com/t-kuni/items/d3d72f429273cf0ee31e

https://qiita.com/taka_katsu411/items/fb1ad876c0017b9fe49d

Discussion