Попалась на глаза англоязычная статья с советами по безопасности при настройке PHP. Там нет чего-то уникального и необычного, но материал хорош как готовый список действий или рекомендаций, по которым стоит пробежаться при настройке веб сервера. Решил на основе её сделать чек-лист на русском языке. Кому нужны подробности, переходите в источник.
✅ Смотрим список активных модулей:
Отключаем ненужные:
✅ Отключаем отображение информации о версии PHP:
Это параметр для php.ini.
✅ Отключаем отображение ошибок PHP для посетителей:
Вместо этого логируем их отдельно:
✅ Если не нужна загрузка файлов на веб сервер, отключите эту возможность:
Если загрузка нужна, то хотя бы ограничьте максимальный размер файла до необходимого предела:
✅ Отключаем функцию allow_url_fopen, если не используются сайтом. Она открывает широкие возможности для взлома, если разработчики забудут о фильтрации входящих данных.
✅ Настройка размера POST запросов. Этот параметр должен быть не меньше upload_max_filesize, если разрешена загрузка файлов. Если же она запрещена, то большой разрешённый размер post запросов не нужен. Вряд ли вам через формы потребуется заливать большой объём данных.
или
✅ Подобрать необходимые лимиты выполнения скриптов. Тут всё сильно зависит от самого сайта. В идеале, много ресурсов не выделять, но, к примеру, тот же Bitrix, требует очень много оперативной памяти и времени выполнения для своих скриптов.
✅ Отключаем потенциально опасные функции PHP. Оставляем только то, что реально нужно.
✅ Убедиться, что параметр cgi.force_redirect не отключен принудительно. По дефолту, если его явно не указать, то он будет включен.
✅ Убедиться, что php работает от отдельного непривилегированного пользователя. Настройка будет зависеть от используемого менеджера процессов php. Проверяем примерно так:
✅ Ограничиваем доступ php к файловой системе:
✅ Настраиваем место хранения для сессий:
Важно убедиться, что туда нет доступа посторонним. Кроме веб сервера эта директория никому не нужна. Также туда не должно быть доступа с сайта.
В статье было гораздо больше информации, но некоторые параметры уже объявлены устаревшими. А часть не относится непосредственно к PHP (настройка selinux, firewall и т.д.), поэтому я не стал включать её в этот список.
❗️Материал имеет смысл сохранить в закладки. Источник.
#security #webserver #php
✅ Смотрим список активных модулей:
# php -m
Отключаем ненужные:
# mv /etc/php.d/sqlite3.ini /etc/php.d/sqlite3.disable
✅ Отключаем отображение информации о версии PHP:
expose_php=Off
Это параметр для php.ini.
✅ Отключаем отображение ошибок PHP для посетителей:
display_errors=Off
Вместо этого логируем их отдельно:
log_errors=On
error_log=/var/log/httpd/php_scripts_error.log
✅ Если не нужна загрузка файлов на веб сервер, отключите эту возможность:
file_uploads=Off
Если загрузка нужна, то хотя бы ограничьте максимальный размер файла до необходимого предела:
file_uploads=On
upload_max_filesize=10M
✅ Отключаем функцию allow_url_fopen, если не используются сайтом. Она открывает широкие возможности для взлома, если разработчики забудут о фильтрации входящих данных.
allow_url_fopen=Off
✅ Настройка размера POST запросов. Этот параметр должен быть не меньше upload_max_filesize, если разрешена загрузка файлов. Если же она запрещена, то большой разрешённый размер post запросов не нужен. Вряд ли вам через формы потребуется заливать большой объём данных.
post_max_size=10M
или
post_max_size=10K
✅ Подобрать необходимые лимиты выполнения скриптов. Тут всё сильно зависит от самого сайта. В идеале, много ресурсов не выделять, но, к примеру, тот же Bitrix, требует очень много оперативной памяти и времени выполнения для своих скриптов.
max_execution_time = 30
max_input_time = 30
memory_limit = 64M
✅ Отключаем потенциально опасные функции PHP. Оставляем только то, что реально нужно.
disable_functions = exec,passthru,shell_exec,system,
proc_open,popen,curl_exec,curl_multi_exec,
parse_ini_file,show_source
✅ Убедиться, что параметр cgi.force_redirect не отключен принудительно. По дефолту, если его явно не указать, то он будет включен.
cgi.force_redirect=On
✅ Убедиться, что php работает от отдельного непривилегированного пользователя. Настройка будет зависеть от используемого менеджера процессов php. Проверяем примерно так:
# ps aux | grep php
✅ Ограничиваем доступ php к файловой системе:
open_basedir = "/var/www/html/"
✅ Настраиваем место хранения для сессий:
session.save_path = "/var/lib/php/session"
Важно убедиться, что туда нет доступа посторонним. Кроме веб сервера эта директория никому не нужна. Также туда не должно быть доступа с сайта.
В статье было гораздо больше информации, но некоторые параметры уже объявлены устаревшими. А часть не относится непосредственно к PHP (настройка selinux, firewall и т.д.), поэтому я не стал включать её в этот список.
❗️Материал имеет смысл сохранить в закладки. Источник.
#security #webserver #php
Вы знали, что php в своём составе имеет собственный веб сервер? Для быстрого запуска php скриптов в браузере не нужно ничего, кроме непосредственно php на сервере. Покажу сразу на примере.
Допустим, вам нужно временно запустить phpmyadmin, но не хочется для него настраивать веб сервер. Его может не быть, либо просто не хочется что-то менять в работе уже настроенного. Нет ничего проще.
Устанавливаем php и модуль mysqli для работы с mysql:
Качаем и распаковываем phpmyadmin:
Запускаем веб сервер:
Идём по адресу http://172.27.50.130:8080 и видим веб интерфейс phpmyadmin. Если он ещё не настроен, то надо зайти в директорию /setup/ и выполнить начальную настройку подключения. Как минимум, адрес сервера указать. Если это не первое подключение, то сразу же подключаемся к базе.
Когда закончите работу, просто остановите веб сервер, завершив его работу в консоли. В ней же, кстати, будет информация обо всех запросах. Подобным образом можно запустить любой php скрипт. Для phpmyadmin этот подход наиболее актуален, так как веб панель нужна не часто, а оставлять её открытой для постоянно доступа не рекомендуется. Для личных нужд проще запустить, всё сделать и закрыть.
#php #webserver
Допустим, вам нужно временно запустить phpmyadmin, но не хочется для него настраивать веб сервер. Его может не быть, либо просто не хочется что-то менять в работе уже настроенного. Нет ничего проще.
Устанавливаем php и модуль mysqli для работы с mysql:
# apt install php php-mysqli
Качаем и распаковываем phpmyadmin:
# wget https://files.phpmyadmin.net/phpMyAdmin/5.2.1/phpMyAdmin-5.2.1-all-languages.tar.gz
# tar xzvf phpMyAdmin-5.2.1-all-languages.tar.gz
Запускаем веб сервер:
# cd phpMyAdmin-5.2.1-all-languages
# php -S 172.27.50.130:8080
Идём по адресу http://172.27.50.130:8080 и видим веб интерфейс phpmyadmin. Если он ещё не настроен, то надо зайти в директорию /setup/ и выполнить начальную настройку подключения. Как минимум, адрес сервера указать. Если это не первое подключение, то сразу же подключаемся к базе.
Когда закончите работу, просто остановите веб сервер, завершив его работу в консоли. В ней же, кстати, будет информация обо всех запросах. Подобным образом можно запустить любой php скрипт. Для phpmyadmin этот подход наиболее актуален, так как веб панель нужна не часто, а оставлять её открытой для постоянно доступа не рекомендуется. Для личных нужд проще запустить, всё сделать и закрыть.
#php #webserver
Как быстро и малыми усилиями попытаться выяснить, почему что-то тормозит в php коде сайта? Расскажу, с чего уместнее всего начать расследование, если вы используете php-fpm. Если нет каких-то особых требований, то лично я всегда исользую именно его.
У него есть две простые настройки, которые можно применить в нужном пуле, когда проводите расследование:
Таймаут выставляете под свои требования. Если сайт в целом тормозной (bitrix, админка wordpress), то 1 секунда слишком малый интервал, но в идеале хочется, чтобы весь код выполнялся быстрее этого времени.
Далее необходимо перезаустить php-fpm и идти смотреть лог:
В логе запросов будет не только информация о скрипте, который долго выполняется, но и его трассировака. Она будет включать в себя все инклюды и функции. То, что было вызвано сначала, будет внизу трейса, последняя функция - в самом верху. Причём верхней функцией будет та, что выполнялась в момент наступления времени, указанного в request_slowlog_timeout. Часто именно она и причина тормозов.
Разобраться во всём этом не такая простая задача, но в целом выполнимая даже админом. Самое главное, что иногда можно сразу получить подсказку, которая ответит на ворос о том, что именно томозит. Бывает не понятно, какой именно запрос приводит к выполнению того или иного скрипта. Нужно сопоставить по времени запрос в access.log веб сервера и slowlog php-fpm.
Очень часто тормозят какие-то заросы к внешним сервисам. Они могут делаться, к примеру, через curl_exec. И вы это сразу увидите в slowlog в самом верху трейса. Нужно будет только пройтись по функуциям и зависимостям, и найти то место, откуда функция с curl вызывается. Также часто в самом верху трейса можно увидеть функцию mysqli_query или что-то в этом роде. Тогда понятно, что тормозят запросы к базе.
По факту это самый простой инструмент, который имеет смысл использовать в самом начале разборов. Зачастую с его помощью можно сразу найти проблему. Ну а если нет, то можно подключать strace и смотреть более детально, что там внутри происходит. Но это уже сложнее, хотя какие-то простые вещи тоже можно сразу отловить. Тот же внешний тормозящий запрос тоже будет виден сразу.
#php #webserver #perfomance
У него есть две простые настройки, которые можно применить в нужном пуле, когда проводите расследование:
slowlog = /var/log/php-fpm/site01.ru.slow.log
request_slowlog_timeout = 1s
Таймаут выставляете под свои требования. Если сайт в целом тормозной (bitrix, админка wordpress), то 1 секунда слишком малый интервал, но в идеале хочется, чтобы весь код выполнялся быстрее этого времени.
Далее необходимо перезаустить php-fpm и идти смотреть лог:
# systemctl restart php8.0-fpm
В логе запросов будет не только информация о скрипте, который долго выполняется, но и его трассировака. Она будет включать в себя все инклюды и функции. То, что было вызвано сначала, будет внизу трейса, последняя функция - в самом верху. Причём верхней функцией будет та, что выполнялась в момент наступления времени, указанного в request_slowlog_timeout. Часто именно она и причина тормозов.
Разобраться во всём этом не такая простая задача, но в целом выполнимая даже админом. Самое главное, что иногда можно сразу получить подсказку, которая ответит на ворос о том, что именно томозит. Бывает не понятно, какой именно запрос приводит к выполнению того или иного скрипта. Нужно сопоставить по времени запрос в access.log веб сервера и slowlog php-fpm.
Очень часто тормозят какие-то заросы к внешним сервисам. Они могут делаться, к примеру, через curl_exec. И вы это сразу увидите в slowlog в самом верху трейса. Нужно будет только пройтись по функуциям и зависимостям, и найти то место, откуда функция с curl вызывается. Также часто в самом верху трейса можно увидеть функцию mysqli_query или что-то в этом роде. Тогда понятно, что тормозят запросы к базе.
По факту это самый простой инструмент, который имеет смысл использовать в самом начале разборов. Зачастую с его помощью можно сразу найти проблему. Ну а если нет, то можно подключать strace и смотреть более детально, что там внутри происходит. Но это уже сложнее, хотя какие-то простые вещи тоже можно сразу отловить. Тот же внешний тормозящий запрос тоже будет виден сразу.
#php #webserver #perfomance
Немного информации для тех, кто имеет дело с обычными веб серверами под php сайты. Вчера провозился несколько часов с одним сайтом, который передали разработчики для публикации. Причём провозился из-за ерунды. Это был немного навороченный мультиязычный сайт на базе Wordpress, но с полностью самописной темой.
Я этих вордпрессов десятки устанавливал и поддерживал. Никак не ожидал проблем с этим движком. Но разработчики сумели меня удивить и нагрузить работой. Для начала пришлось повозиться с тем, что режим работы сайта http или https был жёстко зашит в коде сайта. И не где-то в настройках Wordpress или базе, а в коде темы. Это создавало некоторые проблемы при публикации за Cloudflare и Nginx в режиме proxy_pass. Пока всё развернул, разобрался, нашёл и вычистил в коде, немного подустал. Плюс, сайт под Apache разрабатывали, запустил под Nginx.
В итоге на сайте кое-где всплывали ошибки php, что-то не работало. В логе тоже ошибки и предупреждения со стороны php. Причём ошибки какие-то странные, типа скобки не закрыты, переменная не объявлена и т.д. Сначала подумал, что сайт написали под старую версию php. На веб сервере стояла относительно свежая 8.2. Уточнил у разработчиков, у них на 8.1 нормально работает. Разница в этих версиях не такая большая, должно нормально работать. Потом подумал, что по ошибке скинули какой-то черновик, а не итоговую работу.
Немного поразбирался в ошибках и выяснил, в чём проблема. В php по умолчанию параметр short_open_tag выключен. Это нормальная история, так как стандартному коду Wordpress он не нужен. Мне и в голову не пришло его включить. В версиях php до 6-й он был включен, потом стали отключать из соображений совместимости с другим кодом. Например, с тэгами
В коде этого сайта были конструкции типа
Если где-то придётся писать код php, то пишите сразу полные тэги <?php, а не короткие. Сейчас это более правильный подход, который улучшает переносимость проекта и не вызывает проблем с совместимостью с другим кодом, который использует тэги. Вот наглядный пример, где будут проблемы с короткими тэгами:
Это элемент xml разметки, а с включённым short_open_tag это будет интерпретироваться как php код.
#webserver #php
Я этих вордпрессов десятки устанавливал и поддерживал. Никак не ожидал проблем с этим движком. Но разработчики сумели меня удивить и нагрузить работой. Для начала пришлось повозиться с тем, что режим работы сайта http или https был жёстко зашит в коде сайта. И не где-то в настройках Wordpress или базе, а в коде темы. Это создавало некоторые проблемы при публикации за Cloudflare и Nginx в режиме proxy_pass. Пока всё развернул, разобрался, нашёл и вычистил в коде, немного подустал. Плюс, сайт под Apache разрабатывали, запустил под Nginx.
В итоге на сайте кое-где всплывали ошибки php, что-то не работало. В логе тоже ошибки и предупреждения со стороны php. Причём ошибки какие-то странные, типа скобки не закрыты, переменная не объявлена и т.д. Сначала подумал, что сайт написали под старую версию php. На веб сервере стояла относительно свежая 8.2. Уточнил у разработчиков, у них на 8.1 нормально работает. Разница в этих версиях не такая большая, должно нормально работать. Потом подумал, что по ошибке скинули какой-то черновик, а не итоговую работу.
Немного поразбирался в ошибках и выяснил, в чём проблема. В php по умолчанию параметр short_open_tag выключен. Это нормальная история, так как стандартному коду Wordpress он не нужен. Мне и в голову не пришло его включить. В версиях php до 6-й он был включен, потом стали отключать из соображений совместимости с другим кодом. Например, с тэгами
<?xml
.В коде этого сайта были конструкции типа
<?
вместо <?php
, а для их корректной работы как раз и нужен параметр short_open_tag
. Есть проекты, где явно пишут, что надо включить этот параметр. А тут мне никто ни слова насчёт него не сказал. Включил параметр и всё заработало. Если где-то придётся писать код php, то пишите сразу полные тэги <?php, а не короткие. Сейчас это более правильный подход, который улучшает переносимость проекта и не вызывает проблем с совместимостью с другим кодом, который использует тэги. Вот наглядный пример, где будут проблемы с короткими тэгами:
<?xml version="1.0"?>
Это элемент xml разметки, а с включённым short_open_tag это будет интерпретироваться как php код.
#webserver #php