MotoJapan's Tech-Memo

技術めも

【flask】https対応Webサーバーをバックグランド実行する方法 【お家IT#5】

本件の実装の一部
motojapan.hateblo.jp

前回の続き
motojapan.hateblo.jp

目次

標準入力をバックグラウンドで無視すると落ちる

前回 flaskをhttps化 (http over ssl)したが、実行時にはpass phraseの入力が必要。
サーバーなのでSSHで繋ぎ、バックグラウンドで実行してセッションを切断したいことはよくある。
ただし、前回のスクリプトを無理やりバックグラウンド実行すると次のエラーが出る。

$$ sudo python app.py &
$ Enter PEM pass phrase:
    Traceback (most recent call last):
  File "app.py", line 8, in <module>
    context.load_cert_chain('cert.crt', 'server_secret.key')
IOError: [Errno 22] Invalid argument

バックグラウンド実行対策

load_cert_chainの第3引数にパスワードを入れてあげると可能

#app.py
from flask import Flask, render_template, request
import ssl

app = Flask(__name__)
context = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2)

# >>> 対策前
#context.load_cert_chain('cert.crt', 'server_secret.key')
# <<<

# >>> 対策後
with open('./pwd.txt') as f:
    #平文で書くのは怖いのでローカル管理するファイルを呼び出す
    pwd = f.read()
context.load_cert_chain('cert.crt', 'server_secret.key', pwd)
# <<<

@app.route("/")
def index():
    return render_template('index.html')

if __name__ == "__main__":
    app.run(host='0.0.0.0', port=800, ssl_context=context, threaded=True, debug=True)

下記参考資料のAPI referenceにも次の通りの記載。

password 引数に、秘密鍵を復号するためのパスワードを返す関数を与えることができます。その関数は秘密鍵が暗号化されていて、なおかつパスワードが必要な場合にのみ呼び出されます。その関数は引数なしで呼び出され、string, bytes, または bytearray を返さなければなりません。戻り値が string の場合は鍵を復号化するのに使う前に UTF-8エンコードされます。string の代わりに bytes や bytearray を返した場合は password 引数に直接供給されます。秘密鍵が暗号化されていなかったりパスワードを必要としない場合は、指定は無視されます。

password が与えられず、そしてパスワードが必要な場合には、OpenSSL 組み込みのパスワード問い合わせメカニズムが、ユーザに対話的にパスワードを問い合わせます。


Python 標準ライブラリ」「18.2. ssl — ソケットオブジェクトに対する TLS/SSL ラッパー」より
URL:
https://docs.python.jp/3/library/ssl.html

これでめでたく、PC版Android版でもChromeWebカメラが動くので、次回からは撮影した画像をbase64化してjavascriptで送る部分を進める。