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

Auto HTTPS in CE #4491

Merged
merged 11 commits into from
Sep 10, 2024
Merged

Auto HTTPS in CE #4491

merged 11 commits into from
Sep 10, 2024

Conversation

ruslandoga
Copy link
Contributor

@ruslandoga ruslandoga commented Aug 30, 2024

Changes

This PR starts using https://github.com/sasa1977/site_encrypt in CE to generate (and keep up-to-date) TLS certificates using https://certbot.eff.org.

The goal is to simplify CE deployments by removing the reverse-proxy requirement.

Trying it out locally

  • Launch a local CA like Pebble:

    $ docker run --rm --name pebble -d -p 14000:14000 -p 15000:15000 -e "PEBBLE_VA_NOSLEEP=1" ghcr.io/letsencrypt/pebble

    UPDATE: since Docker Desktop 4.34.0 host networking can be used on non-Linux machines: https://docs.docker.com/engine/network/drivers/host/?uuid=ebc0dd6c-ae8d-43ac-aa17-81671a3a76dd%0A#docker-desktop, that would remove the need for host.docker.internal workaround below.


  • Install Certbot, e.g. with brew install certbot

  • Install new CE deps, e.g. with MIX_ENV=ce mix deps.get

  • Edit config/.env.dev and .iex.exs so as not to interfere with custom ENV used in the next step:

    config/.env.dev

    - BASE_URL=http://localhost:8000
      SECURE_COOKIE=false
      DATABASE_URL=postgres://postgres:[email protected]:5432/plausible_dev
      CLICKHOUSE_DATABASE_URL=http://127.0.0.1:8123/plausible_events_db
      ...

    .iex.exs

      ...
    
      import_if_available(Ecto.Query)
      import_if_available(Plausible.Factory)
    
    - Logger.configure(level: :warning)
    
      ...
  • Launch Plausible with the following ENV:
    console

    $ export BASE_URL=https://host.docker.internal:5001
    $ export HTTP_PORT=5002
    $ export HTTPS_PORT=5001
    $ export ACME_DIRECTORY_URL=https://localhost:14000/dir
    $ export DATA_DIR=./tmp
    $ export MIX_ENV=ce_dev
    $ mix phx.server

    I use host.docker.internal to make Pebble be able to access localhost from its container in "Docker Desktop" for Mac. For Linux machines, I think the host can be localhost with --network host added to docker run flags.


  • Wait for success:

    Successfully received certificate.
    Certificate is saved at:   /Users/x/Developer/plausible/analytics/tmp/site_encrypt/certbot/localhost_14000/config/live/host.docker.internal/fullchain.pem
    Key is saved at:           /Users/x/Developer/plausible/analytics/tmp/site_encrypt/certbot/localhost_14000/config/live/host.docker.internal/privkey.pem
    This certificate expires on 2029-08-30.
    
  • Visit https://host.docker.internal:5001 (you might need to add 127.0.0.1 host.docker.internal to /etc/hosts for it to be resolvable)

Tests

  • This PR does not require tests

Changelog

  • Entry has been added to changelog

Documentation

  • This change does not need a documentation update

Dark mode

  • This PR does not change the UI

@ruslandoga ruslandoga mentioned this pull request Aug 30, 2024
4 tasks
@@ -61,7 +63,13 @@ listen_ip =
)

# System.get_env does not accept a non string default
port = get_var_from_path_or_env(config_dir, "PORT") || 8000
http_port =
get_int_from_path_or_env(config_dir, "HTTP_PORT") ||
Copy link
Contributor Author

Choose a reason for hiding this comment

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

HTTP_PORT is added for consistency with the new HTTPS_PORT.

get_int_from_path_or_env(config_dir, "HTTP_PORT") ||
get_int_from_path_or_env(config_dir, "PORT", 8000)

https_port = get_int_from_path_or_env(config_dir, "HTTPS_PORT")
Copy link
Contributor Author

@ruslandoga ruslandoga Aug 30, 2024

Choose a reason for hiding this comment

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

Setting HTTPS_PORT enables site_encrypt so that auto-TLS is opt-in.

@ruslandoga ruslandoga force-pushed the auto-https branch 2 times, most recently from c368f0f to a551f4b Compare August 30, 2024 08:56
@ruslandoga ruslandoga marked this pull request as ready for review August 30, 2024 10:28
@ruslandoga ruslandoga requested review from a team August 30, 2024 10:35
@ruslandoga ruslandoga added the self-hosting Anything self-hosted label Aug 30, 2024
mode: :auto,
log_level: :notice,
client: :certbot,
domains: [domain],
Copy link
Contributor Author

@ruslandoga ruslandoga Sep 1, 2024

Choose a reason for hiding this comment

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

I wonder if it should try to issue "www.#{domain}" as well.

I think it's OK as is for now, and if someone complains I'll add extra logic to check if www should be issued too. Plausible CE is probably mostly served from a subdomain anyway.

PlausibleWeb.Endpoint.enable_https(https_enabled?)

if https_enabled? do
{SiteEncrypt.Phoenix.Endpoint, endpoint: PlausibleWeb.Endpoint}
Copy link
Contributor Author

@ruslandoga ruslandoga Sep 9, 2024

Choose a reason for hiding this comment

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

Maybe this can be further limited to http_port==80 check since ACME issues challenges only on the default HTTP port.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

secret_key_base: secret_key_base,
websocket_url: websocket_url,
secure_cookie: secure_cookie

if https_port do
config :plausible, PlausibleWeb.Endpoint,
https: [port: https_port, ip: listen_ip, cipher_suite: :compatible] ++ default_http_opts
Copy link
Contributor Author

@ruslandoga ruslandoga Sep 10, 2024

Choose a reason for hiding this comment

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

The Compatible cipher suite supports tlsv1, tlsv1.1 and tlsv1.2.

From https://hexdocs.pm/plug/1.16.1/Plug.SSL.html#configure/1-cipher-suites

The reasoning for using this suite instead of a "strong" one is the same as in #1708 (comment)

Copy link

Preview environment👷🏼‍♀️🏗️
PR-4491

Copy link
Contributor

@zoldar zoldar left a comment

Choose a reason for hiding this comment

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

@zoldar zoldar merged commit 2180ab4 into master Sep 10, 2024
10 checks passed
@zoldar zoldar deleted the auto-https branch September 10, 2024 12:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
preview self-hosting Anything self-hosted
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants