ठीक से https के लिए "डिफ़ॉल्ट" nginx सर्वर की स्थापना


70

मेरे पास एक ही मशीन पर कई सर्वर चल रहे हैं, कुछ http के साथ, कुछ http और https दोनों के साथ। अलग-अलग फ़ाइलों में परिभाषित कई सर्वर ब्लॉक हैं जो मुख्य कॉन्फ़िगरेशन फ़ाइल से शामिल हैं।

मैंने http के लिए एक "डिफ़ॉल्ट" सर्वर स्थापित किया है जो एक सामान्य "रखरखाव पृष्ठ" के लिए अनुरोध करेगा जो अन्य config_names से किसी भी अन्य विन्यास फाइल में मेल नहीं खाता। Http डिफ़ॉल्ट सर्वर अपेक्षा के अनुसार काम करता है, यह server_name "_" का उपयोग करता है और यह पहली बार शामिल की सूची में प्रकट होता है (क्योंकि मैंने देखा है कि सर्वरों के बीच डुप्लिकेट server_names के मामले में, पहले दिखाई देने वाला उपयोग किया जाता है)। यह बहुत अच्छा काम करता है।

मैं उसी सटीक सर्वर ब्लॉक की उम्मीद करूंगा (केवल 443 default_server सुनने के लिए "80 default_server स्विचन" और साथ ही पेज "रिटर्न 444" परोसने के बजाय) हालांकि यह नहीं करता है। इसके बजाय, ऐसा प्रतीत होता है कि नया डिफ़ॉल्ट https सर्वर वास्तव में आने वाले सभी https कनेक्शन को हड़प रहा है और उन्हें विफल कर रहा है, हालांकि अन्य सर्वर ब्लॉक में आने वाले अनुरोधों के लिए अधिक उपयुक्त सर्वर_नाम है। नए डिफ़ॉल्ट https सर्वर को हटाने से फिर से शुरू करने के लिए अर्ध-सही व्यवहार होगा: https वाली वेबसाइटें सही ढंग से लोड होंगी; लेकिन बिना https वाली वेबसाइट्स को शामिल फ़ाइलों में पहले https सर्वर में भेज दिया जाएगा (जो डॉक्स के अनुसार, यदि कोई "default_server" प्रकट नहीं होता है, तो प्रदर्शित होने वाला पहला सर्वर ब्लॉक "डिफ़ॉल्ट" होगा)।

तो मेरा सवाल है, ssl कनेक्शन के लिए nginx में "डिफ़ॉल्ट सर्वर" को परिभाषित करने का सही तरीका क्या है? ऐसा क्यों है कि जब मैं स्पष्ट रूप से "default_server" सेट करता हूं, तो यह लालची हो जाता है और सभी कनेक्शनों को पकड़ लेता है, जबकि जब मैं स्पष्ट रूप से nginx को "डिफ़ॉल्ट सर्वर" तय करने देता हूं तो यह काम करता है जैसे कि मैं अपेक्षा करता हूं (डिफ़ॉल्ट रूप में गलत सर्वर सेट और अन्य वास्तविक सर्वर के साथ) सही ढंग से व्यवहार करना)?

यहाँ मेरे "डिफ़ॉल्ट सर्वर" हैं। Http दूसरे सर्वर को तोड़े बिना काम करता है। Https दूसरे सर्वर को तोड़ता है और सभी की खपत करता है।

server {
    listen 443 ssl default_server;
    server_name _;

    access_log /var/log/nginx/maintenance.access.log;
    error_log /var/log/nginx/maintenance.error.log error;

    return 444;
}

server {
    listen *:80 default_server;
    server_name _;
    charset utf-8;

    access_log /var/log/nginx/maintenance.access.log;
    error_log /var/log/nginx/maintenance.error.log error;

    root /home/path/to/templates;

    location / {
        return 503;
    }

    error_page 503 @maintenance;

    location @maintenance {
        rewrite ^(.*)$ /maintenance.html break;
    }
}

आप में से कोई भी देखता है कि यहां क्या गलत हो सकता है?

ssl  https  nginx 

जवाबों:


27

आपके पास "डिफ़ॉल्ट" https ब्लॉक में परिभाषित कोई भी ssl_certificate या ssl_certificate_key नहीं है। यद्यपि आपके पास इस डिफ़ॉल्ट परिदृश्य के लिए वास्तविक कुंजी नहीं है या आप चाहते हैं, फिर भी आपको एक को कॉन्फ़िगर करने की आवश्यकता है या किसी और nginx का अवांछित व्यवहार होगा जिसका आप वर्णन करते हैं।

एक सामान्य नाम * के साथ एक स्व-हस्ताक्षरित प्रमाणपत्र बनाएं और इसे अपने कॉन्फ़िगरेशन में प्लग करें और जैसा आप चाहते हैं, यह काम करना शुरू कर देगा।

इस सेट के तहत "डिफ़ॉल्ट" व्यवहार यह होगा कि एक ब्राउज़र को एक चेतावनी मिलेगी कि प्रमाण पत्र पर भरोसा नहीं किया जा सकता है, अगर उपयोगकर्ता अपवाद के रूप में प्रमाण पत्र जोड़ता है, तो कनेक्शन को nginx द्वारा छोड़ दिया जाएगा और वे अपने ब्राउज़र का डिफ़ॉल्ट देखेंगे "त्रुटि संदेश कनेक्ट नहीं कर सका"।


1
मैंने यह कोशिश की है, लेकिन यह अभी भी काम नहीं करता है: आईपी के सभी एसएसएल अनुरोध मेरे अन्य एसएसएल होस्ट पर जाते हैं। कुछ और मैं कोशिश कर सकता था?
माइकल Härtl

22

मैं एक एकल IP पर साझा समर्पित होस्टिंग को nginx के साथ कॉन्फ़िगर करने में कामयाब रहा। डिफ़ॉल्ट HTTP और HTTPS आने वाले अज्ञात डोमेन के लिए 404 परोसता है।

1 - एक डिफ़ॉल्ट क्षेत्र बनाएं

के रूप में nginx ascii क्रम में vhosts लोड हो रहा है, आप अपने में एक 00-defaultफ़ाइल / प्रतीकात्मक लिंक बनाना चाहिए /etc/nginx/sites-enabled

2 - डिफ़ॉल्ट क्षेत्र भरें

00-defaultडिफ़ॉल्ट vhosts के साथ भरें । यहाँ मैं उपयोग कर रहा क्षेत्र है:

server {
    server_name _;
    listen       80  default_server;
    return       404;
}


server {
    listen 443 ssl;
    server_name _;
    ssl_certificate /etc/nginx/ssl/nginx.crt;
    ssl_certificate_key /etc/nginx/ssl/nginx.key;
    return       404;
}

3 - स्व हस्ताक्षरित प्रमाण पत्र, परीक्षण और पुनः लोड बनाएँ

आपको स्वयं हस्ताक्षरित प्रमाणपत्र बनाने की आवश्यकता होगी /etc/nginx/ssl/nginx.crt

डिफ़ॉल्ट स्व हस्ताक्षरित प्रमाणपत्र बनाएं:

sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/nginx/ssl/nginx.key -out /etc/nginx/ssl/nginx.crt

याद दिलाने हेतु:

  • पुनः लोड / पुनः आरंभ करने से पहले nginx कॉन्फ़िगरेशन का परीक्षण करें: nginx -t
  • एक आनंद लें: sudo service nginx reload

आशा है ये मदद करेगा।


2
असुरक्षित साइट पर जाने की ब्राउज़र चेतावनी को हल नहीं करता है।
gdbj

4
कैच से हल नहीं किया जा सकता, सभी को किसी भी डोमेन से मेल खाना चाहिए। कोई भी SSL सभी डोमेन को वाइल्डकार्ड नहीं कर सकता है। सोचिए अगर आप अपने सर्वर पर google.fr एड्रेस को खराब कर रहे हैं, तो आप अपने सर्वर को google.fr के रूप में प्रमाणित कर पाएंगे। यह एक गंभीर सुरक्षा मुद्दा होगा :(
ifnot

हां, मुझे लगता है कि समझ में आता है। दुर्भाग्य से क्रोम में, आपको 404 पृष्ठ को देखने से पहले एक डरावनी चेतावनी प्रस्तुत की जाती है जो सर्वर के यातायात को अस्वीकार करने से भी बदतर है। ऐसा लगता है कि सर्वर गलत है।
gdbj

आपका बहुत बहुत धन्यवाद। इसने मेरे लिए काम किया, सिवाय इसके कि मुझे default_server443 सुनने के लिए जोड़ना था और मैंने IPv6 एड्रेस [::]: 80 और [::]: 443 को जोड़ा default_server
चमीक

16

हम मूल रूप से हर कीमत पर बचना चाहते हैं कि हमारी कॉन्फ़िग फ़ाइल में पहली सर्वर परिभाषा SSL कनेक्शन के लिए एक कैच-ऑल-सर्वर के रूप में दी जाती है। हम सभी जानते हैं कि यह ऐसा होता है (http के विपरीत और default_server config का उपयोग करके जो अच्छी तरह से काम करता है)।

यह एसएसएल (अभी तक) के लिए घोषित रूप से प्राप्त नहीं किया जा सकता है इसलिए हमें इसे एक IF के साथ कोड करना होगा ...

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

इसलिए यदि ये दोनों समान नहीं हैं, तो आपने इस SSL सर्वर ब्लॉक को किसी अन्य होस्ट के लिए परोसा है ताकि इसे ब्लॉक कर दिया जाए।

कोड में आपके सर्वर आईपी पते के लिए विशिष्ट संदर्भ नहीं होते हैं ताकि इसे आसानी से बिना संशोधन के अन्य सर्वर कॉन्फ़िगरेशन के लिए पुन: उपयोग किया जा सके।

उदाहरण:

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;

    ###
    ### Section: SSL

    #
    ## Check if this certificate is really served for this server_name
    ##   http://serverfault.com/questions/578648/properly-setting-up-a-default-nginx-server-for-https
    if ($host != $server_name) {
        #return 404 "this is an invalid request";
        return       444;
    }

    ...

क्या आप बता सकते हैं कि क्या listen [::]:443 ssl http2;करता है? मुझे इसके लिए प्रलेखन खोजने में समस्या हो रही है।
एंड्रयू ब्राउन

मुझे लगता है कि मुझे यह मिल गया है, बस यह जानने की जरूरत है कि क्या खोजना है। IPV4 और IPV6 निर्देश।
एंड्रयू ब्राउन

7

रेडमिल्ला मुस्तफा के उत्तर पर अधिक जानकारी के लिए:

Nginx server_name मिलान के लिए 'होस्ट' हेडर का उपयोग करता है। यह टीएलएस एसएनआई का उपयोग नहीं करता है। इसका मतलब यह है कि एसएसएल सर्वर के लिए, nginx को SSL कनेक्शन स्वीकार करने में सक्षम होना चाहिए, जो प्रमाण पत्र / कुंजी रखने के लिए उबलता है। प्रमाणित / कुंजी कोई भी हो सकती है, उदाहरण के लिए स्व-हस्ताक्षरित।

प्रलेखन देखें

इसलिए, समाधान है:

server {
    server_name _;
    listen 80 default_server;
    listen 443 ssl default_server;

    ## To also support IPv6, uncomment this block
    # listen [::]:80 default_server;
    # listen [::]:443 ssl default_server;

    ssl_certificate <path to cert>;
    ssl_certificate_key <path to key>;
    return 404; # or whatever
}

मुझे लगता है कि यह स्वीकृत उत्तर होना चाहिए। बहुत धन्यवाद।
समुच्चय

2

जो कोई भी मेरे ऊपर इस के रूप में अधिक बाल खो दिया है (आज इस पर लगभग पूरा दिन बिताया)। मैंने लगभग हर चीज़ की कोशिश की है, और जिस चीज़ ने इसे सही ढंग से काम किया है वह थी यह बेवकूफी भरी लाइन:

ssl_session_tickets off;

इफोट के उत्तर पर निर्माण , मेरा काम करने का उदाहरण है:

server {
    listen 443 ssl http2 default_server;
    listen [::]:443 ssl http2 default_server;
    server_name _;

    ssl_certificate /etc/nginx/ssl/nginx.crt;
    ssl_certificate_key /etc/nginx/ssl/nginx.key;
    ssl_session_tickets off;

    return 404;
}

मुझे नहीं पता कि यह क्यों आवश्यक था, केवल एक ही सिद्धांत जो मैं इस से निकला था कि नग्नेक्स बहुत अजीब व्यवहार करता है जब हम उसे वह नहीं देते जो वह चाहता है।


1
आप महान व्यक्ति हैं।
निजार ब्लॉन्ड

1

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

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.