我遇到了从Nginxredirect到gunicorn的问题。 我使用proxy_pass
redirect到https://127.0.0.1:5000
,但redirect发送到https://[::1]:5000
。
这里是我自己的.conf
文件,它包含在nginx.conf
:
server { listen 80; server_name mydomain.no www.mydomain.no myotherdomain.no; return 301 https://$server_name$request_uri; } server { listen 443 ssl; add_header Strict-Transport-Security "max-age=63072000; includeSubdomains; preload"; server_name mydomain.no www.mydomain.no myotherdomain.no; ssl_certificate /path/to/chain; ssl_certificate_key /path/to/private/key; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_ciphers HIGH:!aNULL:!MD5; root /var/www/html/; index index.html; charset UTF-8; location /api { proxy_set_header X-Real-IP $remote_addr; proxy_set_header Host $http_host; proxy_pass https://127.0.0.1:5000; } }
这是我的nginx.conf
文件:
user django django; worker_processes 1; error_log /path/to/error.log warn; pid /path/to/nginx.pid; events { worker_connections 1024; } http { include /path/to/mime.types; default_type application/octet-stream; log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; access_log /path/to/access.log main; sendfile on; keepalive_timeout 65; include /path/to/conf.d/*.conf; }
最后的include
包含了我的.conf文件,它是conf.d
目录中唯一的文件(我也检查了隐藏的文件)。
当我今天开始时, proxy_pass
被设置为localhost
,但是当我尝试连接到mydomain.no/api/door
时,我得到了502。 我做的第一件事是检查是否mydomain.no:5000/api/door
工作,而且确实如此。 于是,我去检查error.log
。 在那里我发现这个错误:
2016/02/06 06:35:23 [error] 14280#0: *18082 connect() failed (111: Connection refused) while connecting to upstream, client: nnn.nnn.nnn.nnn, server: mydomain.no, request: "GET /api/door HTTP/1.1", upstream: "https://[::1]:5000/api/door", host: "mydomain.no", referrer: "https://mydomain.no/"
正如你所看到的,出于某种原因,Nginx正在redirect到IPv6本地主机。 然后我尝试将localhost
更改为127.0.0.1
的显式IPv4,但仍然得到了完全相同的错误。
为了尽可能地提供(可能)相关的信息,下面是我的nginx -V
(格式化为可读性):
nginx version: nginx/1.6.3 built by gcc 4.8.5 20150623 (Red Hat 4.8.5-4) (GCC) TLS SNI support enabled configure arguments: --prefix=/usr/share/nginx --sbin-path=/usr/sbin/nginx --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --http-client-body-temp-path=/var/lib/nginx/tmp/client_body --http-proxy-temp-path=/var/lib/nginx/tmp/proxy --http-fastcgi-temp-path=/var/lib/nginx/tmp/fastcgi --http-uwsgi-temp-path=/var/lib/nginx/tmp/uwsgi --http-scgi-temp-path=/var/lib/nginx/tmp/scgi --pid-path=/run/nginx.pid --lock-path=/run/lock/subsys/nginx --user=nginx --group=nginx --with-file-aio --with-ipv6 --with-http_ssl_module --with-http_spdy_module --with-http_realip_module --with-http_addition_module --with-http_xslt_module --with-http_image_filter_module --with-http_geoip_module --with-http_sub_module --with-http_dav_module --with-http_flv_module --with-http_mp4_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_random_index_module --with-http_secure_link_module --with-http_degradation_module --with-http_stub_status_module --with-http_perl_module --with-mail --with-mail_ssl_module --with-pcre --with-pcre-jit --with-google_perftools_module --with-debug --with-cc-opt='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -m64 -mtune=generic' --with-ld-opt='-Wl,-z,relro -specs=/usr/lib/rpm/redhat/redhat-hardened-ld -Wl,-E'
我尝试改变我的机器的IPv6设置,甚至closures所有我的networking接口(包括本地)的IPv6,但没有任何影响。 因此,我转向你的帮助。 什么导致proxy_pass
永远是IPv6?
事实certificate,这个问题是由Gunicorn成立的方式造成的。 我的同事告诉我,他们已经用TLSencryption,但仔细观察,根本没有使用任何encryption。 错误中的[::1]
可能由Nginx在IPv4连接失败后回落到IPv6而引起。
简单地将proxy_pass
从https
更改为http
解决了我的问题,同时保持encryption,因为从Nginx跳转到Gunicorn是内部的。 我也改变了Gunicorn只接受本地连接,因为它只能通过Nginx代理无论如何访问。