Свой веб-сервер на nginx. Часть 1: Настраиваем SSL на «А+».
Эта статья открывает цикл материалов по настройке современного вэб-сервера на вашем собственном VDS. В первой части мы рассмотрим настройку фронтэнда, подходящую для любой выбранной вами технологии на бэкэнде (PHP, python, Ruby on Rails и др).
Негласные требования к сайтам в Сети постоянно изменяются. И если раньше вполне было достаточно обычного HTTP-сервера виртуального хостинга, то сегодня все больше сайтов переходят на HTTPS. Этот процесс поддерживается интернет-гигантами, например Google с недавнего времени ранжирует сайты, работающие по HTTPS несколько выше.
Кроме того, становится хорошим тоном делать сайт доступным также и по протоколу IPv6. Чем больше сайтов в сети будут его поддерживать – тем быстрее провайдеры начнут массовое внедрение IPv6 на последней миле.
В этой статье мы ставим перед собой задачу установить и настроить nginx, работающий как по IPv4, так и по IPv6, с поддержкой SSL. Бонусом мы включим поддержку экспериментального протокола SPDY.
Еще несколько лет назад в интернете с большим отрывом от конкурентов лидировал вэб-сервер Apache. За долгое время своего развития он получил огромное количество функций, способных решать самые разные задачи. Платой за универсальность стало относительно большое потребление ресурсов сервером и соответствующие накладные расходы на обработку запросов.
Однако сейчас его доля на рынке постепенно снижается. В настоящее время большинство новых вэб-ресурсов строятся по следующей, двухуровневой схеме:
- Соединения на 80/443 порту принимает легковесный вэбсервер — frontend, как правило nginx. Он обрабатывает запросы, выполняет базовую фильтрацию, обеспечивает шифрование (при использовании HTTPS/SSL) и отдает статические файлы (картинки, таблицы стилей, js, шрифты и др.)
- Динамические запросы обрабатывает backend – программа, занимающаяся только обработкой логики приложения. Это может быть тот же Apache с mod_php, либо php-fpm, WSGI, Unicorn, Passenger… Как правило, бэкэнд не доступен из Сети напрямую.
Такая схема ненамного более сложна в реализации (по сравнению с «голым» Apache), но имеет ряд преимуществ. Это большая масштабируемость, производительность, уменьшенное для посетителей время отдачи статических файлов (что приводит к более быстрой загрузке страницы), возможность на одном и том же оборудовании обслужить большее количество клиентов.
В первой статье мы рассматриваем только frontend-часть.
Итак, вы заказали новый SSD VDS или выделенный сервер, выбрали OS CentOS 6.x/7.x и провели базовую настройку (сменили порты SSH, обновили OpenSSL, bash для защиты от уязвимостей Heartbleed & Shellshock (командой yum update), включили доступ пользователей только по публичным ключам, настроили firewall (в частности, открыли порты 80 и 443) и пр).
Теперь необходимо установить nginx.
Для начала остановим Apache, если он установлен «из коробки» и отключим его автозапуск при старте (в следующих статьях при необходимости мы вернем его «на место»):
1 2 |
service httpd stop chkconfig httpd off |
(Все команды в данной статье выполняем от имени пользователя root).
Настроим установку nginx из официального репозитория. Это даст возможность получать обновления максимально быстро, «из первых рук». Для этого создадим файл /etc/yum.repos.d/nginx.repo со следующим содержимым:
1 2 3 4 5 |
[nginx] name=nginx repo baseurl=http://nginx.org/packages/centos/$releasever/$basearch/ gpgcheck=1 enabled=1 |
Выполним следующие команды для установки репозитория и вэбсервера:
1 2 3 4 |
wget http://nginx.org/keys/nginx_signing.key rpm –import nginx_signing.key yum install nginx chkconfig nginx on |
Теперь необходимо настроить nginx. В большинстве конфигураций основные настройки сервера хранятся в файле /etc/nginx/nginx.conf, настройки отдельных сайтов (хостов) – в папке /etc/nginx/conf.d/. Подробнее конфигурация рассмотрена на сайте nginx.
Приведенные ниже настройки рассчитаны на сайт с относительно небольшой посещаемостью. Как правило, большинство сайтов работают с такими настройками очень хорошо.
Контроль качества установки SSL сертификата и настройки сервера для работы с HTTPS мы будем проводить при помощи сервиса ssllabs.com/ssltest. Приведенные ниже и в файле хоста настройки SSL специально подобраны так, чтобы давать оценку уровня «А+».
Ниже приводится рекомендуемый файл /etc/nginx/nginx.conf:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
# пользователь, от имени которого будут выполняться рабочие процесы user nginx; # количество рабочих процессов, можно установить равным кол-ву ядер worker_processes auto; # расположение журнала ошибок error_log /var/log/nginx/error.log warn; pid /var/run/nginx.pid; events { worker_connections 1024; # количество соединений для рабочего процесса use epoll; # метод обработки соединений, оптимален для Linux 2.6+ } http { # настройки HTTPS: поддержка возобновления сессий, предпочтение современным шифрам (с поддержкой старых устройств) ssl_session_timeout 5m; ssl_session_cache shared:SSL:2m; ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2; ssl_ciphers "ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-RC4-SHA:ECDHE-RSA-RC4-SHA:ECDH-ECDSA-RC4-SHA:ECDH-RSA-RC4-SHA:ECDHE-RSA-AES256-SHA:RC4-SHA"; ssl_prefer_server_ciphers on; # настройки сертификатов: прикрепление OCSP-ответов сервером ssl_stapling on; ssl_stapling_verify on; ssl_buffer_size 8k; ssl_trusted_certificate /etc/pki/tls/certs/ca-bundle.crt; # используемый DNS-сервер, в частности для целей OCSP resolver 8.8.8.8; include /etc/nginx/mime.types; default_type application/octet-stream; # формат log-файла log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; # включаем прямую передачу файлов для повышения производительности sendfile on; # максимально допустимый размер тела запроса клиента. Если предполагается прием больших файлов через POST - увеличиваем client_max_body_size 10m; keepalive_timeout 65; server_tokens off; # отключаем раскрытие версии сервера ssi off; # если нужно SSI - включите autoindex off; # запрещаем вывод листинга каталога tcp_nopush on; # полезно при sendfile on expires max; # устанавливаем максимальный срок кэширования браузером для статических файлов gzip on; # включаем gzip-сжатие для определенных типов контента gzip_min_length 10240; gzip_proxied expired no-cache no-store private auth; gzip_types text/plain text/css text/xml text/javascript application/x-javascript application/xml; gzip_disable "msie6"; include /etc/nginx/conf.d/*.conf; } |
Следующим шагом будет являться настройка отдельного сайта (хоста). Предположим, что вы владеете доменом example.org.
Для полноценной поддержки HTTPS (в том числе и для устройств, не поддерживающих SNI) нам понадобится отдельный сетевой адрес и сертификат SSL. Поскольку на всех тарифах ITLDC в стоимость сервера уже входят выделенные IPv4/6-адреса, все, что нам остается – приобрести сертификат. В большинстве случаев будет достаточно базового domain control validated за сумму порядка $5 в год.
Оставим в стороне процесс покупки и валидации SSL-сертификата для вашего домена, поскольку эти процедуры различаются у различных компаний. Предположим, что вы выполнили все процедуры, и у вас на VDS по адресу /etc/pki/tls/private/example.org.key находится приватный ключ сервера (с владельцем root и правами доступа 400), а по адресу /etc/pki/tls/certs/example.org.bundle.crt – бандл (связка) сертификатов, полученных от центра сертификации.
В случае, если вам выдали отдельно набор сертификатов, будет необходимо собрать его в один файл. Для этого можно воспользоваться командой cat. К примеру, при покупке сертификата с проверкой владения доменом от COMODO вам выдали zip-архив с четырьмя сертификатами цепочки:
Эти сертификаты необходимо собрать в один файл, начиная вывод с сертификата на домен и далее вверх по восходящей иерархии сертификатов. Просмотреть иерархию сертификатов и определить требуемый порядок следования можно, к примеру, открывая .crt-файлы в проводнике Windows:
Загрузите архив на VDS в /root/ и выполните следующие команды:
1 2 3 4 |
unzip example_org.zip –d /root/cert-bundle && cd /root/cert-bundle cat example_org.crt COMODORSADomainValidationSecureServerCA.crt COMODORSAAddTrustCA.crt AddTrustExternalCARoot.crt > /etc/pki/tls/certs/example.org.bundle.crt chmod 400 /etc/pki/tls/certs/example.org.bundle.crt cd && /bin/rm -r /root/cert-bundle |
На этом размещение сертификата на сервере завершено.
Убедитесь, что ваш сервер имеет IPv6-связность, например, выполнив команду ping6 ipv6.google.com. Подробнее про настройку IPv6 вы можете прочитать в блоге, в заметке Включаем IPv6 на VDS.
Теперь переходим к настройке непосредственно хоста. Ниже приводится файл /etc/nginx/conf.d/example.org.conf:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
server { listen 80 default; # слушаем на 80 порту IPv4-адреса по умолчанию listen [::]:80 default ipv6only=on; # слушаем на 80 порту IPv6-адреса по умолчанию listen 443 ssl spdy; # слушаем на SSL+SPDY порту IPv4-адреса по умолчанию listen [::]:443 ssl spdy ipv6only=on;# слушаем на SSL+SPDY порту IPv6-адреса по умолчанию server_name example.org www.example.org; # имя сервера # путь к журналу доступа для текущего хоста и формат данного журнала (=main) access_log /var/log/nginx/example.access.log main; # кодировка по умолчанию charset utf-8; # путь к бандлу сертификатов ssl_certificate /etc/pki/tls/certs/example.org.bundle.crt; # путь к секретному ключу ssl_certificate_key /etc/pki/tls/private/example.org.key; # включаем HSTS (Strict Transport Security) add_header Strict-Transport-Security 'max-age=15552000'; # переадресовываем все http-соединения сразу в https if ($ssl_protocol = "") { rewrite ^ https://$server_name$request_uri permanent; } # настройки локации (пути) по умолчанию location / { root /home/www/www; # корень вэбсервера try_files $uri @backend; # пробуем найти запрашиваемый по имени файл на диске, если не находим путь - обращаемся к бэкэнду } # стандартные страницы ошибок /50x.html error_page 500 502 503 504 /50x.html; location = /50x.html { root /usr/share/nginx/html; } # ////////////////////////////////////////////////////////// # блок настроек для Apache+mod_php в качестве бэкэнда. См. следующие статьи location ~ \.php$ { proxy_buffering off; proxy_pass http://127.0.0.1:8000; proxy_set_header Host $host; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Forwarded-for $remote_addr; } location @backend { proxy_buffering off; proxy_pass http://127.0.0.1:8000; proxy_set_header Host $host; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Forwarded-for $remote_addr; } # ////////////////////////////////////////////////////////// # запрещаем отдачу файлов .htaccess location ~ /\.ht { deny all; } # запрещаем доступ к служебным папкам систем контроля версий location ~ /\.git { deny all; } location ~ /\.svn { deny all; } } |
Если вы хотите включить поддержку протокола SPDY, необходимо убедиться, что ваша версия nginx собрана с поддержкой соответствующего модуля. Для этого выполните команду
1 |
nginx -V |
и убедитесь в наличии опции —with-http_spdy_module. В случае, если вам не нужна поддержка SPDY или ваша версия собрана без поддержки этого модуля, удалите слово spdy из 4 и 5 строк конфигурационного файла.
На этом основная настройка nginx как фронтэнда завершена. Запустите сервер командой
service nginx start
и проверьте его работу. При обращении по адресу http://example.org вас должно автоматически перебросить на https://example.org, сертификат должен отобразиться в браузере как действительный.
Для проверки установки сертификата вы можете воспользоваться сервисом Qualsys SSL Labs: https://www.ssllabs.com/ssltest/analyze.html
Проверить доступность сайта по IPv6 можно через ipv6-test.com/validate.php, поддержку протокола SPDY — spdycheck.org.
Успешных вам инсталляций!