nginx-proxy-manager icon indicating copy to clipboard operation
nginx-proxy-manager copied to clipboard

Add option for custom ACME CA

Open ionrover2 opened this issue 4 years ago • 23 comments

Is your feature request related to a problem? Please describe. I would like this tool to be used with a self signed CA in an internal environment that has an acme compliant server. I'm currently using Step CA for my acme compliant server. I currently don't have the option to use my own acme server without a ton of involved reconfiguration.

Describe the solution you'd like An advanced configuration option where you can upload a self signed CA and give a custom acme compliant url to be used with a given host.

Describe alternatives you've considered I am currently using a combination of jwilder/nginx-proxy and the encrypt companion to accomplish the same task with a custom acme CA, but it would be ideal to have a graphical frontend for a reverse proxy that can pull a valid internal cert, route traffic to separate physical hosts as needed and also the underlying containers running on the same machine.

Additional context

ionrover2 avatar Sep 22 '21 20:09 ionrover2

Are there any plans to integrate this feature? I'm having the exact same requirement.

Related to https://github.com/NginxProxyManager/nginx-proxy-manager/issues/1884 https://github.com/NginxProxyManager/nginx-proxy-manager/issues/1054 https://github.com/NginxProxyManager/nginx-proxy-manager/issues/301 https://github.com/NginxProxyManager/nginx-proxy-manager/issues/944

NetHero-es avatar Mar 22 '22 07:03 NetHero-es

I'm using NPM both for intranet traffic and for traffic coming from outside. For the latter, it works amazingly as it is, for the internal, would be nice if it could work with Smallstep CA (ACME and compatible with certbot) and avoid the manual certificate renewal every year for each service!

francescocaponio avatar Feb 11 '23 11:02 francescocaponio

+1

SantaSpeen avatar Jan 06 '24 21:01 SantaSpeen

Would love it if this feature was added!

lriley2020 avatar Feb 17 '24 21:02 lriley2020

+1

vshaev avatar Feb 18 '24 08:02 vshaev

+1

charliemaiors avatar Feb 21 '24 15:02 charliemaiors

Just an update, since during the last days there was some traffic on this thread.

By changing the certbot config file, adding the server directive, we were able to point to a local labca instance instead of let's encrypt. Of course, after this mod, all npm domains will ask the local ACME server instead of let's encrypt.

We were able to make it work, but then we had problems with the renewal of the certificates after three months.

We are waiting for the solution of this issue, if everything works properly, we will share the details on how to edit the file.

By the way, since it's a patch to be applied after the release of the official npm image, it should be reapplied per each new version release until there is no real support for multiple ACME servers together implemented in the webapp.

francescocaponio avatar Feb 21 '24 20:02 francescocaponio

So, this is my temporary solution:

I create my own container with this Dockerfile for each new version of NPM:

FROM docker.io/jc21/nginx-proxy-manager:2.11.1

RUN curl http://<internal_http_server>.lan/rootca.crt -o rootca.crt \
    && mv rootca.crt /usr/local/share/ca-certificates/rootca.crt \
    && update-ca-certificates

RUN echo -e "\nserver=https://labca.lan/directory\n" >> /etc/letsencrypt.ini

RUN sed -i "s\Let's Encrypt\LabCa\g" /app/frontend/js/*.js

This custom container can only work with the internal CA instance and not with Let's Encrypt. You can't have both. If you need also external domain you must run a second instance of NPM.

After this, I run the container in the same way I did before with the original NPM container, but I'm able to create and renew internal certificates with LabCA:

image

francescocaponio avatar Mar 05 '24 17:03 francescocaponio

FROM docker.io/jc21/nginx-proxy-manager:2.11.1

RUN curl http://<internal_http_server>.lan/rootca.crt -o rootca.crt
&& mv rootca.crt /usr/local/share/ca-certificates/rootca.crt
&& update-ca-certificates

RUN echo -e "\nserver=https://labca.lan/directory\n" >> /etc/letsencrypt.ini

RUN sed -i "s\Let's Encrypt\LabCa\g" /app/frontend/js/*.js

Hmm. I tried using your solution @francescocaponio but whenever I try to issue a new certificate I get: Certificate is not valid (Cannot read properties of null (reading '1'))

I'm using stepca as the bases for my ACME server. According to the logs from stepca the certificate gets issued but it seems that nginxproxymanager UI doesn't know what to do with it. Don't suppose you have any ideas?

From the logs it looks like it does indeed get issued...

app_1  | Successfully received certificate.
app_1  | Certificate is saved at: /etc/letsencrypt/live/npm-9/fullchain.pem
app_1  | Key is saved at:         /etc/letsencrypt/live/npm-9/privkey.pem
app_1  | This certificate expires on 2024-03-09.
app_1  | These files will be updated when the certificate renews.

accessiblepixel avatar Mar 08 '24 17:03 accessiblepixel

Hi, I also have the same log

Successfully received certificate.
Certificate is saved at: /etc/letsencrypt/live/npm-15/fullchain.pem
Key is saved at:         /etc/letsencrypt/live/npm-15/privkey.pem
This certificate expires on 2024-06-04.
These files will be updated when the certificate renews.
NEXT STEPS:
...

try to analyze the content of the file /tmp/letsencrypt-log/letsencrypt.log of the npm container for a DEBUG level log of certbot, and check also the stepca logs to understand better where the problem could be.

francescocaponio avatar Mar 08 '24 18:03 francescocaponio

@accessiblepixel

Hmm. I tried using your solution @francescocaponio but whenever I try to issue a new certificate I get: Certificate is not valid (Cannot read properties of null (reading '1'))

I'm using stepca as the bases for my ACME server. According to the logs from stepca the certificate gets issued but it seems that nginxproxymanager UI doesn't know what to do with it. Don't suppose you have any ideas?

The problem is caused by npm certbot, which after spending some hours I've just discovered that it removes the subject in the CSR. Also the default Step CA ACME provisioner configuration is not adding a CN/subject, when the CSR has none and this is what the problem is.

To solve you need to add

  "forceCN": true,

in your step-ca config ca.json.

Mine looks now like this and certificates are issued without issues.

                        {
                                "type": "ACME",
                                "name": "acme",
                                "forceCN": true
                        }

Hope this helps you.

oldboys92 avatar Mar 24 '24 22:03 oldboys92

@francescocaponio thank you for your cool solution, the workaround is working like a charm 🖖

PS: it cost me some time, till I realized your sed had a small typo. You used \ instead of / for the regex.

oldboys92 avatar Mar 24 '24 22:03 oldboys92

No disrespect to the project, but if you're facing these kinds of challenges, you might be starting to outgrow nginx-proxy-manager! It might be much easier in this scenario to just switch to plain old nginx, or another reverse proxy (eg: caddy). I just switched to caddy a few days ago for the better custom ACME provider support (and several other more advanced features). What you're trying to achieve here can be done in a few lines in a caddyfile:

my.domain.com {
    tls {
        issuer acme {
            dir https://ca.domain.com:8443/acme/acme/directory
	    trusted_roots /data/caddy/custom-certs/step-ca/step-ca.pem
        }
    }
    reverse_proxy * http://myappserver.local:8080
}


That's it! The whole configuration! The certs will auto renew, HTTPS redirect is implicitly enabled, all sorted. However please feel free to ignore me if you're happy with NPM :)

lriley2020 avatar Mar 24 '24 22:03 lriley2020

No disrespect to the project, but if you're facing these kinds of challenges, you might be starting to outgrow nginx-proxy-manager! It might be much easier in this scenario to just switch to plain old nginx, or another reverse proxy (eg: caddy). I just switched to caddy a few days ago for the better custom ACME provider support (and several other more advanced features). What you're trying to achieve here can be done in a few lines in a caddyfile:

@lriley2020 you are absolutely right, I had same thoughts too. I will probably switch myself to Caddy, but at least for NPM I wanted to see if there is a chance to get ACME working with another RA/CA, since it looked that, not much was missing. And in my case, the package was already there and was convenient to just use it.

oldboys92 avatar Mar 25 '24 11:03 oldboys92