Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding section to generate SSL certificats with Traefik #41

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

guillaumebriday
Copy link

@guillaumebriday guillaumebriday commented Nov 14, 2023

Heavily inspired from basecamp/kamal#112

I think it could be nice to have proper example of how to use built in traefik mechanism to generate SSL certificats. 👍

Also, here is a blog post about how to use from scratch: https://guillaumebriday.fr/how-to-deploy-rails-with-kamal-and-ssl-certificate-on-vps

@nickhammond
Copy link
Contributor

I'm almost wondering if we do the wildcard version since that keeps on getting asked about on Discord. The wildcard version would also support your primary TLD as well as any subdomain under it. I know it'll complicate it a bit more but you can always remove the *. from your configuration.

@guillaumebriday
Copy link
Author

Great idea @nickhammond

Can you share an example of the configuration you have in mind here maybe so I could adapt the PR?

Thanks

@guillaumebriday
Copy link
Author

@dhh what do you think about this one? 👍

@ReDev1L
Copy link

ReDev1L commented Jan 6, 2024

Any way to run command on kamal hosts automatically?

$ mkdir -p /letsencrypt && touch /letsencrypt/acme.json && chmod 600 /letsencrypt/acme.json
```

Now you can access your app throught `https`.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

throught

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

through

@morgoth
Copy link
Contributor

morgoth commented Feb 26, 2024

This helped me setup HTTPS. Let's merge it.

@nickhammond
Copy link
Contributor

Here's the relevant bits for wildcard certs on top of what you already have. I don't think this can be simplified down to just generate the wildcard cert only but I haven't messed with this in a while.

This host match could also change to a regex.

    labels:
      traefik.http.routers.hey-web.rule: Host(`*.example.com`) || Host(`example.com`)
traefik:
  args:
    entrypoints.websecure.http.tls.domains[0].main: "example.com"
    entrypoints.websecure.http.tls.domains[0].sans: "*.example.com"

Writing this out now though I think we just stick with the simpler example since there's a lot more to explain when you add this additional stuff. Also, I'm thinking that Thruster is going to make a lot of this irrelevant.

@kimrgrey
Copy link

kimrgrey commented Mar 1, 2024

I doubt it is going to work for multiple servers. Kamal starts traefik on every host, so if setup has more than 1 machine problems will start occurring. In order to acquire and renew certificate traefik has to be exposed to ACME provider for HTTP / DNS / TLS challenge. But with multiple servers there there is no way to ensure that the correct instance of Traefik will receive the challenge request and subsequent responses.

@kimrgrey
Copy link

kimrgrey commented Mar 1, 2024

Official documentation for Traefik highlights this problem with regards to CRD in K8s but it is general issue with multiple Traefik instances running under load balancer: https://doc.traefik.io/traefik/providers/kubernetes-crd/#letsencrypt-support-with-the-custom-resource-definition-provider

@djmb
Copy link
Contributor

djmb commented Mar 5, 2024

@guillaumebriday - could you add a warning about this only working for single servers?

@@ -579,6 +579,47 @@ traefik:
entrypoints.otherentrypoint.address: ':9000'
```

## Generate SSL certificates with Letsencrypt
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should be "Let's Encrypt" rather than "Letsencrypt"

Comment on lines +616 to +619
Also, create the `acme.json` file and give it correct permissions on each hosts:
```bash
$ mkdir -p /letsencrypt && touch /letsencrypt/acme.json && chmod 600 /letsencrypt/acme.json
```
Copy link

@santiagorodriguez96 santiagorodriguez96 Apr 2, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would be nice to clarify that the file should be created before deploying otherwise we would be mounting a volume on a file that does not exist, which creates a directory and will prevent all of this from working – plus, it's hard to understand why.

I was thinking on something like this:

Finally, _before_ deploying, create the `acme.json` file and give it correct permissions on each hosts:
```bash
$ mkdir -p /letsencrypt && touch /letsencrypt/acme.json && chmod 600 /letsencrypt/acme.json

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you do

volume:
  - "letsencrypt:/letsencrypt"

instead, you do not have to create the file beforehand. Is there a downside to that approach?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm no, I cannot think of any downside 🤔

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can confirm using:

volume:
  - "letsencrypt:/letsencrypt"

in config/deploy.yml worked for me without needing to manually create the directory and file with permissions.

Comment on lines +607 to +609
entryPoints.web.http.redirections.entryPoint.to: websecure
entryPoints.web.http.redirections.entryPoint.scheme: https
entryPoints.web.http.redirections.entrypoint.permanent: true

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These lines will ensure that all http traffic is redirected to https. It feels to me that if we are going to include them as part of this section, we should clearly indicate that this will be the case. What do you think?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If using Rails and config.force_ssl = true, should I still be adding these lines?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems to work for me with just force_ssl true!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.