Gunicorn: デフォルトのSSL暗号設定は、最も安全な暗号を無効にします

作成日 2019年01月23日  ·  3コメント  ·  ソース: benoitc/gunicorn

--ciphersオプションのデフォルトはTLSv1です。

この値は、TLSv1.2でのみ使用可能な新しい強力な暗号をアクティブに無効にするため、不適切なデフォルトです。 特に、このデフォルト値で構成された暗号のセットと、OWASPによってA +と評価された暗号の間に共通部分はありません。

>>> import ssl
>>> ctx = ssl.SSLContext()
>>> ctx.set_ciphers('TLSv1')
>>> tlsv1 = {c['name'] for c in ctx.get_ciphers()}
>>> ctx.set_ciphers('DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256')  # From OWASP
>>> aplus = {c['name'] for c in ctx.get_ciphers()}
>>> aplus & tlsv1
set()

これにより、高セキュリティ設定で構成されたクライアントでOpenSSL NO_SHARED_CIPHERエラーが発生する可能性があります。

1つの解決策は、デフォルトを文字列'TLSv1:TLSv1.2'変更することにより、TLSv1.2暗号をセットに追加することです。 これにより、gunicornの既存のユーザーを壊すことなく、厳格なセキュリティ設定で構成されたクライアントの互換性が追加されます。 ただし、これにより、セットに弱い暗号が残ります。

より安全なオプションは、説明されている互換性レベルに基づいて、 OWASP文字列の1つをデフォルトとして選択することです。 たとえば、OWASP暗号文字列CまたはC-は、既知の弱い暗号を除外しながら、幅広い互換性を維持します。

いずれの場合も、ドキュメントを更新して、OWASPページへのリンクを参照として含め、予想される使用法に基づいてデフォルトをより強力なデフォルトに置き換えることを推奨することができます。

Feedback Requested FeaturSSL

最も参考になるコメント

また、Pythonには独自のデフォルトの暗号リストがあります。OpenSSLのデフォルト(明らかにDEFAULT:!aNULL:!eNULL )にフォールバックすることはありません。 内部/文書化されていませんが、 ssl._DEFAULT_CIPHERSとしてアクセスできるため、デフォルトにアクセスする方法は、SSLContextでset_ciphers()を呼び出さないことです。

Python 3.6の場合、 _DEFAULT_CIPHERS

'TLS13-AES-256-GCM-SHA384:TLS13-CHACHA20-POLY1305-SHA256:TLS13-AES-128-GCM-SHA256:ECDH+AESGCM:ECDH+CHACHA20:DH+AESGCM:DH+CHACHA20:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+HIGH:DH+HIGH:RSA+AESGCM:RSA+AES:RSA+HIGH:!aNULL:!eNULL:!MD5:!3DES'

Python3.7ではそれは

'DEFAULT:!aNULL:!eNULL:!MD5:!3DES:!DES:!RC4:!IDEA:!SEED:!aDSS:!SRP:!PSK'

「DEFAULT:OpenSSLのデフォルトの暗号リスト。1.0.2以降、リストは適切な順序になっています。」というコメントが付い

これらの設定はかなりタイトで、OWASPと同じ精神であるようです。

サーバーでの使用を目的とした_RESTRICTED_SERVER_CIPHERSあり(gunicornに最適)、一部のPythonバージョンでは_DEFAULT_CIPHERSよりもタイトですが、これは内部であり、どこでも使用されていません-しかし、少なくとも3.4以降維持されています。

したがって、オプション3はデフォルトでPythonのデフォルトの暗号スイートになります。

これを行わない唯一の理由は、古いPythonバージョンよりも安全なリストを今日出荷できると考えている場合、またはさらに厳しいOWASPレベルの1つにオプトインしたい場合です。 正直なところ、それはかなり限界です。

全てのコメント3件

この問題を報告していただきありがとうございます。 私たちはこれを完全によく知っています。 Gunicornは、しばらくの間、SSLサポートに大きな変更を加えていません。 #1933とその議論にリンクされている問題を参照してください。

それまでの間、GunicornがPython 3.4以降のみをサポートするようになったため、より賢明なデフォルトがある場合は、プルリクエストを送信してください。マージさせていただきます。 その最小バージョンをさらに高くすることも検討しているため、より安全なデフォルトを可能にするより高い最小Pythonバージョンがある場合は、次のリリースの前にその決定を推進するために、その情報をここに投稿してください。

使用可能な暗号(およびSSLContext.set_ciphers()への引数の解釈)は、Pythonのバージョンではなく、Pythonが構築するOpenSSL / LibreSSLのバージョンの影響を受けます。 Linuxでは、これは通常、ディストリビューションによって提供されるバージョンになります。

あなたの質問が「Python3.4以降で常に機能するより安全なデフォルトを設定できますか」である場合、Pythonのコンパイル方法に依存するため、厳密な答えは「いいえ」です。 強力な暗号がない非常に古いOpenSSLに対して最近のPythonをコンパイルできる可能性があるため、gunicornで強力な暗号が必要な場合は、SSLがまったく機能しない可能性があります。

しかし、私たちはかなり安全だと思います。 Python 3.4は2014年にリリースされ、TLSv1.2を追加したOpenSSL 1.0.1aは2012年4月にリリースされました。したがって、Pythonのディストリビューションバージョンにはおそらく強力な暗号が含まれています。 もう1つは、Pythonのリリースごとに特定のOpenSSLバージョンが必要なことです(たとえば、Python3.7にはOpenSSL1.0.2が必要です)が、どのPythonバージョンに何が必要か正確にはわかりません。

全体として、私はOWASPに導かれる必要があります。 彼らは、C-は「レガシー、実際の古いブラウザやレガシーライブラリとの最も広い互換性」であると言います-ソースとして引用できるという追加のボーナスがあります。

また、Pythonには独自のデフォルトの暗号リストがあります。OpenSSLのデフォルト(明らかにDEFAULT:!aNULL:!eNULL )にフォールバックすることはありません。 内部/文書化されていませんが、 ssl._DEFAULT_CIPHERSとしてアクセスできるため、デフォルトにアクセスする方法は、SSLContextでset_ciphers()を呼び出さないことです。

Python 3.6の場合、 _DEFAULT_CIPHERS

'TLS13-AES-256-GCM-SHA384:TLS13-CHACHA20-POLY1305-SHA256:TLS13-AES-128-GCM-SHA256:ECDH+AESGCM:ECDH+CHACHA20:DH+AESGCM:DH+CHACHA20:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+HIGH:DH+HIGH:RSA+AESGCM:RSA+AES:RSA+HIGH:!aNULL:!eNULL:!MD5:!3DES'

Python3.7ではそれは

'DEFAULT:!aNULL:!eNULL:!MD5:!3DES:!DES:!RC4:!IDEA:!SEED:!aDSS:!SRP:!PSK'

「DEFAULT:OpenSSLのデフォルトの暗号リスト。1.0.2以降、リストは適切な順序になっています。」というコメントが付い

これらの設定はかなりタイトで、OWASPと同じ精神であるようです。

サーバーでの使用を目的とした_RESTRICTED_SERVER_CIPHERSあり(gunicornに最適)、一部のPythonバージョンでは_DEFAULT_CIPHERSよりもタイトですが、これは内部であり、どこでも使用されていません-しかし、少なくとも3.4以降維持されています。

したがって、オプション3はデフォルトでPythonのデフォルトの暗号スイートになります。

これを行わない唯一の理由は、古いPythonバージョンよりも安全なリストを今日出荷できると考えている場合、またはさらに厳しいOWASPレベルの1つにオプトインしたい場合です。 正直なところ、それはかなり限界です。

このページは役に立ちましたか?
0 / 5 - 0 評価