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

Перенаправление на HTTPS и домен Apex с конфигурацией местоположения Nginx

Я хотел бы заставить HTTPS и домен вершины (например, https://example.com) в моем приложении через конфигурацию nginx с использованием блоков местоположения. В настоящее время у меня есть следующий файл nginx_app.conf (который работает как с поддоменом apex, так и с субдоменом www, а также с http и https):

location / {
    try_files $uri @rewriteapp;
}

location @rewriteapp {
    rewrite ^(.*)$ /app.php/$1 last;
}

location ~ ^/(app|config)\.php(/|$) {
    # fastcgi_pass directives go here...
}

Чтобы принудительно использовать домен вершины и https, я попытался использовать операторы if следующим образом, проверяя переменные $ scheme и $ host, но получаю сообщение об ошибке, что страница не перенаправляется должным образом. Я также добавлена ​​директива HSTS.

location / {
    if ($scheme = http) {
        rewrite ^/(.*) https://$host/$1 permanent;
    }
    if ($host = www.example.com) {
        rewrite ^/(.*) https://example.com/$1 permanent;
    }
    try_files $uri @rewriteapp;
}

location @rewriteapp {
    rewrite ^(.*)$ /app.php/$1 last;
}

location ~ ^/(app|config)\.php(/|$) {
    # fastcgi_pass directives go here...
    add_header Strict-Transport-Security "max-age=86400";
}

Как правильно настроить http и домен вершины с конфигурацией nginx? Кроме того, я использую heroku (с DNSimple) для развертывания своего приложения, поэтому я хотел бы, чтобы работали оба следующих домена: https://example.herokuapp.com и https://example.com.

ОБНОВЛЕНИЕ: я попытался переместить операторы if за пределы блока местоположения в блок сервера по умолчанию (нажмите здесь), и измените перезаписи для возврата следующим образом, но это все равно не работает. Я по-прежнему получаю сообщение «Страница не перенаправляется должным образом» при запросе http и «Ошибка подключения» при запросе субдомена www.

if ($scheme = http) {
    return 301 https://$host$request_uri;
}
if ($host = www.example.com) {
    return 301 https://example.com$request_uri;
}

location / {
    try_files $uri @rewriteapp;
}

location @rewriteapp {
    rewrite ^(.*)$ /app.php/$1 last;
}

location ~ ^/(app|config)\.php(/|$) {
    # fastcgi_pass directives go here...
    add_header Strict-Transport-Security "max-age=86400";
}

1) Проблема здесь, вероятно, в балансировщике нагрузки Heroku. Когда в ваше приложение поступает запрос о посещении, он снова становится HTTP. Это просто внутренняя маршрутизация. Вы не можете протестировать против $scheme. Но Heroku установил $http_x_forwarded_proto заголовок для этих запросов.

if ($http_x_forwarded_proto != "https") {
  return 301 https://$host$request_uri;
}

Источник: https://discussion.heroku.com/t/force-ssl-and-no-www-with-nginx-configuration/856


2а) Для перехода на no-www вы можете использовать это:

server {
  listen <%= ENV["PORT"] %>;
  server_name "~^www\.(.*)$";
  return 301 https://$1$request_uri;
}

Для тестирования вы должны использовать 302 вместо 301, потому что браузер будет кэшировать 301 редирект.

Этот также перенаправит вас на https. Но только с субдомена www, поэтому вы должны сохранить указанное выше $http_x_forwarded_proto перенаправить.

2b) Другой вариант - использовать серверный блок с субдоменом www и перенаправить его на домен без www, например:

server {
  listen <%= ENV["PORT"] %>;
  server_name www.example.com;

  location / {
    return 301 https://example.com$request_uri;
  }
}

server {
  listen <%= ENV["PORT"] %>;
  server_name example.com;

  location / {
    try_files $uri $uri/ /index.html =404;
  }
}

В <%= ENV["PORT"] %> код исходит из сборочный пакет. На Heroku вы не можете слушать порт 80.

Лучше всего сделать 301 редирект.

server {
    listen         80;
    return 301 https://$host$request_uri;
}