0,0
рейтинг
11 марта 2015 в 23:41

Разработка → Nginx и https. Получаем класс А+ tutorial

image

Недавно вспомнилось мне, что есть такой сервис — StartSsl, который совершенно бесплатно раздаёт trusted сертификаты владельцам доменов для личного использования. Да и выходные попались свободные. В общем сейчас напишу, как в nginx настроить HTTPS, чтобы при проверке в SSL Labs получить рейтинг А+ и обезопасить себя от последних багов с помощью выпиливания SSL.

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

Вот что у меня получилось:

server {
    server_name dsmirnov.pro www.dsmirnov.pro;
    listen 80;
    return 301 https://dsmirnov.pro$request_uri;
}

server {
    listen 443 ssl spdy;
    server_name dsmirnov.pro;
    resolver 127.0.0.1;
    ssl_stapling on;
    ssl on;
    ssl_certificate /etc/pki/nginx/dsmirnov.pro.pem;
    ssl_certificate_key /etc/pki/nginx/dsmirnov.pro.clean.key;
    ssl_dhparam /etc/pki/nginx/dhparam.pem;
    ssl_session_timeout 24h;
    ssl_session_cache shared:SSL:2m;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers kEECDH+AES128:kEECDH:kEDH:-3DES:kRSA+AES128:kEDH+3DES:DES-CBC3-SHA:!RC4:!aNULL:!eNULL:!MD5:!EXPORT:!LOW:!SEED:!CAMELLIA:!IDEA:!PSK:!SRP:!SSLv2;
    ssl_prefer_server_ciphers on;
    add_header Strict-Transport-Security "max-age=31536000;";
    add_header Content-Security-Policy-Report-Only "default-src https:; script-src https: 'unsafe-eval' 'unsafe-inline'; style-src https: 'unsafe-inline'; img-src https: data:; font-src https: data:; report-uri /csp-report";
}

В первой секции всё вроде понятно, любой вход по http с любым URI редиректит с этим-же URI в схему https.

Начнём разбор секции server для https. Директивой listen 443 ssl spdy; сразу включаем spdy. Вот на картинке разница:

image

Следущим шагом включаем ssl_stapling on; — позволяем серверу прикреплять OCSP-ответы, тем самым уменьшая время загрузки страниц у пользователей. Цепочка сертификатов (доменный — промежуточный центр авторизации — корневой центр авторизации) может содержать 3-4 уровня. И на каждый уровень браузер должен устанавливать соединение и получать сертификат. Можно отправить все сертификаты (включая промежуточный: именно за этим была настройка TCP-окон отправки, чтобы цепочка сертификатов гарантированно поместилась в в одну пересылку пакетов) разом, тогда браузер проверит всю цепочку локально, а запросит только корневой (который в большинстве случаев уже находится на клиенте). Для работы этой функции обязательно описать resolver — у меня поднят свой собственный DNS сервер, поэтому в качестве значения указан 127.0.0.1, Вы можете указать 8.8.8.8, но многие в последнее время на него ругаются. Что такое ssl on; я думаю нет смысла рассказывать.

Далее директивами ssl_certificate и ssl_certificate_key указываем пути к полученным через StartSsl сертификатам. У вас уже есть 3 файла: domain.ru.key, domain.ru.crt и sub.class1.server.ca.pem. Копируем ключи в ( моём случае ) /etc/pki/nginx.

Не забываем, что pem файл для nginx должен быть смержен с сертификатом CA ( Должно получиться из 3х — 2 файла. ):

cp domain.ru.key /etc/pki/nginx
cat domain.ru.crt sub.class1.server.ca.pem > /etc/pki/nginx/domain.ru.pem

Теперь о ssl_dhparam /etc/pki/nginx/dhparam.pem; — это нужно, чтобы у нас заработал Forward Secrecy. Прямая секретность означает, что если третья сторона узнает какой-либо сеансовый ключ, то она сможет получить лишь доступ к данным, защищенным лишь этим ключом. Для сохранения совершенной прямой секретности ключ, используемый для шифрования передаваемых данных, не должен использоваться для получения каких-либо дополнительных ключей. Также, если ключ, используемый для шифрования передаваемых данных, был получен (derived) на базе какого-то еще ключевого материала, этот материал не должен использоваться для получения каких-либо других ключей.

Сгенерировать ключ можно так:

openssl dhparam -out /etc/pki/nginx/dhparam.pem 4096

Далее несложные настройки ssl_session_timeout 24h; и ssl_session_cache shared:SSL:2m;, которые не требуют особенных описаний — срок истечения сессии и размер памяти, выделяемой для хранения кеша — у меня бложик маленький, поэтому 2 Мб вполне достаточно.

Дальше — важные параметы: ssl_protocols TLSv1 TLSv1.1 TLSv1.2; и ssl_ciphers kEECDH+AES128:kEECDH:kEDH:-3DES:kRSA+AES128:kEDH+3DES:DES-CBC3-SHA:!RC4:!aNULL:!eNULL:!MD5:!EXPORT:!LOW:!SEED:!CAMELLIA:!IDEA:!PSK:!SRP:!SSLv2; — тут мы указываем, что мы желаем только TLS и второй строкой выжигаем калёным железом все SSL. В свете последних фейлов с SSL — очень актуально, что и Вам советую. Ну и директивой ssl_prefer_server_ciphers on; принуждаем nginx это всё строго соблюдать.

Директива add_header Strict-Transport-Security «max-age=31536000;»; указывает браузерам сколько они должны помнить данные требования безопасности для моего домена. В данном случае — 1 год. Кстати, если директиву написать вот так: add_header Strict-Transport-Security «max-age=31536000; includeSubDomains; preload»;, то данные условия будут применимы ко всем доменам третьего и выше уровня вашего домена. Тут будте осторожны! Я изначально описал именно так, но так, как StartSsl выдаёт сертификаты на ограниченное количество поддоменов, я наткнулся на невозможность даже попасть на свои поддомены, которые обслуживают разнообразные админки, работали только те, на которые были выписаны trusted сертификаты. Поэтому я для себя выбрал первый вариант.

Далее — add_header Content-Security-Policy-Report-Only «default-src https:; script-src https: 'unsafe-eval' 'unsafe-inline'; style-src https: 'unsafe-inline'; img-src https: data:; font-src https: data:; report-uri /csp-report»; — я толком глубоко ещё не изучил свойства данного заголовка. Content Security Policy (CSP) — новый стандарт, определяющий HTTP-заголовки Content-Security-Policy и Content-Security-Policy-Report-Only, которые сообщают браузеру белый список хостов, с которых он может загружать различные ресурсы.

image

Временно я взял данную строку из статьи Яндекса про применение у них CSP, почитать подробно можно тут: http://www.html5rocks.com/en/tutorials/security/content-security-policy/.

Вот вроде-бы и всё. Несколько ссылкок, где можно проверить результаты своих и чужих трудов:

1. SPDY Checkэто результат моего труда.

2. SSL Labs — проверка качества защиты вашего сервера.

Удачной защиты, коллеги!
Дмитрий Смирнов @DimaSmirnov
карма
15,0
рейтинг 0,0
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Реклама

Самое читаемое Разработка

Комментарии (82)

  • 0
    SSL уже настраивал, SPDY — очень интересно
    Прирост в скорости или снижение нагрузки на сервер есть?
    • 0
      К сожалению не было возможности протестировать, но судя по документации — да.
    • +4
      Я обьединил разные прочитанные материалы просто в конфиг, довёл до ума по тестам и просто поделился. Статей на эту тему последнее время было много, но единого конфига я не увидел, поэтому решился опубликовать свои наработки.
      • 0
        За что вам спасибо)
        Поменял CA сертификат на SHA256 вместо SHA1, ну и ssl_ciphers подправил, теперь A+ вместо А)
  • 0
    А как насчет OCSP stapling?
    • 0
      Вот после первого вопроса провёл небольшой тест — замерял на виртуалке с аналогичной конфигурацией без всех этих плюшек — реально хендшейки скушали ну не в 3 раза больше проца, но оверхед получился на одно соединеие около 80-120%.
      • 0
        Так результат же можно кэшировать на долгое время. Разницы не должно быть.
  • 0
    Что в этой строке add_header Strict-Transport-Security «max-age=31536000; includeSubDomains; preload» означает preload? Вы собираетесь свой сайт в браузерный preload list включать?
    • 0
      ну я же написал, когда мы описываем includeSubDomains мы оговариваем, что мы ставим рестрикт на принятие поддоменов без трастед. а прелоад запрещает ходить на домены, которые сертификаты не защищают. Там болдом выделено предупреждение в статье.
      • +2
        Ок, отвечу сам себе.
        «Recommended: If the site owner would like their domain to be included in the HSTS preload list maintained by Chrome (and used by Firefox and Safari), then use:

        The `preload` flag indicates the site owner's consent to have their domain preloaded. The site owner still needs to then go and submit the domain to the list.»
        Отсюда.
      • 0
        preload — это ваше разрешение на добавление вашего сайта в предзагруженный HSTS-список Google Chrome. Если у вас это прописано, любой может зайти на hstspreload.appspot.com и запросить у Google добавление вашего сайта в браузер, чтобы даже самое первое посещение было сразу по HTTPS. Да, и это всем будет видно из исходников.
  • +1
    Хм, ваша статья мягко говоря не первая на эту тему. И далеко не полная. Лучше всего на тему настройки SSL помогает вики мозиллы.
  • +6
    А разве правилами Хабра не запрещено копипастить?! dsmirnov.pro/post/nginx-https-tls/
    • –2
      Это шутка? На автора-то обрати внимание.
      • +3
        Есть поверие, что поисковики не очень хорошо относятся к контенту, когда находят его 1 в 1 на другом сайте. И на авторство они не смотрят.
      • +2
        Хабрахабр — не место для копипастеров. Размещение полностью скопированного контента с других сайтов запрещено — даже при использовании гиперссылки на источник. Мы за авторские материалы.

        Хабрахабр — не ЖЖ и не центр мирового кросспостинга. Не нужно копировать публикации из других блогов и сайтов, указывая, что ранее они были опубликованы в другом месте.
    • +1
      Это мой блог. Статью изначально писал там, после редактирования опубликовал тут.
      • +1
        Так я о том и говорю: «сначала в блоге, потом на хабре» = «копипаста», что запрещено правилами (выше указали).
        • +2
          Копипаста — это воровство. Я в своём блоге редактирую материал, как только я считаю, что материал готов к публикации, я переношу это сюда — не вижу ничего криминального.
          • –1
            С чего вы решили, что копипаста = воровство? Копипаста своего кода — тоже воровство? Или не это не копипаста? Это раз.
            Два — в правилах вроде четко сказано: «не нужно копировать публикации из других блогов и сайтов». И не важно, свое это или чужое.
            • +2
              Это вот так важно в контексте данного поста? Да, в приведённом конфиге явно указано имя хоста, но я не имел цели как-то его пиарить — там пиарить-то нечего, этому бложику месяц и я его использую для редактирования черновиков. Мне кажется вы из мухи слона сделали.
              • –2
                Вы реально не понимаете? Какая разница, какой домен в конфиге? Вы разместили на хабре копипастный пост, что явно запрещено правилами. Хотите размещать посты в блоге — не вопрос, но тогда не размещайте на хабре их же. Что произойдет с хабром, если каждый будет размещать копии постов со своих блогов/сайтов? Смысл создавать правила, если их не соблюдать?

                P.S.: к самому посту претензий нет, полезный.
                • +1
                  смешно читать претензии о перепостинге авторского контента от человека который так ни в один пост и не смог =)
                  • 0
                    «сперва добейся»?
                  • –1
                    Серьезно?)))) Не размещать посты на хабре = отсутствие собственного контента? Отличная логика… для девушки, но не для it-шника…
                    • 0
                      «Не размещая посты на хабре» = отсутствие видения вашей позиции касаемо «постов на хабре».
                      • 0
                        Мы вроде о правилах хабра разговаривали, а не о видении позиций…
                • +2
                  О ужас, и что же произойдет с хабром?
                  Если он будет размещать свои посты только в своем блоге — их никто не прочитает.
                  Если он будет размещать свои посты только на хабре — о его блоге никто не узнает.
                  Отстаньте от человека, поборник морали.
                  • 0
                    А размещать одно на хабре, другое в блоге — не вариант? Религия не позволяет?
                    Нахрена вообще нужны правила, которые никто не соблюдает?
          • +2
            Хабру нужен уникальный материал, он на этом деньги делает. Ему надо, чтобы вы ссылались на него, но не он на вас. И чтобы гугл всегда вёл на хабр, а не на ваш блог. Отсюда и правило. Понимайте это в этом разрезе. Вы получаете доступ к многотысячной аудитории, хабр получает уникальный контент от вас.
            • +3
              Согласен с кейсом, а как быть, если я просто технический специалист, я периодически записываю свои работы на своём сайте ( блоге ), а потом, если вижу, что материал достоин публикации просто отдаю его тут? Я не хочу подстраиваться под коньюктуру Хабра, я знаю, что результаты моей работы многим понадобятся тут. Где логика? Вы предлагаете мне тратить своё время, чтобы читать правила и накачивать себе карму? Это того не стоит, карма качается в реале на работе.
              • 0
                Вас просто забанят за нарушение правил и всё. Я вам ничего не предлагаю, я просто объясняю ситуацию, правила игры, так сказать. Может быть для вас сделают исключение, буду только рад.
                • 0
                  А разве это правило вообще работает? Его же сплошь и рядом все нарушают. И никому, кроме как, владельцам площадки, это вреда не несёт. Соответственно если бы админы выразили своё недовольство, это было бы логично, т.к. это их деньги, но выражать недовольство обычным пользователям, мне кажется, не совсем резонно.
                  • 0
                    Тут скорее дружеское предупреждение, чем выражение недовольства. Я не хочу, чтобы человека забанили по его незнанию. Если на практике правило не применяется, это хорошо.
              • 0
                Постить сначала на Хабр, а когда его проиндексируют — к себе в блог и писать внизу пометку, что написано для Хабра.
        • +2
          Именно поэтому пусть автор поменяет дату поста в блоге на +1 час или +1 день, и будет миру мир!
          Вы наверное не понимаете, что если раньше люди целенаправленно писали на ИТ ресурсы, то теперь люди делятся материалом.
          Я согласен с тем, что чтобы иметь возможность поделится материалом, надо соблюдать правила ресурса, где материал размещают. Именно поэтому нужна «игра с датами».
          Так же я замечу, что многие держат блог не для извлечения прибыли с рекламы или счетчиков, а потому, что хочется однажды оказаться полезным человеку, который нагуглит свою проблему уже решенной у кого-то.
          • –2
            А нагуглить на хабре не получится? Какой смысл распостранять дублированный контент?
            • –2
              Я согласен поддержать с вами диалог, при наличии у вас собственного материала.
              • +4
                поравил время в блоге)
              • 0
                У меня есть собственный материал. И он в блоге, а не на хабре, ибо я считаю что не надо распостранять дублированный контент ;)
                • +2
                  А я считаю, что аудитории данного ресурса мои работы полезны.
                  • 0
                    Я разве говорил, что это не так? Повторяю — пост полезный, к нему нет претензий. Вопрос только в том, что он является дублем поста из вашего блога, что нарушает правила данного проекта.

                    Давайте на этом закончим. Я считаю, что правила надо соблюдать, вы считаете что это не обязательно. Дальнейшая полемика не имеет смысла.
                    • 0
                      Вы неверно трактуете правила:
                      Размещение полностью скопированного контента с других сайтов запрещено — даже при использовании гиперссылки на источник. Мы за авторские материалы.

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


                      Если первоисточник хабр, то такие формулировки не работают.

                      Что является первоисточником? Ресурс, на которое материал появился раньше. Все просто.
                      • 0
                        Верно. И данный пост появился ПОСЛЕ поста в блоге автора. О чем я и сказал в первом комментарии…
                        • –3
                          Не хочу с вами спорить, но мои глаза ясно видят, что данная статья на хабре была опубликована вчера (11 марта), а пост в блоге судя по Atom'у
                          2015-03-12T14:34:05+03:00
                          — а это сегодня. Я только что проверил.
                          • 0
                            А спорить и нет смысла — автор на своем блоге поправил-же время. Пост здесь появился сегодня ночью, а на блоге автора намного раньше (несколько дней назад, если правильно помню).

                            Да и как в блоге пост мог появится в 14:34, если мой комментарий о дубле был в 3 утра, не задумывались?
                            • –1
                              А что вы хотите доказать? Технически он мог быть в 2 часа ночи, спустя часы после публикации на хабре, и ничего против не сказать.
                              Вы сейчас трактуете правила, как вы их видите. Я трактую как я их вижу.

                              Официальный ответ — за администрацией проекта, и я уверен, что эти люди поставят точки над i, стоит ли публиковать на хабре поста, а затем через несколько часов и на персональных сайтах или нет. Изъявляете ли вы желание связаться с ней?
                              Можете не отвечать на вопрос, я увижу, пропадет ли эта замечательная статья у 531 подписчика или нет.
                              • 0
                                Я хочу сказать, что видел дату поста в блоге. И автор скопипастил пост из блога на хабр. Это все. И повторюсь — к самому посту претензий нет, сам скопировал (правда из блога автора) себе.
                • 0
                  В конечном счёте, ИМХО, из-за вашего соблюдения этого правила, все проиграли. Включая владельцев этого ресурса.
      • 0
        Кстати. Поправьте линки на Gravatar чтобы аватары тоже грузились по https — для полноты гармонии и зеленого замочка в адресной строке
  • 0
    Спасибо.
    Довел до A+, включив Forward Secrecy и SPDY.
    • 0
      На заметку: SPDY для A+ не требуется, но станет на одно замечание меньше у сервиса проверки GlobalSign (что-то вроде русской версии SSL Labs, но не обновлялась с апреля 2014).
  • +3
    Я бы ещё добавил про HPKP: developer.mozilla.org/en-US/docs/Web/Security/Public_Key_Pinning
    На скорость особо не влияет, но защита лучше.
    • 0
      С PKP придётся даже девятым IE пожертвовать, не говоря про всякие Оперы 12.х и прочий антиквариат.
      • 0
        Жертвовать не надо. Это ведь просто заголовок, который читают только те, кто умеет.
        Если браузер не поддерживает, то он просто проигнорирует этот заголовок, но сам сайт будет работать. Без жертв.
        • 0
          Ну да, с HSTS то же самое. Возможно, такие опасения из-за того, что заголовок без "X-" в начале. Только согласно RFC6648, так делать уже и не следует.
  • –4
    КМК, корректнее редирект с 80 порта делать вот так:

    server {

    listen 80;
    server_name example.com www.example.com;
    return 301 https://$host$request_uri;
    rewrite ^ https://$server_name$request_uri? permanent;

    }
    • 0
      Ну и, собственно, на всякий случай листинг кусочка конфига, который спокойно проходит на А+:
      тык
      server {

      listen 80;
      server_name example.com www.example.com;
      return 301 https://$host$request_uri;
      rewrite ^ https://$server_name$request_uri? permanent;

      }

      server {
      listen 80;
      server_name example2.com www.example2.com;
      rewrite ^(.*) $scheme://example.com$request_uri permanent;

      }

      server {
      # port on which we're listening for incoming connections
      listen 443 ssl spdy;
      # 40x error pages
      error_page 404 /404.html;
      error_page 403 /403.html;
      error_page 500 /500.html;
      error_page 502 /502.html;

      # defining a zone for domain to answer to
      server_name example.com www.example.com;

      ssl on;
      ssl_certificate /etc/nginx/conf.d/example.com.unified.crt;
      ssl_certificate_key /etc/nginx/conf.d/example.com.unified.key;

      ssl_session_cache shared:SSL:5m;
      ssl_session_timeout 5m;

      ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
      ssl_ciphers 'EECDH+ECDSA+AESGCM:AES128+EECDH:AES128+EDH:!RC4:!aNULL:!eNULL:!LOW:!3DES:!MD5:!EXP:!PSK:!SRP:!DSS:!CAMELLIA:!ADH';
      ssl_prefer_server_ciphers on;
      ssl_stapling on;

      resolver 8.8.8.8 8.8.4.4 208.67.222.222 valid=300s;
      resolver_timeout 10s;
      add_header X-Frame-Options SAMEORIGIN;
      add_header X-Content-Type-Options nosniff;
      add_header Strict-Transport-Security max-age=31536000;


      Внедряется за пару минут буквально, больше времени на выписку сертификатов и их заливку уходит. Ничего нигде не падает, из софт-специфик вещей приходилось только немного подкрутить конфиг Mediawiki, чтобы она не выдавала mixed-content, а тому же Вордпрессу, phpBB и куче всего прочего — вообще до фонаря, абсолютно так же работает, как и напрямки.
    • +5
      И зачем тут rewrite после return?
  • +2
    Конфиг не идеальный. 24 часа на таймаут сессии — чрезвычайно много. 10 минут достаточно. За 24 часа браузер точно очистит уже информацию о сессии.
    PFS будет работать и без указания dhparam, только будут использоваться 1024-битные ключи. Да и 4096 dhparam значительно замедляет сервер по сравнению с 2048.
    Cipherlist, вроде, нормальный, но можно было бы просто HIGH использовать и поотключать ненужное и небезопасное.
    • 0
      1024-битные параметры Диффи-Хеллмана уже считаются слабыми, скоро с ними получить A+ будет нельзя, минимум 2048.
      4096 или 2048 — это уже в зависимости от ключа.
      • 0
        Да я не спорю. Просто заметил, что PFS будет работать и без dhparam, а в статье говорится другое.
        • 0
          Это с какой стороны посмотреть. Со слабыми параметрами обеспечивать PFS, именно P, сомнительно. Кстати, в баге о присваивании A+ таким сайтам предложил вообще не считать DHE 1024 как обеспечивающий FS: github.com/ssllabs/ssllabs-scan/issues/80
          • 0
            Кстати, в баге о присваивании A+ таким сайтам предложил вообще не считать DHE 1024 как обеспечивающий FS: github.com/ssllabs/ssllabs-scan/issues/80
            Там только предложение снять плашку ROBUST.
            • 0
              Ну да, ROBUST — это когда сайт поддерживает не только Диффи-Хеллман на эллиптических кривых, но и традиционный, а если у традиционного слабые параметры, должно быть только «с современными браузерами», как у google.com, который традиционный DHE не умеет.
              • 0
                Только наоборот.
                • 0
                  В плане? :)

                  www.ssllabs.com/ssltest/analyze.html?d=google.com&s=74.125.239.96
                  Вот сервер, не умеющий обычный DHE, только ECDHE. Старые клиенты (Android 2, Java 6 и OpenSSL 0.9.8) согласовывают RSA, потому что не умеют ECDHE, от этого и результат «With modern browsers».

                  www.ssllabs.com/ssltest/analyze.html?d=crypto.cat
                  Этот умеет DHE 4096 и получает «With most browsers ROBUST».

                  www.ssllabs.com/ssltest/analyze.html?d=www.fastmail.com&s=66.111.4.148
                  У этого DHE 1024 с рейтингом A+ и ROBUST, что свидетельствует о поддержке DHE, но с слабыми параметрами такого сообщения быть не должно.
                  • 0
                    А, вот как оно работает. Я думал, что ROBUST дают тогда, когда есть поддержка ECDHE, а не дают, когда только DHE.
                    • 0
                      Только наоборот :). Если точнее, то:
                      «With modern browsers» дают в случае согласовывания какого-либо Диффи-Хеллмана как минимум со всеми браузерами, помеченными зелёной буквой R справа от их названия.
                      Если хотя бы один браузер с зелёным R согласовывает RSA, будет жёлтое «With some browsers». Кстати, это типичный случай для серверов, которые не умеют ECDHE, но умеют DHE. С Internet Explorer ситуация наоборот, Microsoft имеет тенденцию не поддерживать DHE, но поддерживать ECDHE. Исключение — современные версии, поддерживающие DHE совместно с аутентифицированным шифрованием.
                      Пример наглядно: www.ssllabs.com/ssltest/analyze.html?d=mozilla.org Для таких случаев я предлагал показывать конкретное предупреждение, что сервер не обеспечивает PFS именно с Internet Explorer, но особо не заинтересовались.
                      «With most browsers ROBUST» дают в случае использования DHE и/или ECDHE для всех успешных рукопожатий, кроме IE на XP.
  • 0
    Обычно пользуюсь этой инструкцией:
    wiki.mozilla.org/Security/Server_Side_TLS
    и этой генерилкой конфига:
    mozilla.github.io/server-side-tls/ssl-config-generator/
  • 0
    Строго говоря, последний хедер и ssl_stapling для A+ необязательны.
    Для A+ пока достаточно иметь нормальный cipherlist и поддержку HSTS, Forward Secrecy, TLS_FALLBACK_SCSV (сборка с openssl > 1.0.1i).
  • +2
    ssl on
    уже устарел
    Вместо этой директивы рекомендуется использовать параметр ssl директивы listen.
    nginx.org/ru/docs/http/ngx_http_ssl_module.html#ssl
    • 0
      Хотя у вас он уже указан. ;)
  • 0
    Хочу предупредить по поводу StartSSL: их CA-сертификата нет в списках доверенных сертификатов Oracle JVM. Поэтому HTTPS-фронтенд для Java-клиентов с таким сертификатом сделать не получится.

    А в остальном конфигурация похожа на наш фронтенд, что успокаивает, т.к. была сделана за день и без долгих раздумий :)
    • 0
      Да, Java 6/45 не проходит тест
      • +1
        На всякий случай, чтобы у вас было понимание происходящего: SSL Labs не умеет (на данный момент) проверять доверие к сайту для каждого симулированного клиента, проверяется физическая возможность подключения без учёта доверия. Java 6 не проходит тест из-за невозможности обработки параметров Диффи-Хеллмана больше 1024 бит.

        Java 6 прошла бы тест Handshake simulation при отсутствии ssl_dhparam в конфиге (даже несмотря на недоверие к StartCom), но все наборы шифров с использование традиционного Диффи-Хеллмана были бы помечены слабыми. A+ на данный момент такие сайты всё ещё получают, но это баг в рейтинге, который уже исправляется.
        • 0
          Ещё java 6 и всякая win xp не пройдут, если есть SNI.
          • +1
            Есть ещё такой момент: возможность посещения сайта такими клиентами зависит от сертификата и конфигурации дефолтного HTTPS-хоста. Даже если SNI-хост поддерживает только самые современные протоколы и шифры, старые клиенты без поддержки SNI могут посещать ваш сайт в случае наличия общих алгоритмов с дефолтным хостом. В таком случае сначала клиенты получают ошибку несовпадения адреса сервера (чужой сертификат), в случае игнорирования сайт открывается, но сединение аутентифицировано и зашифровано сертификатом и настройками дефолтного хоста, а не вашего. Видите проблему безопасности?
            Такая проблема возможна и с современными браузерами, особенно Internet Explorer, где поддерживаемые протоколы SSL/TLS переключаются проще всего. Речь идёт о поддержке браузером SSL 2. Это вынуждает браузер отправлять сообщение ClientHello в соответствующем формате, который не поддерживает расширения, включая SNI. Таким образом, в случае включённого SSL 2 посетитель так же получит ошибку несовпадения адреса и шифрование соединения чужим ключом. Так может продолжаться до бесконечности. Вместо чужого сертификата сервер должен сразу обрывать соединение в случае получения ClientHello в формате SSL 2, что вынудит пользователя поправить настройки браузера.

            Подведём итог:
            — Сервер не должен обслуживать клиентов без поддержки SNI, то есть у таких старых клиентов не должно быть общих алгоритмов с дефолтным хостом. Самый эффективный метод — дефолтный сертификат ECDSA вместо RSA. Если клиент не поддерживает SNI, он также не поддерживает ECDSA, и в результате получит ошибку рукопожатия вместо чужого сертификата. С марта 2015 это утверждение справедливо для всех симулируемых в SSL Labs клиентов.
            — Сервер не должен быть совместим с рукопожатиями SSL 2. Посмотреть можно в самом конце отчёта SSL Labs: SSL 2 handshake compatibility. Методы решения этой проблемы ещё до конца не вывел, но вопрос прорабатывается :).

            P.S. Уж столько комментариев оставил, что можно было и свою статью запилить.
  • +3
    Добавлю, что при «ssl_stapling», nginx сам лезет в интернет за OCSP ответом.
    В схемах, где выхода в интернет нет (некоторые типы балансировки и т.д.), это не заработает.
    Там можно попробовать «ssl_stapling_file».
  • +1
    Gist, всё давно известно, только никому не приходило в голову по этому поводу писать статьи на хабр. Посмотрите, вдруг что интересное можно перенести в статью.
  • 0
    Полезная заметка.
    Ещё более полезные комментарии.
    Особенно тот, который ведёт на gist.github.com/plentz/6737338 «Best nginx configuration for improved security(and performance)»
  • +1
    >>Ну и директивой ssl_prefer_server_ciphers on; принуждаем nginx это всё строго соблюдать.

    На самом деле нет. ssl_prefer_server_ciphers on — указывает, чтобы при использовании протоколов SSLv3 и TLS серверные шифры были более приоритетны, чем клиентские и все.

    А относительно заголовков Content-Security-Policy и Content-Security-Policy-Report-Only нужно быть очень аккуратным и вначале тестировать политику через Content-Security-Policy-Report-Only и только потом писать заголовки Content-Security-Policy
    На этот счет есть хорошая статья от Yandex -> http://habrahabr.ru/company/yandex/blog/206508/

    И есть пара хороших сервисов для сбора отчетов и тестирования:
    https://report-uri.io — для сбора отчетов о нарушении Content-Security-Policy и HTTP Public Key Pinning
    https://securityheaders.io — удобный сервис для просмотра заголовков, которые отдает Ваш сервер.

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.