GithubHelp home page GithubHelp logo

Comments (8)

rlion7 avatar rlion7 commented on June 29, 2024 1

Thanks! I really appreciate the work that goes into the open-source world! The DuckDNS option does sound like something I could investigate - looks promising, though possibly with a bit of extra setup on my side, i.e. port forwarding and making sure I know what security risks that might entail.

In the meantime, I did create a parallel setup. I'll leave the description below in case it's useful to any future users!

docker-compose-local.yml => points to the standard nginx image instead of your image

version: "3.8"
services:
  app_container_name:
    build: ./app
    container_name: app_container_name
    restart: always
    environment:
      - APP_NAME=app
    expose:
      - 8080
    volumes:
      - .:/app

  nginx:
    build: ./nginx
    container_name: nginx_local
    restart: always
    ports:
      - "80:80"
      - "443:443"
    depends_on:
      - app_container_name

nginx Dockerfile =>

FROM nginx

# Remove the default nginx.conf
RUN rm /etc/nginx/conf.d/default.conf
# Replace with localhost-specific .conf
COPY nginx_localhost.conf /etc/nginx/conf.d/

# copy in self-signed certs for https testing
COPY certs certs

Note that certs here are created as described in The Flask Mega-Tutorial but I'm sure it would be the same result as from LetsEncrypt

$ mkdir certs
$ openssl req -new -newkey rsa:4096 -days 365 -nodes -x509 \
  -keyout certs/key.pem -out certs/cert.pem

nginx_localhost.conf => mydomain.com is replaced with localhost and I had to bring in the port 80 server block

server {
   listen 80;
   server_name localhost;

   location / {
       # redirect any requests to the same URL but on https
       return 301 https://$host$request_uri;
   }
}

server {
   # listen on port 443 (https)
   listen 443 ssl;
   server_name localhost;

   # location of the self-signed SSL certificate
   ssl_certificate /certs/cert.pem;
   ssl_certificate_key /certs/key.pem;

   location / {
       # forward application requests to the uWSGI server
       include uwsgi_params;
       uwsgi_pass app_container_name:8080;
   }
}

from docker-nginx-certbot.

JonasAlfredsson avatar JonasAlfredsson commented on June 29, 2024

Hi rlion7,

Thank you for reaching out, it makes me really happy to hear that this image was useful for you :)

In regards to your question it is a tricky one that I myself have pondered over from time to time. The problem stems from that Let's Encrypt needs to make sure that they only hands out certificates to those who own the domain in the request, so if you want certificates for example.org then they will "connect" to the certbot instance that is expected to be running on the example.org server. As you might understand this becomes a problem when you want to do local testing, since then their authentication check is routed to the real server instead, which is not expecting to respond at the moment.

This image expects to run on the server which the domain points, in order to make sure you get your certificates, but in cases like this it cause a little bit of a problem (which I suppose is good since this means HTTPS really do makes it difficult to impersonate sites). From what I have seen others do is that they use config files without encryption (just port 80) when they are doing local development, and they are using a separate docker-compose file just as you mentioned. This works OK, but it removes the HTTPS component which might cause the final site to behave a little bit differently.

If you have internet access to your local testing server an alternative might be to point another domain towards it (you can use DuckDNS as mentioned in the preparation steps) and have you local instance configured to respond to that instead. This will allow you to get the "full" setup process, but just another domain name. For an even more modular approach to this you could perhaps even create template files that change the domain name based on a variable you send in (read more about that from the parent container's docs).

However, your comment about providing some kind of self signing service is not that crazy. I could really see the potential to include some kind of function that create temporary self signed certificates instead. This is a larger request that will take some time, but I am willing to investigate this further when I am done with the ECDSA certificate feature. I mean we already have functions to extract the file paths and domain names, so it should not be too difficult to create our own certificates from this.

Extra reading notes:

from docker-nginx-certbot.

JonasAlfredsson avatar JonasAlfredsson commented on June 29, 2024

Oh my, this took way longer than I anticipated, however, I have now uploaded something to the dev branch that you can check out. It is now possible to enable the use of a local certificate authority that is able to create website certificates without needing any internet connection. I have written quite a lot in the documentation about it, so I would really appreciate it if you had time to provide some feedback on it, and tell me if it solves your usecase :)

The image using the dev branch exists on dockerhub as well, with the :dev tag, but it is only built for debian at the moment.

from docker-nginx-certbot.

rlion7 avatar rlion7 commented on June 29, 2024

Very cool! This works for my use case as is. I tested using Dockerfile-alpine (cloned the dev branch and built locally via Docker Compose).

I found that I did not have to change the nginx config file (in user_conf.d). It seemed to accept 'localhost' automatically. I couldn't quite wrap my head around why that might work - could it be that it knows localhost already from the certbot.conf file that comes with the image?

However, this led to a warning in the browser despite importing the caCert.pem file:

This server could not prove that it is localhost; its security certificate is from _my_domain_.com. 
This may be caused by a misconfiguration or an attacker intercepting your connection.

This error makes sense, so I went back and edited my nginx config file and put localhost in front of the other domain name variants ( server_name localhost my_domain.com www.my_domain.com;).
When I re-ran the image and imported the new caCert.pem file, it was successful, i.e. I can now browse to https://localhost and see my website with no security warnings.

I really appreciate all the documentation you added to make this clear. With so many references, one could spend a lot of time learning the details to really make a strong configuration.

I hope others find this useful as well!

from docker-nginx-certbot.

JonasAlfredsson avatar JonasAlfredsson commented on June 29, 2024

Excellent! I am so glad it worked basically first try for you :)
I will re-read everything again, to make sure no spelling mistakes are present and then push to master.

In regards to why you are able to access your site via localhost without specifying it in the server_name first is because the peculiar way that Nginx works. When a request comes in Nginx will try to match it with any of the server names it finds in its configurations, but if none matches it will just default to the (i think) last server configuration it happened to read. This is really confusing if you don't know about it and, as you noticed, the certificate for this config will not be valid for the name which you "came in with" (i.e. localhost != my_domain.com).

A solution to this is to create another server block that is set as a "catchall" default_server (take a look at the redirector.conf), since this will then be the fallback server in case no one else matches the name. This is not as easy to do in the port 443 SSL case as in the port 80 case, but the comments here seems to be discussing a possible solution. The final comment points towards this setting in Nginx, so perhaps you can test to add the following to your setup and see what happens:

server {
    listen               443 ssl default_server;
    ssl_reject_handshake on;
}

server {
    listen              443 ssl;
    server_name         my_domain.org;
    ...
}

This is untested by me, so if you manage to try this before me can you please comment about it here as well? :)

from docker-nginx-certbot.

JonasAlfredsson avatar JonasAlfredsson commented on June 29, 2024

I tested it out quickly, and wrote a section about my findings as well. Take a look if you want :)

from docker-nginx-certbot.

JonasAlfredsson avatar JonasAlfredsson commented on June 29, 2024

This is now built and deployed. If there is nothing else should I go ahead and close this issue? :)

from docker-nginx-certbot.

rlion7 avatar rlion7 commented on June 29, 2024

from docker-nginx-certbot.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.