Веб-сервер на основе Nginx и PHP5-FPM

Материал из Home wiki
Версия от 10:38, 24 октября 2022; KOleg (обсуждение | вклад) (Новая страница: «Существуют различные схемы построения веб-серверов для передачи данных по протоколу HTTP....»)
(разн.) ← Предыдущая | Текущая версия (разн.) | Следующая → (разн.)
Перейти к навигации Перейти к поиску

Существуют различные схемы построения веб-серверов для передачи данных по протоколу HTTP. Среди них достойное место по производительности занимают схемы с использованием «Nginx» в качестве внешнего (кэширующего, front-end) сервера. «Nginx» разработан для отдачи статических данных, при этом, он показывает высокое быстродействие и нагрузочную способность (см. Nginx vs Cherokee vs Apache vs Lighttpd), генерировать же динамическое содержимое он не способен. Поэтому, он часто применяется в связке с внутренним (back-end) сервером для обработки динамических данных которые потом отдаются «Nginx» как статические без участия внутреннего сервера. В качестве внутреннего сервера может применяться «Apache2» или, что и рассматривается в данной статье, «PHP-FPM».

В данной статье рассматривается установка и настройка связки Nginx и PHP-FPM на локальной ЭВМ, если требуется работа на выделенном сервере, то следует обратится к более серьезным инструкциям или/и непосредственной помощи специалистов Данная статья написана любителем, никто из профессионалов её не проверял, она может содержать ошибки и вредные советы и потому нацелена на тех, кто хочет поиграться

Установка

Сервер «Nginx» поставляется в одноименном пакете «nginx» и его установка производится, например, командой в терминале

sudo apt-get install nginx nginx-extras

Установку же «PHP-FPM» можно произвести, например, командой

sudo apt-get install php5-cli php5-common php5-mysql php5-gd php5-fpm php5-cgi php5-fpm php-pear php5-mcrypt

Безопасность

Наряду с уязвимостями присущими ПО сервера, присутствуют также те, что обусловлены неосторожностью администратора сервера. Для их устранения следует соблюдать меры предосторожности:

Должно быть запрещено выполнение PHP-кода из открытых для записи директорий. Например, директории для загрузки аватаров, файлов или директории доступные также FTP-серверу, который позволяет произвести запись в них. Следует следить за логами работы сервера, это позволяет выявить попытку взлома как можно раньше и минимизировать угрозу дальнейшего ущерба. Необходимо обновлять ПО (в том числе «CMS» — системы управления содержимым сайтов), но не обязательно тогда когда выходят новые версии (они тоже могут содержать новые уязвимости), а, прежде всего, тогда, когда обновление связано с устранением серьезной уязвимости. Обязательное наличие файлов для отката состояния сервера (в том числе, конфигурационных файлов). Осторожное и осмотрительное следование подобным инструкциям (см. Don’t trust the tutorials: check your configuration!)

Настройка

Настройка состоит из двух этапов — настройки «Nginx» и «PHP-FPM». Для начала необходимо остановить процессы (демоны) «Nginx» и «PHP-FPM», например, командами

sudo service nginx stop
sudo service php5-fpm stop

Настройка PHP-FPM

Прежде всего, следует открыть файл «/etc/php5/fpm/php.ini» для редактирования, например, командой

sudo nano /etc/php5/fpm/php.ini

после чего, найти строчку содержащую «cgi.fix_pathinfo», которая по-умолчанию выглядит так (закомментирована)

;cgi.fix_pathinfo = 1

и привести её к виду

cgi.fix_pathinfo = 0

Это призвано устранить опасность неправильно трактования (и возникающей уязвимости) запросов вида «/image.gif/foo.php» (см. Don’t trust the tutorials: check your configuration!, Nginx 0day exploit for nginx + fastcgi PHP).

Если планируется загрузка больших файлов (важно для ownCloud версий < 8, в новой версии 8 и выше имеется отдельный файл для этих настроек), то можно увеличить максимальный объем загружаемых данных, например, до 200 МБ

post_max_size = 200M

и ниже

upload_max_filesize = 200M

Затем сохранить изменения в файле.

Далее, необходимо отрыть для редактирования файл «/etc/php5/fpm/pool.d/www.conf», например, командой

sudo nano /etc/php5/fpm/pool.d/www.conf

найти строчку с параметров «security.limit_extensions» и привести её к виду

security.limit_extensions = .php .php3 .php4 .php5

Эта настройка ограничит выполнение файлов по расширению имени. В этом же файле найти строчку с параметром «listen» и привести её к виду

listen = /var/run/php5-fpm.sock

Это определит файл для связи «Nginx» с «PHP-FPM» (сокет). В целях безопасности запрещаем какой-попало программе писать в сокет (см. Обновление PHP 5.5.12 с устранением уязвимости в PHP-FPM ) путём указания прав доступа к сокету. Находим строчки с описанием параметров «listen.owner», «listen.group» и «listen.mode» (по-умолчанию они закомментированы) и приводим их к виду

listen.owner = www-data
listen.group = www-data
listen.mode = 0660

Следует сохранить изменения в файле и перезапустить «PHP-FPM», например, командой

sudo service php5-fpm restart

Можно убедится в том, что права доступа к сокету установлены верно:

ls -la /var/run/php5-fpm.sock

Права доступа должны быть «srw-rw—-», владелец «www-data» (группа «www-data»), например,

srw-rw---- 1 www-data www-data 0 May  2 16:36 /var/run/php5-fpm.sock

Настройка Nginx

Основные настройки «Nginx» хранятся в файле «/etc/nginx/nginx.conf». Настройки базового сайта хранятся в файле «/etc/nginx/sites-available/default». Базовый конфигурационный файл сайта принято помещать в папку «/etc/nginx/sites-available/» и затем включить его путём добавления символической ссылки на этот файл в папке «/etc/nginx/sites-enabled/». Например, создадим конфигурационный файл для сайта с доменным именем (для примера выбрано «example.com») в названии для удобства

sudo touch /etc/nginx/sites-available/example.com
sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/

и откроем его для редактирования

sudo nano /etc/nginx/sites-available/example.com

При редактировании данного файла необходимо учитывать синтаксис конфигурации «Nginx» (см. HttpCoreModule), готовые советы по настройке связки «Nginx + PHP-FPM» (см. PHPFcgiExample) и следовать некоторым правилам/рекомендация для достижения эффективной работы сервера (см. Pitfalls). Описывать конфигурацию сайта в одном файле не очень удобно, для увеличения читабельности конфигурационного файла и гибкости настройки можно воспользоваться директивой «include» позволяющей указать «Nginx», что следует загрузить другой конфигурационный файл и затем продолжить чтение текущего. Создадим в папке «/etc/nginx/» каталог «common», где будут хранится общие настройки для сайта, которые затем будут подгружаться из основного конфигурационного файла «/etc/nginx/sites-available/example.com» с помощью директивы «include»

sudo mkdir /etc/nginx/common

Некоторые запросы «Nginx» будет перенаправлять к «PHP-FPM», который в данном случае называется сервером выгрузки данных (upstream). Укажем как следует это делать. Создадим файл конфигурации с описанием серверов выгрузки данных

sudo touch /etc/nginx/common/upstream

и откроем его для редактирования

sudo nano /etc/nginx/common/upstream

и добавим в него строчки

upstream php-fpm
{
	# PHP5-FPM сервер
	server unix:/var/run/php5-fpm.sock;
}

где «php-fpm» – название для сервера выгрузки данных, для удобства.

Редактируем файл «/etc/nginx/sites-available/example.com». Добавляем строчку

include common/upstream;

для загрузки созданого выше конфигурационного файла. Как можно видеть – допускается указание относительного пути к файлу.

Далее описываем перенаправление от HTTP к HTTPS, если, конечно, это планируется. В таком случае необходимо наличие сертификатов для HTTPS (см. Сертификаты)

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

иначе, можно опустить эти строчки.

Начинаем описывать конфигурацию сайта

server
{
Сетевой порт для приема соединений: 80 — обычный HTTP; 443 — HTTPS (см. выше)

	# Порты
	listen	80;
	listen	443	ssl;	# использовать шифрование для этого порта

Корневая директория сайта работающего на данном сервере

	root			/var/www;

Возможные имена индексных файлов (их «Nginx» пытается открыть если он получил запрос вида «example.com/», вместо явного «example.com/index.html»)

	index			index.php index.html index.htm;

Имя сервера – обычно доменное имя Вашего сервера

	server_name		example.com www.example.com;

Шифрование

Необходимо наличие сертификата «*.crt» или «*.pem» и приватного секретного ключа «*.key» (см. Сертификаты). Самоподписанный сертификат можно сгенерировать командой в терминале (см. man openssl, man req)

openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout example.com_nginx.key -out example.com_nginx.crt

При этом программа запросит данные, среди них «commmon name» — следует указать доменное имя сервера. Можно использовать шаблон, если необходимо учесть домены нижнего уровня, например, «*example.com». Иначе могут возникнуть проблемы с некоторыми программами, например, «davfs2» (см man davfs2.conf).

Но можно пойти дальше и воспользоваться сервисом «StartSSL» где выдают бесплатные сертификаты для личного пользования (см. startssl.com и Получение и установка бесплатного SSL-сертификата), но сам приватный ключ (который нельзя никому показывать) лучше сгенерировать самому, например, так

openssl genrsa -out example_nginx.com.key 4096

затем сформировать файл запроса на подпись (при этом прийдётся вводить те же данные что и для генерации самоподписанного сертификата, но это не важно, т.к. сервис «StartSSL» проигнорирует все кроме публичного ключа)

openssl req -new -sha256 -key example.com_nginx.key -out example.com.csr

открыть полученный файл текстовым редактором

nano example.com.csr

и скопировать его содержимое в текстовое поле на сайте «StartSSL» для запроса сертификата (см. ссылки на подробные инструкции выше). Файл *.csr больше не нужен. Затем загружаем подписанный сертификат (например, файл называется signed.crt) и объединяем его с сертификатом того кто этот сертификат подписал

wget https://www.startssl.com/certs/sub.class1.server.ca.pem
cat signed.crt sub.class1.server.ca.pem > example.com_nginx.crt

Файл «signed.crt» можно удалить.

Копируем секретный ключ в системную папку и выставляем права доступа

sudo cp example.com_nginx.key /etc/ssl/private/
sudo chown www-data:www-data /etc/ssl/private/example.com_nginx.key
sudo chmod 400 /etc/ssl/private/example.com_nginx.key

И в соседнюю папку сам сертификат

sudo cp example.com_nginx.crt /etc/ssl/certs/

Для пущей надежности можно сгенерировать ключ Диффи-Хеллмана (тоже секретный файл который очень долго генерируется)

openssl dhparam -out example.com.dh.key 4096
sudo cp example.com_nginx.dh.key /etc/ssl/private/
chown www-data:www-data example.com_nginx.dh.key
chmod 400 example.com_nginx.dh.key

Продолжаем редактировать конфигурационные файлы.

Для удобства описываем настройки шифрования во внешнем файле «/etc/nginx/common/ssl»

sudo touch /etc/nginx/common/ssl

Редактируем файл «/etc/nginx/common/ssl»

sudo nano /etc/nginx/common/ssl

Файлы сертификатов для «HTTPS»

ssl_certificate /etc/ssl/certs/example.com_nginx.crt;		# сертификат (можно свободно распространять)
ssl_certificate_key /etc/ssl/private/example.com_nginx.key;	# приватный ключ (секретный файл - НИКОМУ НЕ ПОКАЗЫВАТЬ)

Дополнительные параметры требуемые для «HTTPS»

ssl_dhparam				/etc/ssl/private/example.com_nginx.dh.key;	# писать эту строчку только если файл есть
ssl_session_timeout			20m;	# время 20 минут
ssl_session_cache			shared:SSL:20m;	# размер кеша 20МБ
ssl_protocols				TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers		on;
ssl_ciphers				ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM- 
SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA- 
AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256- 
SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!3DES:!MD5:!PSK;

На этом настройки «SSL» в «Nginx» завершены, сохраняем и закрываем файл. После завершения описания конфигурации (см. ниже) можно будет проверить надежность сервисом «SSLLabs»

Продолжаем редактировать файл «/etc/nginx/sites-available/example.com». Подгружаем созданный выше конфигурационный файл с описанием настроек SSL

# Настройка шифрования SSL include common/ssl;

Прочие настройки

Указание максимального размера запроса – необходимо если сервер будет использоваться для загрузки больших файлов (например, для построения небольшого облачного хранилища на основе «ownCloud», эта строчка по сути делает то же что и указанные выше при настройке «PHP-FPM», только теперь для «Nginx»)

client_max_body_size 200m; # увеличение максимального объема файла для загрузки до 200МБ Ещё одна опция

# Buffers fastcgi_buffers 64 4K;

Безопасность

Опишем настройки безопасности в отдельном файле

sudo touch /etc/nginx/common/security
sudo nano /etc/nginx/common/security

И укажем в нём

add_header		X-Frame-Options		"SAMEORIGIN";
add_header		X-Content-Type-Options	"nosniff"; 

Сохраним и закроем файл, а затем подключим его строкой

include common/security;

Сжатие

Для экономии трафика лучше включить сжатие (иногда со влючённым сжатием могут возникать проблемы, например, у «ownCloud», см. ниже). Опишем настройки сжатия в отдельном файле

sudo touch /etc/nginx/common/gzip
sudo nano /etc/nginx/common/gzip

и введём

gzip		on;
gzip_disable	"msie6";
gzip_comp_level	6;
gzip_min_length	1100;
gzip_buffers	16 8k;
gzip_proxied	any;
gzip_types	text/plain application/xml text/css text/js text/xml application/x-javascript text/javascript application/javascript application/json application/xml+rss; 

Следует сохранить, закрыть и затем подключить этот файл срочкой

include common/gzip;

Директории сайта

Далее указание директорий сайта и правил работы с ними с использованием директив «location». Данная директива может обрабатывать регулярные выражения «Perl» (см. Регулярные выражения (шаблоны))

Важно учитывать порядок проверки директив «location» (см. location) Блокировать доступ к файлам и подпапкам обычно следует посредством регулярных выражений Корневая директория

location "/" { index index.php index.html index.htm; # варианты индексных файлов если имя файла в запросе не задано try_files $uri $uri/ =404; # проверить есть ли файл из запроса на диске, иначе - вернуть ошибку 404 } К примеру, если хочется построить сайт на основе «WordPress», то можно описать корневую директорию так

location "/" { index index.php index.html index.htm; try_files $uri $uri/ /wordpress/; # проверяем существования файла или папки, иначе перенаправляем к example.com/wordpress rewrite "^/$" "/wordpress/" redirect; # перенаправляем запрос example.com/ к example.com/wordpress } Соответственно сам сайт должен размещаться в каталоге «/var/www/wordpress/»

Директории можно описывать по одной в этом же файле, но это не удобно и не наглядно. А можно указать строчку

include common/locations/*.inc; которая укажет «Nginx», что нужно подключить все файлы в директории «/etc/common/locations/» которые соответствуют шаблону «*.inc», таким образом, если один из файлов нужно будет временно отключить, то его можно просто переименовать убрав расширение в имени. Создадим директорию где будут хранится эти файлы

sudo mkdir /etc/nginx/common/locations

Некая директория «/var/www/restricted» доступная только авторизованным пользователям сервера. Создадим для неё файл конфигурации «/etc/nginx/common/locations/restricted.inc»

sudo touch /etc/nginx/common/locations/restricted.inc
sudo nano /etc/nginx/common/locations/restricted.inc

со строчками

location ^~ "/restricted/"
{
	auth_basic		"Access to this folder is restricted";
	auth_basic_user_file	htpasswd;
	autoindex	on;
	allow		all;
	try_files	$uri $uri/ =404;
}

Синтаксис «^~» указывает, что при совпадении здесь директивы «location» ниже проверяться не будут.

Этот конфигурационный файл подключится автоматически, за счёт шаблона (см. выше).

Wordpress

Для более полной информации по настройке «Nginx» для «WordPress» следует обратиться к официальной документации (см. codex.wordpress.org/Nginx и wiki.nginx.org/WordPress)

Натройки «Wordpress», который, в данном примере, находится в папке «/var/www/wordpress» будут описаны в файле «/etc/nginx/common/locations/wordpress.inc»

sudo touch /etc/nginx/common/locations/wordpress.inc
sudo nano /etc/nginx/common/locations/wordpress.inc

Указываем виртуальную директорию (используется для удобства и читабельности) в которую будут перенаправляться запросы при необходимости

location @wordpress
{
	rewrite "^/wordpress/(.*)$" "/wordpress/index.php?q=$1" last;
}

Аналогично примеру выше предотвращаем обработку остальных директив «location»

location ^~ "/wordpress/"
{
	root		"/var/www";
	index		index.php;
	try_files	$uri $uri/ @wordpress;	# проверить существует ли файл, иначе направить в виртуальную директорию

# Ограничение доступа к секретному файлу location ~* "^/wordpress/wp-config.php(/.*)?$" { deny all; return 404; } # Ни в коем случае не выполнять файлы php в папках куда их может кто-то загрузить # Проще всего просто заблокировать любые операции с такими файлами регулярным выражением location ~* "/(uploads|files)/.*\.php.?(/.*)?$" { deny all; return 404; } # Перенаправление php-файлов к серверу «PHP-FPM» см. ниже по статье location ~ "^(/wordpress/.+?\.php)(/.*)?$" { # Проверяем существование файлов, пробуем исправить если нет, иначе выдаём ошибку # $1 указывает на первую скобку в регулярном выражении выше - собственно адрес запрошенного php файла try_files $1 $uri $uri/ $uri/index.php =404; include common/php-fpm; } # Другие настройки, см. ниже по статье include common/deny; include common/cache;

}

Сохраняем и закрываем этот файл. Опять же, он будет подключён автоматически.

ownCloud

Для наиболее полной информации следует обратится к официальному руководству «OwnCloud» (см. Nginx Configuration). К примеру, «ownCloud» находится в папке «/var/www/owncloud».

Создадим файл настроек для «ownCloud» и отредактируем его

sudo touch /etc/nginx/common/locations/owncloud.inc
sudo nano /etc/nginx/common/locations/owncloud.inc

Многое аналогично примеру для «Wordpress»

location ^~ "/owncloud/"
{

root "/var/www"; index index.php index.html index.htm; try_files $uri $uri/ =404; # ownCloud предоставляет свои красивые страницы для ошибок 404 и 403 - используем их error_page 403 /owncloud/core/templates/403.php; error_page 404 /owncloud/core/templates/404.php;

# Отключаем сжатие - оно создаёт проблемы для клиента синхронизации ownCloud gzip off; # Переопределяем глобальную настройку описанную в главном файле # увеличиваем максимальный размер загружаемых файлов client_max_body_size 16G; # Запрещаем читать секретные файлы location ~* "^/owncloud/(\.user\.ini|data|config|db_structure\.xml|README)(/.*)?$" { deny all; return 404; } location ~ "^(/owncloud/.+?\.php)(/.*)?$" { try_files $1 $uri $uri/ $uri/index.php =404; include common/php-fpm; } include common/deny; include common/cache;

}

Начиная с версии «ownCloud» 8 появился отдельный файл для переопределения некоторых настроек «PHP-FPM» взамен указанных в «/etc/php5/fpm/php.ini». Открыть его можно командой

sudo nano /var/www/owncloud/.user.ini

и в нем найти строчки

upload_max_filesize=513M
post_max_size=513M

и поменять значения на требуемые.

Базовые ограничения

Выше была написана строчка для подключение файла «/etc/nginx/common/deny»

include common/deny;

рассмотрим его содержание. В нём идет запрет доступа к некоторым стандартным файлам. Создадим этот файл

sudo touch /etc/nginx/common/deny
sudo nano /etc/nginx/common/deny

с содержанием

# Запрет доступа к .htaccess и .htpasswd файлам
location ~* "/\.(htaccess|htpasswd)$"
{

deny all; # запретить все для всех return 404; # вернуть код ошибки

}

Следует быть бдительным, неверно указанный шаблоны для запрета доступа (не только здесь но и в примерах выше) могут сильно навредить. Например, клиент ownCloud может начать удалять файлы которые не сможет загрузить на сервер из-за неправильного запрета где-то в конфигурационном файле Следует переписать все файлы «.htaccess» в директивы «Nginx». Найти эти файлы среди файлов сайта можно, например, командой

sudo find /var/www/ -name .htaccess

Вызов PHP-FPM

В примерах выше использовался файл «/etc/nginx/common/php-fpm» — в нём идет перенаправление обработки php-скриптов внутреннему серверу «PHP-FPM»

В файле «php.ini» должно быть установлено «cgi.fix_pathinfo = 0;» Также, в файле »/etc/php5/fpm/pool.d/www.conf» должно присутствовать ограничение на разширение имени исполняемых скриптов - «security.limit_extensions = .php .php3 .php4 .php5» Создаём этот файл

sudo touch /etc/nginx/common/php-fpm sudo nano /etc/nginx/common/php-fpm с содержанием

# Настройки порта или сокета PHP-FPM производятся в файле "/etc/php5/fpm/pool.d/www.conf"
fastcgi_pass	php-fpm;
# Порядок важен - строчка "include fastcgi_params" должна быть первой
include fastcgi_params;
fastcgi_split_path_info			^(.+?\.php)(/.*)?$;
# Вместо переменной "$document_root" можно указать адрес к корневому каталогу сервера и это желательно (см. http://wiki.nginx.org/Pitfalls)
fastcgi_param	SCRIPT_FILENAME		$document_root$fastcgi_script_name;
fastcgi_param	PATH_TRANSLATED		$document_root$fastcgi_script_name;
# См. http://trac.nginx.org/nginx/ticket/321
set		$path_info		$fastcgi_path_info;
fastcgi_param	PATH_INFO		$path_info;
# Additional variables
fastcgi_param	SERVER_ADMIN		email@example.com;
fastcgi_param	SERVER_SIGNATURE	nginx/$nginx_version;
fastcgi_index	index.php;

Кеширование

Выше, в примерах, был упомянут файл «/etc/nginx/common/cache»

Сайт работает значительно лучше когда часть контента сохранена на стороне клиента с прошлого посещения сайта. Не все файлы можно кешировать. Поэтому описание кеширования производится в самом конце (т.е. эти настройки будут иметь наименьший приоритет и есть шанс что это не повлияет на правильную работу сайта). Создадим файл с параметрами для кеширования

sudo touch /etc/nginx/common/cache
sudo nano /etc/nginx/common/cache

где укажем

location ~* ".+\.(?:ogg|ogv|svg|svgz|eot|otf|woff|mp4|ttf|rss|css|swf|js|atom|jpe?g|gif|png|ico|zip|tgz|gz|rar|bz2|doc|xls|exe|ppt|tar|mid|midi|wav|bmp|rtf)$"

{ access_log off; log_not_found off; expires max; }

Окончание

Закрываем фигурные скобки директивы «server» в «/etc/nginx/sites-available/example.com»

}

На этом правка файла «/etc/nginx/sites-available/example.com» завершена. Убедитесь в том, что все фигурные скобки «{ }» закрыты корректно и части файла верно вложены друг в друга («location» внутри «server» и т.п.).

Сохраняем все изменённые файлы.

Теперь можно перезапустить демоны

sudo service nginx restart
sudo service php5-fpm restart

Проверка

Проверить свой сайт можно создав файл «info.php» с содержанием

<?php
phpinfo();
?>

затем скопировав его, например, в «/var/www/wordpress/wp-content/uploads/», затем открыв адрес в браузере «http://example.com/wordpress/wp-content/uploads/info.php», если он выполнится вместо того чтобы просто сохранится — то что-то настроено неправильно, в этой директории php файлы выполняться не должны ни в коем случае (она доступна для загрузки)

Проверить свой сайт на скорость и прочее можно тут:

webpagetest.org

developers.google.com

ssllabs.com