Let’s Encrypt

С середины ноября, с подачи друга, я активно стал следить за прекрасным начинанием Let’s Encrypt:
Ну наконец-то, кто-то решил массово выдавать халявные ssl-сертификаты. В 2015ом...
— Nick Mokrinsky (@mokrinsky) November 17, 2015
До декабря 2015, сертификаты продавались исключительно за дикий оверпрайс. А теперь появился Let’s Encrypt, и выдает настоящие сертификаты бесплатно.
Для чего нужен SSL-сертификат? Трафик с сайта может быть незашифрованный или зашифрованный и подписанный сертификатом. Во втором случае подтверждается, что весь трафик идет именно с этого сайта и по пути не подменяется злоумышленниками. В первом случае — ничего не известно.
Сертификаты отличаются степенью идентификации. Для личного сайта подходит простой. А вот у Рокетбанка в строку адреса еще добавляется модное 🔒Rocket LLC.
Раньше простой сертификат можно было бесплатно получить только у StartSSL по сложной инструкции на Хабре. Я установил такой сертификат на m4rr.ru полгода назад, и периодически наблюдал, как на каком-нибудь компьютере сайт не открывался due to SSL issue.
Стоит заметить, что корневые центры сертификации подтверждают сертификаты Let’s Encrypt. А это значит, современные браузеры считают их правильными!
Получить и установить сертификат Let’s Encrypt божественно просто. Пара важных замечаний:
- — система Let’s Encrypt сейчас в стадии бета-тестирования — обратите внимание, если вам это не подходит;
- — сертификаты выдаются на 90 дней;
- — не забудьте сделать бекап вашей виртуалки до начала.
В документации все хорошо описано, но нет конкретного примера для веб-сервера nginx. Поэтому, я опишу свой опыт.
Чтобы начать работу, нужно склонировать на свой сервер репозиторий letsencrypt, перейти в эту директорию и запустить враппер letsencrypt-auto:
$ git clone https://github.com/letsencrypt/letsencrypt
$ cd letsencrypt
$ ./letsencrypt-auto --help
После этого нужно запустить создание сертификата. Например, для двух доменов — m4rr.ru и blog.m4rr.ru — код будет таким:
$ ./letsencrypt-auto certonly --standalone -d m4rr.ru -d blog.m4rr.ru
Если в это время nginx был запущен, то программа попросит выключить его на время, чтобы она смогла слушать :80 порт.
Когда все будет готово, система сообщит об этом. Жирным выделено два важных момента:
Congratulations! Your certificate and chain have been saved at /etc/.../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.
Дальше нужно просто внести информацию о сертификате в конфиг сервера. Например:
server {
listen 443 ssl;
server_name m4rr.ru;
ssl on;
ssl_certificate /etc/.../fullchain.pem;
ssl_certificate_key /etc/.../privkey.pem;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers ALL:!aNULL:!ADH:!eNULL:!LOW:!EXP:RC4+RSA:+HIGH:+MEDIUM;
}
И добавить в календарь на Маке специальное событие:

А через 90 дней, я расскажу как это автоматизировать ;)
Ссылки по теме:
Конкретного примера для nginx нет, потому как они пишут плагин для nginx, который будет все делать автоматом — править конфиги, определять, где лежат файлы сайта и т. п. Но на данный момент этот плагин находится в зачаточном состоянии и толку от него, как от козла молока.
К слову, есть небольшая тонкость для тех, у кого аптайм сервера критичен. Лучше использовать не −−standalone, а −−webroot. То есть вот так:
./letsencrypt-auto certonly −−webroot -w <путь к корневому каталогу сайта> -d <домен сайта> -d <алиас основного домена, если есть>
Тогда не будет ругаться на запущенный сервер, не потребует перезапуск, а лишь положит файлы в папку -w и отработает стандартную процедуру проверки.
Вообще их штатный клиент достаточно сомнительный, о чем ребята трубили еще во времена закрытой беты. Я пока не пробовал, но коллеги советуют вот эти два: https://github.com/xenolf/lego и https://github.com/hlandau/acme.t. Оба используют API Let’s Encrypt, но написаны энтузиастами, которые не оценили штатный клиент на, упаси господи, питоне :)
Комментарий к посту из Фейсбука:
1)если версия nginx 1.8 и выше, веключай спиди, http2 пока в бете, включать так listen 443 ssl spdy;
2)надо помнить, что матчинг в сервера по server_name происходит ПОСЛЕ ssl handshake, поэтому если у тебя один nginx обслуживает несколько разных доменов в разных server, то нужен ОДИН общий сертификат на все домены, (в certificate subject alt name должны быть перечислены все)
3)если ты конфигурируешь не дырявое очко, а безопасный сервис, тебе надо разделить твой сертификат на ключ и на сертификат (у тебя не очевидно сразу ли тулза генерит ключ отдельно а цепочку отдельно, но в конфиге потом ключ отдельно вставлен, так вот в самом серте ключа быть не должно), и на ключ надо выставить права 600 для рута (chown root; chmod 600)
4)чиферы лучше настроить так:
ssl_prefer_server_ciphers on;
ssl_ciphers kEECDH+AESGCM+AES128:kEECDH+AES128:kRSA+AESGCM+AES128:kRSA+AES128:DES-CBC3-SHA:!RC4:!aNULL:!eNULL:!MD5:!EXPORT:!LOW:!SEED:!CAMELLIA:!IDEA:!PSK:!SRP:!SSLv2;
при этом обновив openssl(+libssl естесн) до последней версии
5)если у тебя не хуевый стартап, а уже нормальный стартап, которым кто-то пользуется(читай средне или высоконагруженный твой сервис), то лучше включить еще и ssl session cache, чтобы поэкономить время на хэндшейках для клиентов, которые у тебя уже были. Вот так:
ssl_session_cache shared:SSLCACHE:64m;
ssl_session_timeout 24h;
плюс настроить кипалайв, не забыть, если еще не (это не только для https хорошо)
keepalive_timeout 120 120;
keepalive_requests 128;
6)Ну и если хошь чтоб к тебе всегда ходили по https (ты ж не просто так с сертификатом ебался) не забудь включить hsts:
add_header Strict-Transport-Security «max-age=31536000»;