Проксирование в Nginx

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

Простой пример конфига Nginx для проксирования HTTP трафика. Смысл заключается в том, что бы перенаправить запросы с frontend сервера, который у меня обозначен как 1.1.1.1 на back-end сервер 2.2.2.2. Дополнительно мы включаем кэширование, что позволяет существенно снизить нагрузку на сервер.

Для начала кратко напишу про настройки кэширования Nginx. В proxy_cache_path мы указываем расположение кэша. Для максимальной производительности я буду хранить его в оперативной памяти. Параметр levels задаёт уровни иерархии кэша. В нашем случае файлы будут сохранятся в каталог по аналогии примеру ниже:

/var/run/proxy_cache/c/29/b7f54b2df7773722d382f4809d65029c

Далее мы указываем имя зоны, время хранения файлов и размер кэша. Если к данным не обращаться более 8 минут, то закэшированные элементы будут удалены. Директива proxy_cache_key используется для создания схемы идентификации — оставляем без изменений. В proxy_cache_valid задаем время кэширования кодов ответа.

В директивах listen 1.1.1.1:80 и server_name proxy.com мы указываем ip-адрес и доменное имя сервера на котором запущен Nginx. После чего proxy_pass указываем адрес сервера на который будут передаваться запросы.

proxy_cache_path /var/run/proxy_cache levels=1:2 keys_zone=backcache:8m max_size=100m;
proxy_cache_key "$scheme$request_method$host$request_uri$is_args$args";
proxy_cache_valid 200 302 10m;
proxy_cache_valid 404 1m;

server {
    listen 1.1.1.1:80;
    server_name proxy.com;

    location / {
        proxy_pass http://2.2.2.2;

        proxy_set_header HOST $host;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

        proxy_cache backcache;
        proxy_cache_bypass $http_cache_control;
        add_header X-Proxy-Cache $upstream_cache_status;
    }
}

Включаем поддержку Brotli в Nginx

Этот алгоритм сжатия появился совсем недавно, связи с чем о использовании Brotli еще мало упоминаний в сети. Для начала необходимо упомянуть о том, что этот Brotli из себя представляет. Если кратко, Brotli — алгоритм сжатия данных основанный на современном варианте алгоритма LZ77. Brotli был разработан и представлен компанией Google в 2015 году как специализированный алгоритм для сжатия веб-шрифтов. В дальнейшем была представлена версия Brotli, которая содержала улучшения направленные на сжатие всего интернет-трафика (HTML, CSS, JS).

Сейчас момент Brotli используют для ускорения загрузки веб-страниц, его поддержка включена по умолчанию в Chrome 51+, Firefox 47+ и мобильным Chrome. По сравнению с gzip, алгоритм Brotli показывает сравнимую скорость, но при этом имеет лучшие показатели сжатия данных. Следует отметить, что Brotli несовместим с gzip и работает только для HTTPS-ресурсов.

На данный момент нет официального модуля для поддержки Brotli в Nginx. Зато мы имеем возможность использовать сторонние модули, которые параллельно развиваются Google и Cloudflare. В данном посте я расскажу о сборке Nginx с включенным модулем Brotli от Cloudflare. Если интересно, то исчерпывающую информацию по работе алгоритма Brotli можно найти в блоге Cloudflare.

Процесс аналогичен сборке Nginx с любыми другими модулями. Для начала необходимо скачать исходники 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-ключ, после чего не забудьте обновить индекс пакетов 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
apt-get install git autoconf libtool

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

cd /usr/src
apt-get source nginx

Получаем код модуля ngx_brotli_module:

git clone https://github.com/cloudflare/ngx_brotli_module.git

В каталог с модулем ngx_brotli_module необходимо загрузит исходники библиотеки libbrotli:

cd /usr/src/ngx_brotli_module
git clone https://github.com/google/brotli.git

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

nano /usr/src/nginx-1.11.5/debian/rules

Необходимо добавить путь к исходникам ngx_brotli_module в содержимое переменно CFLAGS:

config.status.nginx: config.env.nginx
        cd $(BUILDDIR_nginx) && \
        CFLAGS="" ./configure --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib/nginx/modules --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-compat --with-file-aio --with-threads --with-http_addition_module --with-http_auth_request_module --with-http_dav_module --with-http_flv_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_mp4_module --with-http_random_index_module --with-http_realip_module --with-http_secure_link_module --with-http_slice_module --with-http_ssl_module --with-http_stub_status_module --with-http_sub_module --with-http_v2_module --with-mail --with-mail_ssl_module --with-stream --with-stream_realip_module --with-stream_ssl_module --with-stream_ssl_preread_module --add-module=/usr/src/ngx_brotli_module --with-cc-opt="$(CFLAGS)" --with-ld-opt="$(LDFLAGS)"
        touch $@

Дополнительно рекомендую собрать Nginx c поддержкой APLN. Переходим к компиляции и сборке deb-пакета Nginx:

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

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

Для активации режима сжатия Brotli указываем следующие параметры:

brotli on;
# уровень компрессии от 1 до 11
brotli_comp_level 6;
# минимальный размер файла для использования сжатия
brotli_min_length Num;

Когда Brotli включен, он получает приоритет наl gzip, если браузер не поддерживает Brotli, данные сжимаются при помощи gzip. Теперь остается только проверить поддерживает ли наш сайт сжатие Brotli с помощью онлайн сервиса Brotli Test.

Сборка rpm пакета Nginx в Centos 7

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

Основной недостаток установки программ при помощи make install — это неудобное управление. Вместо этого мы рассмотрим сборку rpm пакетов из исходников. Все действия я буду производить в дистрибутиве CentOS 7, а в качестве примера буду использовать Nginx 1.11.3.

Устанавливаем все необходимое для сборки и компиляции:

yum groupinstall -y "Development Tools" && yum install rpmdevtools nano yum-utils

Собирать пакеты можно из-под любого пользователя, но делать это из-под root не рекомендуется. Создадим для сборки пакета пользователя builder:

useradd builder
usermod -a -G builder builder

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

rpmdev-setuptree

Для настройки репозитория yum необходимо создать файл:

nano /etc/yum.repos.d/nginx.repo

Копируем в файл следующие строки:

[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/mainline/centos/7/$basearch/
gpgcheck=0
enabled=1

[nginx-source]
name=nginx source repo
baseurl=http://nginx.org/packages/mainline/centos/7/SRPMS/
gpgcheck=1
enabled=0
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7

Загружаем пакет с исходниками и запускаем установку rmp:

cd /tmp
yumdownloader --source nginx
rpm -Uvh nginx*.src.rpm

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

yum-builddep nginx

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

cd /usr/src/
wget https://www.openssl.org/source/openssl-1.0.2h.tar.gz
tar -xvzf openssl-1.0.2h.tar.gz

В параметрах сборки необходимо указать путь к исходникам OpenSSL:

nano ~/rpmbuild/SPECS/nginx.spec

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

--with-http_slice_module \
--with-mail \
--with-mail_ssl_module \
--with-file-aio \
--with-ipv6 \
--with-openssl=/usr/src/openssl-1.0.2h \

Запускаем сборку пакета:

cd ~/rpmbuild/SPECS/
rpmbuild -ba nginx.spec

После завершения сборки переносим rpm из папки:

cd ~/rpmbuild/RPM/
ls
nginx-1.11.3-1.el7.centos.ngx.x86_64.rpm
nginx-debuginfo-1.11.3-1.el7.centos.ngx.x86_64.rpm
nginx-module-geoip-1.11.3-1.el7.centos.ngx.x86_64.rpm
nginx-module-image-filter-1.11.3-1.el7.centos.ngx.x86_64.rpm
nginx-module-njs-1.11.3.0.1.0-1.el7.centos.ngx.x86_64.rpm
nginx-module-perl-1.11.3-1.el7.centos.ngx.x86_64.rpm
nginx-module-xslt-1.11.3-1.el7.centos.ngx.x86_64.rpm

И запускаем установку командой:

rpm -Uvh nginx*.rpm

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

В данной записи речь пойдет о настройке поддержки протокола APLN в Nginx. Чтобы понять для чего это все нужно, немного углубимся в тонкости работы HTTP/2. Для переключения с TLS на HTTP/2, браузер и веб-сервер должны выполнить процедуру проверки поддержки соответствующего протокола. До недавнего времени браузер Chrome мог использовать два существующих для этих целей протокола: NPN и APLN. Но связи с тем, что NPN устарел, в Google решили полностью выпилить поддержку этого протокола из Chrome.

Как это касается вас? На данный момент в репозиториях Debian и Ubuntu (и многих других дистрибутивов) находится старая версия OpenSSL. Для работы APLN вам необходим собрать Nginx используя OpenSSL версии 1.0.2 и выше. В противном случае начиная с 31 мая Chrome не сможет использовать HTTP/2 для ваших сайтов.

Проверить поддержку APLN можно на этом сайте. Для поддержки APLN вам понадобится собрать Nginx из исходников. Предварительно нужно указать каталог с исходниками OpenSSL в параметрах сборки Nginx. На момент написания статьи доступна последняя версия OpenSSL 1.0.2h.

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

cd /usr/src
wget https://www.openssl.org/source/openssl-1.0.2h.tar.gz
tar -xvzf openssl-1.0.2h.tar.gz

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

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

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

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

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

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

cd /usr/src
apt-get source nginx

Для того что бы изменить параметры сборки откройте файл:

nano /tmp/nginx-1.11.1/debian/rules

Нас интересует содержимое секции COMMON_CONFIGURE_ARGS. Приведите ее содержимое к следующему виду:

COMMON_CONFIGURE_ARGS := \
        --prefix=/etc/nginx \
        --sbin-path=/usr/sbin/nginx \
        --modules-path=/usr/lib/nginx/modules \
        --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_realip_module \
        --with-http_addition_module \
        --with-http_sub_module \
        --with-http_dav_module \
        --with-http_flv_module \
        --with-http_mp4_module \
        --with-http_gunzip_module \
        --with-http_gzip_static_module \
        --with-http_random_index_module \
        --with-http_secure_link_module \
        --with-http_stub_status_module \
        --with-http_auth_request_module \
        --with-http_xslt_module=dynamic \
        --with-http_image_filter_module=dynamic \
        --with-http_geoip_module=dynamic \
        --with-http_perl_module=dynamic \
        --add-dynamic-module=debian/extra/njs-1c50334fbea6/nginx \
        --with-threads \
        --with-stream \
        --with-stream_ssl_module \
        --with-http_slice_module \
        --with-mail \
        --with-mail_ssl_module \
        --with-file-aio \
        --with-ipv6 \
        $(WITH_HTTP2) \
        --with-openssl=/usr/src/openssl-1.0.2h \
        --with-cc-opt="$(CFLAGS)" \
        --with-ld-opt="$(LDFLAGS)"

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

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

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

dpkg -i nginx_1.11.1-1~jessie_amd64.deb

OCSP stapling для Rapid SSL в Nginx

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

Небольшая заметка на тему настройки функции OCSP stapling в Nginx для сертификатов выданных Rapid SSL. Вообще я сторонник всего свободного и бесплатного. Поэтому долгое время полагал надежды на сертификаты Let’s Encrypt, но, к сожалению, достаточно быстро в них разочаровался после того как стала известна политика срока выдачи сертификатов.

StartSSL не выдает бесплатные сертификаты для коммерческих проектов, а таким Китайским конторам как WoSign я не доверяю в принципе. Зато цены на сертификаты в последнее время значительно упали. И вот я подумал, было бы хорошо перейти на сертификаты от Rapid SSL. Если хотите заказать себе сертификат, то самые низкие цена на Rapid SSL у Cheap SSL. Если хотите приобрести Comodo Positive SSL, рекомендую этого регистратора GoGetSSL.

Заказал я сертификаты Rapid SSL и через некоторое время заметил в логах Nginx следующие ошибки:

2016/04/05 06:25:17 [error] 361#0: OCSP_basic_verify() failed (SSL: error:27069065:OCSP routines:OCSP_basic_verify:certificate verify error:Verify error:unable to get issuer certificate) while requesting certificate status, responder: gv.symcd.com

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

Информация о настройке OCSP stapling в Nginx есть на сайте RapidSSL. Для меня она оказалась абсолютно бесполезна и ничего нового из нее я не узнал. Методом тыка мне удалось составить правильную цепочку сертификатов. Вам нужно скопировать Root 2 — GeoTrust Global CA и Intermediate CA Certificates.

Цепочка сертификатов должна выглядеть следующим образом:

-----BEGIN CERTIFICATE-----
MIIDVDCCAjygAwIBAgIDAjRWMA0GCSqGSIb3DQEBBQUAMEIxCzAJBgNVBAYTAlVT
MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i
YWwgQ0EwHhcNMDIwNTIxMDQwMDAwWhcNMjIwNTIxMDQwMDAwWjBCMQswCQYDVQQG
EwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEbMBkGA1UEAxMSR2VvVHJ1c3Qg
R2xvYmFsIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2swYYzD9
9BcjGlZ+W988bDjkcbd4kdS8odhM+KhDtgPpTSEHCIjaWC9mOSm9BXiLnTjoBbdq
fnGk5sRgprDvgOSJKA+eJdbtg/OtppHHmMlCGDUUna2YRpIuT8rxh0PBFpVXLVDv
iS2Aelet8u5fa9IAjbkU+BQVNdnARqN7csiRv8lVK83Qlz6cJmTM386DGXHKTubU
1XupGc1V3sjs0l44U+VcT4wt/lAjNvxm5suOpDkZALeVAjmRCw7+OC7RHQWa9k0+
bw8HHa8sHo9gOeL6NlMTOdReJivbPagUvTLrGAMoUgRx5aszPeE4uwc2hGKceeoW
MPRfwCvocWvk+QIDAQABo1MwUTAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTA
ephojYn7qwVkDBF9qn1luMrMTjAfBgNVHSMEGDAWgBTAephojYn7qwVkDBF9qn1l
uMrMTjANBgkqhkiG9w0BAQUFAAOCAQEANeMpauUvXVSOKVCUn5kaFOSPeCpilKIn
Z57QzxpeR+nBsqTP3UEaBU6bS+5Kb1VSsyShNwrrZHYqLizz/Tt1kL/6cdjHPTfS
tQWVYrmm3ok9Nns4d0iXrKYgjy6myQzCsplFAMfOEVEiIuCl6rYVSAlk6l5PdPcF
PseKUgzbFbS9bZvlxrFUaKnjaZC2mqUPuLk/IH2uSrW4nOQdtqvmlKXBx4Ot2/Un
hw4EbNX/3aBd7YdStysVAq45pmp06drE57xNNB6pXE0zX5IJL4hmXXeXxx12E6nV
5fEWCRE11azbJHFwLJhWC9kXtNHjUStedejV0NxPNO3CBWaAocvmMw==
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIEJTCCAw2gAwIBAgIDAjp3MA0GCSqGSIb3DQEBCwUAMEIxCzAJBgNVBAYTAlVT
MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i
YWwgQ0EwHhcNMTQwODI5MjEzOTMyWhcNMjIwNTIwMjEzOTMyWjBHMQswCQYDVQQG
EwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEgMB4GA1UEAxMXUmFwaWRTU0wg
U0hBMjU2IENBIC0gRzMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCv
VJvZWF0eLFbG1eh/9H0WA//Qi1rkjqfdVC7UBMBdmJyNkA+8EGVf2prWRHzAn7Xp
SowLBkMEu/SW4ib2YQGRZjEiwzQ0Xz8/kS9EX9zHFLYDn4ZLDqP/oIACg8PTH2lS
1p1kD8mD5xvEcKyU58Okaiy9uJ5p2L4KjxZjWmhxgHsw3hUEv8zTvz5IBVV6s9cQ
DAP8m/0Ip4yM26eO8R5j3LMBL3+vV8M8SKeDaCGnL+enP/C1DPz1hNFTvA5yT2AM
QriYrRmIV9cE7Ie/fodOoyH5U/02mEiN1vi7SPIpyGTRzFRIU4uvt2UevykzKdkp
YEj4/5G8V1jlNS67abZZAgMBAAGjggEdMIIBGTAfBgNVHSMEGDAWgBTAephojYn7
qwVkDBF9qn1luMrMTjAdBgNVHQ4EFgQUw5zz/NNGCDS7zkZ/oHxb8+IIy1kwEgYD
VR0TAQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAQYwNQYDVR0fBC4wLDAqoCig
JoYkaHR0cDovL2cuc3ltY2IuY29tL2NybHMvZ3RnbG9iYWwuY3JsMC4GCCsGAQUF
BwEBBCIwIDAeBggrBgEFBQcwAYYSaHR0cDovL2cuc3ltY2QuY29tMEwGA1UdIARF
MEMwQQYKYIZIAYb4RQEHNjAzMDEGCCsGAQUFBwIBFiVodHRwOi8vd3d3Lmdlb3Ry
dXN0LmNvbS9yZXNvdXJjZXMvY3BzMA0GCSqGSIb3DQEBCwUAA4IBAQCjWB7GQzKs
rC+TeLfqrlRARy1+eI1Q9vhmrNZPc9ZE768LzFvB9E+aj0l+YK/CJ8cW8fuTgZCp
fO9vfm5FlBaEvexJ8cQO9K8EWYOHDyw7l8NaEpt7BDV7o5UzCHuTcSJCs6nZb0+B
kvwHtnm8hEqddwnxxYny8LScVKoSew26T++TGezvfU5ho452nFnPjJSxhJf3GrkH
uLLGTxN5279PURt/aQ1RKsHWFf83UTRlUfQevjhq7A6rvz17OQV79PP7GqHQyH5O
ZI3NjGFVkP46yl0lD/gdo0p0Vk8aVUBwdSWmMy66S6VdU5oNMOGNX2Esr8zvsJmh
gP8L8mJMcCaY
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIDfTCCAuagAwIBAgIDErvmMA0GCSqGSIb3DQEBBQUAME4xCzAJBgNVBAYTAlVT
MRAwDgYDVQQKEwdFcXVpZmF4MS0wKwYDVQQLEyRFcXVpZmF4IFNlY3VyZSBDZXJ0
aWZpY2F0ZSBBdXRob3JpdHkwHhcNMDIwNTIxMDQwMDAwWhcNMTgwODIxMDQwMDAw
WjBCMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEbMBkGA1UE
AxMSR2VvVHJ1c3QgR2xvYmFsIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
CgKCAQEA2swYYzD99BcjGlZ+W988bDjkcbd4kdS8odhM+KhDtgPpTSEHCIjaWC9m
OSm9BXiLnTjoBbdqfnGk5sRgprDvgOSJKA+eJdbtg/OtppHHmMlCGDUUna2YRpIu
T8rxh0PBFpVXLVDviS2Aelet8u5fa9IAjbkU+BQVNdnARqN7csiRv8lVK83Qlz6c
JmTM386DGXHKTubU1XupGc1V3sjs0l44U+VcT4wt/lAjNvxm5suOpDkZALeVAjmR
Cw7+OC7RHQWa9k0+bw8HHa8sHo9gOeL6NlMTOdReJivbPagUvTLrGAMoUgRx5asz
PeE4uwc2hGKceeoWMPRfwCvocWvk+QIDAQABo4HwMIHtMB8GA1UdIwQYMBaAFEjm
aPkr0rKV10fYIyAQTzOYkJ/UMB0GA1UdDgQWBBTAephojYn7qwVkDBF9qn1luMrM
TjAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjA6BgNVHR8EMzAxMC+g
LaArhilodHRwOi8vY3JsLmdlb3RydXN0LmNvbS9jcmxzL3NlY3VyZWNhLmNybDBO
BgNVHSAERzBFMEMGBFUdIAAwOzA5BggrBgEFBQcCARYtaHR0cHM6Ly93d3cuZ2Vv
dHJ1c3QuY29tL3Jlc291cmNlcy9yZXBvc2l0b3J5MA0GCSqGSIb3DQEBBQUAA4GB
AHbhEm5OSxYShjAGsoEIz/AIx8dxfmbuwu3UOx//8PDITtZDOLC5MH0Y0FWDomrL
NhGc6Ehmo21/uBPUR/6LWlxz/K7ZGzIZOKuXNBSqltLroxwUCEm2u+WR74M26x1W
b8ravHNjkOR/ez4iyz0H7V84dJzjA1BOoa+Y7mHyhD8S
-----END CERTIFICATE-----

Сохраняем копируем сертификаты в содержимое файла rapidssl.pem. Чтобы настроить OCSP stapling для Rapid SSL в вашем конфиге Nginx должны быть следующие параметры:

ssl_stapling on;
ssl_stapling_verify on;
ssl_trusted_certificate /ssl/rapidssl.pem;
resolver 8.8.8.8 valid=300s;
resolver_timeout 5s;

Очистка кэша FastCGI в Nginx

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

Если у вас в Nginx настроено кэширование с помощью параметра fastcgi_cache, то вы наверняка задумывались над реализацией функции, которая каждый раз при обновлении страниц сайта выполняла бы автоматическую очистку. Для этих целей в Nginx предусмотрена штатная директива fastcgi_cache_purge, которая задает условия для использования запроса на очистку кэша.

Проблема заключается в том, что использование директивы fastcgi_cache_purge доступно только как часть коммерческой подписки Nginx. Как альтернативное решение я предлагаю использовать модуль ngx_cache_purge. Нужно отметить, что кроме fastcgi модуль поддерживает очистку Proxy, SCGI и uWSGI кэш в Nginx.

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

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

Далее загружаем и распаковываем исходники модуля ngx_cache_purge:

# wget http://labs.frickle.com/files/ngx_cache_purge-2.3.tar.gz
# tar -xzf ngx_cache_purge-2.3.tar.gz

Откройте файл, отвечающий за параметры сборки пакета:

# nano /tmp/nginx-1.9.9/debian/rules

В этом файле нужно найдти секцию override_dh_auto_build и добавить в конец директиву --add-module, которая указывает на директорию размещения модуля ngx_cache_purge:

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_HTTP2) \
        --with-cc-opt="$(CFLAGS)" \
        --with-ld-opt="$(LDFLAGS)" \
        --add-module=/usr/src/ngx_cache_purge-2.3
dh_auto_build

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

# cd /usr/src/nginx-1.9.9
# dpkg-buildpackage -rfakeroot -uc -b

Команда выполнит компиляцию исходников и автоматически соберет deb-пакет nginx_1.9.3-1~jessie_i386.deb. Установим Nginx запустив команду:

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

Откройте файл и измените настройки виртуального хоста Nginx. Добавьте в секцию server, который будет отвечать за функцию очистки кэша FastCGI:

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

Чтобы работала функция очистки кэша, вам необходимо заменить KEYS_ZONE_NAME на свое значение параметра keys_zone. Проверяем конфигурацию и применяем настройки Nginx. Для Debian/Ubuntu выполните команды:

# nginx -t
# service nginx reload

И последний шаг. В админке WordPress установите плагин Nginx Helper.

Скрыть версию PHP и Nginx

Дата: 09.01.2016Метки: ,

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

Для примера с помощью этого сервиса я получил заголовок ответа веб-сервера для первого попавшегося сайта:

Server: nginx/1.9.5
Content-Type: text/html; charset="UTF-8"
Transfer-Encoding: chunked
Connection: keep-alive
Vary: Accept-Encoding
X-Powered-By: PHP/5.5.9-1ubuntu4.14
Set-Cookie: PHPSESSID=bsi4talrrugln1btgfen1mjmj3;
expires="Sun, 08-Jan-2017 19:27:38 GMT"; Max-Age=31536000;
path=/
Cache-Control: no-cache
Date: Sat, 09 Jan 2016 19:27:38 GMT
Content-Encoding: gzip

Как видите, мы без особого труда можем точно установить используемую версию PHP, Nginx, название и версию установленной операционной системы.

Чтобы скрыть версию PHP, измените значение параметра expose_php в файле php.ini:

expose_php = off

Чтобы скрыть версию Nginx, необходимо добавить в секцию http следующий параметр:

server_tokens off;

Не забудьте перезапустить PHP и Nginx, для того чтобы изменения вступили в силу.

Получение сертификата 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 не всегда объединяют несколько файлов в один. Но можно убедиться, что данные фильтры работают, если загрузить на сервер специально подготовленную страницу.