25th December 2023
A RP = Reverse Proxy is a server that sits in front of other servers and forwards client request to those servers behind it. From the client perspective, the destination address to reach a specific server would be the one of the Reverse Proxy, not the server itself. An analogy could be when you meet a bouncer at the entrance of a bar.
In contrast, a FP = Forward Proxy is a server that sits in front of clients and forwards requests to services on the Internet.
Source: https://www.cloudflare.com/learning/cdn/glossary/reverse-proxy/
A RP is often used in conjuction with SSL Offloading, which makes the RP handle the SSL certificates for the backend.
Why you need a Reverse Proxy
With NAT, you can only translate the same layer 4 port once per IP address. At one time or another, you realize that you need to host 2 or more HTTPS (TCP 443) services from your network, but you only have one public IPv4 address available. It doesn’t matter if you have more than 65,534 available subnets for IPv6, with trillions of available address in each subnet, when there’s still many laggards on IPv4-only networks that wants to reach your services. While you could use custom port numbers, it’s not a very user-friendly solution.
Another reason could be the need for load-balancing towards multiple backends that are running the same service.
A third reason could be that you have a guest network that have not exposed your internal DNS server. A reverse proxy would allow the firewall to hairpin the traffic back towards the internal network.
Another Security benefit of using reverse proxy is that it hides your internal IPv6 Prefix.
My Challenge
I’m using a “snappy” nextcloud server that is configured to use a HPB = High Performance Backend server for offloading Nextcloud Talk. The HBP requires communication outside the local network, as well as the Nextcloud server.
While at first it looked like I could get away with only NATing the STUN port towards the HPB server; when using Wireshark, I discovered that there is some initial HTTPS traffic happening in the beginning of a session towards the HPB server. It actually worked when running dual-stack, because IPv6 could be used for the HTTPS establishment, but it fails for IPv4 only hosts. Therefore, both servers needs to communicate to the Internet with the same port number.
Also, a privacy issue is that without a proxy, I need to expose my internal IPv6 prefix.
New Design
What works
Explanations:
The RP is configured to do SSL offloading for SNI=Server Name Indication’s matching hpb.bastuklubben.online and nextcloud.bastuklubben.online. It means that the public certificates for Nextcloud and HPB will be handled by the RP.
HPB and Nextcloud are instead using SSL certificates issued by an internal PKI solution (It could also be self-signed certificates). The important thing is that the RP and the backends are communicating over HTTPS for optimal functionality.
The IPv4 client (and IPv6 clients) will only see the publicly available IP addresses and certificates.
Even though the client may only communicate over IPv4, The RP can forward towards the servers IPv6 addresses.
STUN traffic also get proxied. However, it only uses a default backend for all traffic destined to TCP 5349. Since I’m only using one STUN service, there is no need for advanced ACLs = Access Control lists.
What doesn’t work
You can’t configure Reverse Proxy for HTTPS servers without SSL offloading
That is because the client that terminates with the proxy expects an SSL certificate in return. That is why the RP has to be the device handling the public SSL certificates; so it can decrypt the packet and send it onward to the correct backend.
Using unencrypted communication for Nextcloud Backend disables some services
Some services in Nextcloud requires TLS/HTTPS to be activated. For example, the Password Manager:
Even though you reach the RP using HTTPS, the Nextcloud server itself doesn’t run HTTPS. Therefore you will get that error message. That is why you should at least have a self-signed certificate on the Nextcloud server.
Note: I would recommend using HTTPS for the HPB too.
You can’t SSL offload for IPv4 only, but not for IPv6
Well… in theory you can, but should you? You might as well be consistent with the design for both address families; otherwise you will just confuse yourself. You will end up with 2 different certificates depending if it was reached with IPv4 or IPv6.
At least you can’t use Let’s Encrypt certbot for automatic certification enrollment over IPv6. That will either not work or break stuff.
How it works…
This blog was just meant to get an overview of all the components required in a RP design. The next post will be covering the actual configuration of proxy and SSL offloading.