【问题标题】:Running gunicorn on https?在 https 上运行 gunicorn?
【发布时间】:2011-09-13 18:40:38
【问题描述】:

我们有一些 Django 设置通过代理(Apache 和 Nginx),最终进入实际的 Django 运行时。

我们需要端到端的 HTTPS,即使它在我们的网络中也是如此。由于 Gunicorn 在我们其他设置中的成功和性能,我们一直在重新审视它,但需要使用 HTTPS 进行端到端测试以保持一致。

我们的拓扑是这样的:

https://foo.com -> [面向公众的代理] -> (https) -> [内部服务器https://192...:8001]

如何配置 Gunicorn 以使用自签名证书侦听 HTTPS?

【问题讨论】:

    标签: ssl https gunicorn


    【解决方案1】:

    Gunicorn 现在支持 SSL,as of version 17.0。您可以将其配置为在 https 上侦听,如下所示:

    $ gunicorn --certfile=server.crt --keyfile=server.key test:app
    

    如果您使用--bind 侦听端口 80,请记住将端口更改为 443(HTTPS 连接的默认端口)。例如:

    $ gunicorn --certfile=server.crt --keyfile=server.key --bind 0.0.0.0:443 test:app
    

    【讨论】:

    • 你能告诉我有关如何执行此操作的相关文件吗?我在 heroku 上部署,所以我不确定我的“server.crt”是什么。
    • @DrewV 如果您在 heroku 上部署,则无需自己支持 SSL - heroku 会为您提供支持。请参阅their docs 寻求帮助。您将需要配置 gunicorn 以遵守 heroku 的安全标头配置。我在我的配置文件中使用了这样的东西:forwarded_allow_ips = '*'secure_scheme_headers = {'X-FORWARDED-PROTO': 'https',}
    • 结尾的test:app 部分是什么?
    • 为我运行这个返回AttributeError: 'NoneType' object has no attribute 'uri'
    • 正是我需要的!我将这些设置添加到我的gunicorn_start.bash 文件并重新启动supervisor。现在一切正常。
    【解决方案2】:

    回复晚了很多,但对于遇到此问题的其他人,还有另一种选择,使用 nginx 作为上面的“[面向公众的代理]”。

    配置 nginx 以处理端口 443 上的传入 SSL 流量,然后将 proxy_pass 配置为内部端口上的 gunicorn。外部流量是加密的,nginx和gunicorn之间的流量无论如何都不会暴露。我觉得这很容易管理。

    【讨论】:

    • 你怎么知道它没有暴露?
    • 因为你绑定gunicorn到127.0.0.1,所以只有localhost可以访问
    • 这样做的缺点是它破坏了 Django 的 build_absolute_uri() 函数; Django 将看到 HTTP 协议并使用该方案构建 URI,即使原始请求使用 HTTPS。
    • @robbrit 你可以设置一个标题来避免这个问题。请参阅SECURE_PROXY_SSL_HEADER 文档。
    • 鉴于人们仍在阅读此答案 - 在 2021 年,我建议您不要使用 nginx,而是查看 Caddy 服务器
    【解决方案3】:

    如果您使用的是 gunicorn.config.py 或类似的 gunicorn 配置文件,您可以添加证书文件和密钥文件。

    certfile = '/etc/letsencrypt/live/example.com/fullchain.pem'
    keyfile = '/etc/letsencrypt/live/example.com/privkey.pem'
    

    配置文件可用于将设置初始化为环境变量,如果您有很多设置,这会很有帮助。 使用配置文件

    • 通过创建一个名为的文件来创建一个配置文件 gunicorn.config.py

    • 一些常用的设置是

        bind = "0.0.0.0:8000"
        workers = 4
        pidfile = 'pidfile'
        errorlog = 'errorlog'
        loglevel = 'info'
        accesslog = 'accesslog'
        access_log_format = '%(h)s %(l)s %(u)s %(t)s "%(r)s" %(s)s %(b)s "%(f)s" "%(a)s"'
      

      当然

        certfile = '/etc/letsencrypt/live/example.com/fullchain.pem'
        keyfile = '/etc/letsencrypt/live/example.com/privkey.pem'
      

    查看documentation 和配置文件example

    使用这些设置运行 gunicorn

        $ gunicorn app:app
    

    因为

    默认情况下,将从运行 gunicorn 的同一目录中读取名为 gunicorn.conf.py 的文件。

    【讨论】:

      【解决方案4】:

      除了certfilekeyfile,您还需要添加ca-certs。没有通过ca-certs,我在Android设备上得到Trust anchor for certification path not found.

      示例命令:

      /usr/bin/python3 /usr/local/bin/gunicorn --bind 0.0.0.0:443 wsgi:app --workers=8 --access-logfile=/root/app/logs/access.log --error-logfile=/root/app/logs/error.log --certfile=/root/app/certificate.crt --keyfile=/root/app/private.key --ca-certs=/root/app/ca_bundle.crt --daemon
      

      【讨论】:

        猜你喜欢
        • 2016-06-05
        • 2019-05-09
        • 2017-10-11
        • 2012-06-20
        • 1970-01-01
        • 1970-01-01
        • 2021-12-24
        • 2016-09-09
        • 1970-01-01
        相关资源
        最近更新 更多