【问题标题】:How can I redirect HTTP to HTTPS with uWSGI internal routing?如何使用 uWSGI 内部路由将 HTTP 重定向到 HTTPS?
【发布时间】:2016-02-14 10:42:15
【问题描述】:

我已经使用 uWSGI 部署了一个 WSGI 应用程序,但是 I am not using NGINX。如何使用uWSGI's internal routinghttp 请求重定向到https

我尝试了uwsgi --route-uri="^http:\/\/(.+)$ redirect-permanent:https://\$1",但从 uWSGI 收到错误:unrecognized option '--route-uri=^https:\/\/(.+)$ redirect-permanent:https://\$1'

【问题讨论】:

  • 首先我需要安装支持 PCRE 的 uWSGI:stackoverflow.com/a/27626788/565879
  • 是的,你会在每次 uWSGI 重启时看到关于内部循环支持的警告,除非你不使用 PCRE 安装它。
  • 即使有 PCRE 支持,我也看不出这个配置是如何工作的。选项 --request-uri 没有 URL 的方案/主机/端口部分。请参阅我的答案以获取一种可能的解决方案。

标签: uwsgi


【解决方案1】:

对于不想运行 nginx 的任何人,您可以直接在 uWSGI 中重定向和强制 HTTPS。

[uwsgi]   
master = True
enable-threads = True
thunder-lock = True

shared-socket = :443

https2 = addr==0,cert=yourdomain.crt,key=yourdomain.key,HIGH,spdy=1
http-to-https = 0.0.0.0:80

route-if-not = equal:${HTTPS};on redirect-permanent:https://${HTTP_HOST}${REQUEST_URI}
route-if = equal:${HTTPS};on addheader:Strict-Transport-Security: max-age=31536000; includeSubDomains; preload

经过测试并且也可以与 docker 一起使用 (python:3.6.7-alpine3.8) 此外,如果您要调试 HTTP 请求,您将看到第一个响应标头是 301 到 HTTPS。

如果您再次尝试(从同一浏览器),您将看到 307,因为 HSTS 已启用。

[uWSGI] getting INI configuration from uwsgi.ini
*** Starting uWSGI 2.0.17.1 (64bit) on [Fri Dec 21 20:06:47 2018] ***
compiled with version: 6.4.0 on 21 December 2018 20:05:49
os: Linux-3.10.0-514.26.2.el7.x86_64 #1 SMP Tue Jul 4 15:04:05 UTC 2017
nodename: web1
machine: x86_64
clock source: unix
pcre jit disabled
detected number of CPU cores: 4
current working directory: /usr/src/app
detected binary path: /usr/local/bin/uwsgi
*** dumping internal routing table ***
[rule: 0] subject: ${HTTPS};on func: !equal action: redirect-permanent:https://${HTTP_HOST}${REQUEST_URI}
[rule: 1] subject: ${HTTPS};on func: equal action: addheader:Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
*** end of the internal routing table ***
uwsgi shared socket 0 bound to TCP address :443 fd 3
uWSGI running as root, you can use --uid/--gid/--chroot options
*** WARNING: you are running uWSGI as root !!! (use the --uid flag) *** 
chdir() to /usr/src/app
your memory page size is 4096 bytes
detected max file descriptor number: 65536
lock engine: pthread robust mutexes
thunder lock: enabled
uWSGI http bound on :443 fd 3
uWSGI http bound on 0.0.0.0:80 fd 5
uwsgi socket 0 bound to TCP address 127.0.0.1:45870 (port auto-assigned) fd 4
uWSGI running as root, you can use --uid/--gid/--chroot options
*** WARNING: you are running uWSGI as root !!! (use the --uid flag) *** 
Python version: 3.6.7 (default, Dec 21 2018, 03:29:53)  [GCC 6.4.0]
Python main interpreter initialized at 0x7fdf16663b40
uWSGI running as root, you can use --uid/--gid/--chroot options
*** WARNING: you are running uWSGI as root !!! (use the --uid flag) *** 
python threads support enabled
your server socket listen backlog is limited to 100 connections
your mercy for graceful operations on workers is 60 seconds
mapped 364600 bytes (356 KB) for 4 cores
*** Operational MODE: preforking ***
WSGI app 0 (mountpoint='') ready in 1 seconds on interpreter 0x7fdf16663b40 pid: 1 (default app)
uWSGI running as root, you can use --uid/--gid/--chroot options
*** WARNING: you are running uWSGI as root !!! (use the --uid flag) *** 
*** uWSGI is running in multiple interpreter mode ***
spawned uWSGI master process (pid: 1)
spawned uWSGI worker 1 (pid: 18, cores: 1)
spawned uWSGI worker 2 (pid: 19, cores: 1)
spawned uWSGI worker 3 (pid: 20, cores: 1)
spawned uWSGI worker 4 (pid: 21, cores: 1)
spawned uWSGI http 1 (pid: 22)

注意它以 root 身份运行

希望这会有所帮助。

【讨论】:

    【解决方案2】:

    只是另一个答案。正在做

    [uwsgi]
    <... other uwsgi configs ... >
    plugins = router_redirect
    route-if-not = equal:${HTTPS};on redirect-permanent:https://${HTTP_HOST}${REQUEST_URI}
    

    will force HTTPS for the whole site.

    测试

    【讨论】:

    • 在尝试执行相反操作时进行测试,即尝试从 https to http 强制重定向时进行测试。
    【解决方案3】:

    以 Oleg 的回答为基础:为此,您需要手动添加一些标头以阻止 UWSGI 导致 ELB 出现 502 错误。

    route-if=equal:${HTTP_X_FORWARDED_PROTO};http addheader:Content-Type: */*; charset="UTF-8"
    route-if=equal:${HTTP_X_FORWARDED_PROTO};http addheader:Content-Length: 0  
    route-if=equal:${HTTP_X_FORWARDED_PROTO};http redirect-permanent:https://<your_host_name_here>${REQUEST_URI}
    

    为了让 ELB 识别 302,您需要手动添加 Content-Length 和 Content-Type 标头。这并不明显,即使您添加了 ELB 日志记录。

    要调试,您需要记住实际发送带有 curl 的 X-Forwarded-Proto 标头:

    curl -v  -H "X-Forwarded-Proto: http" http://localhost:port
    

    【讨论】:

      【解决方案4】:

      对于那些尝试了上述两个答案但不幸失败的人,留下 uWSGI 并添加 Nginx CONF:

      server {
          listen          80;
          server_name     <your_domain>;
          rewrite ^/(.*)  https://<your_domain>/$1 permanent;
      }
      

      我觉得 uWSGI 在内部路由方面不是那么友好。

      【讨论】:

        【解决方案5】:

        如果您的反向代理或负载均衡器将 X-Forwarded-Proto 标头与请求一起传递,则以下配置将起作用:

        [uwsgi]
        http-socket = :3031
        <... your uwsgi config options here ... >
        route-if=equal:${HTTP_X_FORWARDED_PROTO};http redirect-permanent:https://<your_host_name_here>${REQUEST_URI}
        

        某些负载均衡器,例如 AWS ELB 会传递此标头 automatically

        【讨论】:

        • 在我的情况下这是正确的解决方案(uwsgi 在处理 SSL 终止的负载均衡器后面的单个端口上侦听)
        • 如果 uwsgi 出错并显示“无法注册路由 ...”消息,可能还需要在 .ini 文件中添加“plugin = router_redirect”
        • 我将${HTTP_X_FORWARDED_PROTO} 更改为${REQUEST_SCHEME}。在 nginx 中查看文件 uwsgi_params
        【解决方案6】:

        要将http重定向到https,请使用以下配置:

        [uwsgi]
        ; privileged port can only be opened as shared socket
        shared-socket = 0.0.0.0:80
        shared-socket = 0.0.0.0:443
        
        ;enable redirect to https
        http-to-https = =0
        
        ; enable https, spdy is optional
        https2 = addr==1,cert=server.crt,key=server.key,spdy=1
        ; alternative
        ; https = =1,server.crt,server.key
        
        ; force change of user after binding to ports as root
        uid = user
        gid = usergroup
        
        ; where original app will be running on IP or UNIX socket
        socket = 127.0.0.1:8001
        
        module = smthg.wsgi
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2011-04-19
          • 2015-06-16
          • 2014-12-27
          • 2016-05-26
          • 2011-04-28
          • 1970-01-01
          • 2017-07-01
          相关资源
          最近更新 更多