Я ломал голову, поскольку все форумы говорят, что следующий простой код должен работать для перенаправления всего трафика с HTTPS на HTTP, кроме одного места (Nginx: принудительно использовать SSL на одном пути, без SSL на других) но в моем случае он не работает должным образом
Это сайт Magento со следующей конфигурацией nginx
upstream examplecombackend {
server unix:/var/run/php-fcgi-examplecom.sock;
}
server {
listen 111.11.111.111:80;
server_name example.com *.example.com;
access_log /home/www/vhosts/example.com/logs/access.log;
error_log /home/www/vhosts/example.com/logs/error.log;
root /home/www/vhosts/example.com/httpdocs;
location / {
index index.html index.php;
try_files $uri $uri/ @handler;
expires 30d;
}
location /checkout/ {
rewrite ^ https://$host$request_uri? permanent;
}
location @handler {
rewrite / /index.php;
}
location ~ .php/ {
rewrite ^(.*.php)/ $1 last;
}
location ~ .php$ {
if (!-e $request_filename) {
rewrite / /index.php last;
}
expires off;
fastcgi_pass examplecombackend;
fastcgi_param HTTPS $fastcgi_https;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
server {
listen 111.11.111.111:443 ssl;
ssl_certificate /etc/nginx/ssl/example.com.crt;
ssl_certificate_key /etc/nginx/ssl/example.com.key;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
server_name example.com *.example.com;
root /home/www/vhosts/example.com/httpdocs;
location / {
rewrite ^ http://$host$request_uri? permanent;
}
location /checkout/ {
}
}
Теперь, после того, как я перейду на SSL https://example.com/ он правильно перенаправляет на Non-SSL http://example.com/ но если я пойду в https://example.com/checkout это говорит
404 Not Found
nginx/1.8.1
Не уверен, что мне здесь не хватает ....
Во-первых, я бы сам такую конфигурацию не делал. Смешав http
и https
на том же сайте делает https
безопасность слабее и подвергает ваш сайт атакам типа "злоумышленник посередине".
Однако здесь должна быть рабочая конфигурация для вас, если вы действительно хотите настроить такую вещь.
Основная проблема в вашей конфигурации - это отсутствие определений PHP для вашего /checkout
URI.
Я бы сделал такую конфигурацию. Это также содержит оптимизацию для вашей конфигурации:
upstream examplecombackend {
server unix:/var/run/php-fcgi-examplecom.sock;
}
server {
listen 111.11.111.111:80;
server_name example.com *.example.com;
access_log /home/www/vhosts/example.com/logs/access.log;
error_log /home/www/vhosts/example.com/logs/error.log;
root /home/www/vhosts/example.com/httpdocs;
location / {
index index.html index.php;
try_files $uri $uri/ /index.php;
expires 30d;
}
location /checkout {
rewrite ^ https://$host$request_uri? permanent;
}
location ~ (.+\.php)/ {
rewrite ^ $1 last;
}
location ~ \.php$ {
expires off;
fastcgi_pass examplecombackend;
fastcgi_param HTTPS $fastcgi_https;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
server {
listen 111.11.111.111:443 ssl;
ssl_certificate /etc/nginx/ssl/example.com.crt;
ssl_certificate_key /etc/nginx/ssl/example.com.key;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
server_name example.com *.example.com;
root /home/www/vhosts/example.com/httpdocs;
location /checkout {
rewrite ^ /index.php;
}
location ~ \.php$ {
expires off;
fastcgi_pass examplecombackend;
fastcgi_param HTTPS $fastcgi_https;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
location / {
rewrite ^ http://$host$request_uri? permanent;
}
}
Изменения, которые я сделал:
location / {
index index.html index.php;
try_files $uri $uri/ /index.php;
expires 30d;
}
Я удалил @handler
место, потому что оно такое же, как если бы index.php
был последним элементом try_files
директива.
location ~ .php/ {
rewrite ^(.*.php)/ $1 last;
}
Я изменил захват регулярного выражения на location
уровень, поэтому на каждый запрос, соответствующий этому местоположению, на одно совпадение регулярного выражения меньше, поскольку мы можем использовать простые ^
как условие совпадения в rewrite
директива.
location ~ \.php$ {
if (!-e $request_filename) {
rewrite / /index.php last;
}
Я добавил обратную косую черту к location
условие регулярного выражения, потому что без обратной косой черты оно будет соответствовать, например, /path/to/aphp
, поскольку .
сам по себе соответствует любому символу.
Я также удалил if
тест, показанный выше из блока, потому что тот же тест выполняется уже в try_files
директива ранее.
И, наконец, исправление вашей реальной проблемы:
В твоем server
блок для https, я изменил location
блоки вроде этого:
location /checkout {
rewrite ^ /index.php;
}
location ~ \.php$ {
expires off;
fastcgi_pass examplecombackend;
fastcgi_param HTTPS $fastcgi_https;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
Так что location /checkout
блок сообщает nginx о необходимости перезаписать все запросы в /index.php
, как в http
серверный блок. Также обработка PHP location
такое же, как в http
блок.
Однако могут возникнуть проблемы со ссылками, которые создает Magento, и с тем, как запросы перенаправляются между http
и https
. Настройки безопасности файлов cookie - это то, что может вызвать проблемы.
Попробуйте это небольшое изменение. ~ * Должен указывать Nginx на то, что регистр не учитывает любой URL-адрес с / checkout / в нем, а не только с точным URL / checkout /.
Я немного заржавел и не могу вспомнить точный порядок и синтаксис соответствия местоположения, но попробовать стоит.
location ~* /checkout/ {
В вашем случае может помочь условная перезапись:
server {
listen 111.11.111.111:80;
listen 111.11.111.111:443 ssl;
ssl_certificate /etc/nginx/ssl/example.com.crt;
ssl_certificate_key /etc/nginx/ssl/example.com.key;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
server_name example.com *.example.com;
access_log /home/www/vhosts/example.com/logs/access.log;
error_log /home/www/vhosts/example.com/logs/error.log;
root /home/www/vhosts/example.com/httpdocs;
location / {
if ($scheme = "https") {
return 301 http://$server_name$request_uri;
break;
}
index index.html index.php;
try_files $uri $uri/ @handler;
expires 30d;
}
location /checkout/ {
if ($scheme = "http") {
return 301 https://$server_name$request_uri;
break;
}
}
location @handler {
rewrite / /index.php;
}
location ~ .php/ {
rewrite ^(.*.php)/ $1 last;
}
location ~ .php$ {
if (!-e $request_filename) { rewrite / /index.php last; }
expires off;
fastcgi_pass examplecombackend;
fastcgi_param HTTPS $fastcgi_https;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}