Gunicorn: 在 --ssl-version 标志中添加对命名常量的支持

创建于 2015-09-15  ·  37评论  ·  资料来源: benoitc/gunicorn

我正在使用带有 ssl 证书和密钥的 gunicorn。 它提供 TLS 连接 1.0。 是否可以将 gunicorn 配置为使用 TLS 1.2?

Improvement Documentation help wanted FeaturSSL - Mailing List -

所有37条评论

@rrajaravi ,您是否尝试设置http://docs.gunicorn.org/en/latest/settings.html#ciphers

如何确定它是否有效?

我们可以关闭这个问题吗?

TL; 博士
Gunicorn 似乎只支持:
TLSv1
SSLv2

并且不支持:
SSLv3
SSLv23
TLSv1_1
TLSv1_2

@berkerpeksag http://docs.gunicorn.org/en/latest/settings.html#ciphers 上的文档似乎不正确。
我在 ssl.py 中找到了协议。 除了 TLSv1 和 SSLv2,它们都在 Ubuntu 14.04 LTS、Python 3.5.1、OpenSSL 1.0.1f 2014 年 1 月 6 日的命令行选项中提供时有效

其余的失败并出现错误:
[2016-03-22 08:51:49 +0000] [2924] [ERROR] 工作进程异常:
回溯(最近一次调用最后一次):
文件“/home/me/Envs/myproject/lib/python3.5/site-packages/gunicorn/workers/sync.py”,第126行,句柄
self.cfg.ssl_options)文件“/usr/local/lib/python3.5/ssl.py”,第 1064 行,在 wrap_socket密码=密码)文件“/usr/local/lib/python3.5/ssl.py”,第 690 行,在 **init 中
self._context.set_ciphers(ciphers)
ssl.SSLError: ('不能选择密码。',)


/usr/local/lib/python3.5/ssl.py
以下常量标识各种 SSL 协议变体:

协议_SSLv2
协议_SSLv3
协议_SSLv23
协议_TLSv1
PROTOCOL_TLSv1_1
PROTOCOL_TLSv1_2

感谢您对此进行分类,@edwardotis。 我正在重新打开它以澄清文档。

@berkerpeksag我们

TLSv1对于较旧的 Python 版本看起来不错,但也许我们可以将默认值更改为SSLv23以使用最佳可用协议(对于客户端和服务器)。

另外,我认为如果在 Gunicorn 20 中使用SSLv2SSLv3 ,我们应该引发异常(在下一个 19.x 版本中弃用它们会很棒)。

@berkerpeksag :+1:

有没有人实施这些更改? 如果没有,我很乐意试一试并打开 PR.. 能够将密码设置为 > TLSv1.0 对我们很重要,从我们可以看到的任何版本的 TLS 大于 1 都可以' t be set..它只是默认回到1.0(我们尝试了文档中列出的那些和这里列出的常量无济于事)——只是输出No cipher can be selected

@AndrewJHart那太好了! :) 谢谢!

可以使用其他版本。 您只需要在命令行上为--ssl-version指定一个常量。 这些常量来自ssl stdlib 模块。

$ python -c "import ssl; print(ssl.PROTOCOL_SSLv23)"     
  2
$ python -c "import ssl; print(ssl.PROTOCOL_TLSv1_2)"
  5

只需指定--ssl-version 2--ssl-version 5获得 TLS 1.2 密码支持。

@AndrewJHart如果您想对 SSL 做出一些改进,请查看 #1440。 我们应该改用 SSLContext 以更好地控制上下文,例如设置服务器密码顺序首选项。 我将立即发布关于该问题的差异,并举例说明开始为同步工作者实现这一点。 任何改进 SSL 支持的帮助将不胜感激。

此外,一个简单的拉取请求来更改 gunicorn/config.py 中的默认值以使用 SSLv23 常量而不是 TLSv1 会很棒。

对不起,我是想说#1140

我不明白为什么重新打开这个问题。 我用--ssl-version 2测试了 Gunicorn,发现 TLS 1.2 密码工作正常。

我将关闭,但如果您认为我这样做有误,请重新打开并解释。

我打开 #1249 来跟踪更改默认值。

我重新打开它是因为:

a) 用户应该能够传递'SSLv23''TLSv1_2'而不是25
b) 我们应该记录可用的选项,而不是将它们重定向到 Python 文档。 https://docs.python.org/3.5/library/ssl.html是 stdlib 中最长的文档之一,用户不应该花太多时间来查看可用选项。

重新打开,添加文档标签。

让我知道这里需要什么,如果我们能在 19.5 版本之前(即周三之前)关闭它会很酷:)

这仍然是开放的,只提供对命名常量的支持
--ssl-version 标志。

在周一年,2016年5月2日,05:43伯努瓦Chesneau [email protected]写道:

让我知道这里需要什么,如果我们可以在 19.5 版本之前关闭它
(即在周三之前)会很酷:)


您收到此消息是因为您修改了打开/关闭状态。
直接回复此邮件或在 GitHub 上查看
https://github.com/benoitc/gunicorn/issues/1114#issuecomment -216225302

让我们暂时忘记 3.x 版本。 要在所有版本的 python 上支持它,需要添加哪些常量?

这是一个概念验证: https :

是否可以指定不同版本的 TLS 来启用或禁用? 例如,通常希望能够禁用或启用旧版本。 从文档中我不清楚“--ssl-version”是否可用于禁用旧版本,或者是否可以多次使用(例如禁用 SSL3 和禁用 TLS1.0)。

我认为这需要切换到使用SSLContext并添加一个新选项--ssl-options (我们可能只使用ssl.create_default_context()因此默认情况下将禁用 SSLv3 和 TLS 1.0)因为有组合太多我认为--ssl-version不会接受命名常量,但用户仍然可以将它放在 Gunicorn 配置文件中:

ssl_options = ssl.OP_NO_COMPRESSION | ssl.OP_NO_SSLv2 | ssl.OP_NO_SSLv3

使用PROTOCOL_ * 来指定协议 _ 和确切版本_ 似乎越来越不推荐使用。 假设当前没有实现ssl_options ,我提出了 #1680。

1890 修复了它。

也许有人可以为我提供一些指导? 我已经为此苦苦挣扎了一段时间。 这是我的环境:

Python 3.4.3
gunicorn==19.9.0
pyOpenSSL==18.0.0
cryptography==2.4.2

我也在使用 gunicorn 标志--ssl-version 5

我的服务器似乎正在提供 TLS 1.2,但它允许大量不安全的密码套件。 如何限制密码套件? 我尝试了--ciphers标志,但没有运气。

谢谢!

--ssl-version 5 --ciphers ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-SHA256
工作得很好:

~# openssl s_client -connect localhost:443 -cipher ECDHE-RSA-AES256-GCM-SHA384
已连接(00000003)
深度=3...

~# openssl s_client -connect localhost:443 -cipher DHE-RSA-AES256-GCM-SHA384
已连接(00000003)
140497569816640:错误:14094410 :SSL例程:ssl3_read_bytes :sslv3 警报握手失败:../ssl/record/rec_layer_s3.c :1407:SSL 警报编号 40

谢谢@lemrouch。 不知道为什么这对我以前不起作用。 它现在对我有用!

如何使用 TLS 1.2 而不是 TLS1.0 用于 gunicorn 烧瓶应用程序? 有人可以分享必须输入的终端命令或代码吗?

@rkbala这是我的烧瓶应用程序的相关代码:

...
from ssl import SSLContext, PROTOCOL_TLSv1_2, OP_NO_SSLv3, OP_NO_TLSv1, OP_NO_TLSv1_1
...
ssl = SSLContext(PROTOCOL_TLSv1_2)
ssl.set_ciphers('ECDH+AES256:ECDH+AES128:' + 
                '!aNULL:!eNULL:!MD5:!DSS:!RC4:!SSLv2:!SSLv3:!TLSv1')
ssl.options |= OP_NO_SSLv3
ssl.options |= OP_NO_TLSv1
ssl.options |= OP_NO_TLSv1_1
ssl.load_cert_chain('/etc/letsencrypt/live/fullchain.pem',
                    '/etc/letsencrypt/live/privkey.pem')
...
if __name__ == '__main__':
    app.run(host='0.0.0.0', port='443', ssl_context=ssl)

@rkbala这是我的烧瓶应用程序的相关代码:

...
from ssl import SSLContext, PROTOCOL_TLSv1_2, OP_NO_SSLv3, OP_NO_TLSv1, OP_NO_TLSv1_1
...
ssl = SSLContext(PROTOCOL_TLSv1_2)
ssl.set_ciphers('ECDH+AES256:ECDH+AES128:' + 
                '!aNULL:!eNULL:!MD5:!DSS:!RC4:!SSLv2:!SSLv3:!TLSv1')
ssl.options |= OP_NO_SSLv3
ssl.options |= OP_NO_TLSv1
ssl.options |= OP_NO_TLSv1_1
ssl.load_cert_chain('/etc/letsencrypt/live/fullchain.pem',
                    '/etc/letsencrypt/live/privkey.pem')
...
if __name__ == '__main__':
    app.run(host='0.0.0.0', port='443', ssl_context=ssl)

@pixelrebel谢谢!! 我会试一试,让你知道。

这个 ssl.options |=OP_NO_* 是什么意思?

我们可以更改密码吗? 或者上面的 set_ciphers 会设置随机密码?

@rkbala我不记得为什么需要按位或操作。 可能没有必要……值得一试。

您可以将密码更改为与 TLS 1.2 兼容的任何密码。 就我而言,我的应用程序为 Slack 提供了一个 API 以与其进行通信。 所以我只需要支持 Slackbot 使用的密码。

@rkbala IO 应该澄清我不记得我为什么需要这种语法,但我相信当时我需要明确指定 OP_NO_* 选项以使我的应用程序仅使用 TLS1.2 而没有更低版本。

@rkbala我不记得为什么需要按位或操作。 可能没有必要……值得一试。

您可以将密码更改为与 TLS 1.2 兼容的任何密码。 就我而言,我的应用程序为 Slack 提供了一个 API 以与其进行通信。 所以我只需要支持 Slackbot 使用的密码。

好的谢谢。 如果我们不指定,我认为 gunicorn 会采用默认的 python 密码。 如果我错了,请纠正我。

上面的flask代码是否也让gunicorn只在TLSv1.2中启动flask应用程序? 问题是因为我想通过 gunicorn 运行 Flask 应用程序。 我今天刚刚了解到,gunicorn 终端命令“gunicorn —ssl-version TLSV1_2 project:app ”将在 tls v1.2 中启动 Flask

是的,这仅适用于 TLS 1.2。 其他所有内容都已弃用 AFAIK。 我假设它们具有相同的效果,但我猜想使用命令行选项会覆盖脚本中的选项。 无论如何,我不是 gunicorn 的专家。 所以请采纳我的建议。

是的,这仅适用于 TLS 1.2。 其他所有内容都已弃用 AFAIK。 我假设它们具有相同的效果,但我猜想使用命令行选项会覆盖脚本中的选项。 无论如何,我不是 gunicorn 的专家。 所以请采纳我的建议。

谢谢@pixelrebel我会在这方面进行探索。

此页面是否有帮助?
0 / 5 - 0 等级

相关问题

haolujun picture haolujun  ·  3评论

thomasjungblut picture thomasjungblut  ·  3评论

gr790 picture gr790  ·  4评论

Abraxos picture Abraxos  ·  4评论

leonardbinet picture leonardbinet  ·  4评论