вторник, 17 ноября 2015 г.

Установка бесплатного сертификата от letsencrypt.org

Я являюсь участником закрытого бета-тестирования https://letsencrypt.org/.
Тут я расскажу, как получить бесплатный сертификат от Let's Encrypt.
Зарегистрироваться в закрытой бете можно тут.
3 декабря 2015 года, планируется запуск открытого бета-тестирования, поэтому ссылка выше уже может быть неактуальна.
UPD: 3 декабря запустили публичную бету, поэтому нет нужды регистрироваться в закрытой бете.

Сертификат дается на три месяца, скорее всего так оно и останется, ибо сами разработчики объясняют это сохранением безопасности, мол времени скомпрометировать шифр гораздо меньше, нежели если бы сертификат генерился на год вперед.

После регистрации в бета-тестировании, должно придти письмо:

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

Собственно установка:
# yum install git
# cd /tmp
# git clone https://github.com/letsencrypt/letsencrypt
# cd letsencrypt

Запускаем инсталлятор сертификатов в ручном режиме (-a manual):
# ./letsencrypt-auto --agree-dev-preview --server \https://acme-v01.api.letsencrypt.org/directory -a manual auth

Соглашаемся с тем, что адреса будут доступны публично, указываем почту для восстановления, а также домены, для которых генерятся сертификаты:

Далее инсталлятор предлагает подтвердить владение доменом:
Make sure your web server displays the following content at
http://vps.amet13.name/.well-known/acme-challenge/411V162ufTxn0p07NigsNHkPkNsFfs86bDYfACcQYTc before continuing:

411V162ufTxn0p07NigsNHkPkNsFfs86bDYfACcQYTc.yBwdvCu_zpol-e8v97glKXXx0XsbRwo39viXWlB3SwU

Content-Type header MUST be set to text/plain.

If you don't have HTTP server configured, you can run the following
command on the target server (as root):

mkdir -p /tmp/letsencrypt/public_html/.well-known/acme-challenge
cd /tmp/letsencrypt/public_html
printf "%s" 411V162ufTxn0p07NigsNHkPkNsFfs86bDYfACcQYTc.yBwdvCu_zpol-e8v97glKXXx0XsbRwo39viXWlB3SwU > .well-known/acme-challenge/411V162ufTxn0p07NigsNHkPkNsFfs86bDYfACcQYTc
# run only once per server:
$(command -v python2 || command -v python2.7 || command -v python2.6) -c \
"import BaseHTTPServer, SimpleHTTPServer; \
SimpleHTTPServer.SimpleHTTPRequestHandler.extensions_map = {'': 'text/plain'}; \
s = BaseHTTPServer.HTTPServer(('', 80), SimpleHTTPServer.SimpleHTTPRequestHandler); \
s.serve_forever()" 

Press ENTER to continue

Для этого либо создаем файлик который просят в корневом каталоге домена (если домен настроен), если же виртуальный хост для домена не настроен или http-сервер не установлен, то можно запустить простенький http-сервер на python, который предлагает letsencrypt.
У меня не было настроено виртуальных хостов для vps.amet13.name и le.amet13.name, поэтому я запустил команды в параллельной вкладке SSH-сессии:
# mkdir -p /tmp/letsencrypt/public_html/.well-known/acme-challenge
# cd /tmp/letsencrypt/public_html
# printf "%s" 411V162ufTxn0p07NigsNHkPkNsFfs86bDYfACcQYTc.yBwdvCu_zpol-e8v97glKXXx0XsbRwo39viXWlB3SwU > .well-known/acme-challenge/411V162ufTxn0p07NigsNHkPkNsFfs86bDYfACcQYTc
# $(command -v python2 || command -v python2.7 || command -v python2.6) -c \
"import BaseHTTPServer, SimpleHTTPServer; \
SimpleHTTPServer.SimpleHTTPRequestHandler.extensions_map = {'': 'text/plain'}; \
s = BaseHTTPServer.HTTPServer(('', 80), SimpleHTTPServer.SimpleHTTPRequestHandler); \
s.serve_forever()"

Когда эта команда запущена, маленький веб-сервер слушает 443 порт.
Возвращаемся в первоначальную SSH-сессию и нажимаем кнопку Enter, после этого сертификаты должны установиться:
IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at
   /etc/letsencrypt/live/vps.amet13.name/fullchain.pem. Your cert will
   expire on 2016-02-15. To obtain a new version of the certificate in
   the future, simply run Let's Encrypt again.

Если доменов несколько, то аналогично сделать с другим доменом.
Осталось только создать виртуальные хосты:
# cd /etc/nginx/conf.d/
# vim vps.amet13.name.conf
server {
   listen 443 ssl;
   server_name vps.amet13.name;
   ssl on;
   ssl_certificate /etc/letsencrypt/live/vps.amet13.name/fullchain.pem;
   ssl_certificate_key /etc/letsencrypt/live/vps.amet13.name/privkey.pem;
   ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
   ssl_ciphers HIGH:!aNULL:!MD5;
   root /var/www/vps.amet13.name;
   index index.html;
}
# mkdir /var/www/vps.amet13.name
# echo vps.amet13.name > /var/www/vps.amet13.name/index.html
# аналогично создаем для le.amet13.name
# systemctl start nginx

Идем по ссылке: https://vps.amet13.name/

20 комментариев:

Анонимный комментирует...

Здравствуйте. Подскажите, пожалуйста, только начинаю разбираться с sll и еще много что не понимаю., не могу разобраться Let's Encrypt можно использовать на виртуальном хостинге, если там нет виртуального сервера? Т.е. сформировать сертификат на рабочей машине, а затем скопировать его на хостинг?

Amet13 комментирует...

Привет. Да, можно. Но для этого нужно будет на время сменить A-запись для домена на другой IP (например на IP впски своей), затем на впске сгенерировать сертификат и снова сменить A-запись для домена на хостинговый IP.

Анонимный комментирует...

Привет. Не могу заново поставить сертификат.
Получаю Self-verify of challenge failed.

Домен работает уже с адресом https может из-за этого?

Amet13 комментирует...

Привет.
Что-то делаете не так.
Со времени беты многое могло поменяться.
Почитайте тут как нужно обновлять сертификат: https://github.com/certbot/certbot

Анонимный комментирует...

Спасибо за ответ!!!
Начну по порядку как я делаю.
1. Скачал git clone https://github.com/letsencrypt/letsencrypt
после командой перехожу в директорию cd letsencrypt

2. даю команду на генерацию
./letsencrypt-auto --agree-dev-preview --server \https://acme-v01.api.letsencrypt.org/directory -a manual auth
получаю предложение ввести имя домена (ввожу без https просто domain.ru

4. получаю инструкцию
mkdir -p /tmp/certbot/public_html/.well-known/acme-challenge
cd /tmp/certbot/public_html
printf "%s" 4wMGodmcn2zBMeFJ5n_qBI64P0Lls4QrBzL5YUFBRRo.ULNeRsvyYQqXootzk4oi6_IB-e6MJqXy7wuDp0ffs9k > .well-known/acme-challenge/4wMGodmcn2zBMeFJ5n_qBI64P0Lls4QrBzL5YUFBRRo
# run only once per server:
$(command -v python2 || command -v python2.7 || command -v python2.6) -c \
"import BaseHTTPServer, SimpleHTTPServer; \
s = BaseHTTPServer.HTTPServer(('', 80), SimpleHTTPServer.SimpleHTTPRequestHandler); \
s.serve_forever()"

5. Выполняю в отдельной вкладке терминала
mkdir -p /tmp/certbot/public_html/.well-known/acme-challenge
cd /tmp/certbot/public_html
printf "%s" 4wMGodmcn2zBMeFJ5n_qBI64P0Lls4QrBzL5YUFBRRo.ULNeRsvyYQqXootzk4oi6_IB-e6MJqXy7wuDp0ffs9k > .well-known/acme-challenge/4wMGodmcn2zBMeFJ5n_qBI64P0Lls4QrBzL5YUFBRRo

6.Жму Press ENTER to continue
и получаю....Self-verify of challenge failed.

Сайт работает под https также есть .htaccess с содержимым
RewriteEngine on
RewriteCond %{HTTPS} off
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

Обновить не получится... с сервера удалено всё что было связано с предыдущей установкой сертификата.

Что делать... не пойму.

Анонимный комментирует...

Кстати https://github.com/certbot/certbo 404

Анонимный комментирует...

Оу... написал большую портянку а она не появилась. Печать.

Amet13 комментирует...

В вашем случае скорее всего ошибка возникает из-за того, что порты 80/443 слушаются веб-сервером (apache или nginx).
Из-за этого команда:
$(command -v python2 || command -v python2.7 || command -v python2.6)...
не срабатывает и не может забиндить нужные порты.
Поэтому предварительно перед генерацией сертификата нужно на время отключить apache или nginx, в зависимости от того, что у Вас установлено.

Анонимный комментирует...

То есть мне нужно остановить nginx

а потом делать

mkdir -p /tmp/certbot/public_html/.well-known/acme-challenge
cd /tmp/certbot/public_html
printf "%s" 4wMGodmcn2zBMeFJ5n_qBI64P0Lls4QrBzL5YUFBRRo.ULNeRsvyYQqXootzk4oi6_IB-e6MJqXy7wuDp0ffs9k > .well-known/acme-challenge/4wMGodmcn2zBMeFJ5n_qBI64P0Lls4QrBzL5YUFBRRo

после

# run only once per server:
$(command -v python2 || command -v python2.7 || command -v python2.6) -c \
"import BaseHTTPServer, SimpleHTTPServer; \
s = BaseHTTPServer.HTTPServer(('', 80), SimpleHTTPServer.SimpleHTTPRequestHandler); \
s.serve_forever()"

и только после этого Press ENTER to continue???

Amet13 комментирует...

Да, все делаете как обычно, единственно перед запуском питоновского веб-сервера, стопните nginx.
По идее ошибок быть не должно.

Анонимный комментирует...

Не вышло...
Получил
Unable to reach
Unable to reach
http://domain.ru/.well-known/acme-challenge/vUW6O3-PqYMOC1mP7pp
2RUvVEK0xjgDLUX1bpfNs3E:
('Connection aborted.', error(104,'Connection reset by peer'))

Собственно я директорию .well-known и его содержимое в корень сайта не переносил. Его нужно перенести?

Amet13 комментирует...

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

Анонимный комментирует...


Скопировал директории с файлком в корень сайта... не помогло.
Не подскажете где логи смотреть?

Amet13 комментирует...

В той ssh-сессии в котором запущен питоновский веб-сервер.

Анонимный комментирует...

Ради интереса попытался скачать файлик
wget http://domain.ru/.well-known/acme-challenge/Fvk03EKYWjJGerZ3qMJq9oa9in1ZZP6Hgtn0Y7WoI_A

... соединение установлено.
HTTP-запрос отправлен. Ожидание ответа... 404 Not Found
2016-07-05 13:57:19 ОШИБКА 404: Not Found.

Анонимный комментирует...

Простите за оффтоп... )))

А Вы случайно не знаете как создать цепочку сертификатов startSSL в панели ispmanager?

Amet13 комментирует...

Промежуточные и корневые сертификаты можно найти тут: startssl.com

Анонимный комментирует...

Я не могу саму цепочку выстроить, показывает ошибку:
"Ошибка: Цепочка сертификатов имеет неверное значение". Интересует порядок, с какого из файлов содержимое первое, какое второе...

На этом сайте можно проверить на ошибки, там пример с сайтом startssl.com
https://www.sslshopper.com/ssl-checker.html#hostname=startssl.com

Amet13 комментирует...

Ищите, я например по первой ссылке из Яндекса сразу нашел.

Анонимный комментирует...

Ну ОК. Я и вправду достал своим нубством )))) Пойду искать.