2017-01-27 6 views
0

У меня есть два виртуальных хоста, каждый из которых имеет пять сайтов (многоэтажный). Сервер имеет три IP-адреса. Два из них являются публичными, а один - внутренним.Redirect loop для многоэтажного сайта Django, когда добавлен балансировщик нагрузки

Оба публичных веб-сайта имеют сертификаты SSL. Один сайт - это мой веб-сайт, и он имеет сертификат passencrypt SSL, другой - сайт на сайте и имеет SSL-сертификат godaddy.

Сначала я установил балансировщик нагрузки Rackspace с одним узлом (мой экземпляр облака), скопировал сертификат и ключ в балансировщик с моего сервера и успешно использовал следующую конфигурацию nginx, чтобы заставить балансировщик нагрузки проксировать мой сайт с мой веб-сервер служит на внутренней облицовочной IP

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 для промежуточного корневого домена), и получил этап, чтобы обслуживать с веб-сервера в порядке. Затем я скопировал информацию сертификата SSL godaddy в балансировщик нагрузки. Затем с помощью следующей 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 конфигурации.
  • Вторая конфигурация сервера прослушивает общедоступный адрес сервера, так что, если чья-то запись DNS для веб-сайта не была обновлена, они получают статическую страницу, в которой говорится, что сервер находится в обслуживании.
  • Конфигурация третьего сервера прослушивает порт 80 на внутреннем адресе, проверяет, установлен ли сервер промежуточного уровня http_x_forwarded_proto, и если он устанавливает тестовую переменную для домена. Я специально перенаправляю HTTP-трафик с пяти сайтов на https.
  • Последние 503 материала обнаруживают существование файла, и если он существует, сайт помещается в режим обслуживания.

Там нет ничего в /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, потому что сервер все еще находится в бесконечном цикле переадресации, когда я вывожу все перенаправления. Я не могу тратить много времени на эксперименты с живым сайтом по очевидным причинам.На самом деле мне нужно перерезать через 10-15 минут. У кого-нибудь есть совет?

ответ

0

Думая об этом, я понял, что это должно быть приложение Django, которое было проблемой. Ничего общего с nginx. Была установлена ​​установка

SECURE_SSL_REDIRECT = True 

, что сделало django перенаправлением http-трафика на https (это было неверно при постановке). Это становится проблемой при добавлении балансировщика нагрузки, поскольку балансировщик нагрузки получает трафик https, но он поставляет не защищенный трафик на порт 80 на мой веб-сервер/приложение. Вот почему вы перенаправлять на состояние

if ($http_x_forwarded_proto = "http") {... 

(который устанавливается балансировки нагрузки) в конфигурации Nginx. Удаление перенаправления таким образом только от nginx не устранит проблему, мне пришлось полностью удалить ее из django.

Независимо от того, насколько опытным является DNS, вы сбиваете с толку, если вы спешите из-за его распределенной природы, и когда сайт, который зарабатывает деньги, не работает, вы спешите.

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 о том, что соединение защищено, поэтому он перенаправляет на защищенную версию, хотя он уже защищен - следовательно, бесконечный цикл. Предоставление заголовка является одним из способов решения этой проблемы.

+0

Хотя эта ссылка может ответить на вопрос, лучше включить здесь основные части ответа и предоставить ссылку для справки. Ответные ссылки могут стать недействительными, если связанная страница изменится. - [Из обзора] (/ review/low-quality-posts/17677422) –

Смежные вопросы