কেন এনগিনেক্স কোনও ডোমেইনের নাম সাড়া দিচ্ছে?


139

আমার কাছে রুবি / সিনাট্রা অ্যাপ্লিকেশনটি নিয়ে চলছে এবং ঠিক আছে। তবে, আমি এখন একই সার্ভার থেকে দ্বিতীয় অ্যাপ্লিকেশন চালানোর চেষ্টা করছি এবং আমি কিছু অদ্ভুত লক্ষ্য করেছি noticed প্রথম, এখানে আমার 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 এর জন্য সার্ভার ব্লকটি প্রথম হচ্ছে সার্ভার ব্লক (আপনার ক্ষেত্রে কেবল সার্ভার ব্লক), সেই অনুরোধটি প্রক্রিয়া করবে।

এ কারণেই যথাযথ এনগিনক্স কনফিগারদের নির্দিষ্ট ডোমেনগুলির জন্য অন্যের সাথে অনুসরণ করার আগে ডিফল্টগুলির জন্য একটি নির্দিষ্ট সার্ভার ব্লক থাকে।

# Default server
server {
    return 404;
}

server {
    server_name domain_1;
    [...]
}

server {
    server_name domain_2;
    [...]
}

ইত্যাদি

** সম্পাদনা করুন **

দেখে মনে হচ্ছে কিছু ব্যবহারকারী এই উদাহরণটি দেখে কিছুটা বিভ্রান্ত হয়েছেন এবং মনে করেন এটি একক কনফ ফাইলের মধ্যেই সীমাবদ্ধ etc.

দয়া করে নোট করুন যে ওপিতে প্রয়োজনীয় হিসাবে বিকাশের জন্য উপরেরটি একটি সাধারণ উদাহরণ।

আমি ব্যক্তিগতভাবে এটির সাথে পৃথক vhost কনফিল্ট ফাইলগুলি ব্যবহার করি (CentOS / RHEL):

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

/etc/nginx/conf.d/ এতে ডোমেন_1.conf, ডোমেন_কমফ ... ডোমেইন_এন.সিএনএফ থাকবে যা মূল এনজিএনএক্সএফ ফাইলটিতে সার্ভার ব্লকের পরে অন্তর্ভুক্ত থাকবে যা সর্বদা প্রথম হবে এবং এটি ডিফল্ট_সার্ভারের সাথে ওভাররাইড না করা থাকলে সর্বদা ডিফল্ট থাকবে unless অন্য কোথাও নির্দেশ।

অন্যান্য সার্ভারের জন্য কনফ ফাইলের ফাইলের বর্ণমালার ক্রমটি এই ক্ষেত্রে অপ্রাসঙ্গিক হয়ে যায়।

তদতিরিক্ত, এই বিন্যাসটি অনেকগুলি নমনীয়তা দেয় যাতে একাধিক খেলাপি সংজ্ঞা দেওয়া সম্ভব।

আমার নির্দিষ্ট ক্ষেত্রে, আমি কেবল অভ্যন্তরীণ ইন্টারফেসে পোর্ট 8080 এ অ্যাপাচি শুনছি এবং আমি অ্যাপাচে পিএইচপি এবং পার্ল স্ক্রিপ্ট প্রক্সি করছি।

যাইহোক, আমি দুটি পৃথক অ্যাপ্লিকেশন চালিয়েছি যা উভয়ই আউটপুট এইচটিএমএল সংযুক্ত ": 8080" এর সাথে লিঙ্কগুলি প্রত্যাবর্তন করে কারণ তারা সনাক্ত করে যে অ্যাপাচি স্ট্যান্ডার্ড পোর্ট 80 এ চলছে না এবং আমাকে "সহায়তা" করার চেষ্টা করবে।

এটি লিঙ্কগুলি এমন একটি সমস্যার কারণ হয়ে দাঁড়ায় যে লিঙ্কগুলি অবৈধ হয়ে যায় কারণ বাহ্যিক ইন্টারফেস থেকে অ্যাপাচি পৌঁছানো যায় না এবং লিঙ্কগুলি পোর্ট 80 এ নির্দেশ করা উচিত।

আমি 808080 এর জন্য অনুরোধগুলি পুনর্নির্দেশের জন্য একটি ডিফল্ট সার্ভার তৈরি করে এটি সমাধান করি।

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' চালায় - আপনার পুনঃসূচনা আটকাতে সমস্যা হতে পারে।
jwhitlock

2
এটি অসম্পূর্ণ এবং গ্রহণযোগ্য উত্তর হওয়া উচিত নয়। এটি কাজ করার জন্য আপনাকে কোনও শোনার দিকনির্দেশ থেকে ডিফল্ট_সার্ভারও সরিয়ে ফেলতে হবে।
বেন

@ বেন প্রথমত, ওপিতে তার সমস্যার উদাহরণে "ডিফল্ট_সভার" নেই এবং উত্তরটি সেই প্রশ্নের সুনির্দিষ্ট অনুসারে তৈরি করা হয়েছে। দ্বিতীয়ত, প্রথম সংজ্ঞায়িত সার্ভারটি ডিফল্ট করার জন্য নির্দেশাবলী অনুসরণ করার পরে কেন কেউ পৃথক সার্ভারের স্থানে ডিফল্ট_সার্ভারটি সংজ্ঞায়িত করবেন me যে কোনও ক্ষেত্রে, যদি কোনও ডিফল্ট_সার্ভার নির্দিষ্টভাবে সংজ্ঞায়িত করা থাকে, তবে এই প্রশ্ন / এ সেটটি এমন নয় যেগুলি তাদের যে কোনও সমস্যা হতে পারে তা সমাধান করার দিকে লক্ষ্য করা উচিত।
দিনো

1
@ ডায়ো আপনি সঠিক যে আপনি ওপি পোস্ট করেছেন এমন নির্দিষ্ট কনফিগারেশনে সম্বোধন করেছেন। তবে জিজ্ঞাসিত প্রশ্নের সম্পূর্ণ উত্তরের জন্য, আমি ডিফল্ট_সভারটি উল্লেখ করা প্রয়োজন বলে মনে করি। আপনার উত্তরটি পড়া এবং ডিফল্ট_সার্ভার এতে কীভাবে হস্তক্ষেপ করবে তা উপলব্ধি করা সম্ভব নয়। এটি আরও বেশি সম্ভবত কারণ কিছু ফাইল ডিফল্ট_সার্ভারের সাথে শিপিংয়ের কোনও ফাইলকে সংজ্ঞায়িত করা হয়েছে যা ব্যবহারকারীর কাছে সুস্পষ্ট নাও হতে পারে।
বেন 21

61

আপনার ক্যাচ- অলটির জন্য একটি ডিফল্ট সার্ভার থাকা উচিত , আপনি ফিরে আসতে পারেন 404বা কোনও প্রতিক্রিয়া না জানানোর জন্য কিছুটা ভাল করতে পারেন (কিছু ব্যান্ডউইথ সংরক্ষণ করবেন) 444যা এনজিনেক্স নির্দিষ্ট এইচটিটিপি প্রতিক্রিয়া যা কেবল সংযোগটি বন্ধ করে দেয় এবং কিছুই ফেরত দেয় না

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 _;। ধন্যবাদ
ড্যানিয়েল

সমাধান। আমি একটি সেমিকোলন ভুলে গেছি; _;
user1201917

2
@ আইটেক: কোনও কারণে এটি সমস্ত অনুরোধের জন্য 444 ফেরত আসছে। কোন সংকেত সনাক্ত করুন?
Divick

সম্পর্কে দুর্দান্ত টিপস 444এবং কোনও ত্রুটি কোড ফেরত দেওয়ার চেয়ে আরও ক্লিনার সমাধান ইমো।
qqilihq

1
একটি শংসাপত্র / কী নির্দিষ্ট করা গুরুত্বপূর্ণ, অন্যথায় সমস্ত এসএসএল সংযোগগুলি মিলবে এবং ব্যর্থ হবে, নীচে তার উত্তর @ অ্যান্ড্রেটি দ্বারা নির্দেশিত হিসাবে।
মার্ক ফ্লেচার

35

আমি অন্য কোনও উত্তর দিয়ে আমার সমস্যা সমাধান করতে পারিনি। হোস্টটি মিলেছে কিনা তা পরীক্ষা করে এবং 403 যদি না পাওয়া যায় তা ফেরত দিয়ে আমি সমস্যার সমাধান করেছি। (আমার ওয়েব সার্ভারের সামগ্রীর দিকে ইঙ্গিত করে কিছু এলোমেলো ওয়েবসাইট ছিল search

server {
    listen 443;
    server_name example.com;

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

    ...
}

1
যদি কোনও খারাপ অনুশীলন হয়: এনগিনেক্স.com
রিসোর্সস

1
এমন কিছু ক্ষেত্রে রয়েছে যেখানে আপনি কেবলমাত্র যদি কোনও ব্যবহার এড়াতে পারবেন না, উদাহরণস্বরূপ, আপনার যদি কোনও ভেরিয়েবল পরীক্ষা করতে হয় যার কোনও সমমানের নির্দেশনা নেই।
এডওয়ার্ড

4
@ এসোলিটস আক্ষরিকভাবে এই নিবন্ধটির তৃতীয় লাইনটি বলছে যে এই ব্যবহারের ক্ষেত্রে ঠিক আছে। আমি সতর্ক হওয়ার প্রয়োজনীয়তাটি বুঝতে পারি, তবে আসুন ব্যবহারের ক্ষেত্রে আঙ্গুলগুলি না চালিয়ে চলি।
mpowered

আমার মতে, সবচেয়ে সহজ এবং সংক্ষিপ্ত সমাধান, কারণ এটির জন্য কেবলমাত্র 3 লাইন কোডের প্রয়োজন হয় আপনি যে কোনও vhost ফাইলে আনন্দের সাথে পেস্ট করতে পারেন, কেবল তুলনামূলক $ হোস্টটি পরে পরিবর্তন করুন।
আকিতো

28

আপনার প্রশ্নের উত্তর দেওয়ার জন্য - মিল না থাকলে এনগিনেক্স প্রথম সার্ভারটি বাছাই করে। ডকুমেন্টেশন দেখুন :

যদি এর মানটি কোনও সার্ভারের নামের সাথে মেলে না, বা অনুরোধে এই শিরোলেখ ক্ষেত্রটি মোটেই না থাকে, তবে 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;
}

নোট করুন যে আপনাকে শংসাপত্র / কী নির্দিষ্ট করতে হবে (এটি স্ব-স্বাক্ষরিত হতে পারে), অন্যথায় সমস্ত এসএসএল সংযোগগুলি ব্যর্থ হবে কারণ nginx এই ডিফল্ট_সার্ভারটি ব্যবহার করে সংযোগ গ্রহণ করার চেষ্টা করবে এবং সার্টিফিকেট / কীটি খুঁজে পাবে না।


3
এই উত্তরটি এতদূর তালিকার নিচে কেন আমার কোনও ধারণা নেই। এই সেই পথটি চকচকে জিনিসগুলি দ্বারা বিভ্রান্ত না হয়ে প্রশ্নের উত্তর দেয়।
এমএমসি

এটি আমাকে এমন একটি সমস্যার সমাধান করতে সহায়তা করেছিল যেখানে আমি নন-www থেকে www এ পুনঃনির্দেশের চেষ্টা করছিলাম যে আমাকে এই পুনর্নির্দেশকারী রুটে আমার এসএসএল শংসাপত্রটি অন্তর্ভুক্ত করতে হবে অন্যথায় আমার ডিফল্ট এসএসএল শংসাপত্রটি ধরার চেষ্টা করা হয়েছিল যা অন্য কোনও ডোমেনের জন্য ছিল।
endyourif

1
এটি বেশিরভাগ কনফিগারেশনের জন্য সেরা উত্তরের মতো বলে মনে হচ্ছে ... আজকাল এসএসএল ছাড়া কে এনগিনেক্স ব্যবহার করছে তা নিশ্চিত নয়, তবে এসএসএলকে আচ্ছাদন করে এমন একমাত্র এটিই চূড়ান্তভাবে জানিয়ে দিচ্ছে।

এটি server_name _;এমনকি প্রয়োজন হয় না বলে মনে হয়।
জুলিয়েন সালিনাস

26

ডিফল্ট সার্ভার নির্দিষ্ট করার কয়েকটি উপায় রয়েছে।

প্রথম উপায় - তালিকাতে ডিফল্ট সার্ভারটি প্রথমে নির্দিষ্ট করুন, যদি আপনি নিজের সার্ভারের কনফিগারেশনগুলিকে একটি কনফিগ ফাইলে রাখেন, যেমন ডেও উপরে দেখানো হয়েছে।

দ্বিতীয় উপায় (আরও ভাল) আরও নমনীয় - নির্দেশের default_serverজন্য প্যারামিটার সরবরাহ করুন listen, উদাহরণস্বরূপ:

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

এখানে আরও তথ্য: এনগিনেক্স ডক / শুনুন

আপনি যখন আলাদা ফাইলগুলিতে সার্ভারের কনফিগারেশনগুলি রাখেন এবং সেই ফাইলগুলিকে বর্ণানুক্রমিকভাবে নাম রাখতে চান না তখন এইভাবে আরও কার্যকর হয় useful


3
এটি সঠিক উত্তর হওয়া উচিত। গৃহীত উত্তরটি বিভ্রান্তিকর। অন্য সার্ভারটি ডিফল্ট সার্ভার হিসাবে কনফিগার করা থাকলে কনফিগারেশনে কেবল অন্য সার্ভার যুক্ত করা সমস্যার সমাধান করবে না।
বেন

1
@ পাভেল এমন কোনও কারণ নেই যে সরবরাহিত উত্তর একাধিক পৃথক ভোস্ট ফাইলের সাথে কাজ করতে পারে না। এছাড়াও, এর সাথে আমি জানি যে আমার ডিফল্ট সার্ভার সর্বদা মূল nginx.conf ফাইলে থাকে এবং আমার অনেক পৃথক vhost ফাইলের মধ্যে কোনটি এতে রয়েছে তা মনে রাখার দরকার নেই।
ডায়ো

এসএসএলের জন্য 443 শুনতেও ভুলবেন না (নীচে @ অ্যান্ড্রেটির প্রতিক্রিয়া দেখুন)।
কনস্টান্টিনো

8

উত্তর দেওয়ার জন্য সামান্য মন্তব্য:

আপনার যদি সাইটগুলি উপলভ্য / বেশ কয়েকটি কনফিগার ফাইলগুলিতে একাধিক আইপিতে একাধিক ভার্চুয়াল হোস্ট থাকে তবে আইপি-র জন্য "ডিফল্ট" ডোমেন প্রথম বর্ণানুক্রমিক ক্রমে নেওয়া হবে।

এবং হিসাবে পাভেল বলেন, "শুনতে" ডিরেক্টিভের জন্য "default_server" যুক্তি http://nginx.org/en/docs/http/ngx_http_core_module.html#listen

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.