nginx-proxy / nginx-proxy/nginx-proxy

[Feature request] Add per-container option to generate self-signed certificate

Open
#2,709 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Python
Stars
19.9k
Forks
3k
Avg merge
2d 11h
Merged PRs (30d)
1

Description

Use cases:

  1. Internal services that do not need to be web-accessible (e.g. pihole, which typically listens on pi.hole)
  2. Services intended to be accessed exclusively via external CDNs, which often have an ability to skip certificate chain validation / trust a custom root certificate. While this does not necessarily provide defense against MITM attacks, it still allows for encryption of data-in-transit, so it's resistant at least to passive evesdropping attacks.

Current options:

  1. Manually generate a self-signed certificate per-domain. (This requires running manual and complex openssl commands on a periodic basis)
  2. Manually generate a wildcard certificate and configure it as the default cert (Reduces the amount of certificate management required compared to previous, but still requires complex manual intervention)
  3. Use DNS and custom configs to allow public access to the ACME challenge directory, but block public access to the rest of the app. (This only works for domains you control, and also lists the domain in public Certificate Transparency logs, which may not be desirable. This can also present challenges when the domain is behind a CDN that also uses Let's Encrypt, where the CDN may not forward LE requests.)
  4. Self-host an ACME-compatible CA, replace challenge code with a mock that always returns success, and setting ACME_CA_URI to the self-hosted ACME URL for domains needing a self-signed certificate. (Cleanest option, but complicated to set up)

As you can see, none of the current options are very straightforwardor ergonomic. (If I am missing an obvious easy way to do this, please let me know)

Proposal:

  • Create a directory within nginx-proxy for storing root certificates. This can (optionally) be bound as a volume in order to provide custom root certificates, or persist the auto-generated default root certificate.
  • Add a per-container boolean CERT_GENERATE environment variable to enable the generation of self-signed certificates.
  • Add the same environment variable to the nginx-proxy container to control the global default
  • Add an nginx-proxy environment variable CA_CERT which indicates the file name of the default root certificate to be used. If specified, prevents auto-generation of a default root certificiate.
  • Add a per-container CA_CERT environment variable allowing the use of different root certificates for different containers
  • Modify certificate selection process so that just before default.crt is used, the value of CERT_GENERATE is checked. If CERT_GENERATE is true for the container (or unspecified for the container and true on the nginx-proxy), automatically generate a certificate for all specified VIRTUAL_HOST domains based on the specified CA_CERT file.
    • NOTE: Maybe needs logic to avoid autogenerating missing certs if they are mentioned within LETSENCRYPT_HOST? If ACME generation was intended but failed we probably don't want to still generate a self-signed cert.
  • If a certificate exists but is out of date, generate a replacement certificate (if above conditions match)
  • If CA_CERT is not specified, generate a default root / CA certificate. (Do we need to potentially automatically renew this too?)

Possible alternative:

Build this into acme-companion instead, since it already deals with certificate signing requests and such. Give acme-companion an option to locally/internally generate certificates based on a specified CA/root certificate.

Final notes

I have been using nginx-proxy in a production capacity for around a year, and across 4 separate Docker instances. But I have not looked through the codebase or contributed, so my apologies if my suggestion doesn't fit with the style of this project, or if I missed something architecturally.

I also have very limited experience with self-signing certificates or operating a local CA. The challenges I have faced with trying to get self-signed certificates working with nginx-proxy are what motivated me to write this feature request. Based on this lack of knowledge, it is also possible that I have missed something important about how certificate generation works.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the certificate selection process documented in the linked nginx-proxy documentation and compare it with the responsibilities of nginx-proxy and acme-companion. Define how per-container and global CERT_GENERATE and CA_CERT settings should interact, including missing, expired, and failed ACME certificates; done means the behavior and ownership are settled and testable.

Written by the indexing model from the issue text.

Assessment

Tech stack
docker, nginx
Domain
infrastructure, security
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
30/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.