नगीनक्स किसी भी डोमेन नाम का जवाब क्यों दे रहा है?


139

मेरे पास एक रूबी / सिनात्रा ऐप है, जो सब कुछ ठीक है। हालाँकि, मैं अब उसी सर्वर से एक दूसरे एप्लिकेशन को चलाने का प्रयास कर रहा हूं और मुझे कुछ अजीब लगा। सबसे पहले, यहाँ मेरा nginx.conf है:

pid /tmp/nginx.pid;
error_log /tmp/nginx.error.log;

events {
  worker_connections 1024;
  accept_mutex off;
}

http {
  default_type application/octet-stream;
  access_log /tmp/nginx.access.log combined;

  sendfile on;
  tcp_nopush on;
  tcp_nodelay off;

  gzip on;
  gzip_http_version 1.0;
  gzip_proxied any;
  gzip_min_length 500;
  gzip_disable "MSIE [1-6]\.";
  gzip_types text/plain text/xml text/css
             text/comma-separated-values
             text/javascript application/x-javascript
             application/atom+xml;

  upstream app {
    server unix:/var/www/app/tmp/sockets/unicorn.sock fail_timeout=0;
  }

  server {
    listen 80;
    client_max_body_size 4G;
    server_name FAKE.COM;

    keepalive_timeout 5;

    root /var/www/app/public;

    location / {
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header Host $http_host;
      proxy_redirect off;

      if (!-f $request_filename) {
        proxy_pass http://app;
        break;
      }
    }

    error_page 500 502 503 504 /500.html;
    location = /500.html {
      root /var/www/app/public;
    }
  }
}
                                                          68,0-1        B

ध्यान दें कि सर्वर server_nameपर FAKE.COMअभी तक कैसे सेट किया गया है, जो अन्य होस्ट नामों के माध्यम से उस सर्वर को हिट करने वाले सभी होस्ट का जवाब दे रहा है। मैं उस विशेष सर्वर को केवल अनुरोधों के लिए कैसे बना सकता हूं FAKE.COM?


listen fake.com | something.com:80 आदेश, फिल्टर नहीं server_name
अलेक्सी मार्टेंको

जवाबों:


202

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

इसलिए आपके कॉन्फ़िगरेशन में, आपका वास्तविक डोमेन मानना ​​REAL.COM है, जब कोई उपयोगकर्ता टाइप करता है, तो वह आपके सर्वर पर हल हो जाएगा, और चूंकि इस सेटअप के लिए कोई सर्वर ब्लॉक नहीं है, इसलिए FAKE.COM के लिए सर्वर ब्लॉक, पहला है। सर्वर ब्लॉक (आपके मामले में केवल सर्वर ब्लॉक), उस अनुरोध को संसाधित करेगा।

यही कारण है कि विशिष्ट डोमेन के लिए दूसरों के साथ अनुसरण करने से पहले उचित Nginx कॉन्फ़िगरेशन में डिफॉल्ट के लिए एक विशिष्ट सर्वर ब्लॉक है।

# Default server
server {
    return 404;
}

server {
    server_name domain_1;
    [...]
}

server {
    server_name domain_2;
    [...]
}

आदि

** EDIT **

ऐसा लगता है कि कुछ उपयोगकर्ता इस उदाहरण से थोड़ा भ्रमित हैं और सोचते हैं कि यह एक एकल फ़ाइल आदि तक सीमित है।

कृपया ध्यान दें कि उपरोक्त ओपी के लिए आवश्यकतानुसार एक सरल उदाहरण है।

मैं व्यक्तिगत रूप से इसके साथ अलग-अलग vhost conf फ़ाइलों का उपयोग करता हूं (CentOS / RHEL):

http {
    [...]
    # Default server
    server {
        return 404;
    }
    # Other servers
    include /etc/nginx/conf.d/*.conf;
}

/etc/nginx/conf.d/ इसमें domain_1.conf, domain_2.conf ... domain_n.conf होगा जो मुख्य nginx.conf फ़ाइल में सर्वर ब्लॉक के बाद शामिल किया जाएगा जो हमेशा पहला होगा और हमेशा डिफ़ॉल्ट रहेगा जब तक कि इसे default_server के साथ ओवरराइड नहीं किया जाता है निर्देश कहीं और।

अन्य सर्वरों के लिए गोपनीय फ़ाइलों के फ़ाइल नामों का वर्णानुक्रम क्रम इस मामले में अप्रासंगिक हो जाता है।

इसके अलावा, यह व्यवस्था बहुत अधिक लचीलापन देती है कि कई चूक को परिभाषित करना संभव है।

मेरे विशिष्ट मामले में, मेरे पास केवल आंतरिक इंटरफ़ेस पर पोर्ट 8080 पर अपाचे को सुनने और मैं अपाचे को PHP और पर्ल स्क्रिप्ट है।

हालाँकि, मैं दो अलग-अलग एप्लिकेशन चलाता हूं, जो आउटपुट HTML में ": 8080" के साथ दोनों लिंक लिंक करते हैं क्योंकि उन्हें पता चलता है कि अपाचे मानक पोर्ट 80 पर नहीं चल रहा है और मुझे "मदद" करने का प्रयास करें।

यह एक समस्या का कारण बनता है कि लिंक अमान्य हो जाते हैं क्योंकि Apache बाहरी इंटरफ़ेस से नहीं पहुँचा जा सकता है और लिंक को पोर्ट 80 पर इंगित करना चाहिए।

मैं इस तरह के अनुरोधों को पुनर्निर्देशित करने के लिए पोर्ट 8080 के लिए एक डिफ़ॉल्ट सर्वर बनाकर इसे हल करता हूं।

http {
    [...]
    # Default server block for undefined domains
    server {
        listen 80;
        return 404;
    }
    # Default server block to redirect Port 8080 for all domains
    server {
        listen my.external.ip.addr:8080;
        return 301 http://$host$request_uri;
    }
    # Other servers
    include /etc/nginx/conf.d/*.conf;
}

चूंकि पोर्ट 8080 पर नियमित सर्वर ब्लॉक में कुछ भी नहीं सुना जाता है, इसलिए पुनर्निर्देशित डिफ़ॉल्ट सर्वर ब्लॉक पारदर्शी तरीके से nginx.conf में अपनी स्थिति के आधार पर ऐसे अनुरोधों को संभालता है।

मेरे पास वास्तव में ऐसे चार सर्वर ब्लॉक हैं और यह एक सरलीकृत उपयोग का मामला है।


1
Nginx को केस सेंसिटिविटी की आवश्यकता होती है- "सर्वर" को सर्वर होना चाहिए और "रिटर्न" को वापस लौटना चाहिए। आशा है कि इस कोड को कॉपी करते समय यह कुछ परेशानियों से बचाता है।
कैपज

2
स्टेटिक, ओलेग न्यूमविंक का जवाब देखें - यदि आपके पास साइटों में एकाधिक कॉन्फिगर फाइलें उपलब्ध हैं, तो वर्णमाला के क्रम से पहली फाइल में पहला सर्वर आपका डिफ़ॉल्ट है। मुझे संदेह है कि यह एक मुद्दा हो सकता है। इसके अलावा, कई वितरण एक 'nginx -t' को पुनः आरंभ करने से पहले विन्यास का परीक्षण करने के लिए चलाते हैं - आपके पास पुनरारंभ को रोकने में त्रुटि हो सकती है।
रात 12:13

2
यह अपूर्ण है और स्वीकृत उत्तर नहीं होना चाहिए। इस काम के लिए आपको किसी भी सुनने के निर्देशों से default_server को निकालना होगा।
बेन

@बेन सबसे पहले, ओपी ने अपनी समस्या के उदाहरण में "default_server" नहीं किया और उत्तर उस प्रश्न की बारीकियों के अनुरूप है। दूसरे, पहले परिभाषित सर्वर बनाने के लिए निर्देशों का पालन करने के बाद कोई भी क्यों एक अलग सर्वर स्थान पर default_server को परिभाषित करेगा, डिफ़ॉल्ट मेरे से परे है। किसी भी स्थिति में, यदि एक default_server को विशेष रूप से परिभाषित किया गया है, तो यह Q / A सेट वह नहीं है, जो उन मुद्दों को हल करने के लिए देखा जाना चाहिए जो वे हो सकते हैं।
डेओ

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

61

आपके पास कैच-ऑल के लिए एक डिफॉल्ट सर्वर होना चाहिए , आप वापस लौट सकते हैं 404या बेहतर कर सकते हैं कि आप किसी भी तरह का जवाब न दें (कुछ बैंडविड्थ बचाएंगे) 444जो कि nginx स्पेसिफिक है

server {
    listen       80  default_server;
    server_name  _; # some invalid name that won't match anything
    return       444;
}

मेरे लिए nginx 1.8.0 के लिए काम किया। server_name _;मैं nginx के लिए पिछले संस्करणों में नहीं था, लेकिन यह काम किया। अब नए नगनेक्स संस्करणों के लिए ऐसा लगता है कि आपको इसकी आवश्यकता है server_name _;। धन्यवाद
daniel

हल किया। मैं अर्धविराम भूल गया; _;
user1201917

2
@ आईटेक: किसी कारण से यह सभी अनुरोधों के लिए 444 लौट रहा है। कोई सुराग?
दिव्य

के बारे में महान टिप 444, और एक त्रुटि कोड लौटने की तुलना में एक बहुत क्लीनर समाधान imho।
क्यूकिलिहॉक

1
प्रमाणपत्र / कुंजी निर्दिष्ट करना महत्वपूर्ण है, अन्यथा सभी SSL कनेक्शन मेल खाएंगे और विफल होंगे, जैसा कि नीचे दिए गए उनके उत्तर में @AndreyT द्वारा बताया गया है।
मार्क फ्लेचर

35

मैं किसी भी अन्य उत्तर के साथ अपनी समस्या को हल करने में असमर्थ था। मैंने यह देखने के लिए जाँच करके समस्या का समाधान किया कि क्या मेजबान ने मिलान किया था और यदि यह नहीं हुआ तो 403 लौटाया। (मेरे पास कुछ बेतरतीब वेबसाइट थी जो मेरे वेब सर्वर कंटेंट की ओर इशारा कर रही थी। मैं खोज रैंक को हाईजैक करने का अनुमान लगा रहा हूं)

server {
    listen 443;
    server_name example.com;

    if ($host != "example.com") {
        return 403;
    }

    ...
}

1
यदि एक बुरा अभ्यास है: nginx.com/resources/wiki/start/topics/depth/ifisevil
Esolitos

1
ऐसे मामले हैं जहां आप बस एक का उपयोग करने से बच नहीं सकते हैं, उदाहरण के लिए, यदि आपको एक चर का परीक्षण करने की आवश्यकता है जिसमें कोई समान निर्देश नहीं है।
एडवर्ड

4
@Esolitos वस्तुतः उस लेख की तीसरी पंक्ति कहती है कि यह उपयोग मामला ठीक है। मैं समझता हूं कि सतर्क रहने की जरूरत है, लेकिन आइए उचित उपयोग के मामलों में उंगलियां न हिलाएं।
बजे

मेरी राय में, सबसे आसान और सबसे संक्षिप्त समाधान, क्योंकि इसमें केवल 3 पंक्तियों की आवश्यकता होती है कोड आप ख़ुशी से किसी भी vhost फ़ाइल में पेस्ट कर सकते हैं, केवल तुलनात्मक $ होस्ट को बदल सकते हैं।
Akito

28

आपके प्रश्न का उत्तर देने के लिए - यदि कोई मैच नहीं है, तो nginx पहला सर्वर चुनता है। प्रलेखन देखें :

यदि इसका मान किसी सर्वर नाम से मेल नहीं खाता है, या अनुरोध में यह शीर्ष लेख फ़ील्ड नहीं है, तो nginx इस पोर्ट के लिए डिफ़ॉल्ट सर्वर के लिए अनुरोध को रूट करेगा। ऊपर कॉन्फ़िगरेशन में, डिफ़ॉल्ट सर्वर पहले एक है ...

अब, यदि आप एक डिफ़ॉल्ट कैच-ऑल सर्वर चाहते हैं, जो कहता है, सभी अनुरोधों पर 404 का जवाब देता है, तो यहां बताया गया है:

server {
    listen 80 default_server;
    listen 443 ssl default_server;
    server_name _;
    ssl_certificate <path to cert>
    ssl_certificate_key <path to key>
    return 404;
}

ध्यान दें कि आपको प्रमाणपत्र / कुंजी (जो स्व-हस्ताक्षरित हो सकती है) निर्दिष्ट करने की आवश्यकता है, अन्यथा सभी SSL कनेक्शन विफल हो जाएंगे क्योंकि nginx इस default_server का उपयोग करके कनेक्शन स्वीकार करने का प्रयास करेगा और प्रमाणपत्र / कुंजी नहीं ढूंढेगा।


3
मुझे नहीं पता कि यह उत्तर सूची में इतनी नीचे क्यों है। यह वह है जो रास्ते में चमकदार चीजों से विचलित हुए बिना सवाल का जवाब देता है।
एमएमसी

इससे मुझे एक समस्या को हल करने में मदद मिली जहां मैं गैर-www से www में पुनर्निर्देशित करने की कोशिश कर रहा था कि मुझे अपने ssl प्रमाणपत्र को इस पुनर्निर्देशित मार्ग में शामिल करना होगा अन्यथा मेरे डिफ़ॉल्ट ssl प्रमाणपत्र को हथियाने की कोशिश कर रहा था जो एक अलग डोमेन के लिए था।
एंडयूरिफ़

1
यह अधिकांश कॉन्फ़िगरेशन के लिए सबसे अच्छा उत्तर की तरह लगता है ... यकीन नहीं है कि इन दिनों एसएसएल के बिना नगेंक्स का उपयोग कौन कर रहा है, लेकिन तथ्य यह है कि एसएसएल को कवर करने वाला एकमात्र ऐसा है जो बेहद बता रहा है।
बजे

ऐसा लगता है कि server_name _;इसकी जरूरत भी नहीं है।
जुलिएन सालिनास

26

डिफ़ॉल्ट सर्वर को निर्दिष्ट करने के कुछ तरीके हैं।

पहला तरीका - सूची में पहले डिफ़ॉल्ट सर्वर निर्दिष्ट करें, यदि आप अपने सर्वर कॉन्फ़िगरेशन को एक कॉन्फ़िगरेशन फ़ाइल में रखते हैं, जैसे कि डेयो ऊपर दिखाया गया है।

दूसरा तरीका (बेहतर) अधिक लचीला - अनुदेश के default_serverलिए पैरामीटर प्रदान listenकरें, उदाहरण के लिए:

server {
    listen  *:80 default_server;
    root /www/project/public/;
}

अधिक जानकारी यहाँ: Nginx doc / Listen

इस तरह से अधिक उपयोगी है जब आप सर्वर कॉन्फ़िगरेशन को अलग-अलग फ़ाइलों में रखते हैं और उन फ़ाइलों को वर्णानुक्रम में नाम नहीं देना चाहते हैं।


3
यह सही उत्तर होना चाहिए। स्वीकृत उत्तर भ्रामक है। यदि किसी अन्य सर्वर को डिफ़ॉल्ट सर्वर होने के लिए कॉन्फ़िगर किया गया है, तो बस कॉन्फ़िगरेशन में किसी अन्य सर्वर को जोड़ने से समस्या का समाधान नहीं होगा।
बेन

1
@ कोई कारण नहीं है कि प्रदत्त उत्तर एकाधिक अलग-अलग vhost फ़ाइलों के साथ काम नहीं कर सकता है। इसके अलावा, मुझे पता है कि मेरा डिफ़ॉल्ट सर्वर हमेशा मुख्य nginx.conf फ़ाइल में होता है और मुझे याद नहीं रखना पड़ता है कि मेरी कई अलग-अलग vhost फ़ाइलों में से कौन सी इसमें है।
डेओ

443 और साथ ही ssl के लिए सुनना न भूलें (नीचे देखें @ AndreyT की प्रतिक्रिया)।
कांस्टेंटिनोस

8

जवाब देने के लिए छोटी टिप्पणी:

यदि आपके पास साइटों-उपलब्ध / में कई कॉन्फ़िगर फ़ाइलों में कई आईपी पर कई वर्चुअल होस्ट हैं, तो आईपी के लिए "डिफ़ॉल्ट" डोमेन अल्फ़ाबेटिक ऑर्डर द्वारा पहली फ़ाइल से लिया जाएगा।

और जैसा कि पावेल ने कहा, "सुनने" के लिए "default_server" तर्क है " http://iveginx.org/en/docs/http/ngx_http_core_module.html#listen

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