सवाल Nginx में, मैं सब-डोमेन को बनाए रखते हुए https पर सभी http अनुरोधों को फिर से लिख सकता हूं?


मैं अपने वेब सर्वर पर सभी अनुरोधों को https अनुरोधों के लिए फिर से लिखना चाहता हूं, मैंने निम्न के साथ शुरुआत की:

सर्वर {
    80 सुनो;

    स्थान / {
      पुनः लिखें ^ (। *) https: //mysite.com$1 स्थायी;
    }
...


एक समस्या यह है कि यह किसी भी सबडोमेन जानकारी को दूर करता है (उदाहरण के लिए, node1.mysite.com/folder), मैं सब कुछ फिर से लिख सकता हूं ताकि सबकुछ https में वापस कर सकें और उप-डोमेन को बनाए रख सकूं?


495
2017-09-21 14:04


मूल


कृपया 'स्वीकृत उत्तर' को ले जाने पर विचार करें serverfault.com/a/171238/90758। यह सही है। - olafure
हार्डकोडेड mysite.com के बजाय बस $ server_name का उपयोग करें - Fedir RYKHTIK


जवाब:


Nginx के नए संस्करणों में सही तरीका

इस सवाल का मेरा पहला जवाब कुछ समय पर सही था, लेकिन यह एक और गड़बड़ी में बदल गया - अद्यतित रहने के लिए कृपया जांचें टैक्सिंग फिर से लिखना नुकसान

मुझे कई एसई उपयोगकर्ताओं द्वारा सही किया गया है, इसलिए क्रेडिट उनके पास जाता है, लेकिन सबसे महत्वपूर्ण बात यह है कि यहां सही कोड है:

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



डोमेन डोमेन के आधार पर आपको इसे डोमेन पर करना होगा - नहीं? क्या होगा यदि आप इसे अपने सर्वर पर हर डोमेन पर लागू करना चाहते हैं? - JM4
@ जेएम 4: यदि आप सर्वर_नाम के बजाय पुनः लिखने में $ होस्ट $ का उपयोग करते हैं और सुनवाई निर्देश में डिफ़ॉल्ट_सर्वर जोड़ते हैं तो यह आपके सर्वर पर प्रत्येक डोमेन के लिए काम करेगा। - Klaas van Schelven
यह उल्लेख करना महत्वपूर्ण है कि 301 को आपके स्थानीय कैश में समाप्ति तिथि के बिना संग्रहीत किया जाता है। कॉन्फ़िगरेशन बदलते समय बहुत उपयोगी नहीं है - Trefex
@ हर कोई पोस्ट सामग्री को संरक्षित करने के लिए 307 रीडायरेक्ट का उपयोग करें। - Mahmoud Al-Qudsi
ध्यान दें कि आपको उपयोग करना होगा $host के बजाय $server_name यदि आप सबडोमेन का उपयोग कर रहे हैं। - Catfish


नोट: ऐसा करने का सबसे अच्छा तरीका प्रदान किया गया था https://serverfault.com/a/401632/3641 - लेकिन यहां दोहराया गया है:

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

सबसे सरल मामले में आपका होस्ट आपकी सेवा के लिए तय किया जाएगा, जिसे आप उन्हें भेजना चाहते हैं - यह ब्राउज़र पर 301 रीडायरेक्ट करेगा और ब्राउज़र यूआरएल तदनुसार अपडेट होगा।

नीचे पिछला उत्तर है, जो regex के कारण अक्षम है, एक साधारण 301 महान है जैसा कि @kmindi द्वारा दिखाया गया है

मैं nginx 0.8.39 और ऊपर का उपयोग कर रहा हूं, और निम्न का उपयोग किया है:

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

ग्राहक को स्थायी रीडायरेक्ट भेजता है।


269
2017-08-17 03:07



मुझे लगता है कि यह 80 होना चाहिए - क्योंकि यह http के लिए सुन रहा है और फिर ग्राहक को https (443) के रूप में वापस आने के लिए कह रहा है। - Michael Neale
यह शीर्ष जवाब होना चाहिए! - Nathan
यह सबसे करदाता जवाब है। - Case
यह सबसे आसान है, लेकिन कम से कम सुरक्षित - इस तरह आप अपने सर्वर को किसी भी पृष्ठ पर किसी उपयोगकर्ता को रीडायरेक्ट करने की अनुमति देते हैं, बिना जांच किए कि क्या इसे आपके सर्वर पर भी उपयोग करने की अनुमति है या नहीं। यदि आपका सर्वर mydomain.co परोसता है, तो दुर्भावनापूर्ण उपयोगकर्ता अभी भी google.com जैसे mydomain.co जैसे अन्य डोमेन पर रीडायरेक्ट करने के लिए आपके सर्वर का उपयोग कर सकते हैं। - friedkiwi
@ cab0lt यहां कोई सुरक्षा समस्या नहीं है। रीडायरेक्ट की सेवा करना सुरक्षा जोखिम नहीं पेश करता है। यदि पहुंच नियंत्रण आवश्यकताओं की आवश्यकता है, तो उन बिंदुओं पर उनको चेक किया जाना चाहिए जहां ब्राउज़र नए यूआरएल का अनुरोध करता है। ब्राउजर को रीडायरेक्ट के आधार पर आसानी से पहुंच नहीं मिलेगी, न ही उन्हें नए यूआरएल का अनुरोध करने के लिए रीडायरेक्ट की आवश्यकता होगी। - mc0e


मुझे लगता है कि सबसे अच्छा और एकमात्र तरीका एक का उपयोग करना चाहिए HTTP 301 स्थायी रूप से स्थानांतरित हो गया इस तरह रीडायरेक्ट करें:

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

HTTP 301 स्थायी रूप से स्थानांतरित हो गया रीडायरेक्ट भी सबसे कुशल है क्योंकि पहले से उल्लिखित अनुसार, मूल्यांकन करने के लिए कोई रेगेक्स नहीं है pitfails


नया HTTP 308 स्थायी रूप से स्थानांतरित हो गया अनुरोध विधि को संरक्षित करता है और है प्रमुख ब्राउज़रों द्वारा समर्थित। उदाहरण के लिए, का उपयोग कर 308 ब्राउज़र से अनुरोध विधि को बदलने से रोकता है POST सेवा मेरे GET पुनर्निर्देशन अनुरोध के लिए।


यदि आप चाहते हैं होस्टनाम और सबडोमेन को सुरक्षित रखें यह रास्ता है।

इस यदि आपके पास कोई DNS नहीं है तो भी काम करता है, क्योंकि मैं इसे स्थानीय रूप से भी उपयोग कर रहा हूं। मैं उदाहरण के लिए अनुरोध कर रहा हूँ http://192.168.0.100/index.php और बिल्कुल ठीक से रीडायरेक्ट हो जाएगा https://192.168.0.100/index.php

मैं उपयोग करता हूं listen [::]:80 मेरे मेजबान पर मेरे पास है bindv6only करने के लिए सेट false, इसलिए यह ipv4 सॉकेट से भी जुड़ा हुआ है। इसे बदलो listen 80 यदि आप आईपीवी 6 नहीं चाहते हैं या कहीं और बांधना चाहते हैं।

सैफ बेचन का समाधान इसका उपयोग करता है server_name जो मेरे मामले में लोकलहोस्ट है लेकिन यह नेटवर्क पर पहुंच योग्य नहीं है।

माइकल नेले का समाधान अच्छा है, लेकिन पिटफेल के अनुसार, 301 रीडायरेक्ट के साथ एक बेहतर समाधान है;)


121
2018-06-23 17:19



अच्छा है कि आप इसे उद्धृत करने का प्रयास करें, लेकिन 301 HTTPS पर काम नहीं करता है। - Case
क्या काम नहीं करता है? निर्दिष्ट सर्वर अनुभाग गैर-एन्क्रिप्टेड http (बिना एस) यातायात को स्थायी रूप से एन्क्रिप्टेड सर्वर पर रीडायरेक्ट करने के लिए है (वह अनुभाग जो 443 (https) पर सुनता है सूचीबद्ध नहीं है) - kmindi
मैंने https और सबकुछ के साथ यह काम बहुत अच्छा देखा - @किमिंदी मैंने आपके उत्तर को आपके संदर्भ में अपडेट किया - जैसा कि मुझे लगता है कि यह सही तरीका है और यह पॉप-अप रहता है! अच्छा काम। - Michael Neale
डोमेन (गैर-आईपी) अनुरोध का उपयोग करते समय, तब तक काम नहीं करता जब तक कि मैं '[::]: 80' से '80' नहीं बदलता। - Joseph Lust
यह अपेक्षित व्यवहार हो सकता है: trac.nginx.org/nginx/ticket/345। मैंने सुनो विकल्प का वर्णन करने के लिए उत्तर अपडेट किया। - kmindi


उपरोक्त नए उपडोमेनों के साथ हर समय बनाए जाने के लिए काम नहीं किया था। जैसे लगभग 30 सबडोमेन के लिए AAA.example.com BBB.example.com।

आखिरकार निम्नलिखित के साथ काम कर रहे एक कॉन्फ़िगरेशन मिला:

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



धन्यवाद! nginx या तो वापस आ जाएगा 301 https://*/ या यहां अन्य उत्तरों में अनुरोध को समय-समय पर रद्द कर दें। server_name _; साथ में $host वह जवाब था जिसने चाल बनाई थी। +1 - zamnuts
यह इष्टतम है! हालांकि, मैं कुछ बदलने के लिए सिफारिश करता हूं _ वास्तविक डोमेन के साथ, उदा। .domain.com मेरे पास दो सर्वर थे, और nginx गलती से मेरे सर्वरों में से एक को डिफ़ॉल्ट सर्वर पर निर्देशित कर रहा था। - zzz
यह एकमात्र उत्तर है जो मेरे लिए काम करता है, धन्यवाद! - Snowman
बहुत बहुत धन्यवाद .. मैंने कई समाधानों की कोशिश की है लेकिन काम नहीं किया है। यह समाधान अद्भुत है और यह मेरे लिए काम करता है। सर्वर का नाम _; इसका मतलब क्या है .. मुझे समझ में नहीं आया। कृपया मुझे यह समझाओ। - Pavan Kumar


सर्वर ब्लॉक के भीतर आप निम्न कार्य भी कर सकते हैं:

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

16
2017-07-31 19:50



इस कॉन्फ़िगरेशन ने मेरे सर्वर को रीडायरेक्ट लूप का उत्पादन करने का कारण बताया - Corkscreewe
हो सकता है कि स्थान पर कोई अन्य रीडायरेक्ट हो या https आपकी साइट / ऐप में सक्षम न हो - Oriol
दूसरों को छोड़कर कोई भी काम नहीं कर रहा था। Nginx संस्करण का उपयोग करना: nginx / 1.10.0 (उबंटू) - ThatGuy343
https: // $ host $ uri के लिए अपवित्र - AMB
यदि आप लोडबैंसर के पीछे हैं तो यह रास्ता तय करने का तरीका है! - Antwan


मैंने बहुत लंबे समय से एक बहुत ही महत्वपूर्ण सुधार के साथ सही उत्तर पर एक टिप्पणी पोस्ट की, लेकिन मुझे लगता है कि इस सुधार को अपने उत्तर में हाइलाइट करना जरूरी है। पिछले उत्तरों में से कोई भी उपयोग सुरक्षित नहीं है अगर किसी भी बिंदु पर आपने असुरक्षित HTTP सेट अप किया है और उपयोगकर्ता सामग्री की अपेक्षा की है, फॉर्म हैं, एक एपीआई होस्ट करें, या अपनी साइट से बात करने के लिए किसी भी वेबसाइट, टूल, एप्लिकेशन या उपयोगिता को कॉन्फ़िगर किया है।

समस्या तब होती है जब ए POST अनुरोध आपके सर्वर पर किया गया है। यदि एक सादे के साथ सर्वर प्रतिक्रिया 30x अनुप्रेषित पोस्ट सामग्री खो जाएगी। क्या होता है कि ब्राउज़र / क्लाइंट अनुरोध को एसएसएल में अपग्रेड करेगा लेकिन ढाल  POST ए के लिए GET निवेदन। POST पैरामीटर खो जाएंगे और आपके सर्वर पर गलत अनुरोध किया जाएगा।

समाधान सरल है। आपको एक का उपयोग करने की जरूरत है HTTP 1.1 307 अनुप्रेषित। यह आरएफसी 7231 एस 6.4.7 में विस्तृत है:

  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).

स्वीकार्य समाधान से अनुकूलित समाधान का उपयोग करना है 307 आपके रीडायरेक्ट कोड में:

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



बहुत, बहुत ही सौहार्दपूर्ण कमांड। धन्यवाद! - Denis Matafonov


मैं इसे ऐसा करने में कामयाब रहा:

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



अद्यतन संस्करण, w / o अगर: paste.debian.net/plain/899679 - stamster