我有两个虚拟主机,每个主机运行五个站点(多租户)。服务器有三个IP地址。两个是公开面对的,一个是内部的。
两个面向公众的网站都有SSL证书。一个站点是我的暂存站点,有一个letsencrypt SSL证书,另一个是实时站点,并且有一个godaddy SSL证书。
我首先使用一个节点(我的云实例)设置Rackspace负载均衡器,将证书和密钥从我的服务器复制到平衡器,并成功使用以下nginx配置以使负载均衡器从我的代理我的站点服务于内部IP的Web服务器
upstream django {
server unix:///run/uwsgi/app/introtest/socket;
}
# configuration of the server, first redirect http to https...
server {
listen 10.181.104.195:80;
if ($http_x_forwarded_proto = "http") {
return 302 https://$http_host$request_uri;
}
# the domain name it will serve for
charset utf-8;
# max upload size
client_max_body_size 75M; # adjust to taste
# Django media
location /media {
alias /srv/test/media;
}
location /static {
alias /srv/test/static;
}
# Finally, send all non-media requests to the Django server.
location / {
if (-f /srv/maintenance_test.html) {
return 503;
}
uwsgi_pass django;
uwsgi_param QUERY_STRING $query_string;
uwsgi_param REQUEST_METHOD $request_method;
uwsgi_param CONTENT_TYPE $content_type;
uwsgi_param CONTENT_LENGTH $content_length;
uwsgi_param REQUEST_URI $request_uri;
uwsgi_param PATH_INFO $document_uri;
uwsgi_param DOCUMENT_ROOT $document_root;
uwsgi_param SERVER_PROTOCOL $server_protocol;
uwsgi_param REQUEST_SCHEME $scheme;
uwsgi_param HTTPS $https if_not_empty;
uwsgi_param REMOTE_ADDR $remote_addr;
uwsgi_param REMOTE_PORT $remote_port;
uwsgi_param SERVER_PORT $server_port;
uwsgi_param SERVER_NAME $server_name;
uwsgi_param X-Real-IP $remote_addr;
uwsgi_param X-Forwarded-For $proxy_add_x_forwarded_for;
uwsgi_param X-Forwarded-Host $server_name;
}
# Error pages
error_page 503 /maintenance_test.html;
location = /maintenance_test.html {
root /srv;
}
}
顺便说一句,如果我可以提供帮助,我不会使用永久重定向,也不会使用登台服务器。实时服务器已经设置好并且有永久重定向到https,但我想我们总是希望将实时站点重定向到SSL,因此重定向是301。
将我的暂存站点的根域的DNS条目更改为负载均衡器后,这很好用。
tail -f /var/log/nginx/access.log
显示请求来自负载均衡器的内部IP地址,并且页面正在正确提供。
我改回了所有内容(即nginx conf和登台根域的DNS条目),并且可以从网络服务器进行暂存服务。然后我将godaddy SSL证书信息复制到负载均衡器。然后使用以下用于实时服务器的nginx配置:
upstream intro_live {
server unix:///run/uwsgi/app/introsites/socket;
}
server {
listen <SERVER PUBLIC IP>:80;
listen <SERVER PUBLIC IP>:443;
location / {
return 503;
}
error_page 503 /interruption.html;
location = /interruption.html {
root /srv;
}
}
# configuration of the server
server {
# the port your site will be served on
listen 10.181.104.195:80;
# reidrect http to https from load balancer
if ($http_x_forwarded_proto = "http") {
set $http_test S${http_host};
}
if ($http_test = 'Sintrotravel.com') {
rewrite ^ https://www.introtravel.com$request_uri;
}
if ($http_test = 'Sozintro.com') {
rewrite ^ https://www.ozintro.com$request_uri permanent;
}
if ($http_test = 'Sbalintro.com') {
rewrite ^ https://www.balintro.com$request_uri permanent;
}
if ($http_test = 'Sthaintro.com') {
rewrite ^ https://www.thaintro.com$request_uri permanent;
}
if ($http_test = 'Svietnamintro.com') {
rewrite ^ https://www.vietnamintro.com$request_uri permanent;
}
charset utf-8;
# max upload size
client_max_body_size 75M; # adjust to taste
# Django media
location /media {
alias /srv/intro/media;
expires 7d;
add_header Pragma public;
add_header Cache-Control "public";
}
location /static {
alias /srv/intro/static;
expires 1d;
add_header Pragma public;
add_header Cache-Control "public";
}
# Finally, send all non-media requests to the Django server.
location / {
if (-f /srv/maintenance_on.html) {
return 503;
}
uwsgi_pass intro_live;
uwsgi_param QUERY_STRING $query_string;
uwsgi_param REQUEST_METHOD $request_method;
uwsgi_param CONTENT_TYPE $content_type;
uwsgi_param CONTENT_LENGTH $content_length;
uwsgi_param REQUEST_URI $request_uri;
uwsgi_param PATH_INFO $document_uri;
uwsgi_param DOCUMENT_ROOT $document_root;
uwsgi_param SERVER_PROTOCOL $server_protocol;
uwsgi_param REQUEST_SCHEME $scheme;
uwsgi_param HTTPS $https if_not_empty;
uwsgi_param REMOTE_ADDR $remote_addr;
uwsgi_param REMOTE_PORT $remote_port;
uwsgi_param SERVER_PORT $server_port;
uwsgi_param SERVER_NAME $server_name;
uwsgi_param X-Real-IP $remote_addr;
uwsgi_param X-Forwarded-For $proxy_add_x_forwarded_for;
uwsgi_param X-Forwarded-Host $server_name;
}
# Error pages
error_page 503 /maintenance_on.html;
location = /maintenance_on.html {
root /srv;
}
}
upstream django
指向我的uwsgi配置。 http_x_forwarded_proto
,以及是否已为域设置测试变量。我专门将来自五个站点的http流量重定向到https。/etc/nginx/conf.d/中没有任何内容,我的/etc/nginx/nginx.conf看起来像这样:
user www-data;
worker_processes 20;
pid /run/nginx.pid;
events {
worker_connections 768;
# multi_accept on;
}
http {
##
# Basic Settings
##
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
# server_tokens off;
# server_names_hash_bucket_size 64;
# server_name_in_redirect off;
include /etc/nginx/mime.types;
default_type application/octet-stream;
##
# SSL Settings
##
ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE
ssl_prefer_server_ciphers on;
##
# Logging Settings
##
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
##
# Gzip Settings
##
gzip on;
gzip_disable "msie6";
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_buffers 16 8k;
gzip_http_version 1.1;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
##
# Virtual Host Configs
##
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
一旦我将五个站点的DNS A记录设置为指向负载均衡器,重定向到https就可以了,但我在每个页面中都有一个重定向循环。所以,我从配置中取出了所有重定向,即
if ($http_test = 'Sintrotravel.com') {
rewrite ^ https://www.introtravel.com$request_uri;
}
if ($http_test = 'Sozintro.com') {
rewrite ^ https://www.ozintro.com$request_uri permanent;
}
if ($http_test = 'Sbalintro.com') {
rewrite ^ https://www.balintro.com$request_uri permanent;
}
if ($http_test = 'Sthaintro.com') {
rewrite ^ https://www.thaintro.com$request_uri permanent;
}
if ($http_test = 'Svietnamintro.com') {
rewrite ^ https://www.vietnamintro.com$request_uri permanent;
}
并重新启动nginx。我还有一个重定向循环。为什么???我知道重写是永久性的,但这不是因为return 302
和rewrite
的区别,因为当我取出 all 时,服务器仍处于无限重定向循环中重定向。由于显而易见的原因,我不能花很多时间尝试实时网站。真的,我需要在10-15分钟内完成任何人有任何建议吗?
答案 0 :(得分:0)
考虑到这一点,我意识到它必须是Django应用程序才是问题所在。与nginx无关。有一个设置
SECURE_SSL_REDIRECT = True
使django将http流量重定向到https(在暂存时这是假的)。当您添加负载均衡器时,这会成为一个问题,因为负载均衡器会收到https流量,但它只会将端口80上的非安全流量传递到我的Web服务器/应用程序。这就是你重定向条件的原因
if ($http_x_forwarded_proto = "http") {...
nginx配置中的(由负载均衡器设置)。仅从nginx以这种方式删除重定向不会解决问题,我不得不从django中完全删除它。
无论您多么有经验,如果您因为分散的性质而匆忙,DNS会让您感到困惑,当一个赚钱的网站瘫痪时,您就会匆忙。
答案 1 :(得分:0)
Django可以通过以下方式解决这个问题:
https://docs.djangoproject.com/en/1.11/ref/settings/#std:setting-SECURE_PROXY_SSL_HEADER
添加: SECURE_PROXY_SSL_HEADER =('HTTP_X_FORWARDED_PROTO','https')
确保您的代理设置适当的标头将阻止重定向循环。会发生什么事情是你的代理没有告诉Django连接是安全的,所以它保持重定向到安全版本,虽然它已经是安全的 - 因此无限循环。提供标题是解决此问题的方法之一。