Good way(s) to secure App access from the internet

Hi everyone,

After almost 10 years of using TrueNAS mainly as storage appliance, I feel the moment is right to expand the ways I use the Apps and start using few also outside of the home network. This inevitably raises the question of security so I am hoping to collect sound advice from the community.

Let’s take immich photo manager as an example - I’d like to open it to the internet so that extended family members can use it as well. I am currently deliberating on the adequate security and considering 2 approaches:

  1. DNS - DDNS - Nginx Proxy Manager - Immich server - Fail2ban
    NPM handles server certificates for encrypting traffic, f2b monitors logon attempts and bans IPs. I am still not sure where best to implement the ban, on the router (preferred but may not be possible without custom firmware in my case) or at the NPM

  2. DNS - DDNS - NPM with mTLS - Immich server
    NPM again handles server certificates and also requires a client certificate. Immich clients (mostly mobile phone app) are provided with client certificates and only those clients are able to go pass NPM, others getting 400 error

Is [1] considered secure enough? Is it sufficient to implement IP banning at the router level, or even NPM level? I could imagine also IP banning at CloudFlare, but haven’t studied limitations of CloudFlare proxying to the image server (file sizes, bandwidth).
Is [2] an overkill? Managing client certificates feel cumbersome, any recommendations there? How people are doing it at such a small scale? Should I add f2b to the option [2], to make it even more secure?

Happy to hear thoughts and comments and let me know if I missed some relevant background info.

Thanks,
Vinko

“Is (it) considered secure enough?” - that all depends on your own requirements, doesn’t it? How secure do you need to make the service? Do you expect it to be under directed attack? How sensitive is the data you’re going to be hosting?

I don’t think you can implement fail2ban on TrueNAS apps, as they run in a container, and fail2ban puts rules into the host’s firewall based on log files it’s monitoring. TrueNAS Scale doesn’t have a firewall, as it’s not intended to be exposed to the Internet.

FWIW, I run a number of Apps on my Scale box that are exposed to the Internet via Nginx Proxy Manager. Setting up and maintaining a letsencrypt SSL cert with it is trivial, and this can provide secure and trusted access to your Apps, while also mitigating a number of well-known attack vectors.

Have you considered to just setup a VPN instead of the direct forward?
I can understand what you mean when you say

But at the same time risks are quite scaring.

Also, just to mention in case you didn’t know, NPM can be also be set to let access to services using a password

The safest way to handle this is to not expose them to the public Internet at all, and instead to use Tailscale to allow other folks to access the apps in question–though the more people you want to have access, the trickier that gets. Here are some resources addressing that method:

3 Likes

I don’t know exact answers to all your questions, I’m here to find out :slight_smile:

Do you exepct it to be under direct attack?

I don’t know and was wondering the same. How often does it happen that private servers get attacked? How do they get attacked?

As for Fail2ban, I don’t speak from experience as I haven’t tried it yet, but based on what I read, this can be done. Logs folder can be mounted on the host system and f2b can monitor it. Then f2b can be set to do action on whatever appliance it has access to and can talk to. I foud instructions even on how to ban IP outside at CloudFlare (my DNS registrar).

Regarding NPM and certificates - can you please elaborate more on what you mean? I am also using NPM to manage server certificates via letsencrypt, and those encrypt traffic between client and the server. I am not aware you can use similar system to manage client certificates, which serve authentication purposes. Can you?

Thanks for the hints and ideas! I did consider VPN but was hoping for a more streamlined solution with the least amount of extra clicks. If you think of the example here, ideal would be that the mobile phone on the other side of the world can backup images to my immich instance without needing to activate VPN for that purpose, or having to run VPN all the time. Same consideration guides me when thinking about NPM restricted access - I never tried it in practice but I understood it’s only useful for people accessing resources manually, as you have to type in login credentials, less useful for apps.

Thanks for the hint about the Tailscale and custom domains, I will look into that. I am noticing right away that free plans are limited to 3 users so I’d have to calculate that in. Do you know if there are other limitations to this solutions? I read about CloudFlare tunnels (which I understand comes down to similar functionality) limiting maximum file sizes and bandwidth in the free plan, such that sysncing media wouldn’t be feasible due to file sizes of videos.

Tailscale is a no-go if you want to just share your Immich photo albums with your family members, for instance by sending someone a link as you would with Google Photos. Grandma is not going to set up Tailscale on her phone or PC.

This will costs an overhead, but at this point i would consider to expose a VM instead of apps hosted directly in TN… Afaik this should provide a layer of isolation.

Why not? She can handle clicking one link, but not clicking a different link and using an account she already has to register? Particularly when there’s a video guide (linked above) telling her exactly what to do?

I’m frankly not sure how that works. The tutorial I linked above appears to have the remote user create a completely separate account, which wouldn’t seem to affect that limit. I’ve asked that question in the comments on that video; I’ll see if I get an answer there.

Very different. Cloudflare tunnels act as an alternative to a reverse proxy, and eliminate the need for you to open/forward ports to (say) NPM, but they’re completely exposed to the public Internet (though you can set up authentication on them). Tailscale is a VPN, which only allows access to your network (or devices on your network) to people to whom you give access. The latter is considerably more secure, but the former gives access to the entire Internet, which may be desirable.

Interesting… yes, I see, I looked into it a bit more now. I will give it a try and see how it works.

I agree our proverbial grandmas might manage this task :smiley: If not, it appears simple enough to be brought to life with remote assistance.

Agree. I watched few videos and read few guides and it seems that everyone has their own free account so the user limit does not apply there. Please share if you get a response to your question, thanks for asking there!

I agree and understand the distinction. The tailscale solution might work for my use case, for now - it will likely work well and serve the handful of family members, each with one or two devices (mobile phone and laptop). Ultimately, though, I see a case for a solution which does not require special tools but builds on the “standard” internet technologies (DNS, firewalls, access rules, TLS certificates). This can be my aspiring goal for the next 10 years (I hope to arrive there much sooner, though) :slight_smile:

For the problem of “expose services on my LAN to (at least some) people outside my LAN”, broadly speaking, there are three possible solutions:

  • Put those people on your LAN–this is the VPN solution.
    • Tailscale is teh new hawtness in this regard, but it certainly isn’t the only possible solution. But it’s available as an app for TrueNAS, it can be added as a “sidecar” to Docker Compose apps, and you can run your own coordination server if you like.
    • If you use Tailscale as it’s intended to be used–each service appearing separately on your tailnet–you can be pretty granular about who has access to what.
  • Expose those services directly to the Internet–forward ports 80/443 (and others if needed) to the service in question (or a proxy like NPM).
    • This is the simplest solution in terms of technology, but a variety of factors (e.g., dynamic IPs, ISP blocking port 80, CGNAT) may make it impractical.
  • Hybrid–put something on the public Internet, and have it communicate with your LAN services over a VPN-like connection.
    • This is the “Cloudflare tunnel” solution, and avoids all three problems noted above.
    • But you don’t need to use Cloudflare tunnels; the open-source Pangolin does this as well
    • Or you could even piece it together yourself using Wireguard and a reverse proxy like Caddy, Traefik, or nginx
    • If you’re self-hosting this (rather than using Cloudflare tunnels), you’ll need some system that’s open to the Internet. Google, Oracle, and Amazon will all provide small VPSs for free.

For what it’s worth, VPNs have been a pain in my ass to setup manually to allow myself to gain access to my LAN remotely. Once I tried Tailscale there is no going back due to its ease of operation and setup. For my use case it’s exposing Plex server to my plexamp clients so I can stream my music library at FLAC quality when I’m out and about. The risk of exposing ports was greater than my desire to stream so tailscale saved the day and while I don’t give them access my parents would be able with my assistance to download, setup and flip the VPN on switch for the tailscale app. It’s lightweight and set it and forget it on a phone. You as the admin would have the ability to see their connection status on the dashboard at all times. Highly recommend Tailscale.

…and just as a data point, my wife is not tech-savvy in the least, but I was able to successfully get her logged into my Headscale network (which is somewhat more complicated than using Tailscale’s native solution) over the phone. OK, I had to text her the auth key, but still…

Grandma can do this (OK, mine can’t; she’s been gone several years. But a living one, who’s using a computer and/or smart phone at all, can).

Many great suggestions here. I’ve found that Immich doesn’t work well through Cloudflare. You’ll have chunking issues which will make uploading a challenge for your family.

This is what I do.

  1. IPS/IDS enabled on my router.
  2. Block unwanted countries at the router.
  3. Configure NPM with TLS and expose this through port forwarding. It’s really the only thing I expose.
  4. Authenticate with an idP. I’m using authentik with GeoIP rules, IP reputation, MFA/2FA, and OIDC. You can limit to what apps you want your family to access with it. Also will set them up for any future services you want to implement for them in the future via SSO, proxy, etc
  5. VLAN segregation internally. My apps VLAN is blocked off to everywhere except for a few locations.

You could get fancy with OpenZiti as well and implement zero trust on your network as well. I’ve not gone this far, yet…

You’re asking for everyone I send a photo album link to, to install a new app on their phone or PC and somehow get authenticated, just to look at some photos. No, I really don’t think various friends and family are going to do this. They’re going to think I’m crazy and simply ignore my photo album.

This might work for the people in your very immediate family (esp. since you can actually set it up for them, since you’re right there), or for people who you frequently share stuff with, but for everyone else it’s a no-go.

1 Like

Interesting. Just to start thinking about this properly, can you share few additional pieces of information?

  1. What kind of router do you have?
  2. How do you leverage VLAN in your example? If I understood correctly, you put all Apps on a single VLAN and limit access by location. What’s the effect of this if you already have GeoIP rules in authentik? And how would you isolate apps in a VLAN if they’re served as docker containers on a TrueNAS?

Thanks!

How many people do you expect this to be? If you’re expecting to share your Immich instance with dozens of people, then no, Tailscale isn’t likely to be the best way to do it–which was the reason I mentioned this in the first sentence of my first response to OP.

Different solutions for different needs. Tailscale is likely to be much more secure than opening any of your services to the public Internet, but it takes some doing to get set up. If you want a handful of people to have access, it’s probably among the best solutions. If you want hundreds of people to have access, it’s clearly a poor solution, but you’re accepting additional security risk.

I personally use a UDM Pro, but most of the Unifi Cloud Gateways should be able to handle what you want to do. You could use a pfsense or opnsense router as well. Basically, as long as your router can handle L2 VLAN’s and firewall for the LAN, you should be able to do this.

I configure the firewall to block all traffic to/from my apps VLAN, and only punch holes for things that need access, like my proxy, database servers, user access from the local network (99.9% handled mostly through NPM [proxy]), etc.

I have a bond setup with LACP on my switch with VLAN tagging on my ports, then VLAN’s and bridges setup in TNCE to allow for access to those networks. If I don’t need the app to talk back to the host, then I just use a VLAN interface, as a result the apps will be segregated to their own networks. I have jails setup that run docker and those jails are configured on the VLAN’s I need. With the jails, they are locked up in their own sandboxed “jail” with no access to the host except for host based storage (which they have app permissions set, so very little access) and locked down networks.

This shouldn’t affect authentik. authentik checks against failed logins, ip addresses, impossible travel, and will act accordingly. You can customize the polices and reputation as well. Besides, the RAC access is pretty cool too.

1 Like

I’m not even talking about hundreds of people here, and I’m flabbergasted that I even have to explain this use-case. It’s simple: I meet an occasional friend that I only see once every few years. We take a bunch of photos together. I share the album with him/her. Expecting him/her to install a new app on their phone and go through a bunch of security crap just to access some shared photos is utterly asinine; they’re going to be insulted. You absolutely cannot expect every person you interact with to go through all this just to see some photos.