Which ssl certificates go where on an reverse proxy? - nginx
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?
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.
There are quite some possibilities, here are 2:
- You have 1 certificate on your reverse proxy containing all your domains using SANs
- 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.