सवाल Nginx में एसएसएल को कैसे मजबूर या पुनर्निर्देशित करें?


मेरे पास सबडोमेन पर एक साइनअप पेज है जैसे: https://signup.example.com

यह केवल HTTPS के माध्यम से सुलभ होना चाहिए, लेकिन मुझे चिंता है कि लोग किसी भी तरह HTTP पर इसके माध्यम से ठोकर खा सकते हैं और 404 प्राप्त कर सकते हैं।

Nginx में मेरा एचटीएमएल / सर्वर ब्लॉक इस तरह दिखता है:

html {
  server {
    listen 443;
    server_name signup.example.com;

    ssl                        on;
    ssl_certificate        /path/to/my/cert;
    ssl_certificate_key  /path/to/my/key;

    ssl_session_timeout 30m;

    location / {
      root /path/to/my/rails/app/public;
      index index.html;
        passenger_enabled on;
    }
  }
}

मैं जो जोड़ सकता हूं ताकि लोग जो जा सकें http://signup.example.com रीडायरेक्ट हो जाओ https://signup.example.com ? (एफवाईआई मुझे पता है कि रेल प्लगइन्स हैं जो बल दे सकते हैं SSL लेकिन उस से बचने की उम्मीद कर रहा था)


210
2018-03-22 18:45


मूल


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


जवाब:


इसके अनुसार nginx pitfalls, उपयोग करके अनावश्यक कब्जा छोड़ना थोड़ा बेहतर है $request_uri बजाय। उस स्थिति में, nginx को किसी भी क्वेरी तर्क को दोगुना करने से रोकने के लिए एक प्रश्न चिह्न संलग्न करें।

server {
    listen      80;
    server_name signup.mysite.com;
    rewrite     ^   https://$server_name$request_uri? permanent;
}

137
2018-03-22 19:22



या, आपके द्वारा लिंक की गई साइट के अनुसार, "बेहतर": return 301 http://domain.com$request_uri; - nh2
एक टिप्पणी। $ server_name $ पहले server_name चर को चुनता है। इसलिए यदि आपके कॉन्फ़िगरेशन में आपके पास FQN नाम नहीं हैं तो इस बारे में अवगत रहें - engineerDave
@ nh2 यह उपयोग करने के बाद से दस्तावेज गलत होने का एक और मामला है return 301... रीराइट विधि वास्तव में काम करता है, जबकि "बहुत अधिक रीडायरेक्ट" त्रुटि का कारण बनता है। - Mike Bethany
अब इसे "बीएडी" के रूप में भी दस्तावेज किया गया है। @MikeBethany return 301 काम करता है, जब तक (मुझे लगता है) आप इसे ट्रिगर कर रहे हैं भी सही यूआरएल के लिए, दोनों बंदरगाहों पर सुनकर (कॉन्फ़िगरेशन का उदाहरण। समस्या को ट्रिगर करना: ले लो serverfault.com/a/474345/29689's पहले जवाब दें और अगर छोड़ दें)। - Blaisorblade
मुझे आश्चर्य है कि पिछले कुछ वर्षों में क्या बदल गया है और क्या यह दूसरा जवाब बेहतर है: serverfault.com/a/337893/119666 - Ryan


जैसा कि वर्णन किया गया सबसे अच्छा तरीका है आधिकारिक कैसे करें का उपयोग कर है return निर्देश:

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

237
2017-09-03 23:50



सबसे छोटा जवाब और मेरे मामले में पूरी तरह से काम किया - mateusz.fiolka
आमतौर पर इसकी सिफारिश की जाती है क्योंकि यह एक देता है 301 Moved Permanently (आपके लिंक स्थायी रूप से स्थानांतरित हो गए हैं) साथ ही फिर से लिखना - sgb
यह काम नहीं करता है क्योंकि यह सेट होने पर भी "बहुत अधिक रीडायरेक्ट" त्रुटि का कारण बनता है proxy_set_header X-Forwarded-Proto https; - Mike Bethany
@ माइकबेथनी आप परिभाषित कर रहे हैं listen 443; एक ही ब्लॉक में? - Joe B
यह स्वीकार्य उत्तर होना चाहिए। - sjas


यदि आप इसे एक सर्वर ब्लॉक में रखना चाहते हैं तो यह सही और सबसे प्रभावी तरीका है:

server {
    listen   80;
    listen   [::]:80;
    listen   443 default_server ssl;

    server_name www.example.com;

    ssl_certificate        /path/to/my/cert;
    ssl_certificate_key  /path/to/my/key;

    if ($scheme = http) {
        return 301 https://$server_name$request_uri;
    }
}

उपरोक्त सब कुछ, "पुनः लिखना" या "अगर ssl_protocol" आदि का उपयोग धीमा और बदतर है।

यहां एक ही है, लेकिन यह भी अधिक कुशल है, केवल http प्रोटोकॉल पर पुनर्लेखन चलाकर, यह प्रत्येक अनुरोध पर $ योजना चर की जांच करने से बचाता है। लेकिन गंभीरता से, यह एक मामूली बात है कि आपको उन्हें अलग करने की आवश्यकता नहीं है।

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

    server_name www.example.com;

    return 301 https://$server_name$request_uri;
}
server {
    listen   443 default_server ssl;

    server_name www.example.com;

    ssl_certificate        /path/to/my/cert;
    ssl_certificate_key  /path/to/my/key;
}

108
2018-01-31 20:43



बढ़िया, कुछ डरावनी इस जवाब को बिना बताए मतदान कर रहे थे, भले ही यह जवाब सही है। शायद उनमें से एक "अगर बुरा है" पंथवादी। यदि आप Nginx दस्तावेज़ के बारे में पढ़ने के लिए परेशान हैं, तो आपको पता चलेगा कि IfIsNOTEvil, केवल CERTAIN इसका उपयोग किसी स्थान {} संदर्भ में करता है, जिसमें से कोई भी हम यहां नहीं करते हैं। मेरा जवाब चीजों को करने का बिल्कुल सही तरीका है! - DELETEDACC
मैंने इसे वोट नहीं दिया, लेकिन मैं यह इंगित करना चाहता हूं कि नवीनतम संस्करणों में डिफ़ॉल्ट को 'default_server' में बदल दिया गया है। - spuder
पहला समाधान सबसे कुशल नहीं हो सकता है, अगर दूसरा एक और अधिक कुशल है। और आपने यह भी वर्णन किया है कि आपको वहां क्यों उपयोग नहीं करना चाहिए: "यह हर अनुरोध पर $ स्कीम चर की जांच करने से बचाता है"। Ifs का उपयोग न करने का बिंदु न केवल प्रदर्शन के बारे में है, बल्कि घोषणात्मक होने के बारे में भी, और अनिवार्य नहीं है। - pepkin88
अगर ($ योजना = http) के लिए +1 - Fernando Kosh
जैसा कि अन्य उत्तरों में उल्लिखित है, यहां $ होस्ट का उपयोग करना चाहिए। - Artem Russakovskii


यदि आप नई दोहरी HTTP और HTTPS सर्वर परिभाषा का उपयोग कर रहे हैं, तो आप निम्न का उपयोग कर सकते हैं:

server {
    listen   80;
    listen   [::]:80;
    listen   443 default ssl;

    server_name www.example.com;

    ssl_certificate        /path/to/my/cert;
    ssl_certificate_key  /path/to/my/key;

    if ($ssl_protocol = "") {
       rewrite ^   https://$server_name$request_uri? permanent;
    }
}

यह मेरे लिए काम करता प्रतीत होता है और रीडायरेक्ट loops का कारण नहीं है।

संपादित करें:

जगह ले ली:

rewrite ^/(.*) https://$server_name/$1 permanent;

प्रतििक की पुनर्लेखन लाइन के साथ।


56
2017-08-08 11:12



@ डेविडपैशले आपका समाधान मेरे लिए एक आकर्षण की तरह काम करता था। धन्यवाद - Jayesh Gopalan
If you are using the new dual HTTP and HTTPS server definition तो आपको इसे अलग करना चाहिए। - VBart
सुरुचिपूर्ण और सही काम करता है! - jipipayo
यह एकमात्र समाधान था जो मेरे लैरावेल / होमस्टेड निजिनक्स कॉन्फ़िगरेशन के साथ मेरे लिए काम करता था। - Jared Eitnier
इसके अलावा पुनः लिखना लाइन होना चाहिए return 301 https://$server_name$request_uri; क्योंकि यह पसंदीदा तरीका है। - Jared Eitnier


फिर भी एक और संस्करण, जो होस्ट को संरक्षित करता है: अनुरोध हेडर और "अच्छा" उदाहरण का पालन करता है nginx pitfalls:

server {
    listen   10.0.0.134:80 default_server;

    server_name  site1;
    server_name  site2;
    server_name  10.0.0.134;

    return 301 https://$host$request_uri;
}

परिणाम यहां दिए गए हैं। ध्यान दें कि उपयोग कर रहा है $server_name के बजाय $host हमेशा रीडायरेक्ट करेगा https://site1

# curl -Is http://site1/ | grep Location
Location: https://site1/

# curl -Is http://site2/ | grep Location
Location: https://site2/


# curl -Is http://site1/foo/bar | grep Location
Location: https://site1/foo/bar

# curl -Is http://site1/foo/bar?baz=qux | grep Location
Location: https://site1/foo/bar?baz=qux

27
2018-04-11 12:20



Note that using $server_name instead of $host would always redirect to https://site1 वह नहीं है $request_uri के लिए है? - Jürgen Paul
$request_uri इसमें होस्ट या डोमेन नाम नहीं है। दूसरे शब्दों में, यह हमेशा एक "/" चरित्र से शुरू होता है। - Peter
दूर तक का सबसे अच्छा जवाब। - Ashesh
मुझे यकीन नहीं है कि वोट में यह जवाब इतना कम क्यों है। यह उपयोग करने के लायक एकमात्र एक है। - zopieux
कैंट का मानना ​​है कि बहुत से लोग $ server_name का उपयोग करते हैं, यह करने का सही तरीका है - Greg Ennis


सुनिश्चित करें कि आप किसी भी कुकीज पर 'सुरक्षित' सेट करते हैं, अन्यथा वे HTTP अनुरोध पर भेजे जाएंगे और फायरशेप जैसे टूल द्वारा पकड़े जा सकते हैं।


3
2018-03-23 00:40





server {
    listen x.x.x.x:80;

    server_name domain.tld;
    server_name www.domian.tld;
    server_name ipv4.domain.tld;

    rewrite     ^   https://$server_name$request_uri? permanent;
}

यह बेहतर काम करता है मुझे लगता है। x.x.x.x आपके सर्वर के आईपी को संदर्भित करता है। यदि आप Plesk 12 के साथ काम कर रहे हैं, तो आप जो भी डोमेन चाहते हैं उसके लिए निर्देशिका "/var/www/vhosts/system/domain.tld/conf" में "nginx.conf" फ़ाइल को बदलकर ऐसा कर सकते हैं। कॉन्फ़िगरेशन को सहेजने के बाद nginx सेवा को पुनरारंभ करना न भूलें।


1
2017-08-23 19:40



rewrite ^ https://$host$request_uri? permanent;  एक बेहतर समाधान होगा क्योंकि आपके पास vhost पर कई सर्वर नाम हो सकते हैं