Which ssl certificates go where on an reverse proxy? - nginx

9,337

Solution 1

The certificate of a domain should go where the clients "see" it, so in your case, if you want only the nginx server to be available from the internet, all of the public certificates should go to the nginx server.

If you want to secure the backend connections, you can use whatever certificate you want on those servers. You can even use self-signed ones, and disable the certificate check on the nginx server, but it is probably wiser to create your own CA, and distribute certificates to the backends.

Your configuration would look like exactly you drew, except that the backend servers would have an internal certificate matching their "internal" name:

                                                 client
                                                   |
                                                 nginx
                                           (https://example1.com)
                                           (https://example1.com)
                                           (https://example1.com)
                                                    |
            +---------------------------------------+-----------------------------------+
            |                                       |                                   |
            |                                       |                                   |
https://example1.internal.local/   https://example2.internal.local/   https://example3.internal.local/
       a.b.c.d                                  e.f.g.h                               i.j.k.l

If the backend servers are accessible from the internet, then you might want to firewall their https ports so only the nginx server could connect them.

Regarding your question about client and server: in networking, a client is the one who initiates the connection. So in your setup, the browsers are the clients, and the nginx server is a client and a server in the same time: it is the server for the browsers, but it is the client for the backend servers.

Solution 2

There are quite some possibilities, here are 2:

  1. You have 1 certificate on your reverse proxy containing all your domains using SANs
  2. You redirect every domain from your nginx to their corresponding server, rewriting the URLs

Either you have your clients communicate solely with your reverse proxy (1) and nginx will handle connections to the upstream servers, or you let nginx tell your clients to connect to the other servers (2), which need a public IP/ DNS/ certificates of their own, then.

You can (and maybe should) also encrypt the traffic between your reverse proxy and the upstream servers using certificates, depending on your network layout. For this, you still need a certificate for every upstream server, but they could also be self-signed (but shouldn't).

If you are using something like Let's Encrypt, generating SANs on certificates is pretty easy nowadays, so I usually go with option 1.

Share:
9,337

Related videos on Youtube

Altimus Prime
Author by

Altimus Prime

Updated on September 18, 2022

Comments

  • Altimus Prime
    Altimus Prime over 1 year

    Need clarification for upstream SSL on an nginx reverse proxy server

    I've been reading the nginx docs regarding reverse proxy and securing ssl connections to upstream servers but I'm still confused about which ssl certificates go where. Many of the examples I find have nginx proxying localhost, but my situation has the endpoints on different servers, ports and physical locations.

    I'd like to have several domains resolved at the nginx server. Each of those domains has an ssl certificate on its current server for its actual domain name.

    Right now I have each server running at it's own network location and physical location, but I'd like to have a single point to manage those endpoints.

    My end result should look like

                                 client
                                   |
                                 nginx
                           https://example1.com
                           https://example2.com 
                           https://example3.com
                                 x.x.x.x
                                   |
                   -----------------------------------------
                   |                |                      |
    https://example1.com    https://example2.com    https://example3.com
       a.b.c.d:1234             e.f.g.h:5678            i.j.k.l:9012
    

    Right now https://example1.com resolves to a.b.c.d:1234 which has it's own ssl certificate installed. Because I need to represent to clients that the nginx server is serving for the domain example1.com I think I need the example1.com ssl moved to the frontrunning nginx server, right? If I do that, what ssl certificate do I use on a.b.c.d:1234 to maintain a secure upstream connection?

    The nginx docs say client.crt and server.crt, but the CA uses a domain to register these. What is client and server in a reverse proxy situation? To me the client is the browser making the request.

    Which ssl certificates go where on an reverse proxy?

    Edit:

    I already know you can look like you have a secure connection by simply placing the url based certificates on the proxy server. What I'm hoping to know is what ssl certificates to put on the backend servers. Just reuse their respective certificates? Could example1.com.crt go on both the proxy server and the backend server?

    • Altimus Prime
      Altimus Prime over 4 years
      In case it helps anyone, Yes, you CAN use the same cert on both the proxy server and the backend server, although I don't know that's the right way. Since you only need it encrypted between points, you can also self sign the certificate. The browser only gets the certificate from the proxy server.
  • Altimus Prime
    Altimus Prime almost 5 years
    In the proxy_pass on nginx, I can put https://a.b.c.d or else I have to make the host file resolve example1.internal.local to a.b.c.d. Would I need the backend ssl certificate made out to either a.b.c.d or example1.internal.local depending which way I went about it?
  • Altimus Prime
    Altimus Prime almost 5 years
    The whole point of the question is to secure/encrypt data between the reverse proxy and the backend servers. Thank you for making me aware of SANs.
  • Lenniey
    Lenniey almost 5 years
    OK I didn't read that in your question. Then you either: use your own certificates from your own CA, or self-signed certificates and trust them on your reverse proxy. If you want to use your LE certificates on the backend servers, you have to serve the domain there and handle LE domain verification on the reverse proxy (or pass it through). See here, for example: serverfault.com/questions/341023/…
  • Lacek
    Lacek almost 5 years
    I think it is a better idea to issue the certificate to a name, and not to an IP address, so I would go for example1.internal.local (or any name, really). Technically (to my knowledge), you can issue the certificate to an IP address, but I don't have experience with certificates like that (I don't even know if nginx will accept it).