Nginx ile www dışı www 'ye SSL üzerinden yönlendir


25

Yönlendirme çalışırken bir hata yaşıyorum https://example.com için https://www.example.com .

Https://example.com adresine gittiğimde yönlendirme yapmıyor ve sayfa / 200 durumunu döndürüyor.

Bunu istemiyorum, https://www.example.com adresine yönlendirmesini istiyorum .

Http://example.com adresine gittiğimde https://www.example.com adresine yönlendiriliyor.

Biri bana nerede yanlış gittiğimi söyleyebilir mi?

Bu benim varsayılan ve default-ssl yapılandırma dosyalarım:

default.conf

server {
    listen 80;
    server_name example.com;
    return 301 https://www.example.com$request_uri;
}

Varsayılan-ssl.conf

upstream app_server_ssl {
    server unix:/tmp/unicorn.sock fail_timeout=0;
}

server {
    server_name example.com;
    return 301 https://www.example.com$request_uri
}
server {
    server_name www.example.com;

    listen 443;
    root /home/app/myproject/current/public;
    index index.html index.htm;

    error_log /srv/www/example.com/logs/error.log info;
    access_log /srv/www/example.com/logs/access.log combined;

    ssl on;
    ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2;
    ssl_certificate /srv/www/example.com/keys/ssl.crt;
    ssl_certificate_key /srv/www/example.com/keys/www.example.com.key;
    ssl_ciphers AES128-SHA:RC4-MD5:ECDH+AESGCM:ECDH+AES256:ECDH+AES128:DH+3DES:RSA+3DES:!ADH:!AECDH:!MD5:AES128-SHA;
    ssl_prefer_server_ciphers on;

    client_max_body_size 20M;


    try_files $uri/index.html $uri.html $uri @app;


    # CVE-2013-2028 http://mailman.nginx.org/pipermail/nginx-announce/2013/000112.html
    if ($http_transfer_encoding ~* chunked) {
            return 444;
        }

    location @app {
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_redirect off;
        proxy_pass http://app_server_ssl;
    }

    error_page 500 502 503 504 /500.html;

    location = /500.html {
        root /home/app/example/current/public;
    }
}

1
2 conf dosyası oluşturmanın amacı nedir?
Sandip Subedi

Endişelerin ayrılması, SSL olmayan yapılandırmanın öylesine küçüktü ki, onu yalnızca SSL yapılandırmasından ayırmanın en iyi yolu.
Thomas V.

Yanıtlar:


34

listenDosyada direktif eksik default-ssl.conf. listen 443;Bu yönetmeliğe ekle

server {
    server_name example.com;
    return 301 https://www.example.com$request_uri;
}

Varsayılan olarak, bu yönergeyi çıkarırsanız, nginx, 80 numaralı bağlantı noktasında dinlemek istediğinizi varsayar. İşte bu varsayılan davranışın belgeleri .


Düzenleme: @TeroKilkanen'den yorum yaptığınız için teşekkür ederiz.

Burada default-ssl.conf için eksiksiz config

server {
    listen 443 ssl;
    server_name example.com;

    ssl_certificate /srv/www/example.com/keys/ssl.crt;
    ssl_certificate_key /srv/www/example.com/keys/www.example.com.key;
    return 301 https://www.example.com$request_uri;
}

Sidenote : ssl on;Direktifi nginx dokümantasyonununlisten 443 ssl; önerileriyle değiştirebilirsiniz .


4
Ayrıca , bu blokta ayarlamalar yapmanız ssl_certificateve ssl_certificate_keyyönergeler listen 443 ssl;yapmanız ve bunun bir SSL vhost'u olması için kullanmanız gerekir.
Tero Kilkanen

Lütfen akımın içeriğini gönderin default-ssl.conf. Belki bazı yazım hatası veya yeniden sipariş sorunu buna neden oldu.
masegaloeh

Bu utanç verici: \ Suçlu, / etc / nginx / sites etkin / nc / nginx yapılandırmasında yinelenen bir nginx yapılandırmasıydı, /etc/nginx/sites-enabled/default-ssl.backup, default-ssl içindeki herhangi bir yönlendirmeye engel oldu. Aptal hata.
Thomas V.

bu yüzden 2 tane sertifika vermem gerekiyordu: www-domain ve www-non-www one için
vladkras

Bu, liman 5007: example.com:5007 ila example.com:5007
CP3O

5

Sadece bir if ifadesi atın ve yolda olmalısınız. Sonuçları curl.exe -I olarak kontrol ettim ve https://www.example.com dışındaki tüm durumlar 301 olarak kabul edildi. SSL zor, çünkü 301 URL yönlendirmesini almadan önce kontrol ediliyor. Bu nedenle, sertifika hataları alırsınız.

Şahsen, www alan adından kaldırmayı seviyorum ama sorunuzu yanıtlamak için aşağıdaki kodumu yazdım.

server {
listen 443 ssl;
listen [::]:443 ssl; # IPV6

server_name example.com www.example.com; # List all variations here

# If the domain is https://example.com, lets fix it!

if ($host = 'example.com') {
  return 301 https://www.example.com$request_uri;
}

# If the domain is https://www.example.com, it's OK! No changes necessary!

... # SSL .pem stuff
...
}

server {
listen 80;
listen [::]:80;

# If the domain is http://example.com or https://www.example.com, let's change it to https!

server_name example.com www.example.com;
return 310 https://www.example.com$request_uri;
}

3

Bunu yapmamın yolu, www https adresine yönlendiren ssl sunucu bloğu içinde bir if ifadesi kullanmaktır

ssl_certificate /srv/www/example.com/keys/ssl.crt;
ssl_certificate_key /srv/www/example.com/keys/www.example.com.key;
ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers AES128-SHA:RC4-MD5:ECDH+AESGCM:ECDH+AES256:ECDH+AES128:DH+3DES:RSA+3DES:!ADH:!AECDH:!MD5:AES128-SHA;
ssl_prefer_server_ciphers on;
client_max_body_size 20M;

upstream app_server_ssl {
    server unix:/tmp/unicorn.sock fail_timeout=0;
}

server {
    server_name example.com;
    return 301 https://www.example.com$request_uri
}

server {
    listen 443 default_server ssl;
    server_name www.example.com;

    # redirect https://example.com to https://www.example.com
    # mainly for SEO purposes etc
    #we will use a variable to do that
    set $redirect_var 0;

    if ($host = 'example.com') {
      set $redirect_var 1;
    }
    if ($host = 'www.example.com') {
      set $redirect_var 1;
    }

    if ($redirect_var = 1) {
      return 301 https://www.example.com$request_uri;
    } 

    try_files $uri/index.html $uri.html $uri @app;

    # CVE-2013-2028 http://mailman.nginx.org/pipermail/nginx-announce/2013/000112.html
    if ($http_transfer_encoding ~* chunked) {
            return 444;
        }

    location @app {
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_redirect off;
        proxy_pass http://app_server_ssl;
    }

    error_page 500 502 503 504 /500.html;

    location = /500.html {
        root /home/app/example/current/public;
    }
}

Elbette, bir nginx config dosyasında bir if ifadesi kullanmak istediğinizde; Okumalısınız: https://www.nginx.com/resources/wiki/start/topics/depth/ifisevil/


durum if ($host = 'www.example.com')gerekli değildir.
Karl.S,

2

2018 şimdi ve birisinin basit bir çözüm araması durumunda, buna yenilenmiş bir şans vermeyi düşündüm.

Bunu nispeten yeni bir oyuncu olarak kabul etmem, olayları mümkün olduğunca basitleştirmektir. Temelde her iki yönlendirmek isteyen http://example.com ve https://example.com için https : // www .example.com. Ve yalnızca http ://example.com’u yönlendirmeyi başarabilmeniz

Bu sadece iki sunucu bloğu gerektiren oldukça basit bir işlemdir (bunu kısaca tek bir yapılandırma dosyasında göstereceğim)

# 1. Server block to redirect all non-www and/or non-https to https://www
server {
    # listen to the standard http port 80
    listen 80; 

    # Now, since you want to route https://example.com to http://www.example.com....
    # you need to get this block to listen on https port 443 as well
    # alternative to defining 'ssl on' is to put it with listen 443
    listen 443 ssl; 

    # define server_name
    server_name example.com *.example.com; 

    # DO NOT (!) forget your ssl certificate and key
    ssl_certificate PATH_TO_YOUR_CRT_FILE;
    ssl_certificate_key PATH_TO_YOUR_KEY_FILE; 

    # permanent redirect
    return 301 https://www.example.com$request_uri;  
    # hard coded example.com for legibility 
}
# end of server block 1. nearly there....

# 2. Server block for the www (primary) domain
# note that this is the block that will ultimately deliver content
server {
    # define your server name
    server_name www.example.com; 

    # this block only cares about https port 443
    listen 443 ssl;

    # DO NOT (!) forget your ssl certificate and key
    ssl_certificate PATH_TO_YOUR_CRT_FILE;
    ssl_certificate_key PATH_TO_YOUR_KEY_FILE; 

    # define your logging .. access , error , and the usual 

    # and of course define your config that actually points to your service
    # i.e. location / { include proxy_params; proxy_pass PATH_TO_SOME_SOCKET; }
}
# End of block 2.
# voilà! 

Şimdi hem http://example.com ve https://example.com yönlendirmelidir https://www.example.com . Temel olarak bu kurulum www olmayan ve / veya https olmayan her şeyi https: // www yönlendirir .


-1

Tüm istekleri yönlendirmek için https://www.example

SSL portunuzdaki yönlendirme ve birincil alan adı için bir sunucu bloğu oluşturun (genellikle 443) ve varsayılan http portu 80

# non-www to ssl www redirect
server {
  listen 80; 
  listen 443 ssl;
  server_name example.com;
  return 301 https://www.example.com$request_uri;
  # ... ssl certs
}

# ssl setup for www (primary) domain
server {
  listen 80;
  listen 443 ssl;
  server_name www.example.com;
  if ($scheme = http) {
    return 301 https://www.example.com$request_uri;
  }
  # ... the rest of your config + ssl certs
}

kaydet ve takip et sudo nginx -s reload

Bu yönlendirecek

http://example      301 -> https://www.example
https://example     301 -> https://www.example
http://www.example  301 -> https://www.example
https://www.example 200

;İf yan tümcesinde ikinci sunucu bloğunda bir eksik . Olması gerekenreturn 301 https://www.example.com$request_uri;
Lukas Oppermann

1
Ancak bu işe yarar mıydı? Onun için dinleyebilir miyim httpüzerinde 443?
Lukas Oppermann,

haklısın, seni özlüyorum 80 dinledim, onu da ekledim.
lfender6445 15
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.