Переходим на HTTPS на Nginx: шпаргалка

Уже второй раз сталкиваюсь с задачей «поставь https на наш сервер» от моего босса, поэтому решил сделать для самого себя шпаргалку, а заодно и для всех остальных. Итак, ситуация следующая: к нам пришел босс и заявил, что ему нужен https. Под катом я напишу 5 простых шагов, как все сделать буквально за час. Приступим.

0. Отправляем босса покупать нам доменное имя, если его у нас еще нет — без доменного имени https поставить нельзя. После покупки не забываем прописать NS-записи в панели управления нашего сервера, а также A-запись.

1. Отправляем босса за SSL-сертификатом на nic.ru и пускай он там покупает себе thawte 123 сертификат, а мы тем временем сгенерируем для него CSR-запрос.

2. Заходим по SSH на сервер и далее пишем:
openssl genrsa -out private.key 2048


3. Создаем CSR-запрос вот этой строкой:
openssl req -new -sha256 -key private.key -out csr.csr
, причем информацию (типа company name, email) берем через сервис whois (зачем еще раз спрашивать все у босса, когда можно все узнать самостоятельно).

4. В это время босс дошел до той стадии, когда ему потребуется только что созданный нами CSR-запрос. Мы говорим ему, чтобы он залез по SSH на сервер и командой
cat csr.csr
скопировал код и вставил его куда нужно.

5. Затем босс попросит нас подтвердить владение доменом через создание почты типа admin@our-domain.com. Для этого мы воспользуемся сервисом «почта для доменов» от «Яндекса». Создаем там почту и сообщаем боссу логин/пароль.

6. Создаем bundled PEM-сертификат. Босс должен будет переслать письмо от thawte, в котором в PEM-формате будет лежать наш сертификат. Мы должны открыть sublime text и вставить туда этот сертификат, а также скачать промежуточный сертификат с сайта thawte, вставить его в тот же файл и сохранить в /etc/nginx/certificate_bundled.crt. Внимание! Сначала идет то, что нам выслал босс, а уже потом — промежуточный сертификат, который мы скачали по той ссылке.

7. Копируем приватный ключ туда же командой
mv private.key /etc/nginx/private.key


8. Открываем конфиг /etc/nginx/nginx.conf и настраиваем согласно инструкциям в публикации «Настраиваем HTTPS-сервер на nginx». Если вкратце, нам надо в /etc/nginx/nginx.conf в секцию http прописать
    ssl_session_cache   shared:SSL:10m;
    ssl_session_timeout 5m;
    ssl_prefer_server_ciphers on;
    ssl_stapling on;
    resolver 8.8.8.8;

Затем в /etc/nginx/conf.d/example_ssl.conf в секции server:
server {
    listen       443 ssl;
    server_name  www.site.ru;

    root /var/www/html/web/; #не забываем здесь тоже указать свой root, если он какой-то специфический как у меня
    index index.php index.html;
    set $yii_bootstrap "index.php";
   
    # здесь немного конфига для yii, для тех кто его использует
    location / {
        # Define the index
        index  index.html $yii_bootstrap;
        try_files $uri $uri/ /$yii_bootstrap?$args;
    }

    # Any of the protected directories, we will ignore.  There is no reason
    # to share out the protected web spaces
    location ~ ^/(commands|components|config|controllers|models|vendor|views) {
        deny  all;
    }

    #avoid processing of calls to unexisting static files by yii
    location ~ \.(js|css|png|jpg|gif|swf|ico|pdf|mov|fla|zip|rar)$ {
        try_files $uri =404;
    }
    .......

    keepalive_timeout   60;
    ssl_certificate      certificate_bundled.crt;
    ssl_certificate_key  private.key;
    ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers  "RC4:HIGH:!aNULL:!MD5:!kEDH";
    add_header Strict-Transport-Security 'max-age=604800';

    .......
    location ~ \.php$ {
    .......
        fastcgi_param HTTPS on; # Для php-fpm
    .......
    }
}


9. Отключаем пароль для приватного ключа командой:
openssl rsa -in /etc/nginx/private.key -out /etc/nginx/private.key


10. Перезагружаем nginx командой
nginx -s reload
и — вуаля!
Share post
AdBlock has stolen the banner, but banners are not teeth — they will be back

More
Ads

Comments 60

    +21
    А затем идём на www.ssllabs.com/ и проверяем что же нам скажет сей сервис. Overall Rating — C.
    Меняем протоколы на:
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    А ssl_ciphers выбираем отсюда: wiki.mozilla.org/Security/Server_Side_TLS#Recommended_configurations
      +4
      Тут много что неправильно. Вот наилучшая возможная конфигурация nginx с объяснениями на GitHub Gist, а вот результат теста таких настроек — оценка A+.
      А вот статья и видео с YAC 2014 от Эльдара Заитова, он простыми словами и безумно интересно рассказывает, что же происходит на уровне пониже, когда вы заходите на сайт с использованием HTTPS.
      +4
      SSLv3 то зачем? Уязвимость POODLE же.
      ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
      

      а еще хорошо
      ssl_prefer_server_ciphers   on;
      
        +48
        Вот пример моего конфига с которым ssllabs.com дает A+
        listen                      443 ssl spdy;
        ssl                         on;
        ssl_protocols               TLSv1.2 TLSv1.1 TLSv1;
        ssl_session_cache           shared:SSL:20m;
        ssl_session_timeout         10m;
        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;
        
        resolver                    8.8.8.8 8.8.4.4 valid=300s;
        resolver_timeout            10s;
        add_header                  X-Frame-Options             "DENY";
        add_header                  X-Content-Type-Options      "nosniff";
        add_header                  Strict-Transport-Security   "max-age=31536000";
        add_header                  Public-Key-Pins 'pin-sha256="[SOME_BASE64]"; max-age=5184000;';  #[SOME_BASE64] надо выставлять свое, гуглить как считать Public-Key-Pins
        ssl_stapling            on;
        ssl_trusted_certificate /etc/nginx/ssl/[SITE]/trustchain.pem;
        ssl_certificate         /etc/nginx/ssl/[SITE]/server.crt;
        ssl_certificate_key     /etc/nginx/ssl/[SITE]/server.key;
        ssl_dhparam             /etc/nginx/ssl/[SITE]/dh.pem;        #openssl dhparam 2048 -out dh.pem
        
          +39
          Очередная статья, где комментарии полезней самой статьи…
            +9
            Так и правильно же, на то оно и сообщество, коллеги — подняли тему и делимся опытом.
              –6
              Вот только эти комментаторы не удосужились написать СВОЮ статью… ;)
                +1
                А зачем? Почти все указанное мной описано в этой статье, нафига плодить? А вот текущую дополнить можно, раз уж она есть.
              +5
              Строка в конфиге:
              add_header                  X-Frame-Options             "DENY";
              


              вызовет ошибку ERR_BLOCKED_BY_CLIENT для сайтов, которые используют загрузку контента в фреймы. У меня была проблема с WYSIWYG-редактором tinyMCE — открывались пустые окна.

              Чтобы разрешить загрузку в фреймах, я поменял «DENY» на «SAMEORIGIN».
                0
                Да, это частный случай конфигурации (у меня нет фреймов, по этому я их и заблочил), не догадался пометить комментарием. Ну а потом у меня же не статья а пример моего конфига :)
                0
                Маленькая ремарка: для А+ все сертификаты должны быть подписаны SHA-2 (SHA-256)
                  0
                  Настройки как у вас, алгоритм SHA384withRSA, но А+ не получаю, только А.
                    0
                    Проблема (по общению в ЛС) в отсутствии TLS_FALLBACK_SCSV (скорее всего старая версия OpenSSL).
                    А+ может отсутствовать и по причине неподходящих (старых и/или уязвимых версий ПО) поэтому не забывайте обращать внимание и на этот аспект. Дело не только в конфиге nginx.
                      0
                      Да проблема была в этом, после обновления OpenSSL получил А+, спасибо за подсказку!
                  0
                  Подскажите, у вас в trustchain.pem корневой+промежуточные или же только промежуточные?
              0
              Добавлю, что если веб-сервис предназначен для внутренних нужд компании, то можно использовать самоподписанный сертификат.
                +2
                Ну лучше все же использовать внутренний CA. Чтобы не оказаться в ситуации, когда есть 100 внутренних сервисов — и у всех свои самоподписанные сертификаты…
                  0
                  Конечно. Я бы даже сказал, что если нужно 100 сервисов, то лучше PKI развернуть.
                +3
                Час))) это с пятью перекурами?
                  0
                  Час это в первый раз )
                  +9
                  > Мы говорим ему, чтобы он залез по SSH на сервер и командой
                  > cat csr.csr
                  > скопировал код и вставил его куда нужно.

                  Отличный у вас босс :)
                  — Дай мне CSR
                  — Сам зайди на сервер и возьми
                    0
                    А так же «сам купи домейн», «сам купи сертификат» и прочее. Можно смело добавить «сам сделай https».
                      0
                      мы пытались переслать по скайпу, но он видимо коверкает как-то символы, в итоге «залезть по SSH» оказалось самым лучшим способом
                        0
                        skype — лучший файлообменник! :)
                        Надо просто csr сохранять в файлик и пересылать файлом.
                      +1
                      Неплохо было бы написать, что важен порядок подключения сертификатов (сначала основной, затем промежуточный)
                        +1
                        По этому поводу сходу две ссылки:
                        habrahabr.ru/post/195808/
                        habrahabr.ru/company/yandex/blog/249771/

                        Зачем нужно еще одно хауту — неясно.
                          0
                          Данная статья смахивает на заметку из раздела «для себя».
                          В принципе, автор и написал: «поэтому решил сделать для самого себя шпаргалку, а заодно и для всех остальных.»
                          Для себя шпаргалка удалась, а вот для всех остальных — спорно.
                          +1
                          Создаем bundled PEM-сертификат. Босс должен будет переслать письмо от thawte, в котором в PEM-формате будет лежать наш сертификат. Мы должны открыть sublime text и вставить туда этот сертификат, а также скачать промежуточный сертификат с сайта thawte, вставить его в тот же файл и сохранить в /etc/nginx/certificate_bundled.crt.

                          А не проще что-то вроде?
                          $ cat our.crt thawte.crt > /etc/nginx/certificate_bundled.crt
                          

                          Копируем приватный ключ туда же командой
                          mv private.key /etc/nginx/private.key
                          


                          Все таки не копируете, а перемещаете, может так случиться, что кто-то долго будет искать оригинал, когда сотрет перемещенный.
                          openssl rsa -in /etc/nginx/private.key -out /etc/nginx/private.key
                          


                          Тоже сомнительно перетирать оригинал, лучше сделать просто новый файл без пароля:
                          openssl rsa -in /etc/nginx/private.key -out /etc/nginx/private_nopass.key
                          
                            0
                            Проще уж сразу делать ключ без пароля:

                            openssl genrsa -out private.key 2048
                            +1
                            8.8.8.8 давно уже не торт. Все чаще бывают перебои и не раз замечен в «забывании» доменов. Сегодня резолвит домен, завтра — нет. Для тестовой настройки, чтобы адрес сразу из головы — можно. Для продакшн — не подходит.
                              0
                              А в ситуации
                              Добавлю, что если веб-сервис предназначен для внутренних нужд компании, то можно использовать самоподписанный сертификат.
                              может сильно помешать.
                                0
                                Есть ли рекомендации, что использовать вместо него? А то недавно перешел на яндексовский днс, когда гугловский лежал.
                                Пока не было проблем, но мало ли…
                                  0
                                  Если свой поднимать нет желания — можно попробовать resolv.conf в таком порядке:

                                  208.67.222.222
                                  208.67.220.220
                                  4.2.2.2
                                  4.2.2.1

                                  первые два — сервера OpenDNS, два последних — DNS, которые обслуживаются Level 3 из меркантильных соображений (при ошибке резолвинга они подставляют адрес searchguide.level3.com).
                                0
                                без доменного имени https поставить нельзя
                                А просветите по п. 0 — разве это так? На ip разве нельзя получить сертификат? Понятно, что боссу нужно domain.com, но все же.
                                И еще, не нужно ли послать босса купить и выделенный ip заодно?
                                  0
                                  А просветите по п. 0 — разве это так? На ip разве нельзя получить сертификат? Понятно, что боссу нужно domain.com, но все же.
                                  Можно: www.gogetssl.com/comodo-ssl-certificates/comodo-instantssl-premium/
                                  Current SSL may secure IP address

                                  И еще, не нужно ли послать босса купить и выделенный ip заодно?
                                  Только если требуется совместимость с Internet Explorer на Windows XP. Без выделенного IP придётся каждый раз игнорировать предупреждение безопасности.
                                    0
                                    Эм, т.е. уже можно привязать SSL не к ip, а к доменному имени?
                                    И повесить на один ip несколько SSL доменов?
                                    И все (кроме IE на XP) поддерживают и не ругаются?
                                    Вот до чего техника дошла.
                                        0
                                        Да, ещё ругаются Safari на Windows XP и стандартный браузер Android 2. Есть ещё более экзотические случаи, но чаще всего встречающиеся перечислил.

                                        В общем, выше ссылку написали.
                                          0
                                          А что с мобильными браузерами?
                                            +1
                                            — Стандартный браузер Android 1 и Android 2, а также использующий родной HTTPS-стек от ОС
                                            — BlackBerry по 7.1 включительно
                                            — Windows Mobile (не путать с Windows Phone)
                                            — Symbian Series60
                                          +1
                                          Да, но с переменным успехом. SNI.
                                          Здесь про nginx.
                                          Здесь про Apache.
                                          0
                                          Можно: www.gogetssl.com/comodo-ssl-certificates/comodo-instantssl-premium/
                                          Current SSL may secure IP address


                                          Выдать сертификат для IP или же для .local можно, но до 31октября 2015 года, это последний день, с 1-го ноября поддержки SSL для IP или .local уже не будет, ни у одного провайдера…
                                        0
                                        У меня были проблемы с
                                        ssl_stapling on;

                                        когда было более одного хоста на одном сервере, использующих SSL.
                                          +6
                                          Поднять SSL на сервере и перейти на https — не одно и тоже. Переход на https подразумевает, что вы как минимум перелопатите все содержимое и скрипты сервера, чтобы избежать mixed content, разберетесь с куками, чтобы они стали secure и настроите HSTS для поддоменов. Без этого практического толку от поднятия ssl ноль. Вы как были уязвимы к MitM так и остались.
                                            +1
                                            С самого начала надо подключать ресурсы не указывая протокол явным образом.
                                              0
                                              Разумеется, но по опыту в реальной жизни так не бывает. Если бы разработчики думали о совместимости между протоколами, то они бы сразу думали и о https-версии.
                                                +1
                                                Бывает, конечно, вы чего. Если с самого начала научить участников проекта ставить два слеша, вместо «http://», то они и будут ставить, даже просто из-за лени — на целых 5 символов меньше печатать!
                                              0
                                              Раз такая жара, то подскажите пожалуйста сервис. На нем вбиваешь домен, он сканирует его и находит объекты, которые подключены не по https протоколу.
                                                0
                                                Возможно такие и есть, но средства автоматического аудита в любом случае требуют настройки под конкретный сервис, поэтому лучше сразу использовать тулзы типа skipfish и включить CSP в режиме Content-Security-Policy-Report-Only чтобы отслеживть mixed content.
                                                  0
                                                +3
                                                2. Заходим по SSH на сервер и далее пишем:
                                                openssl genrsa -des3 -out private.key 2048
                                                9. Отключаем пароль для приватного ключа командой:
                                                openssl rsa -in /etc/nginx/private.key -out /etc/nginx/private.key
                                                Бред какой-то. Зачем сначала создавать ключ с параметром des3, а потом отключать пароль, если можно сразу создать ключ с параметром nodes?
                                                2. Заходим по SSH на сервер и далее пишем:
                                                3. Создаем CSR-запрос вот этой строкой:
                                                Почему создание ключа и CSR разбивается на две команды? Вот так слабо?
                                                openssl req -new -newkey rsa:2048 -nodes -keyout private.key -out csr.csr
                                                  +2
                                                  Потому что так написано в одном частокопируемом мануале, и люди плохо понимающие что происходит просто его копируют.
                                                    0
                                                    Интересно, зачем вообще понадобилось в мануале des3, если это и так параметр по умолчанию? Вспомнилось.
                                                  +2
                                                  В команде к openssl надо еще -sha256 указать, SHA-1 очень-очень скоро будет неактуален.
                                                    0
                                                    В т.ч. 41 версия хрома уже будет ругаться на подпись SHA-1. Да и А+ у ssllabs не получить с SHA-1
                                                      0
                                                      Так теперь получается новый сертификат покупать или как-то можно пересоздать? У меня thawte123 и, как все уже давно поняли, в администрировании серверов я чайник…
                                                        0
                                                        Да, надо новый покупать.
                                                      –1
                                                      -

                                                      Only users with full accounts can post comments. Log in, please.