Привет! Думаю, в последние 2 года каждый из нас испытал на себе тренд ухода в HTTPS. Про это говорят все: на конференциях, в подкастах и блогах. Причин несколько. Во-первых, тема сесурити стала сильно актуальнее, чем раньше, из-за многочисленных взломов. Во-вторых, появились бесплатные SSL/TLS Certificates. Давайте тогда же посмотрим, как просто прикрутить сертификат ко своему сайту?
Начнём попорядку. Есть сайт (и одноименная организация) — Let’s Encrypt. По итогам 2017 года, это самый крупный SSL регистратор. Он выдал огромное количество сертов. Ещё бы, ведь они бесплатны! То есть, мы будем получать свой сертификат тут.
Есть одна проблема: Let’s Encrypt выдаёт сертификаты лишь только на 3 месяца. А ведь это так утомительно продлять сертификаты, а если ещё и доменов много — то це біда. К счастью для нас, был разработан умный, интелектуальный бот — https://certbot.eff.org/, который будет жить с нами и сам, когда прийдёт время (например, раз в месяц) будет ходить и продлять сертификат. Вам даже делать ничего не прийдётся.
Остаётся понять, как же это всё дело скрестить. Ведь тут тебе и боты, и сертификаты, и nginx, и докеры, и шмокеры, и композы. Мутное дело, сразу видно. Но ясен красен за нас уже всё сделано. Корневая вещь, которая создана — это специальный контейнер для ЛетсЭнкрипта — https://hub.docker.com/r/jrcs/letsencrypt-nginx-proxy-companion/. Этот контейнер позволяет использовать Nginx в качестве прокси, а сам он будет отвечать за регистрацию и продление сертификатов.
Теперь нам надо всё это дело подружить с docker-compose. На самом деле, у letsencrypt-nginx-proxy-companion много документации и примеров, как это можно сделать. Лично мне понравился этот пример — https://github.com/evertramos/docker-compose-letsencrypt-nginx-proxy-companion.
Первое, что вы должны сделать — это clone проекта — https://github.com/evertramos/docker-compose-letsencrypt-nginx-proxy-companion. Из этого проекта нам понадобяться следующие файлы:
Конечно же, в docker-compose.yml требуется добавить свои сервисы, которые вам нужны. Например так может выглядить итоговый композ-конфиг с одним бизнес-сервисом (контейнер gateway):
version: '3' services: nginx-web: image: nginx labels: com.github.jrcs.letsencrypt_nginx_proxy_companion.nginx_proxy: "true" container_name: ${NGINX_WEB} restart: always ports: - "${IP}:80:80" - "${IP}:443:443" volumes: - ${NGINX_FILES_PATH}/conf.d:/etc/nginx/conf.d - ${NGINX_FILES_PATH}/vhost.d:/etc/nginx/vhost.d - ${NGINX_FILES_PATH}/html:/usr/share/nginx/html - ${NGINX_FILES_PATH}/certs:/etc/nginx/certs:ro - ${NGINX_FILES_PATH}/htpasswd:/etc/nginx/htpasswd:ro nginx-gen: image: jwilder/docker-gen command: -notify-sighup ${NGINX_WEB} -watch -wait 5s:30s /etc/docker-gen/templates/nginx.tmpl /etc/nginx/conf.d/default.conf container_name: ${DOCKER_GEN} restart: always volumes: - ${NGINX_FILES_PATH}/conf.d:/etc/nginx/conf.d - ${NGINX_FILES_PATH}/vhost.d:/etc/nginx/vhost.d - ${NGINX_FILES_PATH}/html:/usr/share/nginx/html - ${NGINX_FILES_PATH}/certs:/etc/nginx/certs:ro - ${NGINX_FILES_PATH}/htpasswd:/etc/nginx/htpasswd:ro - /var/run/docker.sock:/tmp/docker.sock:ro - ./nginx.tmpl:/etc/docker-gen/templates/nginx.tmpl:ro nginx-letsencrypt: image: jrcs/letsencrypt-nginx-proxy-companion container_name: ${LETS_ENCRYPT} restart: always volumes: - ${NGINX_FILES_PATH}/conf.d:/etc/nginx/conf.d - ${NGINX_FILES_PATH}/vhost.d:/etc/nginx/vhost.d - ${NGINX_FILES_PATH}/html:/usr/share/nginx/html - ${NGINX_FILES_PATH}/certs:/etc/nginx/certs:rw - /var/run/docker.sock:/var/run/docker.sock:ro environment: NGINX_DOCKER_GEN_CONTAINER: ${DOCKER_GEN} NGINX_PROXY_CONTAINER: ${NGINX_WEB} gateway: container_name: gateway build: ./gateway hostname: gateway restart: always environment: VIRTUAL_HOST: ${DOMAINS} LETSENCRYPT_HOST: ${DOMAINS} LETSENCRYPT_EMAIL: ${LETSENCRYPT_EMAIL} networks: default: external: name: ${NETWORK}
Далее вам требуется немного поменять параметры окружения в .env. Итоговая версия файла может выглядить так:
# # docker-compose-letsencrypt-nginx-proxy-companion # # A Web Proxy using docker with NGINX and Let's Encrypt # Using the great community docker-gen, nginx-proxy and docker-letsencrypt-nginx-proxy-companion # # This is the .env file to set up your webproxy enviornment # Define the names for your local containers NGINX_WEB=nginx-web DOCKER_GEN=nginx-gen LETS_ENCRYPT=nginx-letsencrypt # Your external IP address IP=5.45.80.213 # Network name NETWORK=webproxy # NGINX file path NGINX_FILES_PATH=/etc/nginx/data # Your domain (or domains) DOMAINS=hixon.ru # Your email for Let's Encrypt register LETSENCRYPT_EMAIL=hixon@yandex.ru
После этого вам нужно закинуть ваши исходники, а также эти 3 файла: .env, docker-compose.yml и run.sh (логично предположить, что они будут лежать в коне вашего git-проекта) на сервер.
Далее, всё, что вам остаётся сделать — это запустить run.sh. Он сделает пару очевидных вещей: создаст сетку, получит актуальный шаблон для Nginx с гитхаба (если вы параноик, закэшиуйрте локально nginx.tmpl и убирите сетевой вызов в гитхаб), а также запустит ваш docker-compose.
Важно, что первый запуск у вас займёт порядка 5 минут. Ведь именно в этот момент времени вы будете получать сертификат.
У вас есть домен, защищенный сертификатом. Серт будет автоматически обновляться. При попытке открыть сайт по http, будет выполняться редирект на https (HTTP 301). Все статические ресурсы — css, js, images — доступны только по https.
С точки зрения инфраструктуры тут следующее решение. Есть прокси — nginx, который слушает на 80 и 443. Есть ваши бизнесовые контейнеры — например, «сайты». Каждый из них должен экспозить 80-й порт. 443-й порт экспозить не требуется. Других изменений энвайронмента тут не произошло.
Категории: Программирование