Веб сервер nginx позволяет работать в разных режимах, как с использованием интерпретатора php, так и без.
Для работы OpenCart лучше выбирать оптимальный режим работы php-fpm. Многих данный режим пугает тем, что в данном случае
файл htaccess напрочь игнорируется и все необходимые настройки нужно вносить в конфиг nginx.
Но в этом нет ничего сверх сложного. Конфигурационный файл - это обычный текстовый файл на сервере, который
подчиняется определённым правилам. И по данному поводу можно найти много готовых описаний и инструкций.
Данная статья не претендует на уникальность, а просто представляет краткую выжимку по настройкам, учитывая особенности
работы с движком OpenCart и сборками на его основе.
Для удобства будут приводится примеры настройки с использованием панели ISPmanager.
Основные настройки будут касаться секции location, и зависимость описания от используемой панели будет минимальной.
Для начала переведём nginx в режим работы php-fpm. Для этого в панели сделаем следующие настройки разделе WWW-домены для
нужного сайта:
1. Выбираем в списке нужный сайт, если их несколько, и жмём кнопку "Изменить".
2. Находим настройки PHP и настраиваем следующим образом:
Обратите внимание, что версия php у вас может отличаться. При необходимости, можно эту версию изменить на нужную, но этот вопрос выходит за рамки данной статьи.
После сохранения настроек будет работать почти всё, что и раньше. Если в настройках OpenCart отключены ЧПУ ссылки, то всё будет работать, как
и работало до переключения режима работы.
Теперь можно приступать к непосредственной настройке самого конфигурационного файла nginx для текущего сайта.
Для этого в списке www доменов находим нужный нам и нажимаем справа на иконку с тремя точками. В выпадающем меню выбираем
пункт "Конфиг":
Вот примерный конфигурационный файл, который будет создан у вас по умолчанию:
server { server_name test.ru www.test.ru; charset off; index index.php index.html; disable_symlinks if_not_owner from=$root_path; include /etc/nginx/vhosts-includes/*.conf; include /etc/nginx/vhosts-resources/test.ru/*.conf; access_log /var/www/httpd-logs/test.ru.access.log; error_log /var/www/httpd-logs/test.ru.error.log notice; ssi on; set $root_path /var/www/myoc/data/www/test.ru; root $root_path; location / { location ~ [^/]\.ph(p\d*|tml)$ { try_files /does_not_exists @php; } location ~* ^.+\.(jpg|jpeg|gif|png|svg|js|css|mp3|ogg|mpe?g|avi|zip|gz|bz2?|rar|swf)$ { expires 365d; } } location @php { fastcgi_index index.php; fastcgi_param PHP_ADMIN_VALUE "sendmail_path = /usr/sbin/sendmail -t -i -f webmaster@test.ru"; fastcgi_pass unix:/var/www/php-fpm/myoc.sock; fastcgi_split_path_info ^((?U).+\.ph(?:p\d*|tml))(/?.+)$; try_files $uri =404; include fastcgi_params; } listen 8.8.8.8:80; } server { server_name test.ru www.test.ru; ssl_certificate "/var/www/httpd-cert/myoc/test.ru.crt"; ssl_certificate_key "/var/www/httpd-cert/myoc/test.ru.key"; ssl_ciphers EECDH:+AES256:-3DES:RSA+AES:!NULL:!RC4; ssl_prefer_server_ciphers on; ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; add_header Strict-Transport-Security "max-age=31536000;"; ssl_dhparam /etc/ssl/certs/dhparam4096.pem; charset off; index index.php index.html; disable_symlinks if_not_owner from=$root_path; include /etc/nginx/vhosts-includes/*.conf; include /etc/nginx/vhosts-resources/test.ru/*.conf; access_log /var/www/httpd-logs/test.ru.access.log; error_log /var/www/httpd-logs/test.ru.error.log notice; ssi on; set $root_path /var/www/myoc/data/www/test.ru; root $root_path; listen 8.8.8.8:443 ssl http2; location / { location ~ [^/]\.ph(p\d*|tml)$ { try_files /does_not_exists @php; } location ~* ^.+\.(jpg|jpeg|gif|png|svg|js|css|mp3|ogg|mpe?g|avi|zip|gz|bz2?|rar|swf)$ { expires 365d; } } location @php { fastcgi_index index.php; fastcgi_param PHP_ADMIN_VALUE "sendmail_path = /usr/sbin/sendmail -t -i -f webmaster@test.ru"; fastcgi_pass unix:/var/www/php-fpm/myoc.sock; fastcgi_split_path_info ^((?U).+\.ph(?:p\d*|tml))(/?.+)$; try_files $uri =404; include fastcgi_params; } }
В конфигурации у вас будет две секции server, если у вас включено защищённое соединение SSL (и оно должно быть обязательно включено).
Если у вас включен принудительный редирект с http на https, то можно редактировать только секцию server для https.
Определить её легко: в самом начале есть параметр с указанием сертификата ssl_certificate. Также в этой секции указан параметр listen с указанием порта 443:
listen 8.8.8.8:443 ssl
Но лучше делать настройки сразу в двух секциях server, чтобы не допустить механической ошибки.
На данный момент нас интересует вот эта часть конфигурационного файла:
location / { location ~ [^/]\.ph(p\d*|tml)$ { try_files /does_not_exists @php; } location ~* ^.+\.(jpg|jpeg|gif|png|svg|js|css|mp3|ogg|mpe?g|avi|zip|gz|bz2?|rar|swf)$ { expires 365d; } }
Все дальнейшие изменения мы будем вносить внутри этой секции "location /".
В первую очередь нам не хватает вот такой директивы:
if (!-e $request_filename){ rewrite ^/(.+)$ /index.php?_route_=$1 last; }
Данное условие очень простое: если сервер не может найти файл по указанному в запросе пути, то запрос будет переписан на вызов index.php, а в параметр _route_ будет передан запрашиваемый путь. Именно это и позволит корректно отрабатывать всем ЧПУ ссылкам движка.
Это правило является аналогом записи в файле htaccess:
RewriteRule ^([^?]*) index.php?_route_=$1 [L,QSA]
На этом можно было бы и закончить, но стоит внести ещё некоторые изменения для улучшения безопасности.
Рассмотрим более внимательно вот эту секцию:
location ~ [^/]\.ph(p\d*|tml)$ {
Тут отбираются все все подходящие динамические файлы с типами .php (в том числе с числами в окончании) и .phtml
Но у движка OpenCart в штатном режиме есть всего две точки входа для вызова php файлов через web окружение - это index.php и admin/index.php
Есть ещё install/index.php, но она используется только при установке движка.
Учитывая данные обстоятельства, логично запретить прямое выполнение всех остальных php скриптов через web окружение, кроме указанных администратором.
Сделать это можно следующим образом:
location ~ ^/(index|admin/index|install/index)\.php {
try_files /does_not_exists @php;
}
В скобках через разделитель "|" указываем все php скрипты, которые можно выполнять. После завершения установки можно будет сократить это список
до такого: (index|admin/index)
ВНИМАНИЕ!!! Очень важный момент! После того, как убрали вызов интерпретатора php для всех файлов, кроме указанных, при попытке запроса любого другого php файла он будет отдан как обычный текстовый файл.
И при запросе https://test.ru/config.php любой желающий сможет получить содержимое вашего конфигурационного файла, где содержится доступ к БД.
Поэтому нам обязательно нужно запретить доступ для всех остальных файлов с расширением php. Ну и заодно к другим типам файлов, которые не
стоит отдавать по запросу извне. Сделать это можно простым правилом:
location ~* \.(php|log|tpl|txt|twig|xml|ini)$ { deny all; }
В скобках через разделитель "|" указываем все расширения файлов, которые мы хотим запретить.
Но у нас есть несколько важных файлов, которые пока попали под запрет, например: robots.txt и sitemap.xml. Этот вопрос мы решим чуть позже.
А сейчас ещё немного запретов. Запретим открывать файлы, которые начинаются с точки, а также все файлы в папке system:
location ~ /\. { deny all; } location ~ ^/system/ { deny all; }
Этих запретов вполне достаточно, чтобы сделать невозможным выполнение каких-либо несанкционированных скриптов. А также просмотр логов, текстовых и xml файлов.
Теперь нам необходимо открыть доступ к файлу robots.txt, для этого нам нужно такое правило:
location = /robots.txt { allow all; }
Также пропишем разрешение на открытие sitemap.xml и rewrite правило:
location = /sitemap.xml { allow all; rewrite ^/(.*)$ /index.php?route=extension/feed/google_sitemap last; }
Если вы используете сторонний модуль сайтмапа, то нужно указать соответствующий route для данного модуля.
Если у вас несколько файлов sitemap или вы используете фиды для выгрузки данных, то просто пропишите для них права по аналогии.
В итоге мы должны получить вот такую секцию location:
location / { if (!-e $request_filename){ rewrite ^/(.+)$ /index.php?_route_=$1 last; } location ~ ^/(index|admin/index)\.php { try_files /does_not_exists @php; } location = /sitemap.xml { allow all; rewrite ^/(.*)$ /index.php?route=extension/feed/google_sitemap last; } location = /robots.txt { allow all; } location ~ /\. { deny all; } location ~ ^/system/ { deny all; } location ~* \.(php|log|tpl|txt|twig|xml|ini)$ { deny all; } location ~* ^.+\.(jpg|jpeg|gif|png|svg|webp|js|css|mp3|ogg|mpe?g|avi|zip|gz|bz2?|rar|swf)$ { expires 365d; } }
Этих настроек достаточно для корректной работы движка OpenCart. И при этом данная конфигурация является безопасной с точки зрения выполнения
несанкционированных скриптов php через web окружение.
После всех настроек обязательно проверьте правильность работы, сделав запросы по указанному чек-листу (test.ru замените на адрес вашего сайта):
https://test.ru/config.php https://test.ru/admin/config.php https://test.ru/admin/1.php https://test.ru/admin/1.txt https://test.ru/admin/1.log https://test.ru/admin/1.xml https://test.ru/system/modification.xml
Для всех этих ссылок вы должны получить ошибку "403 Forbidden", вне зависимости от того, есть файл по указанному пути на сервере, или нет.
Также проверяем белый список:
https://test.ru/robots.txt https://test.ru/sitemap.xml
Эти файлы не должны вызывать ошибок и вы должны корректно получать их содержимое.
Дополнительно стоит проверить все ваши дополнительные сайтмапы или фиды, если вы их добавляли.
Ещё раз повторюсь, что данная настройка является базовой, с небольшими правилами для улучшения безопасности.
Но даже уже при такой настройке вы в среднем получите выигрыш 100-200ms для параметра TTFB, по сравнению с остальными режимами работы.
49 Комментариев
Рекомендуемые комментарии