Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

nginx redirect to docker container

before posting my issue, I would like to know if it is even possible to achieve what I want.

I have, lets say, myserver.com running a docker container with nginx & letsencrypt. On the same server are 2 more docker containers running websites.

For now all is redirected fine, so www.myserver.com goes to docker 1 and site2.myserver.com goes to docker 2.

I would like to have all communication running over HTTPS, but here starts the trouble. So, my question is: is it possible for the docker with nginx and letsencrypt to connect to another docker using the certificates from letsencrypt? To me it seems to be some kind of man-in-the-middle "attack". A bit more schematic:

Browse to http:// site2.myserver.com -> nginx redirects to https:// site2.myserver.com -> connect to container 2 (192.168.0.10) on port 80. Or another option: Browse to http:// site2.myserver.com -> nginx redirects to https:// site2.myserver.com -> connect to container 2 (192.168.0.10) on port 443 having the site2.myserver.com certificates.

If it can't be done, what is the solution then? Copying the certificates to the docker containers and make them run https, so that a http request gets redirected to the https port of that container?

Browse to http:// site2.myserver.com -> nginx forwards request -> connect to container 2 (192.168.0.10) on port 443 having the site2.myserver.com certificates.

Thanks, Greggy

like image 411
Greggy Avatar asked Dec 21 '16 14:12

Greggy


People also ask

Should you run nginx in Docker?

If nginx is running in a container then your site is going to be 100% dead to the world while Docker isn't running. Users will get a connection error. When nginx is installed directly on your host you can serve a 503 maintenance page that doesn't depend on Docker or any containers running.


2 Answers

As I understand it your nginx reverse proxy is on the same network as the containers, so there is not much need to secure the connection between them with TLS (as this is a private network and if an attacker has access to that network he would have access to the server, too, and all the unencrypted data).

If you absolutely want valid certificates to secure the connections on your local network you could create additional sub-domains that resolve to the local IPs. Then you will need to use the manual DNS option to get your certificate (this is a certbot option where you need to manually enter a key as a TXT entry for your domain).

Example Nginx configuration to redirect http to https

server {
    listen 80;

    server_name example.com;
    return 301 https://example.com/;
}
server{
    listen 443 ssl http2;

    server_name  example.com;

    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
    ssl_trusted_certificate /etc/letsencrypt/live/example.com/fullchain.pem;

    location / {
        proxy_pass http://container:8080/;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }

    include tls.conf;
}
like image 169
Paul Trehiou Avatar answered Sep 21 '22 06:09

Paul Trehiou


I would go with the out of the box solution:

JWilder Nginx + Lets Encrypt.

First we start NGINX Container as Reverse Proxy:

docker run -d -p 80:80 -p 443:443 \
    --name nginx-proxy \
    -v /path/to/certs:/etc/nginx/certs:ro \
    -v /etc/nginx/vhost.d \
    -v /usr/share/nginx/html \
    -v /var/run/docker.sock:/tmp/docker.sock:ro \
    jwilder/nginx-proxy

Next we start the Lets Encrypt Container:

docker run -d \
-v /path/to/certs:/etc/nginx/certs:rw \
--volumes-from nginx-proxy \
-v /var/run/docker.sock:/var/run/docker.sock:ro \
jrcs/letsencrypt-nginx-proxy-companion

For your Websites you need some Environment variables to be set:

docker run -d \
--name website1 \
-e "VIRTUAL_HOST=website1.com" \
-e "LETSENCRYPT_HOST=website1.com" \
-e "LETSENCRYPT_EMAIL=webmaster@website1" \
tutum/apache-php

The Nginx container will create a new entry in his config, and the lets encrypt container will request a certificate (and does the renew stuff).

More: Nginx+LetsEncrypt

like image 44
opHASnoNAME Avatar answered Sep 24 '22 06:09

opHASnoNAME