Закрываем доступ к админке WordPress

Если у вас до сих пор свободно открыт доступ к админке WordPress, во избежание лишних проблем, я советую закрыть эту потенциальную дыру в безопасности. Возможно вы считаете, что для WordPress надежного пароля будет вполне достаточно. Но поверьте, закрыв доступ к админке WordPress вы не только снизите вероятность взлома, но и устраните одну из лазеек через которую могут положить ваш сайт.

Один из самых распространенных методов защиты админки сайта — использование HTTP-авторизации на уровне веб-сервера. Для этого нам необходимо предварительно сгенерировать файл .htpasswd, в котором будут хранится данные для авторизации. Затем указываем путь к .htpasswd в конфигурационном файле Nginx. Теперь при переходе по адресу /wp-admin или /wp-login.php Nginx запросит данные для авторизации.

Для генерации пароля необходимо использовать утилита генерации паролей .htpasswd. Пример конфигурации Nginx:

server {
    listen       80;
    server_name  localhost;

    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
    }

    location ~ ^/(wp-admin|wp-login.php) {
        auth_basic "closed site";
        auth_basic_user_file conf/.htpasswd;
        location ~ .php$ {
            root           html;
            fastcgi_pass   127.0.0.1:9000;
            fastcgi_index  index.php;
            fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
            include        fastcgi_params;
        }
    }
    
    location ~ .php$ {
        root           html;
        fastcgi_pass   127.0.0.1:9000;
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
        include        fastcgi_params;
    }
}

Для удобства можно вынести секцию location ~ .php$ в отдельный файл:

# nano /etc/nginx/php-fpm.conf

location ~ .php$ {
    root           html;
    fastcgi_pass   127.0.0.1:9000;
    fastcgi_index  index.php;
    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
    include        fastcgi_params;
}

Тогда конфигурация Nginx будет выглядеть следующим образом:

server {
    listen       80;
    server_name  localhost;

    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
    }

    location ~ ^/(wp-admin|wp-login.php) {
        auth_basic "closed site";
        auth_basic_user_file conf/.htpasswd;

        include php-fpm.conf;
    }
    
    include php-fpm.conf;
}

Как по мне, метод описанный выше не самый удобным вариант для защиты WordPress. Поэтому, вместо HTTP-авторизации по паролю, я предпочитаю ограничить доступ к админке WordPress используя фильтр на основе ip-адреса. Данный способ не совсем правильно использовать если ваш провайдер использует динамическую адресацию, но как вариант придется указать диапазон адресов подсети провайдера.

server {
    listen       80;
    server_name  localhost;

    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
    }

    location ~ ^/(wp-admin|wp-login.php) {
        allow 82.82.82.82;    // Указываем адрес вашего подключения
        allow 82.82.82.0/24;  // Или подсети вашего провайдера (ip-calculator.ru)
        deny all;

        include php-fpm.conf;
    }
    
    include php-fpm.conf;
}

Nginx: an upstream response is buffered to a temporary file

Дата: 26.08.2015Метки:

Данное предупреждение можно увидеть в логах Nginx при работе в связке с PHP-FPM:

[warn] 3400#3400: *21 an upstream response is buffered to a temporary file /var/cache/nginx/fastcgi_temp/1/00/0000000001 while reading up

Проблема вызвана недостаточным размером буфера Nginx, связи с чем для передачи полученных от PHP данных, Nginx предварительно записывает их во временный файл на диске.

Исправить: an upstream response is buffered to a temporary file

Для устранения предупреждения, необходимо увеличить размер буфера в Nginx. Для этого в секцию location ~ .php$, необходимо добавить следующие параметры:

fastcgi_buffers 4 256k;
fastcgi_busy_buffers_size 256k;
fastcgi_temp_file_write_size 256k;

В итоге должно получится как в примере ниже:

location ~ .php$ {
    try_files $uri = 404;
    fastcgi_pass unix:/var/run/php-fpm.sock;
    fastcgi_index  index.php;
    fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
    fastcgi_buffers 4 256k;
    fastcgi_busy_buffers_size 256k;
    fastcgi_temp_file_write_size 256k;
    include fastcgi_params;
}

Подробнее о изменении размера буфера под конкретно ваши условия можно прочитать в этой статье.

Редирект c HTTP на HTTPS в Nginx

Дата: 23.08.2015Метки:

Важным моментом в настройке SSL, является перенаправление всего HTTP-трафика на защищенное HTTPS-соединение. Надежнее всего это реализуется на уровне веб-сервера. Для того что бы принудительно с HTTP переадресовать всех посетителей на защищенное HTTPS соединение, необходимо в Nginx прописать в секцию server 301 редирект:

if ($scheme = http) {
       return 301 https://$server_name$request_uri;
    }
if ($host ~* www.) {
       return 301 https://$server_name$request_uri;
    }

Код статуса 301 означает, что запрашиваемая страница на постоянной основе перемещена на новый адрес. Что касается поисковых систем, то 301 редирект будет сигналом для переноса PR, тИЦ и всей ссылочной массы сайта. В результате, позиции сайта после повторной индексации останутся на прежнем уровне.

Влияние GZIP на производительность Nginx

Дата: 16.08.2015Метки:

Использование GZIP в Nginx может создавать сильную нагрузку на процессор и серьезно снизить производительность. Для устойчивой работы веб-сервера под нагрузкой, важно заранее подобрать оптимальные параметры. В процессе приходится искать своего рода компромисс межу степенью сжатия GZIP и производительностью Nginx.

В интернете много информации по настройке GZIP в Nginx. Вместо того что бы слепо полагаться на сухую информацию, я решил проверить на практике влияние сжатия на производительность Nginx. Затем на основе полученных данных выбрать оптимальные настройки.

Для замеров на виртуальной машине под Debian 8.1 была установлена последняя на текущий момент версия Nginx 1.9.3, собранного с параметром --with-http_gzip_static_module. Для тестирования использовался статический HTML-документ с главной страницы моего блога.

Производительности Nginx измерялась утилитой ApacheBench, запущенная со следующими параметрами:

service nginx restart && ab -c 100 -n 25000 -H "Accept-Encoding: gzip,deflate" "http://192.168.1.32/static.html"

Посмотреть полные данные тестирования можно на сайте GitHab. Для лучшей наглядности данные представлены в виде графиков ниже.

Поочередно изменяя значения параметра gzip_comp_level от 1 до 9 запускался ApacheBench. В конце каждого теста записывались данные о количестве обработанных запросов и объеме переданных данных.

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

Следующий график содержит информацию о количестве переданных данных для различного уровня сжатия.

На последнем графике мы можем сравнить скорость работы Nginx с включенным и отключенным сжатием GZIP и использованием модуля gzip_static.

Исходя из полученных данных, можно сделать вывод о том, что уровень сжатия GZIP существенно влияет на производительность Nginx. На первом графике видно, что разница между максимальным и минимальным значениями достигает почти 2,5 раза.

Производительность операции упирается в ресурсы процессора. Начина с значения параметра gzip_comp_level равным 3, скорость начинает значительно проседать. По сравнению с данными полученными без использования сжатия, дальнейшее увеличение уровня компрессии не приносит существенного результата. Использование степени сжатия больше 6 вовсе не имеет смысла и приносит больше вреда чем пользы.

Дополнительно выполнены замеры для отдачи предварительно сжатых данных.  Результаты показывают, что использования модуля http_gzip_static_module является хорошей альтернативой GZIP сжатию на лету и позволяет существенно увеличить производительность Nginx.

Таким образом, на основе полученных данных можно сделать вывод, что наиболее эффективно будет передавать предварительно сжатые данные с использованием максимального уровнем сжатия. Для сжатия всех имеющихся CSS и JS файлов, необходимо выполнить команду:

for i in `find /home/www/* -type f -name '*.js'`; do echo $i; gzip -c -9 $i > $i.gz; touch -r $i $i.gz; done;
for i in `find /home/www/* -type f -name '*.css'`; do echo $i; gzip -c -9 $i > $i.gz; touch -r $i $i.gz; done;

Для того что бы удалит .gz архивы:

for i in `find /home/www/* -type f -name '*.js.gz'`; do echo $i; rm $i; done;
for i in `find /home/www/* -type f -name '*.css.gz'`; do echo $i; rm $i; done;

Для сжатия динамически создаваемых страниц напротив лучше использовать минимальные параметры уровня сжатия, я рекомендую становить значение параметра gzip_comp_level равным 2.

Рекомендуемые параметры GZIP для Nginx:

gzip on;
gzip_static on;
gzip_comp_level 2;

Установка Nginx с поддержкой HTTP/2

Дата: 14.08.2015Метки:

Завершение разработки протокола HTTP/2 стало первым крупным обновлением HTTP за последние 16 лет. При проектировании HTTP/2 основной фокус был направлен на оптимизацию алгоритмов передачи данных и ускорение загрузки страниц.

В качестве основы для HTTP/2 был взят уже существующий открытый протокол SPDY/3, первую версию которого Google представила в 2009 году. Согласно планам, HTTP/2 должен быстро вытеснить протокол SPDY, став его эволюционным продолжением. Уже в начале 2016 года Google планирует полностью перейти на новый стандарт и отказаться от поддержки SPDY в браузере Chrome.

Недавно была представлен тестовая версия модуля HTTP/2 для Nginx. В данный момент доступна альфа версия патча. Полную поддержку протокола HTTP/2 планируется ввести к концу этого года, а пока все желающие могут протестировать его в своих проектах.

Для сборки Nginx с поддержкой HTTP/2 необходим NGINX 1.9.0 и OpenSSL 1.0.2 или новее.

Добавим в /etc/apt/sources.list официальный репозиторий для mainline-ветки Nginx:

deb http://nginx.org/packages/mainline/debian/ codename nginx
deb-src http://nginx.org/packages/mainline/debian/ codename nginx

Скачиваем и устанавливаем PGP-ключ, затем обновляем индекс пакетов apt:

cd /tmp/ && wget http://nginx.org/keys/nginx_signing.key && apt-key add nginx_signing.key
apt-get update

Скачиваем необходимые для компиляции и сборки пакета программы, устанавливаем зависимости необходимые для Nginx:

apt-get install dpkg-dev
apt-get build-dep nginx

Скачиваем исходники Nginx:

cd /tmp
apt-get source nginx

Страница с патчами HTTP/2 для Nginx. Скачиваем патч HTTP/2 для нашей версии Nginx, проверяем возможность применения и если нет ошибок, по устанавливаем патч:

cd /tmp/nginx-1.9.3
wget http://nginx.org/patches/http2/patch.http2.txt
patch -p1 --dry-run < patch.http2.txt
patch -p1 < patch.http2.txt

Скачиваем и распаковываем исходники OpenSSL:

cd /tmp
wget https://openssl.org/source/openssl-1.0.2d.tar.gz
tar ixzvf openssl-1.0.2d.tar.gz

Перед началом сборки и компиляции необходимо внести изменения в файл:

nano /tmp/nginx-1.9.3/debian/rules

В секциях override_dh_auto_build и configure_debug необходимо удалить строку $(WITH_SPDY) и добавить в конец следующие опции:

--with-http_v2_module 
--with-openssl=/tmp/openssl-1.0.2

Для примера привожу фрагмент с изменениями из моего файла:

override_dh_auto_build:
	dh_auto_build
	mv objs/nginx objs/nginx.debug
	CFLAGS="" ./configure 
		--prefix=/etc/nginx 
		--sbin-path=/usr/sbin/nginx 
		--conf-path=/etc/nginx/nginx.conf 
		--error-log-path=/var/log/nginx/error.log 
		--http-log-path=/var/log/nginx/access.log 
		--pid-path=/var/run/nginx.pid 
		--lock-path=/var/run/nginx.lock 
		--http-client-body-temp-path=/var/cache/nginx/client_temp 
		--http-proxy-temp-path=/var/cache/nginx/proxy_temp 
		--http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp 
		--http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp 
		--http-scgi-temp-path=/var/cache/nginx/scgi_temp 
		--user=nginx 
		--group=nginx 
		--with-http_ssl_module 
		--with-http_gzip_static_module 
		--with-threads 
		--with-file-aio 
		--with-cc-opt="$(CFLAGS)" 
		--with-ld-opt="$(LDFLAGS)" 
		--with-ipv6 
		--with-http_v2_module 
		--with-openssl=/tmp/openssl-1.0.2
	dh_auto_build

После чего выполняем компиляцию и сборку deb-пакета:

cd /tmp/nginx-1.9.3
dpkg-buildpackage -rfakeroot -uc -b

После сборки пакета, установим Nginx командой:

dpkg -i nginx_1.9.3-1~jessie_i386.deb

Для включения поддержки HTTP/2 добавьте в конфигурационный файл Nginx вашего сайта параметры ssl и http2 к директивам listen:

server {
    listen 443 ssl http2 default_server;

    ssl_certificate     server.crt;
    ssl_certificate_key server.key;
    ...
}

На момент написания статьи в браузерах не реализована поддержка HTTP/2 без SSL шифрования, поэтому параметр ssl является обязательным. Как вариант — можно создать самоподписанный сертификат.

На данный момент статья частично потеряла свою актуальность, Начиная с версии Nginx 1.9.5 присутствует встроенная поддержка протокола. Информация о том как включить HTTP/2 в Nginx.

Установка Nginx из исходников

Дата: 13.08.2015Метки:

Как правило, в стандартных репозиториях Debian находится устаревшая версия пакета Nginx. Для того чтобы установить последнюю стабильную версию и включить автоматическое обновление пакетов, рекомендуется использовать официальный репозиторий Nginx.

Для более тонкой настройки и выбора модулей, которые войдут в состав сборки, я предпочитаю самостоятельно собирать Nginx из исходников. При необходимости у меня всегда есть проверенный и настроенный под себя deb-пакет Nginx, а в случае каких-либо проблем, всегда есть возможность откатится до предыдущей сборки.

Несмотря на очевидные преимущества, у данного варианта есть и свои недостатки. Приходится самостоятельно следить за выходом обновлений и при необходимости повторно собирать пакет.

Для того что бы не засорять систему ненужными пакетами, компиляцию и сборку deb-пакета я предпочитаю выполнять на виртуальной машине, после чего для установки необходимо просто перенести deb-пакет на сервер.

Для начала необходимо добавить официальный репозиторией Nginx. Для Debian замените codename на кодовое имя дистрибутива, и добавьте в конец файла /etc/apt/sources.list строки:

Для mainline-ветки.

deb http://nginx.org/packages/mainline/debian/ codename nginx
deb-src http://nginx.org/packages/mainline/debian/ codename nginx

Или для стабильной ветки.

deb http://nginx.org/packages/debian/ codename nginx
deb-src http://nginx.org/packages/debian/ codename nginx

Для проверки подлинности подписи репозитория Nginx, скачиваем PGP-ключ и устанавливаем его в связку ключей программы apt:

cd /tmp/ && wget http://nginx.org/keys/nginx_signing.key && apt-key add nginx_signing.key

Для обновления индекса пакетов выполним команду:

apt-get update

Выполним установку необходимых для компиляции и сборки программ, установим все необходимые зависимости для nginx:

apt-get install dpkg-dev
apt-get build-dep nginx
apt-get install libxslt1-dev libgd2-dev libgeoip-dev

На момент написания поста, я использовал последнюю версию nginx-1.9.3. Для сборки deb-пакета скачиваем с официального репозитория исходники Nginx:

cd /tmp
apt-get source nginx

Для того что бы изменить параметры компиляции, добавить или удалить модули Nginx, необходимо отредактировать файл:

nano /tmp/nginx-1.9.3/debian/rules

Нас интересует содержимое секции override_dh_auto_build. Здесь мы можем включить в сборку необходимы нам модули или удалить ненужные. Ниже приведен пример используемой мной конфигурация:

override_dh_auto_build:
	dh_auto_build
	mv objs/nginx objs/nginx.debug
	CFLAGS="" ./configure 
		--prefix=/etc/nginx 
		--sbin-path=/usr/sbin/nginx 
		--conf-path=/etc/nginx/nginx.conf 
		--error-log-path=/var/log/nginx/error.log 
		--http-log-path=/var/log/nginx/access.log 
		--pid-path=/var/run/nginx.pid 
		--lock-path=/var/run/nginx.lock 
		--http-client-body-temp-path=/var/cache/nginx/client_temp 
		--http-proxy-temp-path=/var/cache/nginx/proxy_temp 
		--http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp 
		--http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp 
		--http-scgi-temp-path=/var/cache/nginx/scgi_temp 
		--user=nginx 
		--group=nginx 
		--with-http_ssl_module 
		--with-http_gzip_static_module 
		--with-threads 
		--with-file-aio 
		$(WITH_SPDY) 
		--with-cc-opt="$(CFLAGS)" 
		--with-ld-opt="$(LDFLAGS)" 
		--with-ipv6
	dh_auto_build

После того как все необходимы настройки сделаны, можно начинать компиляцию и сборку пакета:

cd /tmp/nginx-1.9.3
dpkg-buildpackage -rfakeroot -uc -b

Если в процессе не было ошибок, в каталоге /tmp мы увидим собранный из исходников deb-пакет nginx_1.9.3-1~jessie_i386.deb. Для его установки необходимо выполнить команду:

dpkg -i nginx_1.9.3-1~jessie_i386.deb

 

Обновление 07.03.16
Начиная с версии Nginx 1.9.11 используется поддержка динамических модулей. Связи с чем в процессе сборки пакета произошли изменения. При отключении некоторых модулей процесс сборки может завершаться ошибкой.

Установка сертификатов StartSSL

Дата: 05.08.2015Метки:

Данная статья предполагает, что мы уже успешно прошли процедуру регистрации на сайте StartSSL и в нашем распоряжении есть следующие файлы: сертификат ssl.crt с проверкой домена и приватный ключ ssl.key. Копируем эти два файла на сервер. Приватный ключ перед использованием необходимо расшифровать командой:

openssl rsa -in ssl.key -out private.key

На этом этапе необходимо будет ввести пароль, который мы указывали в процессе заказа сертификата на сайте StartSSL.

Для безопасности установим права доступа на private.key:

# Только владелец может читать файл
chmod 400 /etc/nginx/ssl/*

Скачиваем сертификат Class 1 Intermediate Server CA:

wget http://www.startssl.com/certs/sub.class1.server.ca.pem

Объединяем сертификаты в один файл:

cat ssl.crt sub.class1.server.ca.pem > domain.pem

Минимальная конфигурацию NGINX для проверки работы SSL:

server {
    listen       443 ssl;
    server_name  domain.net;

    ssl_certificate      /etc/nginx/ssl/domain_com/domain.pem;
    ssl_certificate_key  /etc/nginx/ssl/domain_com/domain.key;

    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
    }
}

После изменения настроек необходимо перезапустить NGINX:

service nginx restart

Для проверки правильности установки сертификатов используем сервис Symantec SSL Toolbox.