If you want to make your home server accessible on the Internet but can’t use port forwarding (if you are behind CGNAT for example) or just aren’t comfortable having your home IP public, there are a few ways to do it.
You could just use Cloudflared, it is free, easy to set up and gives you some security protection through Cloudflare’s WAF. However, Cloudflare is a reverse proxy, meaning that your connection is decrypted, analyzed and then re-encrypted back to its origin, it also has specific T&S limits.
Herein comes Rathole, it’s a small standalone program written in Rust, it’s basically a simple TCP proxy, it doesn’t decrypt anything, it just forwards TCP traffic from one host to another using NAT traversal to avoid the need to port-forward anything.
You just need a server with a public IP to tunnel TCP traffic back to your home server.
I am going to use it to proxy Caddy, the reverse proxy I use on my home server, without MITMing any connections.
Installing Rathole
Rathole is a self-contained package, just download the one that’s compiled for your platform and run it from GitHub. You can also run it in a container.
This will be split into two parts, as Rathole needs to run on your home server and on the server with a static IP.
Public server docker-compose.yml
|
|
Rathole sever Config
|
|
Home server docker setup
|
|
Home server Rathole Config
|
|
Just start them both and you should be up and running! You will also need to make sure that the domains are pointing to the VPS correctly so that HTTPS and applications work as expected.
Source IP
There is one caveat though, and it’s kind of a big one, the source IP for all connections will be set to 127.0.0.1. That’s a big problem if you want to protect your applications from DOS or endless login attempts.
There is a solution, however, the PROXY protocol
Forward source IP with PROXY protocol in Rathole
The proxy protocol is a protocol that allows you to forward the source IP without needing too much computation.
Both the TCP proxy and the upstream application must support the PROXY protocol for this to work. Caddy supports the PROXY protocol, as a client and as a proxy.
There is an open PR for Rathole which adds support for the PROXY protocol. You can use my docker image to use the version with PROXY protocol support, or just build it locally.
Just use the same Configs as before, while adding enable_proxy_protocol = true
under the [server.services.home-proxy]
block.
Make sure that the web server/app you’re tunneling to supports the PROXY protocol and that it’s set up correctly.
Now you should be able to get the correct source IP even with a TCP tunnel in between!