I am working on a system where each of my clients have a separate raspberry pi assigned to them, which they can run whatever they want on them (eg. Game Server or web server with a custom port). How would I reverse proxy each one? According to this question, I can use a NAT. What is that, and how do I set it up? Also, can I use it to block specific ports, eg. port 25, and get logs, etc?
-
Please elaborate on why you want to "reverse proxy" each device or service in the first place. Do you have more clients than IP addresses?– grawity_u1686Commented Feb 2, 2019 at 12:27
-
I have 1 IP address, and each pi will have a subdomain like pi1.example.org.– user936203Commented Feb 2, 2019 at 14:56
2 Answers
How would I reverse proxy each one?
In general: you wouldn't.
From your question, it sounds like you're trying to share a single public IP address between many client devices. Both NAT and reverse-proxying are mechanisms for that, although they work at different levels.
(However, if you can afford a dedicated public IP address for every device, then the problem doesn't exist in the first place and both mechanisms are practically irrelevant.)
DNAT (usually called "port forwarding") usually works at transport level – it allows several devices to "share" an IP address by assigning each device a range of TCP or UDP ports.
For example, if you own the IP address
x.y.z.t
, you can forward TCP port 80 (x.y.z.t:80
) to device A, port 81 to device B, and so on.Reverse proxying usually works at application level – it allows several devices or services to "share" a single IP:port combination by separating requests based on some identifier found in the protocol.
For example, if you have a HTTP reverse proxy running on
x.y.z.t:80
, you can make it forward HTTP requests to different devices based on what domain name was requested.
Reverse proxying has the advantage that the proxy lets you share the same IP:port across multiple domains, but it comes with requirements:
- The proxy software needs to understand the protocol in question; it needs to be purpose-built for that protocol. This means you can't just arbitrarily proxy "all ports" and have it work for any miscellaneous service your clients would run.
- The protocol needs to actually have some sort of "host" or "domain" identifier as part of its messages. Not all protocols carry such identifiers; in fact most don't.
- Proxying rewrites lower-layer addresses; your clients will see all connections as coming from the proxy itself, unless the service also has methods for dealing with that (e.g. X-Forwarded-For or the so-called "PROXY protocol").
So proxying for multiple devices is practically limited to HTTP and HTTPS (which have a "Host" header); plus TLS-based services (which have SNI and ALPN); plus maybe DNS and SMTP (based on recipient address); and mayyybe insecure POP3/IMAP/FTP (based on login name).
For game servers though it's not an option – you pretty much have to use a dedicated port (or several) for each service on each device. That's usually called "port forwarding" or "DNAT"; it is exactly the same thing as the port forwarding feature in your home router; and it has its own set of problems:
It doesn't know about DNS domains and works directly on IP address level. If all your domains resolve to the same single IP address, they all have the exact same port forwarding rules.
This means each TCP or UDP port on a given IP address can only be forwarded to one device. For example, if client 1 gets the standard SSH port, say
pi1.example.com:22
, that meanspi2.example.com:22
orpi3.example.com:22
will also go to client 1's device – other clients now cannot use this port for inbound connections at all. (Depending on what software performs NAT, they probably cannot use it for outbound connections either.)There are only ~65k TCP ports and ~65k UDP ports (per IP address), and they're required for both inbound connections (one per service, sometimes more) and for outbound connections (as the source port; generally one per connection). So in practice you can't have more than... say, ~32k port-forwarding rules.
Some services require a specific port. For example, SMTP for inbound mail delivery always uses TCP port 25; IKE uses UDP ports 500 and 4500; game servers often require a specific range of ports. If one of your clients reserves that specific range, other clients cannot run the same service.
As for how to set it up – I suggest starting with DNAT, because most likely you'll need it for the reverse proxy anyway.
What is that, and how do I set it up?
As mentioned, NAT for incoming connections (DNAT) is often known as "port forwarding" and is configured directly on your router (the device which 'owns' your public IP address), and it will surely be explained in the device's manual.
(If the router just runs regular Linux or FreeBSD, then DNAT rules are added through iptables or pf, same as firewall rules.)
Also, can I use it to block specific ports, eg. port 25, and get logs, etc?
Yes and no. Those are features of your firewall. Any decent firewall will have them (I mean, that's what a firewall does), but they'll be there alongside NAT, but not part of NAT.
-
Is there anything I can use that allows me to both have separate devices for different domains and work with all ports? Like a special type of software I could run on a router?– user936203Commented Mar 3, 2019 at 14:02
-
No. The only way to make this work with any protocol (i.e. not limited to HTTP or TLS) is to get more IP addresses. Otherwise your system literally doesn't receive the information necessary to distinguish between domains, and there's no software nor hardware that could just pull it out of thin air. Commented Mar 3, 2019 at 14:09
-
Okay, is there an average cost for static IPs?– user936203Commented Mar 3, 2019 at 19:23
-
For IPv4 – it varies a lot; it depends on whether you're buying individual from your ISP (sometimes could be as low as $1/address/month), or whole blocks on the market (requires BGP services in order to actually use the block, with extra costs). Commented Mar 3, 2019 at 20:09
This answer, while technically accurate, it isn't the only answer. Although, if gaming, port forwarding definitely comes into play.
You can also use one static IP and a NAT router. The affordability question doesn't have to come into play for having a static IP address per device. NAT also enhances security by masking the many devices behind the one static IP.
You can definitely create as many subdomains as you want and assign each subdomain to a unique reverse proxy port on your routing/hosting server that points to each individual IP (or tor address).
I am not saying this isn't complicated, it kind of is, and it's a bit tedious if you are doing this for 30 raspberry pi's (or other devices).
The Bitcoin community has this documented well for both nginx and apache2. NGINX: https://docs.btcpayserver.org/Deployment/ReverseProxyToTor/ APACHE2: https://medium.com/@brewsbitcoin/apache-reverse-proxy-to-tor-19d012592620