Soru Nginx'te, alt alan adı korurken tüm http isteklerini https’e nasıl yazabilirim?


Https istekleri olmak için web sunucumdaki tüm http isteklerini yeniden yazmak istiyorum, aşağıdakilerle başladım:

sunucu {
    80'i dinle;

    yer / {
      ^ (. *) https: //mysite.com$1 kalıcı olarak yeniden yazmak;
    }
...


Bir Sorun, bunun herhangi bir alt alan bilgisini (ör. Node1.mysite.com/folder) çıkarmasıdır, her şeyi yeniden yönlendirmek ve alt alanı korumak için yukarıdakileri nasıl yeniden yazabilirim?


495
2017-09-21 14:04


Menşei


Lütfen 'kabul edilen yanıtı' serverfault.com/a/171238/90758. Doğru olan bu. - olafure
Sadece sabit kodlanmış mysite.com yerine $ server_name kullanın - Fedir RYKHTIK


Cevaplar:


Nginx'in yeni sürümlerinde doğru yol

Bu sorunun ilk cevabım belli bir zamanda doğruydu, ama başka bir tuzağa dönüştü - güncel kalmak için lütfen kontrol edin Vergi yeniden başlatma tuzakları

Birçok SE kullanıcısı tarafından düzeltildim, bu yüzden kredi onlara gider, ama daha önemlisi, doğru kod:

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

server {
       listen         443 ssl;
       server_name    my.domain.com;
       # add Strict-Transport-Security to prevent man in the middle attacks
       add_header Strict-Transport-Security "max-age=31536000" always; 

       [....]
}

737
2017-12-05 20:43



Bunu ancak alan adına göre yapmak zorunda kalacaksınız - hayır? Ya sunucunuzdaki her etki alanına uygulamak isterdiniz? - JM4
@ JM4: sunucu_adı yerine rewrite $ $ 'ı kullanıyorsanız ve default_server öğesini dinleme yönergesine eklerseniz, sunucunuzdaki her etki alanı için çalışır. - Klaas van Schelven
301'in yerel önbelleğinizde son kullanma tarihi olmadan saklandığından bahsetmek önemlidir. Yapılandırma değişikliklerinde çok kullanışlı değil - Trefex
@everyone POST içeriğini korumak için 307 yönlendirme kullanın. - Mahmoud Al-Qudsi
Kullanmanız gerektiğini unutmayın $host yerine $server_name alt alan adları kullanıyorsanız. - Catfish


NOT: Bunu yapmanın en iyi yolu, https://serverfault.com/a/401632/3641 - ama burada tekrarlanır:

server {
    listen         80;
    return 301 https://$host$request_uri;
}

En basit durumda sunucunuz, göndermek istediğiniz hizmetiniz olacak şekilde sabitlenecektir - bu, tarayıcıya bir 301 yönlendirmesi yapacaktır ve tarayıcı URL'si buna göre güncellenecektir.

Aşağıda, regex nedeniyle verimsiz olan önceki cevap, 301 @kmindi ile gösterildiği gibi harika

Nginx 0.8.39 ve üstünü kullanıyorum ve aşağıdakileri kullandım:

 server {
       listen 80;
       rewrite ^(.*) https://$host$1 permanent;
 }

İstemciye kalıcı bir yönlendirme gönderir.


270
2017-08-17 03:07



Bence bu 80 olmalı - çünkü bu http dinliyor ve sonra müşteriye geri dönüp https olarak geri dönmesini söylüyor (443). - Michael Neale
Bu en iyi cevap olmalı! - Nathan
Bu en çok vergi veren cevaptır. - Case
Bu en kolay olanıdır, ancak en az güvenlidir - bu şekilde sunucunuzun bir kullanıcı için herhangi bir sayfaya yönlendirmesine izin verirsiniz, sunucunuzda kullanılmasına bile izin verilip verilmediğini kontrol etmeden. Sunucunuz mydomain.co hizmet ediyorsa, kötü amaçlı kullanıcılar, kullanıcıları google.com gibi mydomain.co gibi diğer alanlara yönlendirmek için sunucunuzu kullanmaya devam edebilir. - friedkiwi
@ cab0lt burada güvenlik sorunu yoktur. Yönlendirme hizmeti sunmak bir güvenlik riski sunmaz. Erişim kontrol gereksinimleri varsa, bunlar tarayıcının yeni URL'yi talep ettiği noktada kontrol edilmelidir. Tarayıcı, yalnızca yönlendirme temelinde erişim elde etmeyecek ve yeni URL'yi istemek için yönlendirmeye ihtiyaç duymaz. - mc0e


Bence en iyi ve tek yol bir HTTP 301 Kalıcı Olarak Taşındı şu şekilde yönlendir:

server {
    listen         [::]:80;
    return 301 https://$host$request_uri;
}

HTTP 301 Kalıcı Olarak Taşındı Yönlendirme aynı zamanda en verimlidir çünkü daha önce bahsedilen değerlere göre değerlendirilmek üzere bir regex yoktur. pitfails.


Yeni HTTP 308 Kalıcı Olarak Taşındı İstek yöntemini korur ve büyük tarayıcılar tarafından desteklenir. Örneğin, kullanarak 308 tarayıcıların istek yöntemini değiştirmesini engeller POST için GET yönlendirme isteği için.


Eğer istersen ana makine adını ve alt alan adını koru yol budur.

Bu DNS’niz yoksa hala çalışırBen de yerel olarak kullanıyorum. Örneğin ile rica ediyorum http://192.168.0.100/index.php ve tam olarak yönlendirilecek https://192.168.0.100/index.php.

kullanırım listen [::]:80 ev sahibi üzerinde çünkü benim bindv6only ayarlanır falsebu yüzden ipv4 soketine de bağlanır. onu değiştir listen 80 IPv6 istemiyorsanız veya başka bir yere bağlamak istiyorsanız.

Saif Bechan'un çözümü server_name Benim durumumda localhost ama bu bir ağ üzerinden ulaşılamaz.

Michael Neale'ın çözümü iyi, ama pitfails'e göre, 301 yönlendirme ile daha iyi bir çözüm var;


121
2018-06-23 17:19



Güzel alıntı yapmaya çalışın ama 301 HTTPS'de çalışmıyor. - Case
ne çalışmıyor? Belirtilen sunucu bölümü şifrelenmemiş http (s) trafiğinin kalıcı olarak şifreli sunucuya yeniden yönlendirilmesi içindir (443 (https) dinleyen bölüm listelenmemiş) - kmindi
Bu çalışmayı https ve her şeyle çok iyi kontrol ettim - @kmindi Cevapımı sizinkiyle güncelledim - doğru yol olduğunu düşündüğümden ve bu durum devam ediyor! İyi iş. - Michael Neale
Bir etki alanı (non-ip) isteği kullanırken, '[::]: 80' ila '80' değiştirmedikçe çalışmaz. - Joseph Lust
Bu beklenen davranış olabilir: trac.nginx.org/nginx/ticket/345. Dinleme seçeneğini açıklamak için cevabı güncelledim. - kmindi


Yukarıda her zaman oluşturulmakta olan yeni alt etki alanları ile birlikte çalışmadı. Örneğin. Yaklaşık 30 alt alan için AAA.example.com BBB.example.com.

Sonunda aşağıdakilerle çalışan bir yapılandırma var:

server {
  listen 80;
  server_name _;
  rewrite ^ https://$host$request_uri? permanent;
}
server {
  listen  443;
  server_name example.com;
  ssl on;
  ssl_certificate /etc/ssl/certs/myssl.crt;
  ssl_certificate_key /etc/ssl/private/myssl.key;
  ssl_prefer_server_ciphers       on;
# ...
# rest of config here
# ...
}

17
2018-06-25 04:29



teşekkür ederim! Nginx ya dönecekti 301 https://*/ veya buradaki diğer cevaplarda isteği erken olarak iptal edebilirsiniz. server_name _; ile $host hile yaptığı cevap oldu. +1 - zamnuts
Bu en uygun! Ancak, bazı değiştirmek için tavsiye ederim _ gerçek alan ile, ör. .domain.com İki sunucum vardı ve nginx yanlışlıkla bir sunucumu varsayılan sunucuya yönlendiriyordu. - zzz
Bu benim için çalışan tek cevap, teşekkürler! - Snowman
Çok teşekkürler dostum .. Çözümlerin çoğunu denedim ama işe yaramadı. Bu çözümler harika ve benim için çalıştı. sunucu adı _; Bu ne anlama geliyordu ... Ben anlamadım. Lütfen bunu bana açıkla. - Pavan Kumar


Sunucu bloğu içinde aşağıdakileri de yapabilirsiniz:

# Force HTTPS connection. This rules is domain agnostic
if ($scheme != "https") {
    rewrite ^ https://$host$uri permanent;
}

16
2017-07-31 19:50



Bu yapılandırma sunucumun bir yönlendirme döngüsü oluşturmasına neden oldu - Corkscreewe
Belki yerinde başka bir yönlendirme var veya sitenizde / uygulamanızda https etkin değil - Oriol
Diğerlerinin hiçbiri bunun dışında çalışmadı. Nginx sürümünü kullanma: nginx / 1.10.0 (Ubuntu) - ThatGuy343
https: // $ host $ uri için aşağı çekildi - AMB
Bir yük dengeleyicinin ardındaysan gitmenin yolu budur! - Antwan


Doğru cevaba uzun, uzun zaman önce çok önemli bir düzeltmeyle ilgili bir yorum gönderdim, ancak bu düzeltmeyi kendi cevabında vurgulamak gerektiğini düşünüyorum. Herhangi bir noktada, güvensiz HTTP kurulumu yaptığınız ve kullanıcı içeriği beklediğiniz, formlarınız olduğu, bir API barındırdığı veya sitenizle konuşacak herhangi bir web sitesi, araç, uygulama veya yardımcı programı yapılandırdıysanız, önceki cevaplardan hiçbiri güvenli değildir.

Sorun, bir POST istek sunucunuza yapılır. Eğer sunucu düz bir şekilde cevap veriyorsa 30x yönlendirme POST içeriği kaybolacak. Ne olur, tarayıcı / istemci isteği SSL'ye yükseltir ancak bozmak  POST bir GET istek. POST parametreler kaybolacak ve sunucunuza yanlış bir istek yapılacaktır.

Çözüm basit. Kullanmalısın HTTP 1.1 307 yönlendirir. Bu, RFC 7231 S6.4.7'de ayrıntılı olarak açıklanmıştır:

  Note: This status code is similar to 302 (Found), except that it
  does not allow changing the request method from POST to GET.  This
  specification defines no equivalent counterpart for 301 (Moved
  Permanently) ([RFC7238], however, defines the status code 308
  (Permanent Redirect) for this purpose).

Kabul edilen çözümden uyarlanan çözüm kullanmaktır. 307 yönlendirme kodunuzda:

server {
       listen         80;
       server_name    my.domain.com;
       return         307 https://$server_name$request_uri;
}

server {
       listen         443 ssl;
       server_name    my.domain.com;
       # add Strict-Transport-Security to prevent man in the middle attacks
       add_header Strict-Transport-Security "max-age=31536000"; 

       [....]
}

6
2018-03-19 20:24



çok, çok çok el komut. Teşekkürler! - Denis Matafonov


Bunu böyle yapmayı başardım:

server {
listen 80;
listen 443 ssl;

server_name domain.tld www.domain.tld;

# global HTTP handler
if ($scheme = http) {
        return 301 https://www.domain.tld$request_uri;
}

# global non-WWW HTTPS handler
if ($http_host = domain.tld){
        return 303 https://www.domain.tld$request_uri;
}
}

https://stackoverflow.com/a/36777526/6076984


4
2018-04-21 18:27



Güncelleme sürümü, IF / W: paste.debian.net/plain/899679 - stamster


Bir AWS ELB'nin arkasında ngnix çalışıyorum. ELB, http üzerinden ngnix ile konuşuyor. ELB'nin istemcilere yönlendirmeler göndermesinin bir yolu olmadığından, X-Yönlendirmeli Protokolün üstbilgisini kontrol edip yönlendiriyorum:

if ($http_x_forwarded_proto != 'https') {
    return 301 "https://www.exampl.com";
}

3
2018-01-04 17:09