Nginx 400 ile başa çıkma "Düz HTTP isteği HTTPS bağlantı noktasına gönderildi" hatası


115

Passenger / nginx'in arkasında bir Sinatra uygulaması çalıştırıyorum. Hem http hem de https çağrılarına yanıt vermesini sağlamaya çalışıyorum. Sorun, her ikisi de sunucu bloğunda tanımlandığında https çağrılarına normal şekilde yanıt verilir, ancak http, 400 "Düz HTTP isteği HTTPS bağlantı noktasına gönderildi" hatası verir. Bu statik bir sayfa için, bu yüzden Sinatra'nın bununla hiçbir ilgisi olmadığını tahmin ediyorum. Bunu nasıl düzelteceğine dair bir fikrin var mı?

İşte sunucu bloğu:

server {
        listen 80;
        listen 443  ssl;
        server_name localhost;
        root /home/myhome/app/public;
        passenger_enabled on;

        ssl on;
        ssl_certificate      /opt/nginx/ssl_keys/ssl.crt;
        ssl_certificate_key  /opt/nginx/ssl_keys/ssl.key;
        ssl_protocols        SSLv3 TLSv1;
        ssl_ciphers          HIGH:!aNULL:!MD5;

        location /static {
            root  /home/myhome/app/public;
            index  index.html index.htm index.php;
        }

        error_page 404 /404.html;

        # redirect server error pages to the static page /50x.html
        error_page 500 /500.html;

        access_log /home/myhome/app/logs/access.log;
        error_log /home/myhome/app/logs/error.log;
}

Benim durumumda, tarayıcıdaki url: my.example.com:443işe yaramadı. Bunun yerine https://my.example.comişe yarayacak şekilde değiştirmek . Garip, apache ile hiç böyle bir problem yaşamadım.
Sebastian

1
ssl on;NGINX'e, SSL yoluyla HERHANGİ bir içeriği sunucuya bildirir . listen 443;Örneğin listen 443 ssl;sunucunuz hem http hem de https trafiği sağlıyorsa ve ssl on;yönergeyi kaldırıyorsa , sonunda "ssl" bayrağını kullanın .
Stphane

Yanıtlar:


195

Benzer bir sorunla karşılaştım. Bir sunucuda çalışır ve aynı Nginx yapılandırmasına sahip başka bir sunucuda çalışmaz. Igor tarafından cevaplanan çözümü burada http://forum.nginx.org/read.php?2,1612,1627#msg-1627 buldum

Evet. Veya SSL / SSL olmayan sunucuları tek bir sunucuda birleştirebilirsiniz:

server {
  listen 80;
  listen 443 default ssl;

  # ssl on   - remember to comment this out

}

Rapam iosif'in söylediği şeye göre, şunları da eklediğinizden emin olunssl off;
aceofspades

20
Sadece satırı kaldırmanız gerekir ssl on;(ssl off eklemenize gerek yoktur). Ayrıca, hangi Nginx versiyonunu hatırlamıyorum çünkü kullanımına artık ihtiyaç vardır defaultüzerinde listen 443çizgi. Dolayısıyla OP yapılandırması tamamdı, yalnızca kaldırılması gerekiyor ssl onve çalışması gerekiyor.
laurent

@bobojam cevabımdaki açıklamayı eklemekten çekinmeyin, böylece sizinki daha eksiksiz olur. OP yazarından cevabınızı kabul etmesini istedim.
Alexander Azarov

2
SSL amacını yorum yaparak nasıl çözer ssl on? @ MichaelJ.Evans aşağıdaki cevap çok daha iyi bir çözüm.
Neel

1
Birden çok conf dosyasıyla çalışmıyor gibi görünüyor. 2 yinelenen varsayılan olduğunu söylüyor. Alexander'ın çözümünü kullan.
Ryall

39

Yukarıdaki yanıtlar, sayfaların bağlantı güvenliğinden bağımsız olarak http üzerinden sunulmasına izin vermek için 'bu bağlantı HTTPS'sidir' testinin çoğunun aşırı kullanımı nedeniyle yanlıştır.

İstemciyi aynı isteği https'ye yeniden yönlendirmek için NGINX'e özgü bir http 4xx hata kodunda bir hata sayfası kullanan güvenli yanıt. (burada belirtildiği gibi /server/338700/redirect-http-mydomain-com12345-to-https-mydomain-com12345-in-nginx )

OP şunları kullanmalıdır:

server {
  listen        12345;
  server_name   php.myadmin.com;

  root         /var/www/php;

  ssl           on;

  # If they come here using HTTP, bounce them to the correct scheme
  error_page 497 https://$host:$server_port$request_uri;

  [....]
}

1
Muhtemelen $ host yerine $ server_name istiyorsunuz, server_name muhtemelen SSL'nin onayladığı CN'ye ayarlanmış. Bu şekilde, kullanıcı bir IP veya localhost aracılığıyla gelirse bir korku ekranı görmez.
George

Bunu yerel GitLab yüklememde uygulamaya çalışıyordum , ancak özel NGINX ayarlarını GitLab sunucu blok yöntemine ekleme yöntemini kullandım, bu yüzden nginx['custom_gitlab_server_config'] = "error_page 497 https://$host:$server_port$request_uri;"hile yaptım
Aaron C

17

Hata aslında her şeyi söylüyor. Yapılandırmanız Nginx'e 80 numaralı bağlantı noktasını (HTTP) dinlemesini ve SSL kullanmasını söyler. Tarayıcınızı işaret ettiğinizde http://localhostHTTP üzerinden bağlanmaya çalışır. Nginx, SSL beklediğinden, hatadan şikayet ediyor.

Çözüm çok basit. İki serverbölüme ihtiyacınız var :

server {
  listen 80;

  // other directives...
}

server {
  listen 443;

  ssl on;
  // SSL directives...

  // other directives...
}

7
Aslında iki sunucu bölümüne ihtiyacınız yok. "Ssl on" satırını kaldırın ve dinleme satırlarını @ bobojam'ın cevabına göre değiştirin.
toxaq

12

Tam olarak aynı sorunu yaşadım, örneğinizle aynı yapılandırmaya sahibim ve şu satırı kaldırarak çalıştırdım:

ssl on;

Belgeden alıntı yapmak için:

HTTP ve HTTPS sunucuları eşitse, hem HTTP hem de HTTPS isteklerini işleyen tek bir sunucu, "ssl on" yönergesi silinerek ve *: 443 bağlantı noktası için ssl parametresi eklenerek yapılandırılabilir.


1
Doktora bağlantınız var mı?
Adam Parkin

12

Durum kodlarıyla ilgili Wikipedia makalesine göre . Nginx, http trafiği https bağlantı noktasına gönderildiğinde özel bir hata koduna sahip (hata kodu 497)

Hata_sayfasındaki nginx belgelerine göre , belirli bir hata için gösterilecek bir URI tanımlayabilirsiniz.
Böylece, 497 hata kodu ortaya çıktığında istemcilerin gönderileceği bir uri oluşturabiliriz.

nginx.conf

#lets assume your IP address is 89.89.89.89 and also 
#that you want nginx to listen on port 7000 and your app is running on port 3000

server {
    listen 7000 ssl;
 
    ssl_certificate /path/to/ssl_certificate.cer;
    ssl_certificate_key /path/to/ssl_certificate_key.key;
    ssl_client_certificate /path/to/ssl_client_certificate.cer;

    error_page 497 301 =307 https://89.89.89.89:7000$request_uri;

    location / {
        proxy_pass http://89.89.89.89:3000/;

        proxy_pass_header Server;
        proxy_set_header Host $http_host;
        proxy_redirect off;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-Protocol $scheme;
    }
}

Ancak, bir müşteri GET dışında başka bir yöntemle bir talepte bulunursa, bu talep bir GET'e dönüştürülecektir. Böylece müşterinin geldiği istek yöntemini korumak için; error_page üzerindeki nginx belgelerinde gösterildiği gibi, yeniden yönlendirmeleri işleme hatası kullanıyoruz

Ve bu yüzden 301 =307yönlendirmeyi kullanıyoruz.

Burada gösterilen nginx.conf dosyasını kullanarak, aynı bağlantı noktasında http ve https dinleyebiliyoruz


bu benim için çalışıyor - error_page 497 301 = 307 89.89.89.89:7000$request_uri ;
ugali soft

7

İpv6 desteği ile aynı yapılandırma bloğunda HTTP ve HTTPS'yi yapılandırmak için bir örnek . Yapılandırma, Ubuntu Sunucusunda ve NGINX / 1.4.6'da test edilmiştir, ancak bu tüm sunucularla çalışmalıdır.

server {
    # support http and ipv6
    listen 80 default_server;
    listen [::]:80 default_server ipv6only=on;

    # support https and ipv6
    listen 443 default_server ssl;
    listen [::]:443 ipv6only=on default_server ssl;

    # path to web directory
    root /path/to/example.com;
    index index.html index.htm;

    # domain or subdomain
    server_name example.com www.example.com;

    # ssl certificate
    ssl_certificate /path/to/certs/example_com-bundle.crt;
    ssl_certificate_key /path/to/certs/example_com.key;

    ssl_session_timeout 5m;

    ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers "HIGH:!aNULL:!MD5 or HIGH:!aNULL:!MD5:!3DES";
    ssl_prefer_server_ciphers on;
}

Hataya ssl onneden olabilecekleri eklemeyin 400. Yukarıdaki yapılandırma şunun için çalışmalıdır:

http://example.com

http://www.example.com

https://example.com

https://www.example.com

Bu yardımcı olur umarım!



4

Aslında bunu şununla yapabilirsiniz:

ssl off; 

Bu, nginxvhosts kullanırken sorunumu çözdü; artık hem SSL hem de düz HTTP kullanabiliyorum. Birleşik bağlantı noktalarında bile çalışır.


Benim için çalışıyor nginx / 1.6.3 :)
djthoms
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.