FlaskでHTTPS化をしてAndroid Chromeでエラーが出ないローカルIPのSSL証明書の作り方
概要
- 通常のオレオレ証明書(自己署名証明書)だと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)の設定ファイルを生成
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
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というのも使えそうですね。
参考
Discussion