zkat’s diary

技術ブログ

SNIに非対応のHTTPSサーバーを立ち上げる

はじめに

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.

Configuring HTTPS servers

とのことなので、0.5.22 を使えば、SNIに非対応のHTTPSサーバーになるはずです。