Получение сертификата Let’s Encrypt

Ранее мною была подана заявка на участие в тестировании сервиса выдачи бесплатных SSL сертификатов Let’s Encrypt. И вот сегодня, наконец-то пришло письмо о том что я могу принять участие в тестировании и получить сертификат для указанного в заявке домена.

На данный момент процесс закрытого бета-тестирования Let’s Encrypt закончен и любой желающий может создать сертификат для своего сайта.

В этой статье я опишу процесс создания и автоматического продления сертификатов с помощью сервиса Let’s Encrypt. Я использую Nginx на всех своих сайтах, поэтому, инструкция рассчитана под использование именно этого веб-сервера.

Для автоматизации получения сертификата, Let’s Encrypt использует ACME — специальный клиент написанный на Perl. Все действия осуществляются непосредственно через консоль и после получения сертификата, дальнейшее его продление будет проходить полностью в автоматическом режиме.

Для создания сертификатов использовалась виртуальная машина с OS Debian 8.2, но вы можете использовать любой другой Linux дистрибутив по своему усмотрению.

Перед тем как перейти к процессу создания сертификатов Let’s Encrypt, необходимо определится с расположением файлов ACME. Клиент нам понадобится в дальнейшем для продления сертификатов.

В моем случае ACME будет расположен в директории home:

cd /home

Если следовать официальной инструкции, для загрузки ACME необходимо установить клиент Git:

# apt-get install git

После чего загрузить файлы командой:

# git clone https://github.com/letsencrypt/letsencrypt
# cd letsencrypt

Как альтернативный вариант, я предлагаю просто скачать zip-архив ACME с официального репозитория GitHub.

# wget https://github.com/letsencrypt/letsencrypt/archive/master.zip

Извлекаем архив и переходим в каталог с файлами:

# unzip master.zip
# mv letsencrypt-master letsencrypt
# cd letsencrypt

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

server {
        listen 80;
        server_name test.codebeer.ru;

        root /var/www/test.codebeer.ru;

        location '/.well-known/acme-challenge' {
            default_type "text/plain";
            alias /tmp/letsencrypt-auto';
        }
}

Для уже существующего сайта, нужно добавить в секцию server алиас:

location '/.well-known/acme-challenge' {
    default_type "text/plain";
    alias /tmp/letsencrypt-auto';
}

Создание сертификата Let’s Encrypt

Есть несколько параметров запуска клиента Let’s Encrypt. Подробнее о каждом из них можно прочитать на странице официальной документации. Чтобы создать сертификат, просто выполните команды ниже:

# export DOMAINS="-d test.codebeer.ru -d www.test.codebeer.ru"
# export DIR=/tmp/letsencrypt-auto
# mkdir -p $DIR
# ./letsencrypt-auto certonly --server https://acme-v01.api.letsencrypt.org/directory -a webroot --webroot-path=$DIR --agree-dev-preview $DOMAINS

Не забудьте заменить названия доменов на свои.

В процессе генерации сертификата Let’s Encrypt необходимо будет указать email:

Enter email address (used for urgent notices and lost key recovery)

Примите условия использования:

Please read the Terms of Service at
https://letsencrypt.org/documents/LE-SA-v1.0.1-July-27-2015.pdf. You 
must agree in order to register with the ACME server at
https://acme-staging.api.letsencrypt.org/directory

Соглашаемся на сохранение вашего адреса в логах Let’s Encrypt:

NOTE: The IP of this machine will be publicly logged as having
requested this certificate. If you're running letsencrypt in manual
mode on a machine that is not your server, please ensure you're okay
with that.

Are you OK with your IP being logged?

Если проверка прошла успешно, то вы увидите следующее сообщение:

IMPORTANT NOTES:
- Congratulations! Your certificate and chain have been saved at
/etc/letsencrypt/live/test.codebeer.ru/fullchain.pem. Your cert
will expire on 2016-03-06. To obtain a new version of the
certificate in the future, simply run Let's Encrypt again.
- If like Let's Encrypt, please consider supporting our work by:

Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate
Donating to EFF: https://eff.org/donate-le

Сгенерированный сертификат и ключи для нашего домена будет расположены в папке:

/etc/letsencrypt/live/test.codebeer.ru/

Не меняя расположение, вам необходимо указать путь к файлам в настройка Nginx или другого веб-сервера.

Продление сертификата Let’s Encrypt

Все сертификаты Let’s Encrypt имеют срок действия равный 90 дней. Поэтому, обновлять вручную сертификаты каждые 3 месяца не совсем удобно. По словам представителей Let’s Encrypt, время жизни сертификата в будущем может быть уменьшено.

Чтобы автоматизировать процесс продления сертификата, необходимо добавить в cron скрипт:

export DOMAINS="-d test.codebeer.ru -d www.test.codebeer.ru"
export DIR=/tmp/letsencrypt-auto
mkdir -p $DIR
/home/letsencrypt/letsencrypt-auto --renew certonly --server https://acme-v01.api.letsencrypt.org/directory -a webroot --webroot-path=$DIR --agree-dev-preview $DOMAINS
service nginx restart

Защита WordPress в Nginx

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

Используя стандартные архитектурные особенности движка WordPrees и популярных плагинов, злоумышленники путем специально сформированного запроса могут получить информацию о версии используемой СMS и используемых плагинов. Для того чтобы на основе этой информации использовать известные уязвимости в плагинах или устаревшей версии WordPress.

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

Защита WordPress в Nginx

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

  • Каталог wp-includes. Содержит в себе все основные и необходимые файлы для работы фронтэнда WordPress. Папка содержит файлы PHP, CSS и JavaScript, которые обеспечивают основные функции WordPress.
  • Каталоги uploads, themes и plugins, которые находятся в папке wp-content. Папки используются для загрузки изображений, шаблонов и плагинов WordPress.

Запретить доступ к php-файлам в wp-includes

Чтобы запретить доступ к php-файлам wp-includes, необходимо использовать следующие правила в настройках Nginx:

location ~* /wp-includes/.*.php$ {
	deny all;
	access_log off;
	log_not_found off;
}

Этот каталог всегда расположен в корне WordPress, изменять название или расположение не рекомендуется.

Запретить доступ к php-файлам в wp-content

Чтобы запретить доступ к php-файлам wp-content, необходимо использовать следующие правила в настройках Nginx:

location ~* /wp-content/.*.php$ {
	deny all;
	access_log off;
	log_not_found off;
}

При желании вы можете изменить расположение каталога wp-content, для этого необходимо использовать параметры WP_CONTENT_DIR и WP_CONTENT_URL в файле wp-config.php

Запретить доступ к php-файлам в папке uploads

Чтобы запретить выполнение php-файлов в каталоге загрузок wp-content, следующие правила в настройках в настройках Nginx:

location ~* /(?:uploads|files)/.*.php$ {
	deny all;
	access_log off;
	log_not_found off;
}

По умолчанию каталог с загружаемыми файлами расположен в wp-content, но при желании может быть изменен в настройка WordPress.

Запретить доступ к php-файлам в папках themes и plugins

Чтобы запретить доступ к php-файлам шаблона и плагинов, необходимо добавить соответствующие правила в настройках Nginx.

Для каталога шаблонов:

location ~* /themes/.*.php$ {
	deny all;
	access_log off;
	log_not_found off;
}

Для каталога плагинов:

location ~* /plugins/.*.php$ {
	deny all;
	access_log off;
	log_not_found off;
}

Каталоги шаблонов и плагинов WordPress расположены в папке wp-content и имеют название themes и plugins соответственно. Вы можете самостоятельно задать расположение папки плагинов, задав параметры WP_PLUGIN_DIR и WP_PLUGIN_URL. Для того чтобы изменить расположение файлов темы, необходимо использовать функцию register_theme_directory().

Запретить доступ к xmlrpc.php

Если вы не используете XML-RPC, можно закрыть все запросы к этому файлу в Nginx:

location = /xmlrpc.php {
	deny all;
	access_log off;
	log_not_found off;
}

Настройка PageSpeed в Nginx

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

Ранее я уже описывал процесс установки Nginx с поддержкой модуля ngx_pagespeed из исходников. В этой статье я опишу процесс настройки параметров PageSpeed для Nginx. Модуль PageSpeed представляет собой набор фильтров для оптимизации и ускорения загрузки страниц и связанных с ними объектов: CSS, JavaScript, изображений.

Модуль PageSpeed имеет большое количество настроек для оптимизации содержимого страницы, которые дальше я буду называть фильтрами. Для удобства управления модулем, фильтры в PageSpeed объединены в логические структуры — уровни, которые можно задать с помощью параметра RewriteLevel.

Описание настроек PageSpeed

В зависимости от требуемого функционала модуля Nginx PageSpeed, с помощью директивы RewriteLevel мы можем задать три основных уровня его работы: CoreFilters, OptimizeForBandwidth и PassThrough.

  • CoreFilters — задает максимальный набор фильтров, которые по мнению разработчиков, подойдут для работы большинства сайтов;
  • OptimizeForBandwidth — задает минимальный набор фильтров, которые в основном ограничены оптимизацией внешних CSS и JavaScript файлов страницы;
  • PassThrough — «сквозной режим», данный уровень настройки полностью отключает все используемые фильтры PageSpeed.

Каждый из перечисленных уровней оптимизации, содержит стандартный набор фильтров для работы PageSpeed. Поэтому, вместо того чтобы самостоятельно перечислять все необходимые фильтры в конфиге Nginx, сначала укажем параметр RewriteLevel, а затем уже дополним его своими фильтрами.

Для того чтобы понять, какие фильтры уже содержат CoreFilters и OptimizeForBandwidth, а какие нужно добавить самостоятельно, необходимо использовать таблицу RewriteLevel.

С помощью EnableFilters или ForbidFilters можно  добавить или удалить выбранные фильтры. Директивы позволяют указать в качестве параметра название одного или нескольких разделенных запятыми фильтров:

pagespeed EnableFilters rewrite_css,rewrite_javascript;
pagespeed DisableFilters rewrite_css,rewrite_javascript;

Настройка PageSpeed в Nginx

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

Откройте файл nginx.conf:

nano /etc/nginx/nginx.conf

Чтобы включить PageSpeed в Nginx и задать параметры кэширования, необходимо указать следующие настройки:

pagespeed on;
# Путь к каталогу кэша
pagespeed FileCachePath "/var/run/pagespeed-cache/";
# Максимальный размер кэша
pagespeed FileCacheSizeKb 102400;
# Интервал для очистки кэша
pagespeed FileCacheCleanIntervalMs 360000;
# Максимальное количество дескрипторов
pagespeed FileCacheInodeLimit 500000;

Для улучшения производительность Nginx, мы будем хранить файлы кэша PageSpeed на RAM-диске. В Debian можно использовать каталог /var/run, который смонтирован в оперативной памяти как tmpfs. Размер кэша зависит от количества свободной памяти в системе.

Процедура очистки кэша запускается через заданный в FileCacheCleanIntervalMs промежуток времени, если его размер превышает значение FileCacheSizeKb или количество используемых дескрипторов приблизилось к предельному значению FileCacheInodeLimit.

Далее необходимо настроить фильтры PageSpeed для нашего сайта. Откройте конфигурационный файл виртуального хоста Nginx:

nano /etc/nginx/sites-enabled/default.conf

Мы задаем для RewriteLevel шаблон CoreFilters, который затем дополняем своими фильтрами:

server {
    listen       80;
    server_name  example.com;

    root   /www/example/html/;
    index  index.html index.htm;
    }

    # Настройки фильтров
    pagespeed RewriteLevel CoreFilters;
    pagespeed EnableFilters collapse_whitespace,remove_comments;
    pagespeed DisableFilters rewrite_images;
    # Адрес и директория сайта
    pagespeed LoadFromFile "http://example.com/" "/www/example/html/";
}

Дополнительно к CoreFilters, мы добавляем фильтры для минификации и удаления комментариев из HTML-кода страницы. Чтобы снизить нагрузку на сервер, я отключил фильтр для сжатия изображений, который по умолчанию включен в CoreFilters. Вы можете добавить или отключить любые фильтры по своему усмотрению. В процессе настройки PageSpeed, будет полезна таблица с описанием фильтров.

Следует отметить, что для оптимизации CSS и JavaScript файлов, необходимо в директиве LoadFromFile указать адрес и путь к каталогу вашего сайта.

Проверяем конфигурацию Nginx и применяем настройки:

nginx -t
service nginx reload

Для проверки работы PageSpeed, необходимо предварительно очистить кэш браузера. Для Chrome можно использовать горячие клавиши Ctrl + F5.

Из своего опыта, могу отметить следующее. Фильтры rewrite_css и combine_javascript не всегда объединяют несколько файлов в один. Но можно убедиться, что данные фильтры работают, если загрузить на сервер специально подготовленную страницу.

Включить HTTP/2 в Nginx

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

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

Добавим в /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-ключ и обновляем индекс пакетов:

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

После установки необходимо проверить, что Nginx собран с поддержкой модуля HTTP/2, для этого используем команду ниже:

# nginx -V
nginx version: nginx/1.9.5
built by gcc 4.9.2 (Debian 4.9.2-10)
built with OpenSSL 1.0.1k 8 Jan 2015
TLS SNI support enabled
configure arguments: --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-threads --with-file-aio --with-http_v2_module --with-cc-opt='-g -O2 -fstack-protector-strong -Wformat -Werror=format-security' --with-ld-opt=-Wl,-z,relro

Команда выведет информацию о параметрах сборки Nginx. Нас интересует опция --with-http_v2_module, которая указывает на поддержку протокола. Что бы включить поддержку HTTP/2 в Nginx, необходимо изменить параметр listen как указано в примере ниже:

listen 443 ssl http2;

Применяем настройки в Nginx:

nginx -t && service nginx reload

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

Установка Nginx с поддержкой PageSpeed

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

Основная функция использования модуля ngx_pagespeed — автоматическая оптимизации сайта с целью увеличения отзывчивости и пропускной способности при отдаче контента. Среди основных функций поддерживаемых модулем ngx_pagespeed: оптимизация страницы и всех связанных с ней CSS, JavaScript файлов, объединение нескольких файлов в один, уменьшение разрешения и сжатие изображений, оптимизация использования заголовков Expires, Cache-Control и Last-Modified.

Использование модуля ngx_pagespeed не требует изменения содержимого сайта, все преобразования выполняются на лету. Для снижения нагрузки на сервер PageSpeed использует встроенный механизм кэширования.

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

Вначале необходимо установить все необходимы для сборки пакеты:

apt-get install build-essential zlib1g-dev libpcre3 libpcre3-dev unzip

Скачиваем скачиваем и распаковываем файлы модуля PageSpeed:

cd /usr/src
wget https://github.com/pagespeed/ngx_pagespeed/archive/release-1.9.32.6-beta.zip
unzip release-1.9.32.6-beta.zip
cd ngx_pagespeed-release-1.9.32.6-beta
wget https://dl.google.com/dl/page-speed/psol/1.9.32.6.tar.gz
tar -xzvf 1.9.32.6.tar.gz

Добавим в файл /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

Устанавливаем пакет dpkg-dev и все необходимые для сборки Nginx зависимости:

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

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

cd /usr/src
apt-get source nginx

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

nano /tmp/nginx-1.9.3/debian/rules

Необходимо добавить путь к исходникам ngx_pagespeed в содержимое секций override_dh_auto_build и configure_debug:

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-threads 
                --with-file-aio 
                $(WITH_SPDY) 
                --with-cc-opt="$(CFLAGS)" 
                --with-ld-opt="$(LDFLAGS)" 
                --add-module=/usr/src/ngx_pagespeed-release-1.9.32.6-beta
        dh_auto_build

Переходим к компиляции и сборку deb-пакета Nginx:

cd /usr/src/nginx-1.9.4
dpkg-buildpackage -rfakeroot -uc -b

Если в процессе не было ошибок, то в рабочем каталоге мы увидим собранные deb-пакеты Nginx. Перенесем их на рабочий сервер и выполним установку командой:

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

На этом процесс установки Nginx с поддержкой модуля ngx_pagespeed. Для проверки работы модуля PageSpeed, необходимо открыть конфигурационный файл Nginx:

nano /etc/nginx/nginx.conf

В секцию http необходимо добавить настройки ниже:

http {
pagespeed On;
# Указываем расположение кэша
pagespeed FileCachePath "/var/cache/ngx_pagespeed/";
}

Проверяем конфигурацию и применяем настройки Nginx:

nginx -t && service nginx reload

В следующей записи я подробнее опишу процесс настройки модуля PageSpeed в Nginx.

Определяем MIME-типы для файлов сайта

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

При настройке веб-сервера или прокси, часто возникает необходимость указать список MIME-типов используемых на конкретном сайте. С данным вопросом я часто сталкиваюсь в процессе настройки GZIP на Nginx, когда необходимо указать список MIME-типов для файлов, которые будут передаваться клиенту в сжатом виде. Также список MIME-типов может потребоваться при настройке различных фильтров в SQUID.

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

После установки HttpWatch автоматически интегрируется с браузерами Internet Explorer и Firefox. После чего с помощью HttpWatch можно просмотреть весь HTTP и HTTPS трафик генерируемый во время доступа к веб-странице. Для запуска инструмента необходимо Firefox, после чего выбрать «HttpWatch» в контекстном меню браузера. Затем необходимо нажать кнопку «Record» и открыть адрес анализируемой страницы. Для просмотра MIME-типа для каждого из загруженных сайтов, необходимо навести курсор на иконку расположенную в столбце «Type».

Настройка Nginx fastcgi_cache для WordPress

Как показывает опыт, только лишь с помощью утилиты ApacheBench можно положить WordPress на среднестатистическом VPS. Проблема заключается том, что в большинстве случаев PHP является узким местом в работе веб-сервера. Использование OPCache позволяет значительно ускорить работу PHP скриптов, но это не изменить ситуацию, когда при высокой посещаемости скрипты будут создавать серьезную нагрузку на CPU.

Связи с чем, на высоконагруженных сайтах приходится использовать кеш в CDN или устанавливать дополнительные плагины для кэширования страниц в WordPress. Я предлагаю более практичный и удобный вариант — использовать внутреннее кэширование Nginx fastcgi_cache. После чего производительность веб-сервера возрастает в десятки раз.

Главный недостаток использования fastcgi_cache — отсутствие встроенного механизма для удаления из кэша потерявших свою актуальность страниц. Зато данная проблема легко решается за счет использования специального плагина для WordPress, который при наличии изменений на сайте будет давать команду Nginx очищать кэш.

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

nginx -V 2>&1 | grep nginx-cache-purge -o

В результате выполнения команды вы должны увидеть следующее:

nginx-cache-purge

В противном случае необходимо установить Nginx c поддержкой с поддержкой модуля fastcgi_cache_purge. В зависимости от потребностей вашего сайта, можно вообще отказаться от данной функции. Для этого необходимо убрать из конфигурационного файла Nginx секцию location ~ /purge(/.*).

Для того чтобы дать сигнал Nginx какая страница была изменена, мы будем использовать WordPress плагин Nginx Helper. После каждого обновления записи он автоматически даст команду Nginx удалить страницу из кэша. После активации плагина в настройках необходимо включить опцию «Enable Cache Purge» и задать соответствующие правила.

Если на вашем сервере достаточно свободной памяти, то я рекомендую использовать ramdisk для хранения содержимого fastcgi_cache. На серверах с Debian или Ubuntu кэша рекомендуется использовать смонтированный как tmpfs в RAM каталог /var/run. При этом следует учитывать, что по умолчанию для него зарезервировано 20% от используемой в системе RAM.

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

df -h /var/run

Результат выполнения команды:

Filesystem      Size  Used Avail Use% Mounted on
tmpfs           2.1G  316K  2.1G   1% /run

В моем случае, для использования fastcgi_cache можно выделить до 2Гб памяти.

Обычно под fastcgi_cache я выделяю 100Мб памяти, время жизни страниц в кэше устанавливаю равным 60 минутам. обычно эти настройки подбираются опытным путем на основе конкретного сайта и характеристик сервера. Для использования fastcgi_cache в Nginx необходимо добавить в конфигурационный файл /etc/nginx/nginx.conf следующие настройки:

fastcgi_cache_path /var/run/nginx-cache levels=1:2 keys_zone=WORDPRESS:100m inactive=60m;
fastcgi_cache_key "$scheme$request_method$host$request_uri";
fastcgi_cache_use_stale error timeout invalid_header http_500;
fastcgi_ignore_headers Cache-Control Expires Set-Cookie;

Отдельно следует уделить внимание опции fastcgi_cache_use_stale, она указывает веб-серверу что если PHP перестанет отвечать, Nginx должен отдать страницу из кэша.

Секция server описывающая настройки сайта, должна выглядеть следующим образом:

server {
	server_name example.com www.example.com;

	root /usr/local/nginx/html;
	index index.php index.html;

	set $skip_cache 0;

	# Отключаем кэш для POST-запросов
	if ($request_method = POST) {
		set $skip_cache 1;
	}   
	if ($query_string != "") {
		set $skip_cache 1;
	}   

	# Не кэшировать страницы админки, rss и sitemap
	if ($request_uri ~* "/wp-admin/|/xmlrpc.php|wp-.*.php|/feed/|index.php|sitemap(_index)?.xml") {
		set $skip_cache 1;
	}   

	# Отключить кэш для пользователей прошедших авторизацию или оставивших комментарий
	if ($http_cookie ~* "comment_author|wordpress_[a-f0-9]+|wp-postpass|wordpress_no_cache|wordpress_logged_in") {
		set $skip_cache 1;
	}

	location / {
		try_files $uri $uri/ /index.php?$args;
	}    

	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;
		include fastcgi_params;

		fastcgi_cache_bypass $skip_cache;
	        fastcgi_no_cache $skip_cache;
		fastcgi_cache WORDPRESS;
		fastcgi_cache_valid 60m;
	}

	location ~ /purge(/.*) {
	    fastcgi_cache_purge WORDPRESS "$scheme$request_method$host$1";
	}	

}

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

nginx -t
service nginx reload

Для проверки работы кэширования необходимо открыть Chrome в режиме инкогнито, открытые в браузеры страницы должны попасть в кэш Nginx. Для проверки содержимого fastcgi_cache используем команду:

ls -la /var/run/nginx-cache

Закрываем доступ к админке 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, тИЦ и всей ссылочной массы сайта. В результате, позиции сайта после повторной индексации останутся на прежнем уровне.