はじめに
SNI(Server Name Indication)に非対応のHTTPSサーバーを、検証のために立ち上げる必要がありました。
構築の方法をメモします。
うまくいった方法
Python の BaseHTTPServer で HTTPS サーバーを立ち上げる方法です。
肝になるのは、SSLContextオブジェクトにset_servername_callbackをしている箇所です。
set_servername_callbackについてはドキュメントには下記のように記載されています。
コールバック関数 server_name_callback は 3 つの引数で呼び出されます; 最初の引数は ssl.SSLSocket です。2 つ目の引数は、クライアントが相手をしようと意図しているサーバ名を表す文字列 (または TLS Client Hello がサーバ名を含まない場合は None) です。そして 3 つ目の引数はオリジナルの SSLContext です。サーバ名引数は IDNA デコードされたサーバ名です。
TLS ネゴシエーションを継続させるならば、 server_name_callback 関数は None を返さなければなりません。TLS が失敗することを必要とするなら、 constant ALERT_DESCRIPTION_* を返してください。ここにない値を返すと、致命エラー ALERT_DESCRIPTION_INTERNAL_ERROR を引き起こします。18.2. ssl --- ソケットオブジェクトに対する TLS/SSL ラッパー — Python 3.6.7 ドキュメント
ということで、SNIに対応しないためには、ALERT_DESCRIPTION_UNRECOGNIZED_NAMEを返せばおっけいです。
うまくいかなかった方法
SNIに対応する前の Nginx をビルドしようと思いましたが、ビルドにはまってうまくいきませんでした。
次のページよれば、
SNI has been supported since 0.5.23.
とのことなので、0.5.22 を使えば、SNIに非対応のHTTPSサーバーになるはずです。