1. ホーム
  2. nginx

[解決済み] nginxが任意のドメイン名で応答するのはなぜですか?

2022-04-27 11:20:50

質問

Ruby/Sinatraアプリでnginxを立ち上げ、すべてうまくいっています。しかし、現在、同じサーバから2つ目のアプリケーションを実行しようとしているところ、奇妙なことに気づきました。まず、私の 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 ?

解決方法は?

nginx の設定にある最初のサーバブロックは、特定のサーバブロックが存在しないサーバにヒットするすべてのリクエストのデフォルトです。

つまり、あなたの設定において、あなたの本当のドメインがREAL.COMであると仮定すると、ユーザーがそれを入力すると、あなたのサーバーに解決します。この設定のためのサーバーブロックがないので、最初のサーバーブロック(あなたのケースでは唯一のサーバーブロック)であるFAKE.COMのサーバーブロックが、そのリクエストを処理します。

このため、Nginxの適切な設定には、デフォルトで特定のサーバーブロックがあり、その後、特定のドメイン用に他のブロックが続きます。

# Default server
server {
    return 404;
}

server {
    server_name domain_1;
    [...]
}

server {
    server_name domain_2;
    [...]
}

その他

** 編集

この例を見て、1つのconfファイルに限定されているなどと考えているユーザーもいるようです。

上記は、OPが必要に応じて開発するための簡単な例であることに留意してください。

私自身は、このように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 ファイル内の server ブロックの後に置かれます。

この場合、他のサーバーの conf ファイルのファイル名のアルファベット順は関係ありません。

また、この配置では、複数のデフォルトを定義することが可能であるため、自由度が高い。

私の場合、Apacheは内部インターフェイスのみポート8080でリッスンしており、PHPとPerlスクリプトをApacheにプロキシしています。

しかし、私は2つの別々のアプリケーションを実行しており、どちらもApacheが標準のポート80で実行されていないことを検出し、私を助けようとするため、出力htmlに":8080"が付いたリンクを返しました。

これは、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 内の位置によって透過的にそのようなリクエストを処理します。

私は実際にこのようなサーバーブロックを4つ持っており、これは簡略化された使用例です。