Назад | Перейти на главную страницу

Удалите www с помощью NGINX за AWS ELB

Я пытаюсь удалить www из своих URL-адресов запросов, но когда я добавляю следующее в свою конфигурацию nginx, моя проверка работоспособности AWS ELB не выполняется.

server {
    listen 80;
    server_name www.example.com;
    return 301 $scheme://example.com$request_uri;
}

Есть идеи, что могло вызвать проблему? Это остальная часть моей конфигурации:

server {

    listen 80;

    server_name .example.com;
    root /var/www/static;
    index index.html;

    try_files $uri.html $uri $uri/ =404;

    charset UTF-8;

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

    # ELB test route
    location /test {
        add_header X-Robots-Tag noindex;
        default_type text/plain; 
        return 200 'success';
    }

    # Redirect any request http request that come from AWS ELB to https
    if ($http_x_forwarded_proto = "http") {
        return 301 https://$server_name$request_uri;
    }
}

Вот моя настройка проверки работоспособности:

Из Документы Amazon:

Чтобы обеспечить правильное масштабирование балансировщика нагрузки, убедитесь, что каждая подсеть для балансировщика нагрузки имеет блок CIDR с битовой маской не менее / 27 (например, 10.0.0.0/27) и имеет не менее 8 свободных IP-адресов. Ваш балансировщик нагрузки использует эти IP-адреса для установления соединений с экземплярами.

Создается впечатление, что проверка работоспособности ELB выполняется через частный IP-адрес AWS, а не через доменное имя. Насколько я знаю об Amazon, они предпочитают делать что-то именно так, когда это возможно (по очевидным причинам производительности, нет необходимости в поиске DNS, могут обрабатывать более близкие маршрутизаторы и т. Д.)

В этом случае заголовок хоста (если он не пуст, я не на 100% уверен, как работают заголовки хоста, когда вы делаете запрос на чистый IP-адрес) будет частным адресом AWS экземпляра EC2 (я ' m при условии, что это EC2), на котором запущен веб-сервер. Это влияет на то, как Nginx выбирает, какой виртуальный сервер должен обрабатывать запрос.

Поскольку у Nginx два server блоков, он должен решить, какой из них получит тот или иной запрос. Процесс выбора серверных блоков (подробности Вот) как следует:

  • Сначала он ищет серверы, прослушивающие порт, на который поступил запрос. В этом случае оба сервера прослушивают один и тот же порт, поэтому это никому не помогает.

  • Затем он просматривает заголовок хоста запроса и ищет серверы с server_name который соответствует заголовку хоста. В этом случае ни один из них не будет совпадать, потому что заголовок хоста - это частный IP-адрес AWS, назначенный экземпляру (или пустой, как я сказал, я не уверен).

  • Наконец, если ни один из них не дает совпадения, он просто идет с тем сервером, который используется по умолчанию. В отсутствие явного объявления по умолчанию сервер, который определен первый в конфиге сайта выбрано по умолчанию.

Если ваш сервер перенаправления находится перед основной конфигурацией сервера (как я предполагаю), то это, вероятно, ваша проблема. Вам нужно сделать одно из трех:

  • Укажите, что вы хотите Другой сервер (главный сервер) по умолчанию, добавив default_server к listen директива, т.е. listen 80 default_server;

  • Переключите location /test блок на другой серверный блок, или

  • Поменяйте порядок, в котором определены серверные блоки.

Первый вариант кажется подходящим, поскольку он имеет смысл для default_server директива должна быть явной, а не неявной, и имеет смысл использовать основной сервер по умолчанию, а не сервер перенаправления «у вас было одно задание».

Если я прав в своем предположении, это должно решить эту проблему.

Я могу посоветовать следующее из опыта настройки AWS ELB I / F.

  1. Определить местоположение / {} блок
  2. Лучше использовать location = / test {} блокировать точное соответствие URL
  3. Лучше использовать специальный server_name _ и написать блок location = / test {}.

ссылка:
http://nginx.org/en/docs/http/ngx_http_core_module.html#server_name


server {

    listen 80;

    # changed for 1. "anonymous server" (without Host: header) will accept request.
    server_name _ .example.com;
    root /var/www/static;
    index index.html;

    try_files $uri.html $uri $uri/ =404;

    charset UTF-8;

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


    # changed for 1. defined location / {} for default behavior
    location / {
        try_files $uri $uri/ =404;
    }
    # ELB test route
    # changed for 2. exactly match only /test request
    location = /test {
        add_header X-Robots-Tag noindex;
        default_type text/plain; 
        return 200 'success';
    }

    # Redirect any request http request that come from AWS ELB to https
    if ($http_x_forwarded_proto = "http") {
        return 301 https://$server_name$request_uri;
    }
}