в Администририрование

Крайнее время, в связи с различными факторами — всё чаще встает вопрос безопасности передачи данных между клиентом и сервером. Разные жулики и спец. службы перехватывают трафик, вытаскивают из него различные данные (включая пароли), некоторые провайдеры публичные точки доступа в сеть даже встраивают в него рекламные баннеры. Для решения этой задачи уже имеются необходимые механизмы под именем SSL, с которыми мы сейчас довольно плотно и поработаем. Данная технология позволяет дать почти 100% гарантии, что трафик не будет прослушан и видоизменен. Подробнее об этом есть смысл спросить у Вики.

Постановка задачи

В рассматриваемом примере у нас в качестве «внешнего» (front-end) веб-сервера используется nginx (протокол http, разумеется), «слушающий» 80 порт. Исходный конфиг тестового домена domain.ltd для него может быть таким:

server {
  listen      80;
  server_name domain.ltd;
  root        /home/domain.ltd/docs;
  access_log  /home/domain.ltd/log/nginx.access.log;
  error_log   /home/domain.ltd/log/nginx.error.log;
}

Какой используется «внутренний» (back-end) веб-сервер, и имеется ли он вообще — значения не имеет, т.к. нам необходимо шифровать именно внешний трафик, который передается и принимается от клиента.

Для того чтоб передавать данные по защищенному (зашифрованному) соединению — нам необходимо использовать протокол https (расширение протокола http, по умолчанию работающее на 443 порту), а для этого в свою очередь необходимо получить сертификат от доверенного источника (которым будет производиться подпись передаваемого трафика и при помощи которого будет происходить шифрование), а получив его — настроить работу nginx с ним.

Получение сертификата

Для получения сертификата мы можем дождаться бесплатной раздачи от Mozilla, а можем получить его уже сейчас и бесплатно, например, у WoSign (так же существуют аналоги).

Рассмотрим вариант с WoSign — заполняем необходимые поля и ожидаем готовый сертификат на почте:

Для подтверждения прав владения доменом необходимо будет ввести код из письма, который будет отправлен на, например, [email protected]. Если необходимо подключить шифрование ещё и на поддоменах — то все их сразу указываем в поле «Domain name» — по одному на строчку. Введенный пароль обязательно сохраняем. Ожидание готового сертификата составляет около суток. Письмо придет на адрес, которым подтверждали права владения доменом.

Настройка nginx

После того, как письмо с ссылкой на скачивание готового сертификата (пароль на него — это пароль что мы установили на шаге заполнения формы) придет — нас ждет приятный бонус в виде уже подготовленных форматов сертификатов для Apache, IIS, nginx, Tomcat и пр. Мы же берем лишь содержимое архива «for Nginx.zip» (предварительно приведя имена файлов в порядок, а именно удалив 1_ и 2_ из их начала) и заливаем его на наш сервер любым доступным способом.

Далее — создаем директорию /etc/nginx/ssl переносим файлы (domain.ltd_bundle.crt и domain.ltd.key) в неё, после чего выставляем права и создаем конфигурационный файл:

$ mkdir /etc/nginx/ssl/
$ mv domain.ltd* /etc/nginx/ssl/; cd /etc/nginx/ssl/
$ chown root:root ./domain.ltd*; chmod 644 ./domain.ltd*
$ nano ./domain.ltd_ssl.conf

Его содержание (подробнее об этом):

ssl_certificate     /etc/nginx/ssl/domain.ltd_bundle.crt;
ssl_certificate_key /etc/nginx/ssl/domain.ltd.key;
ssl_protocols       SSLv3 TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers         "RC4:HIGH:!aNULL:!MD5:!kEDH";
add_header          Strict-Transport-Security 'max-age=604800';

Именно этот файл (/etc/nginx/ssl/domain.ltd_ssl.conf) мы будем подключать как на самом домене, так и всех поддоменах в секции server {...} для включения поддержки SSL. Теперь добавляем в секцию http {...} (файл /etc/nginx/nginx.conf) следующие строки:

ssl_session_cache   shared:SSL:10m;
ssl_session_timeout 5m;
ssl_prefer_server_ciphers on;
ssl_stapling on;
resolver 8.8.8.8;

И на этом настройку сервера можно считать завершенной. Всё что остается — это «активировать» SSL на нужном виртуальном сервере. Поправим конфиг, приведенный в самом начале статьи:

server {
  listen      80;
  listen      443 ssl;
  include     /etc/nginx/ssl/domain.ltd_ssl.conf;
  server_name domain.ltd;
  root        /home/domain.ltd/docs;
  access_log  /home/domain.ltd/log/nginx.access.log;
  error_log   /home/domain.ltd/log/nginx.error.log;
}

И перезапустим nginx:

$ service nginx restart

Проверяем всё ли заработало — должен открываться как http://domain.ltd/, так и https://domain.ltd/.

Принудительное перенаправление

Если у тебя стоит задача перевести все запросы с http на https — можешь воспользоваться следующим примером:

server {
  listen 80;
  ...
  server_name domain.ltd;
  return 301 https://$server_name$request_uri;
  ## -- or --
  #rewrite ^(.*) https://$server_name$1 permanent;
}

server {
  listen  443 ssl;
  include /etc/nginx/ssl/domain.ltd_ssl.conf;
  server_name domain.ltd;
  ...
}

Пояснение: будут работать 2 виртуальных сервера — один на стандартном 80 порту (только для редиректа), второй — на 443 (основной). Все запросы, которые будут приходить по http (на 80 порт) — будут безжалостно перенаправляться на этот же домен, но на протокол https, сохраняя url строку запроса.