uWSGI + Nginx 的 HTTPS 支持

有时我们在一台机器上部署多个 uWSGI 服务,并提供 HTTPS 支持。使用 proxy_pass 代替 uwsgi_pass 是很简单的方案:

 1server {
 2        listen 443;
 3        server_name your.domain.com;
 4
 5        root /srv/www/static;
 6        index index.html index.htm;
 7        ssl on;
 8        ssl_certificate /your/ssl/certificate.pem;
 9        ssl_certificate_key /your/ssl/certificate.key;
10
11        ssl_session_timeout 5m;
12
13        ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2;
14        ssl_ciphers "HIGH:!aNULL:!MD5 or HIGH:!aNULL:!MD5:!3DES";
15        ssl_prefer_server_ciphers on;
16
17        location / {
18                try_files $uri $uri/ =404;
19        }
20
21        # 把 test1 代理到 5000 端口
22        location ^~/test1/ {
23                proxy_pass http://localhost:5000;
24        }
25
26        # 仅允许 1.2.3.4 访问
27        location ^~/test1/private/ {
28                allow 1.2.3.4;
29                deny all;
30                proxy_pass http://localhost:5000;
31        }
32
33        # 把 test2 代理到 5001 端口
34        location ^~/test2/ {
35                proxy_pass http://localhost:5001;
36        }
37}

如果在服务器前端启用了负载均衡,需要做一些调整。因为负载均衡服务器已经帮我们把 https 流量进行解密了,到了 web 服务器就不必再配置证书。因此 nginx 改为 listen 80 端口。

这么做的问题是,当 uwsgi app(这里是 flask) 的内部路由进行跳转的时候 (flask url_for),由于侦听的是 80 端口,app 会自动把原有的 https url 路由到 http url。导致跳转失败。

例如:

当我们在 https://your.domain.com/test1/ 中跳转 url_for('index') 的时候,URL 会变成 http://your.domain.com/index/ ,这会导致访问失败。

 1server {
 2        listen 80;
 3        server_name your.domain.com;
 4
 5        root /srv/www/static;
 6        index index.html index.htm;
 7
 8        location / {
 9                try_files $uri $uri/ =404;
10        }
11
12        location ^~/test1/ {
13                proxy_pass http://localhost:5000;
14        }
15}

解决方案,就是把 proxy_pass 改回 uwsgi_pass ,并修改 uwsgi_params,在最后加入:

1uwsgi_param UWSGI_SCHEME https;

修改后的 nginx 配置:

 1server {
 2        listen 80;
 3        server_name your.domain.com;
 4
 5        root /srv/www/static;
 6        index index.html index.htm;
 7
 8        location / {
 9                try_files $uri $uri/ =404;
10        }
11
12        location ^~/test1/ {
13                uwsgi_pass 127.0.0.1:5000;
14                include uwsgi_params;
15        }
16}

更多内容请阅读: 部署Flask + uWSGI + Nginx

(全文完)