2017-01-04 5 views
1

Я использую docker-compose для приложения rails для приложения и контейнера db. Чтобы проверить некоторые функции приложения, мне нужен SSL ... так что я собираюсь с LetsEncrypt против самозаверяющего.LetsEncrypt в контейнере приложения Docker (docker-compose) не работает

Приложение использует Nginx, и сервер убунту 14.04 LTS, с Phusion пассажирской Docker изображения в качестве базового изображения (легкая DEBiAN)

Обычно с LetsEncrypt, я бегу обычный ./certbot-auto certonly --webroot -w /path/to/app/public -d www.example.com

Мой сервер запускает nginx (прокси-сервер, передающий приложение в контейнер), поэтому я прыгнул в контейнер, чтобы запустить команду certbot без проблем.

Однако, когда я пытаюсь перейти на https://test-app.example.com, он не работает. Я не могу понять, почему.

Ошибка на сайте (Chrome):

This site can’t be reached 

The connection was reset. 

Curl дает немного лучше ошибку:

curl: (35) Unknown SSL protocol error in connection to test-app.example.com 

сервер Nginx Nginx приложение app.conf

upstream test_app { server localhost:4200; } 
server { 
    listen 80; 
    listen 443 default ssl; 
    server_name test-app.example.com; 

    # for SSL 
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2; 
    ssl_dhparam /etc/ssl/dhparam.pem; 
    ssl_prefer_server_ciphers on; 
    ssl_ciphers 'ECDHE-RSA-blahblahblah-SHA'; 

    location/{ 
    proxy_set_header Host $http_host; 
    proxy_pass http://test_app; 
    } 
} 

контейнера .conf

server { 
    server_name _; 
    root /home/app/test/public; 

    ssl_certificate /etc/letsencrypt/live/test-app.example.com/fullchain.pem; 
    ssl_certificate_key /etc/letsencrypt/live/test-app.example.com/privkey.pem; 

    ssl_protocols TLSv1 TLSv1.1 TLSv1.2; 
    ssl_dhparam /etc/ssl/dhparam.pem; 
    ssl_prefer_server_ciphers on; 
    ssl_ciphers 'ECDHE-RSA-blahblah-SHA'; 

    passenger_enabled on; 
    passenger_user app; 
    passenger_ruby /usr/bin/ruby2.3; 
    passenger_app_env staging; 

    location /app_test/assets/ { 
    passenger_enabled off; 
    alias /home/app/test/public/assets/; 

    gzip_static on; 
    expires +7d; 
    add_header Cache-Control public; 
    break; 
    } 
} 

В моей Dockerfile, у меня есть:

# expose port 
EXPOSE 80 
EXPOSE 443 

В моей докер-compose.yml файл у меня есть:

test_app_app: 
    build: "." 
    env_file: config/test_app-application.env 
    links: 
    - test_app_db:postgres 
    environment: 
    app_url: https://test-app.example.com 
    ports: 
    - 4200:80 

И docker ps он показывает, как :

Up About an hour 443/tcp, 0.0.0.0:4200->80/tcp 

Я теперь подозреваю, что это потому, что сервер nginx сервера - «front-front» server - не имеет сертификатов, но я не могу запустить команду LetsEncrypt без местоположения приложения.

Я попробовал запустить команду LetsEncrypt на сервере, но, поскольку я предположительно обнаружил порт 80, я получаю следующее: socket.error: [Errno 98] Address already in use Я что-то пропустил?

Что мне делать?

ответ

0

Я знал, что мне не хватает одной маленькой вещи. Как указано в этом вопросе, поскольку nginx на сервере является «front-face» nginx, с nginx контейнера специально для приложения, nginx сервера должен знать о SSL.

Ответ был супер простым. Скопируйте сертификаты! (Престижность опс моего клиента свинца)

Я cat в fullchain.pem и privkey.pem в контейнере Докер и создали соответствующие файлы в /etc/ssl на сервере.

На сервера /etc/nginx/sites-enabled/app.conf я добавил:

ssl_certificate /etc/ssl/test-app-fullchain.pem; 
    ssl_certificate_key /etc/ssl/test-app-privkey.pem; 

Проверено конфигурации и перезапуска Nginx. Boom! Работал как шарм. :)

2

Fun один.

Я хотел бы согласиться с тем, что это, скорее всего, из-за отсутствия сертификатов.

Прежде всего, прочитайте мой отказ от ответственности в конце. Я бы попытался использовать DNS authentication., ИМХО это лучший метод для чего-то вроде Докера. Несколько идей приходят на ум. Самый простой, который отвечает на ваш вопрос будет докер EntryPoint скрипт, который получает сертификаты первым, а затем начинает Nginx:

#!/bin/bash 
set -ea 

#get cert 
./certbot-auto certonly --webroot -w /path/to/app/public -d www.example.com 

#start nginx 
nginx 

Это «хорошо» решение, имхо, но на самом деле не «автоматизированы» (который является частью позволяет зашифровать цели).На самом деле это не касается обновления сертификата по дороге. Если это не твоя забота, тогда ты уходишь.

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

Более сложное (но и более масштабируемое решение) было бы создание образа докеров, единственной целью в жизни которого является обработка сертификатов и продлений let_encrypt, а затем предоставление способа распространения этих сертификатов в других контейнерах, например: nfs (или общие объемы докеров, если вы действительно осторожны).

Для тех, кто в будущем будет читать это: это было написано до compose hooks, было доступно, что было бы лучшим способом справиться с чем-то подобным.

Пожалуйста, прочтите этот отказ от ответственности:

Docker не является действительно лучшим решением для этого, ИМХО. Изображения докеров должны быть статическими. Поскольку позволяет зашифровать сертификаты истекают через 3 месяца, это означает, что ваш контейнер должен иметь срок хранения не менее трех месяцев (или, как я уже сказал выше, объясняю обновление). "Хорошо!" Я слышу, как ты говоришь. Но это также означает, что вы постоянно получаете новый сертификат, выдаваемый при каждом запуске контейнера (с помощью метода точки входа). По крайней мере, это означает, что предыдущий сертификат отзывается каждый раз. Я не знаю, для чего это необходимо для Lets Encrypt. Они могут дать вам столько отбросов, пока они не подумают, что происходит что-то подозрительное.

То, что я обычно делаю чаще всего, на самом деле использует управление конфигурацией и использует nginx как «фронт» в главной системе. Или полагаться на какой-то другой механизм для обработки завершения SSL. Но это не отвечает на ваш вопрос о том, как получить Lets Encrypt для работы с докером. :-)

Я надеюсь, что это поможет вам в лучшем направлении. :-)

+0

спасибо @ nick-burke, я сделаю простое решение (поскольку это действительно тестовое приложение, которое не будет продолжаться даже 90 дней), хотя после прочтения остальной части вашего сообщения это звучит как покупка сертификата возможно, будет лучшим вариантом. то nginx хост-сервера может правильно разобраться в деталях и до сих пор иметь контейнер докеров без особых проблем. (к сожалению, нам нужно использовать докер - я лично не выбрал бы его, но это то, как печенье рухнуло). надеюсь, простое решение работает! –

+0

@rbatta Мне действительно очень нравится докер, просто нужно знать, что это сильные и слабые стороны. Я использую Lets Encrypt for - это среды разработки или среды тестирования по требованию.Таким образом, у вас нет средств для запроса или вы можете перехватить запрос на $$, чтобы присвоить реальный сертификат. –

+0

К сожалению, простое решение не сработало. Но, поговорив с руководством по работе с клиентами, я пропустил простейшее их решение ... просто копируя сертификаты SSL для хост-сервера, чтобы узнать об этом. –

Смежные вопросы