I love the idea too but the implementation is a bit scary in my opinion. The return (!!strchr(req, '/')); forbids slashes in file paths given to open(2) so I think that this is safe against directory traversals, but there are so many subtleties that can cause security bugs that I’m not sure to trust this code that doesn’t even look at req in respond()… And if you look carefully at main(), buf[len-1] = '\0'; can erase an already-read character. Again, this shouldn’t be an issue in practice, but hey, this is C. It’s a language where security issues are way to easy to introduce. I requires discipline. I think that it’s really easy to introduce a serious bug in such code with a lot of subtleties.
return (!!strchr(req, '/'));
buf[len-1] = '\0';
On the other hand, if this is jailed inside a KVM virtual machine with nothing else, why not. Lots of companies and people rely on scary code in production being properly jailed.
The file has changed quite a bit since I looked at it a few hours ago! Both versions are scary to me though. I think this is a good example of why it’s a good idea to reach for a language other than C when dealing with strings, untrusted input, and the like. What would the equivalent Zig code look like?
I self-host as well and find great inspiration from this. It highlights the extent that one can simplify the process. Again, wonderful work!
edit: I’ll be studying server.c!
woah crazy. I know nothing about selfhosting like that. What’s that it talks about with a reverse proxy? How’s that go from a public IP on vultr to a closet in your home?
I think his main motivation was to not expose his residential IP address. If he’s on a dynamic IP address, a cron job could access a secret URL on his VPS over at Vultr. The receiving end over at the VPS could then look at the client’s IP address (ie. his current residential IP address) and reconfigure nginx (or HAProxy, etc.) to route traffic to that specific IP adress instead of the old one.
If you wanna be fancy you can have a gpg key pair and send an encrypted payload to a doesn’t-need-to-be-secret url. Swap out for other asymmetric encryption schemes to your liking. I just picked what I know.
You can also simply run a client for any dynamic DNS at home, then you have an A record to lookup. It’s probably more reliable to not rely on DNS propagation times and just push your IP periodically, like @enpo wrote.
I use duckdns.org, but I don’t host anything public at home, but I do access my MP3s with subsonic, so I don’t need the static IP.
In addition to @enpo’s suggestion, you could easily do this with a VPN or SSH.
Ah! Why didn’t I think of that :)
The clever thing about a VPN is that you can leave the residential firewall as-is with no open ports to the outside world.
You’ll also benefit from basically no delay if your ISP changes your IP address as the VPN would just reconnect.
On top of this, your layer 7 reverse proxy (nginx, HAProxy, etc.) wouldn’t need to be reconfigured in the event of an IP address change, as the IP address over the VPN would be private (RFC 1918), and most importantly: static.
Just benefits and no downsides :)