2013-01-03 11 views
13

Mam dość standardową konfigurację z nginx fronting aplikacji django. Chcę, aby aplikacja django była tylko SSL, więc mam dwa bloki nasłuchiwania w moim nginx conf, przy czym ruch przychodzący na porcie 80 (HTTP) jest przekierowywany do portu 443 (SSL). Działa to zgodnie z oczekiwaniami.Czy mogę przekierować ruch nie-SSL, który jest dostarczany na porcie SSL z Nginxem

Uruchomiłem to ustawienie w maszynie wirtualnej z włączonym przekierowaniem portów, dzięki czemu mogę przeglądać witrynę z komputera hosta, przechodząc do portu 8080 (HTTP) lub 8081 (SSL). Ponownie, to działa dobrze, zgodnie z oczekiwaniami.

Problem pojawia się, gdy jestem wewnętrznie przekierowywany z aplikacji Django podczas przepływu pracy rejestracji. Ponieważ Django nigdy nie widzi statusu SSL (SSL jest zakończone w nginx, a ruch do aplikacji jest przekazywany na port 5000 przez HTTP), ale widzi port, przekierowanie jest coraz bardziej zniekształcone **.

Rezultatem jest to, że ruch skierowany jest do portu nginx na porcie SSL, to znaczy nie jest to SSL, np. http://127.0.0.1:443/. Czy istnieje sposób konfiguracji nginx do obsługi tego?

** Uwaga Ustawiam nagłówek X-Forwarded-Proto w Nginx, a Django zbiera poprawną wartość .is_secure(), jest to specyficzny problem z zewnętrzną biblioteką, która nie sprawdza is_secure i po prostu przekierowuje na schemat przychodzącego adresu URL.

[UPDATE 1]

Dołączone są odpowiednie ustawienia konfiguracyjne. Jest to z samego Vagrantfile, pokazując przekierowania portów:

config.vm.forward_port 80, 8080  # website, via nginx (redirects to SSL:8081) 
config.vm.forward_port 443, 8081 # website, via nginx (accepts SSL) 
config.vm.forward_port 5000, 8180 # website, via gunicorn (direct) 

stosując powyższą konfigurację przekierowania portów, jeśli przejdź do strony na komputerze hosta na porcie HTTP (8080), a następnie wniosek zostanie zaakceptowany, i nginx (patrz poniżej) przekierowuje to żądanie do HTTPS (działa na porcie 8081). Raz jestem na HTTPS sama strona działa prawidłowo:

(host) http://127.0.0.1:8080 -> forwarded to -> (guest vm) http://127.0.0.1:80 
(host) https://127.0.0.1:8081 -> forwarded to -> (guest vm) https://127.0.0.1:443 

Problem pojawia się, gdy dostaję przekierowanie wewnętrznie z Django, który mieszany protokołu schemat &, a kończy się z prośbą o http:\\127.0.0.1:8081\..., który zawodzi, jak nginx jest oczekując, że ruch w 8081 będzie SSL.

To, czego naprawdę chcę, to reguła "słuchaj w 443 dla SSL i bez SSL i przekierowuj bez SSL".

Jest to istotne konfiguracji nginx:

# Django app is served by Gunicorn, running under port 5000 (via Foreman) 
upstream gunicorn { 
    server 127.0.0.1:5000 fail_timeout=0; 
} 

server { 
    listen 80; 
    # 8081 is the port I am forwarding to on the host machine 
    rewrite^https://127.0.0.1:8081$request_uri? permanent; 
} 

server { 
    listen 443; 

    ssl on; 
    ssl_protocols  SSLv3 TLSv1; 
    ssl_ciphers   HIGH:!ADH:!MD5; 
    ssl_prefer_server_ciphers on; 
    ssl_certificate  /etc/nginx/ssl/self-signed.crt; 
    ssl_certificate_key /etc/nginx/ssl/self-signed.key; 

    access_log /var/log/nginx/access.log; 
    error_log /var/log/nginx/error.log; 

    location /static/ { 
     alias /app/static/; 
    } 
    location /media/ { 
     alias /app/media/; 
    } 
    location/{ 
     # everything else is to be served by the django app (upstream 'gunicorn') 
     proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 
     # this is set to ensure that django is_secure returns True 
     proxy_set_header X-Forwarded-Proto $scheme; 
     proxy_set_header Host $http_host; 
     proxy_pass http://gunicorn; 
    } 
} 
+0

Czy możesz opublikować odpowiednie części plików conf za pomocą przekierowań? – ProfessionalAmateur

+0

Mam zaktualizowany oryginalny wpis z konfiguracją i wyjaśnieniem. –

Odpowiedz

20

Należy sprawdzić sekcję "błąd przetwarzania" tego dokumentu:

http://nginx.org/en/docs/http/ngx_http_ssl_module.html

niestandardowy kod błędu 497 może być stosowany do przetwarzać zwykłe żądanie HTTP, które zostało wysłane do portu HTTPS.

Coś jak to powinno działać (niesprawdzone):

error_page 497 https://$host$request_uri; 

nazwane lokalizacje mogą być również wykorzystywane w error_page patrz http://nginx.org/r/error_page szczegóły.

+0

Perfect - dokładnie to, czego szukałem. Dziękuję Ci. –

+0

To spowodowało tyle bólu dla mnie, a rozwiązanie jest tak proste, DZIĘKI! – dotz

Powiązane problemy