How do you actually self-host securely?

109 points by pralkarz a day ago on lobsters | 61 comments

Hell yea. I love this question.

It sounds like what you may want is "nobody can read my packets but me!" If that's the case I would look at the chain of things.

  • you need to route traffic to the pi. DNS for translating the hostname to the static ip, and then some way to route on the internal network from the static ip to your pi.
  • you need a valid key and certificate so the traffic you serve is recognized as secure to other browsers (keys and certs)
  • you want tls, and to deliberately terminate tls somewhere you control

These three are super intertwined, "self hosting" is choosing which of these you want to own.

My personal favorite setup:

  • rent a $5/mo box from any provider (anything works - vultr, linode, digital ocean, hetzner)
  • use your pi to ssh to the box you rent, port forward 443 to your pi.
  • run acme.sh on whatever is terminating tls (eventually your pi)

I like this setup for a few reasons.

  1. This provides a static IP address you can point DNS records to. It also doesn't disclose where you live. You may or may not care about this. But it also means you spend more time learning about internet and less about fighting port forwarding on home networks.
  2. If your pi can touch the internet at all, it can find your box. this means you can duct tape your pi to a mint mobile hotspot and a solar panel and have your static site served anywhere there's sunshine. I always picture it baking in the sun on the cracked back dash of a 1996 Toyota Camry flying down the highway. I don't know why, it just makes me smile.
  3. Because you're using ssh, there's TLS over TLS. But that really doesn't matter. The point is that nothing between you and a user is visible to anyone but your pi. When you eventually move off of ssh port forwarding to something more stable nothing else changes.
  4. When your initially setting this up and debugging, anything you do on your pi you can do on the $5 box you're renting. It's a touch more stable, and closer to what someone will actually pay you to do some day.

You may end up using nginx or haproxy somewhere to get ports to line up. But you can also use iptables. Dealer's choice.

Tailscale and Cloudflare tunnels are really cool. They take a bit of the headache away, but you're right that they give up that bit of security (and the learning!).

I'm so psyched for you :) let me know how it goes!

johnklos | 19 hours ago

I just drove across the Untied States with my backup MX. My phone provided a hotspot, a GL.inet did tethering and provided Internet, and my backup MX ran a tinc tunnel to give itself a public IP.

Since my backup MX runs off of 5 volts (USB powered) and has a battery backup, I ran it off of the cigarette lighter USB power adapter, but it could've just as easily been off my solar panel (which I run through the hatchback window :)

quindarius | 18 hours ago

so sick dude

dsschnau | 23 hours ago

I always picture it baking in the sun on the cracked back dash of a 1996 Toyota Camry flying down the highway.

I have to admit that I smiled at this too.

dzwdz | 20 hours ago

I'm not sure if acme.sh is the best choice.

Also, for a lot of self-hosting setups (where you've got a server at home with services that you want to reach from other devices), I'd argue that Tailscale is overkill. Plain Wireguard is pleasantly simple to configure.

Sure, it has some niceties - it has NAT traversal, it's smart enough to figure out more efficient routing than the star topology you'd probably end up with in the simplest plain wg setup, it has fancy multiple user support - but do you actually need any of that?

gecko | 20 hours ago

The reason (the only reason!) I'm using Tailscale instead of WireGuard is that Tailscale has native apps all over the place (including critically for Apple TV and Google's streamer-du-jour), whereas WireGuard doesn't.[1]. Given I don't have to pay anything to use Tailscale, that makes it worth it for me for at least that specific use-case.

[1]: Well, there's a paid subscription app for the Apple TV, and I could jailbreak the Google thing, but there's a limit to how much effort I wanna put into just getting my Jellyfin files available.

altano | 19 hours ago

WireGuard is available on tvOS. Plain, free, open source WireGuard.

gecko | 18 hours ago

Oh awesome! I'll have to take another look. That was extremely not true in 2024 or '25

altano | 18 hours ago

Uhhh I was so certain and yet… I think I hallucinated this. Doesn’t seem available.

weberc2 | 19 hours ago

I'd argue that Tailscale is overkill. Plain Wireguard is pleasantly simple to configure.

I keep hearing this, but I haven't seen anyone explain how to make this work nicely, and all of my forays into wg have been exercises in frustration (not that Tailscale has been pain-free). Getting the tunnel up and running works fine, but figuring out how to keep the tunnel from falling over or silently not forwarding traffic has been considerably more difficult.

Also, I'm not really sure how I would get wireguard working on my Apple TV without Tailscale.

weberc2 | 19 hours ago

use your pi to ssh to the box you rent, port forward 443 to your pi

When I tried this, the SSH tunnel would fall over all the time and need to be recreated. Seems like at a minimum you need some control loop to watch it, but even then sometimes the failure wasn't "the SSH process went away" but rather that it was alive but silently not working, and I couldn't figure out how to detect this case from the control loop running in the pi so I would have to kick it manually once or twice a month.

In my experience you can get decent reliability with autossh by setting the ServerAliveInterval so that there's always a trickle of traffic. You can also set TCPKeepAlive but since that operates at the TCP level it's subject to middleboxes, which I'd guess is a particular risk on a mobile network.

But I do agree that SSH is not the right tool here.

marginalia | 21 hours ago

As a chronic putting stuff publicly accessible online guy, I'd say you get 95% of the way there by:

  • Regularly updating your system
  • Disabling password logins on SSH
  • Running SSH on a non-standard port (low effort automated drive-by intrusion attempts are, to be realistic, the main threat vector for this type of stuff, so reducing your target profile does help a fair bit even if your grandma could run nmap and find your hidden port)
  • Setting up UFW (or the like) and blocking every port that shouldn't be accessible
  • If you do not have a PhD in docker networking, don't use docker as it's very easy to have it helpfully poke holes in your firewall
  • For anything you want accessible only by you, put it behind caddy or nginx and add basic_auth. Never trust a web app's login screen to keep you safe. You can further improve this with fail2ban. Client certs are a way to level this up even further but it's a bit of a hassle to set up. Just basic_auth goes a very long way.

quindarius | 18 hours ago

great stuff here

tuxes | a day ago

It's safer to start with services that aren't public facing, e.g. install Tailscale on your phone, laptop, and Raspberry Pi, and then start setting up services you want for yourself.

Some people I asked this question recommended solutions like Cloudflare Tunnels to make it secure, but using such a provider almost feels like it defeats the point of self-hosting

I like to do the end-to-end myself but sometimes I just can't be bothered and so use Cloudflare Tunnels to make it work, and that's a better outcome for me than giving up entirely.

[OP] pralkarz | 23 hours ago

I've heard about Tailscale many times but, to be honest, their website reads the same as corporate emails to me, as in I cannot digest any substance from it (might be another skill issue, I know). Would you mind sharing some concrete use case for it (e.g. an example of what you use it for)? That might make it easier for me to grasp the concept.

The simplest way to explain it I think would be to say that Tailscale makes all your devices act like they’re on the same home network, no matter where they actually are.

tuxes | 23 hours ago

Their site from 2020 is a bit clearer: https://web.archive.org/web/20201129111934/https://tailscale.com/

But basically it lets your various devices connect to each other, whereever they are, without having to deal with port forwarding, firewalls, dynamic DNS... so your phone or laptop can access self-hosted services on your Raspberry Pi (photos, Jellyfin, RSS, files, ...). It does this while keeping it all hidden from random people/attackers.

I don't use Tailscale, and instead just use plain Wireguard/mTLS, but Tailscale is easiest to set up and seems to be the most popular option for people that want to access their Raspberry Pi when away from home.

I primarily use it for a personal "private intranet"; I host services like Grafana and Forgejo on homelab machines inside my home, and then connect them to Tailscale so I can access them remotely through the tailnet without needing to put them on the public internet. As a bonus it also provides "funnel", a public reverse-proxy which works the same as serving to the tailnet, avoiding the need for a public IP to serve those services.

Unlike traditional VPNs, Tailscale does not tunnel traffic through its infrastructure per se - the control plane server governs access and routing, but traffic transits through establishing point-to-point WireGuard tunnels, with Tailscale operating relays which forward encrypted packets between machines when needed for e.g. NAT traversal. That said, you do give up some amount of self hosting - you can rent a cheap VPS and set up e.g. Headscale to get a decent subset of functionality (though I personally haven't tried this myself).

alethkit | 20 hours ago

The best high-level overview of why Tailscale came to be, IMO, is https://tailscale.com/blog/two-internets-both-flakey

cyberia | 18 hours ago

Tailscale is decent, but if you want to do some learning, I recommend setting up a WireGuard tunnel manually.

My setup is a cloud VPS (on OVH) running TLS termination, which forwards traffic to my homelab server, which connects up to the VPS over WireGuard. That way, my home IP is not publicly visible, and it doesn't matter if it changes or whatever -- my homelab server just reconnects the tunnel and the cloud VPS addresses it by its WireGuard IP.

frontsideair | 5 hours ago

Shameless self-plug here because my blog that explains Tailscale for self-hosting has been positively received so it may be of use (İ was even using a Raspberry Pi!)

https://blog.6nok.org/tailscale-is-pretty-useful/

hafiz | 23 hours ago

Specific example: say you want to have a job server whose dashboard you can access via a stable identifier, runs on an isolated machine, and is not exposed to the public internet. Then Tailscale is a great solution. Other examples: tunnels into other VPCs which should not be exposed to the internet; sharing local demos between those in the network; using a specific machine as an exit node when you don’t trust the network you’re currently on; access your devices via stable IDs (eg I have a cluster of Macs whose IPs are dynamic, but I can log in via screen share with stable IDs)

Comment removed by its author

creesch | 20 hours ago

It's simply a way to set up a VPN to your home network. The thing that makes it attractive is that you don't need a static IP for your home to connect to as they do routing through them and it is extremely easy to set up.

But it also means you are trusting them. Personally I do have a static IP at home and my router also supports WireGuard so I am using that. Same thing.

simonw | 22 hours ago

Ten mentions of Tailscale in this conversation already, I'm going to make it 11.

It really does solve the home lab security problem so well.

Run it on your devices - it works in everything (I even have it on an Apple TV) and it's trivial to install and configure.

Now your phone or laptop, anywhere in the world, can securely talk to the other devices via their 100. IPs (or through Tailscale DNS) - and nothing else can reach them.

And it's free for that kind of personal use!

Prior to Tailscale I was too afraid to even try running a home lab of any sort. Now I have several devices on mine and I actually use them remotely (from my phone) several times a week.

Sometimes I deliberately leave my laptop at home because controlling it from my phone while I'm out and about is more efficient than physically getting it out of my bag.

(Tailscale is basically just a wrapper around Wireguard, so if you want to roll your own you can - I'm not nearly confident enough in my own skills to attempt that for something as security-critical as this myself.)

catwell | 22 hours ago

As an alternative to Tailscale I do the same with ZeroTier, which I think predates it (I actually started doing it with an in-house technology we had at a defunct startup called Lima...)

johnklos | 21 hours ago

Here're some broad generalzations that may help you.

First, yes, most of what you find using search engines is poor quality, regurgitated marketing stuff. Sure, you can learn good things from those results, but you'll also learn poor practices at the same time. For instance, most marketed how-tos will tell you to download binary programs or Docker images, which might be OK for learning, but become security issues over time.

One good practice is to learn how to install software via source, or at least using a package manager that's updated often. Docker images are made when the creators feel like it, and often have dependencies baked in that are ancient and may have vulnerabilities. A proper packaging system that's updated often will use the same dependencies for all of your software and will be updated regularly, particularly when any of those dependencies have exploitable vulnerabilities.

Learn about and become comfortable with the Unix permissions model. It's actually quite good, and what some of these marketing people will tell you is wrong: if you use a separate, unprivileged user for each service you host, and one of those users gets compromised, and it can lead to a root escalation, then the issue is that your system isn't updated enough to not allow a root escalation. The number of people who want you to address the symptom and not the problem is huge, and they often advocate for, for instance, Docker or some other thing because it's popular, not because it actually makes sense.

Don't let feature creep win. I host dozens of Wordpress sites for friends and small businesses, and every time PHP gets updated, someone's site ends up not working because they got excited when setting up their site and install a dozen plugins, most which aren't necessary, but which aren't updated and cause their site to stop working with the latest PHP. I've gotten good at disabling plugins without logging in to WP. It's better to only install and use what you really want to use.

Related to that, I recommend installing, playing, getting everything working properly, making notes, then using those notes to reinstall from scratch so you know which steps are superfluous. Your first install might have twenty steps, but once you understand things, the second might have six. Clean is good.

Avoid passwords everywhere you can. Use ssh keys, only allow access to https login pages to certain IPs or IP ranges, if possible, make those links custom if you can, and so on. An OpenCloud login page that people (and bots) don't know is worlds better than a public one that bots will hit constantly.

For anything that does require passwords, don't reuse, don't use simple or basic passwords, and don't let anyone get away with thinking their weak password is "good enough" or that nobody will find the service to try too hard to log in. Assume everything will get tested, including every username, email address and password in every leak, ever.

Don't believe gatekeepers that tell you that you can't, that you shouldn't do certain things. I've taught people who are non-technical to self-host email. If non-technical people can do it, then why should gatekeepers who claim to be technically proficient be believed when they insist that email can't reasonably be self-hosted?

If you find yourself in communities of people who are condescending to you, or who are trying to tell you that a Raspberry Pi isn't a proper server, for instance, then find another community. This community is a good one :)

Oh - get good, durable storage for your Pi, and have fun!

sjamaan | an hour ago

Use ssh keys, only allow access to https login pages to certain IPs or IP ranges, if possible, make those links custom if you can, and so on.

Even better, if you can get away with it: put "internal" webapps on loopback and connect via ssh forwarding. For example, I have a static blog and whenever I want to see analytics (AWstats), which I access by starting a small webserver on localhost and then tunneling the port via ssh to my own box. This way, the analytics aren't available at all via the general internet.

Come to think of it, I haven't checked my analytics in years. But the point is, you can do this for any web interface to sensitive info or where you don't trust the security of the app (which should be every app, really).

Similarly, I run a private IRC server on which I chat to folks who have SSH access to my machine. This IRC server also listens on localhost only. I feel way better about this than when it would be available to anyone, even if it were locked down.

Finally, use a nftables or similar rule set where you block all ports and then selectively and explicitly allow only the services you intend to allow to be reachable from the outside. Then, if you accidentally misconfigure something to listen on external IPs, it's still not reachable.

A very non-concrete advice is simplicity.

When you self-host, you're responsible for security yourself (duh). And maintenance is gonna be a hobby. So scale accordingly: Choose software that doesn't aim to change from under your feet, because that'll make you put off maintenance (this is what some of us like to use the word "stable" to mean). Choose software that's easy to get back into and understand without having to be in the weeds every day. Choose software that'll at least break in obvious ways. Choose software where lots of things have to go wrong for things to break.

Choose boring.

vincent-uden | a day ago

How much you need to care about security is entirely dependent on what you host. I would for example greatly invested in security if I self-hosted a public facing file storage or an email server.

I would in general care much less if as you describe I would be hosting a static website on a Raspberry Pi. The risk just isn't that big. It can't cost you a lot of money since it's your own hardware. The worst thing that could happen is that a stranger gains complete control over your Raspberry Pi. They could possibly probe your local network (but not if you put the Rasberry Pi on a subnet), display other information on your website or put your Rasberry Pi to work on something benefitting them (as part of a botnet or crypto mining for example).

I personally wouldn't consider any of those possibilities as great risks. And as a bonus, setting up logging to detect if any of these were happening could be a fun side project.

icefox | 22 hours ago

For only a static website? Only allow SSH private keys, no passwords. Run stable versions of stable distros and patch whenever something bad happens. Use nginx. Turn off everything you don't need, and use a firewall to double-check.

That's really all.

Using a VPN to a server elsewhere is useful, but mainly as a way to avoid having to talk a residential ISP into allowing you to serve websites and such. I like Nebula more than Tailscale, it's a bit chonky to set up but works magically well once it's up. Tried Wireguard and it seemed to have real issues with hole-punching.

jaredkrinke | 12 hours ago

Any suggestions on how to tell when something bad happens? Subscribe to distro security mailing list? Some easy to setup performance monitoring?

My biggest hesitation with hosting a public server is that I won’t even know if something bad happened. Not that that stops me…

msangi | 23 hours ago

I avoid exposing my services to the public internet since I am the only user. They are available only via WireGuard. I use plan WireGuard, but solutions like Tailscale or NetBird are fine if you need something else to deal with configuration for you.

On top of that, I still do HTTPs everywhere (using the ACME DNS-01 challenge so I get proper certificates from Let's Encrypt without exposing anything on the public Internet).

Authentication is mostly based on passkeys (I use PocketID for single-sing-on) and I only use SSH keys (backed by secure enclaves whenever possible).

I run my services in NixOS. For my threat model it's okay to run everything on the same machine but to get more workload segregation you could separate the various services across several VMs/micro-VMs.

bahlo | 22 hours ago

I described my NAS setup here: https://arne.me/blog/buildlog-nas#security, tl;dr is Tailscale with self-hosted control server, nothing exposed to the internet, HTTPS, encrypted drives.

I think self-hosting a website from your home and self-hosting other things like storage/rss/photos/etc. should be treated as distinct problems with different approaches. Ideally they shouldn't live on the same system even.

hoistbypetard | 22 hours ago

Several years ago, I wrote down how I do it, step-by-step. I still use mostly the same approach, though some of the steps have changed over the years. The biggest difference is that now I use tailscale for new things, and and have my reverse proxy connect to the backend over the tailnet. Tailscale is essentially automating the wireguard setup I described in that post, while adding a few nice features around it.

I like having my own reverse proxy VPS. The cheapest possible Linux VPS from whatever provider you want works fine for this. For new VPSes, netcup is my current favorite. (I also use Hetzner, DigitalOcean and Linode for some projects. They are a little easier to navigate than netcup, and all 3 are available for smaller units of time than a month. For things that will be online for a full month or more, though, netcup's pricing is hard to beat. It does make me chuckle that I'm paying in euros for a server I could bike past on the east coast of the US.)

But if you're only hosting things for yourself and for people you trust on your network, you could skip the reverse proxy VPS and just use your wireguard network/tailnet.

creesch | 20 hours ago

Most things I self host are private use anyway. So my home server only gets network access and I use WireGuard to access things remotely.

This of course doesn't apply to a public facing static website. I'd honestly never host those from home network since that also provides people visiting it with too much geo information than I'd like. So for that I'd rent a VPS and keep it as simple as possible. Either nginx with the lets encrypt certbot or caddy which has certificates build in and also supports static websites.

Make sure security updates are automatically applied, make ssh key only and you already have most of your bases covered as far as static hosting goes.

As you can't control upcoming exploits, you want to:

  • Reduce the number of people getting access to a potential zero-day exploit
  • Reduce the impact of exploiting a zero-day I mentioned zero day, because I am assuming your system will be kept up-to-date. => Automate your updates (both for your packages and container images)

Reducing the access: Some only allow access to these ports: 22 for SSH (if you leave it on standard port, which you will see some people advise to change), 80 (normally never used except to ease SSL setup via Let's encrypt), and 443 (only for services that need to be public). For the services not intended to general public, people would use a VPN or Tailscale, which means only people you allow on the network will be able to access these (it means you will likely need to help your family member and friends to setup Twingate if you want them to access these, and they won't be able to reach your services from any laptop). Some people find the above even too open, and would reduce it further. Everything is behind tailscale (even SSH), and public services leverage Tailscale Funnel. No port is open on your machine, but a tunnel exist between your machine and tailscale infrastructure that expose your websites there. Reducing impact: The public websites can still be vulnerable to zero days (from tailscale funnel or not), so the idea is containing damage. Run your services in a containers is an easy way to limit impact to that service only if things go wrong (and not the whole server).

If you want to go a bit more advanced, I found this blog contains good advice generally:

There are obviously much more you can do: VLAN for your home server, and a lot of permutation for the same idea: wireguard instead of tailscale, iroh instead of tailscale, VM instead of containers, different service users instead of containers, etc.

bramh | 18 hours ago

I run two reverse proxies: one is publicly accessible, and one is only accessible over WireGuard. The public reverse proxy can only communicate with the public services (e.g. website), and the private one can only communicate with the private services (e.g. Immich). The services can only talk to the reverse proxy and aren't exposed in any other way. This is all done using basic Docker networking.

There are a lot of posts about Tailscale already, but I prefer WireGuard. It's trivial to set up, and there's no magic involved. Some serious missteps by Tailscale, such as this incident, and general enshittification concerns make me not want to use it.

I wrote a simple script to manage and distribute my WireGuard configs and deal with the various edge cases my setup has, but you can also just copy your configs to your devices manually. It really isn't as big of a deal as some people make it out to be.

amiantos | 14 hours ago

Not really an answer to your question, but I think hosting publicly accessible sites for broader access through your home internet is a bad idea, because if you get real traffic going to it, you are likely in violation of your ISP's policies and risk ending up in a bad position in the future. Home internet is how I work, so if I lost it, I would be hurting. You're also opening yourself up to getting your home internet DDOS'd, which would also hurt quite a bit and make your ISP grumpy.

If your site is static, you can host a static site completely for free with Cloudflare R2, and publish it easily via wrangler. No need to expose your home network in any way for a static site, that seems like overkill to me. I understand it's about learning and tinkering and so on, but the amount of learning and tinkering you're going to do while hosting a static site is basically nil. Personally I think there is more learning to be done figuring out how to generate a static site and publish it automatically via wrangler. This is also a great way to run a Wordpress site as you can use Wordpress safely on your home network, use a static site plugin to generate the site, publish it with wrangler, and avoid all the 'hacking' attempts that come from having a Wordpress site.

Personally, I run all of my homelab services inside containers and expose them via Cloudflared, and I know you already dismissed this, but I am not quite sure why as the only thing Cloudflared does is terminate TLS and eliminate issues with residential dynamic IPs. Other solutions for handling this are just as automated these days (caddy, nginx+certbot, etc), there's little difference and not much learning to do there.

instead of a cloudflare tunnel you could grab a vps, and set up a wireguard tunnel with NAT. I do this for my torrent and DirectConnect clients, so they get public IPs without UPnP/NAT-PMP. I am considering doing same for Jellyfin so it's available outside of tailscale. But I might still require some extra layer, not sure.

bwbuhse | 22 hours ago

I'm lazy and not a good model, so maybe dont do what I do but:

I have WireGuard set up on my OPNsense box so I can VPN into my home network when I'm out. Services I want on the public internet are just open on 443, mostly static sites but a couple of things like Jellyfin. Services I don't want public have a default deny all in my Nginx config with a whitelist for my LAN and Wireguard subnets. I containerize stuff, idk, I figure if some container escape gets discovered then I'm not the biggest target anyway hopefully I have (encrypted) backups at rsync.net in case anything goes down

That's basically the gist. I guess I also keep my nftables fairly locked down on my server and have Crowdsec to block known bad IPs and can detect some things like port scans and block those too + IP-location based blocking on OPNsense to fully block connections from, e.g. China and Russia,

alexwennerberg | 20 hours ago

Many people suggest some publicly facing tunnel / proxy server, but doesn't this defeat the purpose of self-hosting: if you are running a VPS proxy, why not just host things on that proxy? If you're using some VPN service, why not just use AWS or something? Self-hosting loses its independence.

ggpsv | 16 hours ago

A VPS proxy can be just a gateway into your network, and you don't need much resources for WireGuard. A tiny VPS at $5-12 per year is enough. Your machines at home likely have more resources to host the applications.

Well, conceptually yes, in practice it's a trade-off between security & convenience. If you tunnel to a cloud service the traffic, you still own the data and most of the infra, and just delegating data passing to an external service (I wouldn't rent a whole VPS for that though, and just leverage off-the-shelf solutions like Tailscale or Cloudfare) You can still do the same without these external services (Headscale or Wireguard self hosted, and/or a proxy for the few public facing websites), it's all a trade-off about what you want to manage.

romforth | 19 hours ago

Anders Pitman had collected a boatload of resources regarding this:

https://github.com/anderspitman/awesome-tunneling

Both closed and open source solutions are listed.

From looking at it just now, it still seems to be actively maintained

maurycy | 19 hours ago

Services like cloudflare tunnels have little to do with security. The problem they solve is getting incoming internet traffic to a server without a public IP address. Those are very different problems.

Re: routing:

Some ISPs give out fixed public facing IPv4 address. If this is the case, set up port forwarding and enjoy. Otherwise, you'll need a reverse proxy service. Cloudflare tunnels is an option, but it's also easy to run your own on a rented server. (which can also work for non-HTTP services)

In any case, proxy based systems will introduce a dependency on some other server. If you don't like this, go complain to your ISP.

Re: security:

  • Most important: updates and proper service isolation
  • Use strong ssh passwords or disable passwords (key-only)
  • Firewall outgoing traffic
  • Minimize public facing services (i.e., If you server is at home, ssh doesn't have to be internet exposed)

grsecurity + PaX + RBAC rules, possibly using learn feature to build up ruleset

When configuring the grsec kernel, ensure to set up the socket limitation groups, GIDs which cannot open sockets (or flip it to require membership to open sockets "nosocks vs allowsocks")

Audit the system for setuid executables and, creating similar groups, limit access to them to certain users. If users cannot access a vulnerable SUID executable, they cannot exploit it.

Ensure to set sane limits.conf to avoid forkbombs.

Ring fence stuff with UIDs - one user, one service. That way a hacked service can leak its own stuff and not much more.

Don't rely on containers, sandboxes, or magic solutions. Real security is boring. Boring usually works. Docker, firejail, Podman, cgroups, etc all add code on top of the already-running access control and permissions, and in modern times, more code means more bugs.

Things like SEL4 would be perfectly secure on verified hardware, but that says nothing of the applications you build on top of them.

I, uh, am surprised there are people running grsec for self-hosted stuff. I wouldn't have budget to get that.

chriswarbo | 17 hours ago

Lots of great advice here for a "standard" Web server setup. I wanted to mention that there are some less standard approaches, like P2P and overlay networks, which can side-step issues like tunnelling, DNS and HTTPS.

For example, TOR has a feature called "onion services", where any Internet-connected machine can make a port accessible via a .onion address (I used this twenty years ago to run a Wiki from my dorm room; despite knowing very little about networking!)

Static Website hosting is also a pretty good fit for content-addressed storage like IPFS, dat, freenet, etc.

The downside to these approaches is that they're not quite compatible with a standard OS + DNS + Web browser setup. In the best case, that can be avoided via a gateway like Tor2web or an IPFS gateway; but in the worst case it might require installing a particular client in order to access. That might be fine for applications where you just want to connect together machines that you control.

unixdigest | 11 hours ago

I don't recommend Cloudflare Tunnels, Cloudflare in general, or any semi-self hosting/cloud based solutions as that defeats the whole point, as you also mentions.

Personally I also don't recommend hosting anything unless you run a router/firewall between the Internet and your machines. I highly recommend OpenBSD because a lot of the base system is build specifically for that and it's very well documented, very secure, and easy to setup.

I am running a setup almost like the one I have described in my tutorial OpenBSD Router Guide and I have everything I host behind that. That also takes care of DNS and everything else I need.

If you don't need to access your router from the Internet, only allow access from the local network. Otherwise you can disable password based SSH logins, run SSH on a non-standard port, use fail2ban, auto-block malicious IPs, etc. in order to improve security.

As a start, you can run everything on the router itself, such as your static website, and you can even just use a Raspberry Pi as the router (with an extra USB Ethernet dongle), but I personally prefer to split things up a bit. So I have a couple of other machines behind the firewall running web stuff and some other stuff too.

If you're up to it you can also host your own email, which I have done in the past with great success using OpenSMTPD - actually on Raspberry Pi. You can find some tutorials on my website on how I did that on Arch Linux, however they are outdated now, but it worked great for a long time - until a drive broke. I used Arch Linux at the time for fun and in order to see how difficult it would be to maintain as Arch is bleeding edge. It ran very well for the time I used it. Normally I always prefer OpenBSD and FreeBSD.

Other than that, I recommend using a close to the metal approach without extra layers as that will make you understand the tech you're using better and it will also decrease the amount of problems. Using something like Docker or other "shenanigans" may make it easier to get started, but will often eventually cause unnecessary problems in the long run.

Don't be afraid to self-host! The entire "cloud" basically IS self-host, only someone else is doing it for you ;)

atmosx | 23 hours ago

Hello @pralkarz,

I assume your internet connection has enough bandwidth to sustain a small to moderate website. Self-hosting a publicly facing service is an order of magnitude more dangerous than self-hosting private services such as photo management applications or media servers because of the security implications. On the bright side, static pages can be hosted securely with relatively low effort compared to LAMP stack.

(a) Applying network segmentation is a good start. The RPi should not be able to communicate with other devices through router / firewall configuration. Maybe allow just one device based on IP or MAC address to access the RPi from the LAN.

(b) Then setup DNS records. I assume you own an FQDN. Use an ready-made or custom script to update the DNS records. I'm using dnscontrol alongside envsubst and to perform the changes but there are simpler solutions out there.

(c) Once the DNS is working and updating properly, use an application to issue SSL certificates. My favourite is acme.sh but there are quite a few polished alternatives, e.g. certbot, lego, etc.

(d) Now you're ready to setup a reverse proxy. Note that modern rev-proxies like Caddy can manage (c) on their own. I'm not using them, I'm familiar with nginx so I use that.

(e) Create a deployment user with minimum permissions and use that user to upload data via sftp or other secure protocol. If you want to setup a deployment pipeline via git, that's also possible through webhooks.

(f) Secure the system. I'm pretty sure that you can flat-out ban the big cloud CIDRs. That will save you from dumb scanners abusing your website. Since very few humans use these addresses for outgoing connections, I think it's a good strategy to block them straight-up. You can setup a cron script to download CIDRs and update your firewall "block" tables.

f.1 Make sure you setup some sort of monitoring, so that you can quickly measure things like resources and even incoming requests (e.g. response latency, No of incoming requests, etc). Since you're going to self-host you'll have log access which means full visitors info.

f.2 You might want to explore the possibility of setting a "chroot"

f.3 Alerting: pushover is a good "host -> mobile" alternative, another is to setup the SMTPd in a way that the system can send you emails with status reports, etc. to your personal email.

(g) Backup everything locally (e.g. another NAS) or remotely (backblaze is fairly cheap), or both.

I believe that's all I'd say :-)

Happy self-hosting!

To echo the other comments in this thread so far, I've similarly used the Tailscale/Cloudflare Tunnel combination. Tailscale for "personal" services (Syncthing, remote wake-up, etc.) while the Cloudflare tunnel is for anything publicly available (e.g a library site). Yes, definitely less learning than trying to full roll up your own infrastructure, but it's free and fairly painless while giving me a bit more flexibility w.r.t how I'm hosting services.

gerardnico | 19 hours ago

If your router at home is capable to forward a port, do a http port forwarding to your raspberry pi, get your public ip and put it in your dns. Note sure what you mean with security but an exploit on http is pretty small for a static website. If you want more security put your site in docker with a user other than root. Lot of fun, a lot to learn.

spc476 | 17 hours ago

One thing I don't see mentioned here is---if you host a web site, your ISP connection will be swamped with bot activity if it's publicly available. There are multiple ways to mitigate this, but they all come with different tradeoffs; Cloudflare is easy to set up, but you are relying upon a huge corporation that is part of the web consolidation problem. The other solution is to tune your web server/firewall to limit concurrent connections/block traffic, but that's more work on your side.

Personally, I do self-host, but it's a VM server that I manage myself. It's not a ton of work, but I do keep an eye on it and have had to spend quite a bit more time than I wanted in tuning Apache (which I've been using for 25+ years) not to fall over (to the point of compiling it myself with a custom module to limit IP connections).

vakradrz | 16 hours ago

You can start small and (relatively) safe and use CloudFlare to give you free DNS, TLS certs, a Tunnel that'll let you sidestep a lack of static IP (if you don't have such a thing) and put you behind their infrastructure.

You can then take steps towards running your own pieces of that, as you gain confidence.

Making your own TLS certs is pretty easy, using Let's Encrypt, and there's plenty of tooling to run that for you automatically if you just run through its setup process.

Running your own DNS can also be easy, and there's plenty of material to read. If it's a site that you don't mind dropping off the web occasionally if (when) you're waiting for DNS to propagate after you messed up an entry, just do it and enjoy!

apropos | 13 hours ago

I think ~mw and ~marginalia have covered most of the advice I would give. The only thing I have to add to that is that for hosting larger amounts of services, NixOS is the only operating system I will use. Its packages (nixpkgs) have good defaults -- most services have extensive sandboxing already set up for you -- and it provides for one place where all the vulnerability-knobs (i.e. open ports, weird user permissions, etc) can be found. It also forces you to be very explicit about security. If there are any services / dependencies with critical CVEs, it will refuse to build until you enter their names and versions verbatium into the configuration file. This is simultaneously good motivation to not run vulnerable software, and also serves to alert you if you missed a vulnerability report.

Though for hosting smaller amounts of software, really whatever's fine. I run Alpine Linux with HAProxy on my VPS. Just make sure you understand the system, and update it frequently.

In theory I agree with what most people wrote, but I kinda exactly don't want to expose any machine on the LAN to the internet, not even just by port forwarding https.

Maybe one day I'll make a local VM that has no connectivity to the lan so a potential attacker would need to break out of that VM first.

Plus the problems with DNS and addressing hosts from the LAN and from outside, but maybe I have not read the tailscale docs 100% correctly.

jpmonette | 12 hours ago

Used to have my apps exposed to the internet for ease of access but following the stream of AI hacks, got Tailscale and it turned out really way to setup and use. There’s also an open source version called Headscale that you can self host. My apps reside on a Pi I have under my desk and also a free Oracle VM.

erock | 9 hours ago

https://tuns.sh is a great way to expose local services to the internet in a safe, secure way. It's similar to cloudflare tunnels but uses ssh port forwarding to provide access only to your service.

katdork | 5 hours ago

hi pralkarz, i have heard of you from elsewhere (clonk)!

i like to run local services over a wireguard tunnel to a cheap vps with unmetered bandwidth if you care about not having to stare at usage or have potentially high usage. back in the day i would recommend buyvm. this works great for having heavier lifting at home, but with a pi, you might ask yourself why you're paying for a box.

if you didn't want to pay for a box, you'd be looking at dynamic dns and having to actually concern yourself with external access of your network through port forwarding.

in any case, if you own a domain you'd be able to use ACME challenges / certbot for obtaining TLS certificates, whether using HTTP-01 or DNS-01 challenges. i would presume HTTP-01 would be easiest for getting started, since all it requires is the certificate obtaining program to put some files on your web root

if you were using a dynamic DNS provider that provides a subdomain, you could probably use HTTP-01 challenges to that once you have nginx or something set up there.

setting up NGINX properly is relatively simple. a lot of this is particularly simple in NixOS land. a static website is just setting a server with a virtualHost with a root to the directory containing your site (typically a /var/www subpath). all of my stuff runs on NixOS, and i eventually intend to move it over to Guix, but this is neither here nor there. NixOS is a great entrypoint to beginners, in so as far as services.<thing>.enable and the options search and the NixOS manual makes it to navigate setting up services. guix's manual is better tho :(

aarroyoc | 3 hours ago

My setup is simple:

  • From my ISP router:

    • Configure No-IP. Many ISP routers already have the option to setup No-IP or other DynDNS services
    • Setup port forwarding in the ISP router for ports 80, 443 and a non standard one for SSH (also my ISP router doesn't allow to forward the 22 port, I think it's the only one limited)
  • Pi (in my case VisionFive 2, a RISC-V SBC)

    • Setup the Pi with a static IP and a firewall, nftables.
    • Keep it updated. I'm running Alpine Linux.
    • All web traffic goes to a reverse proxy first, which in my case is Caddy, because of how easy is to set up new sites and how easy is to get Let's Encrypt certificates. I use different subdomains, configured at my DNS registrar, but everything goes to the same machine in the end.

Some things could be better I guess but the stack is so simple, there's little attack surface