I’ve been researching different ways to expose Docker containers to the internet. I have three services I want to expose: Jellyfin, Omnivore (Read-it-later app), and Overseerr.

I’ve come across lots of suggestions, like using Nginx with Cloudflared, but some people mention that streaming media goes against Cloudflared tunnel TOS, and instead recommend Tailscale, or Traefik, or setting up a WireGuard VPN, or using Nginx with a WireGuard VPN.

The amount of conflicting advice has left me confused. So, what would be the best approach to securely expose these containers?

  • MXX53@programming.dev
    link
    fedilink
    English
    arrow-up
    1
    ·
    1 小时前

    I just tried tailscale in the last month and it will now be my preferred way to access my services outside of my network.

  • maplebar@lemmy.world
    link
    fedilink
    English
    arrow-up
    4
    ·
    4 小时前

    Do you actually want to expose the things to “the internet”, or do you just want yourself (and an approved set of other users) to be able to access them from outside of your network?

    If it’s the former, you’re going to want to learn about DNS, NAT, exposing ports, firewall settings, and network monitoring.

    But if it’s the latter, then I recommend checking out tailscale because that gives you and some friends LAN-like access with a great internal DNS and it works really well.

  • notfromhere@lemmy.ml
    link
    fedilink
    English
    arrow-up
    4
    ·
    8 小时前
    1. Never host anything that is externally accessible
    2. If you have to, put it behind a VPN (OVPN, Wireguard, IPSec, Tailscale, etc.)
    3. Certificate based authentication is preferred for VPN tunnels
    4. Always TLS encrypt your actual endpoints. Private CAs are most secure but a pain in the ass. Let’s Encrypt is very simple to set up in most cases.

    Just my 2 cents.

    • slazer2au@lemmy.world
      link
      fedilink
      English
      arrow-up
      1
      ·
      7 小时前

      How is a private CA more secure then an offline CA with cross signed intermediate signing subCA?

        • slazer2au@lemmy.world
          link
          fedilink
          English
          arrow-up
          1
          ·
          2 小时前

          A public CA (Let’s Encrypt, Komodo, GoDaddy, etc) don’t actually sign certificates with their root CA certificate. The root CA creates a subCA (Or signing CA) that actually generates the certificates and the system holding the private keys of the root certificate is shutdown to prevent access but is brought back online every so often to update the revocation list.

          You said a private CA is more secure so I am wondering how that is?

  • Shimitar@feddit.it
    link
    fedilink
    English
    arrow-up
    3
    ·
    16 小时前

    Sorry third post. Trying to summarize.

    1. Get external access. Either via port-forward (you lucky American) or via VPS+ssh-tunnel or VPS+wireguard. Stay away from an hard dependency like tailscale and cloudflare (my personal opinion).

    2. Setup a reverse proxy with SSL certs via let’s Encrypt (don’t go wildcard, no need to, just add complexity)

    That’s the concept, implementation requires clearly extra steps…

    See my wiki (https://wiki.gardiol.org/). O describe both the simple and the complex solution. But to be honest, the complex solution is not fully described yet.

    • archomrade [he/him]@midwest.social
      link
      fedilink
      English
      arrow-up
      1
      ·
      6 小时前

      Is the reason you advocate avoiding VPN dependencies simply due to downtime if the tailscale service fails? Or is there a particular security vulnerability associated with using VPN subnets?

      • Shimitar@feddit.it
        link
        fedilink
        English
        arrow-up
        2
        ·
        3 小时前

        Mostly not being dependent from a specific vendor, that’s all.

        I prefer to use a VPS of my choice that I can replace when I want or need to.

        As far as its backed by wireguard its safe enough I guess.

    • MoonlitSanguine@lemmy.oneOP
      link
      fedilink
      English
      arrow-up
      2
      ·
      13 小时前

      I am leaning towards Wireguard, as I don’t think I’m behind a CGNAT. But, I’ll check out your wiki for more details though. Thankyou

      • @shimitar’s advice is what I’d go with.

        Ideally:

        1. Set up a Wireguard subnet. Test it thoroughly, including restarting the server a couple of times.
        2. Close all ports except your Wireguard ports in your server firewall. Do this manually first (not persistent) and test.
        3. Make the firewall changes permanent.

        Then, it kinda doesn’t matter what else you do on the server, although you can fuss around with locking things down more.

        Caveats:

        • you won’t be able to use LetsEncrypt with this
        • accessing your services from an Android phone will be futzy, because Android is too stupid to be able to use more than one VPN at a time. Unless you don’t use a VPN on your phone, in which case it won’t be an issue.
        • you’ll only be able to access your server from computers/systems in your Wireguard subnet, so make sure you include multiple devices in the config from which you can ssh

        Wireguard is super easy to build VPN networks with, and there are tools (e.g. dsnet) to make it even easier.

  • Shimitar@feddit.it
    link
    fedilink
    English
    arrow-up
    3
    ·
    16 小时前

    Slap a good reverse proxy in front of it (nginx I what I use) and set it up with HTTPS using let’s Encrypt. For added layer of security setup also some SSO like Authelia.

    Or just go the VPN way but then, that will not be access from internet, only via VPN, only you will be accessing it.

  • MangoPenguin@lemmy.blahaj.zone
    link
    fedilink
    English
    arrow-up
    45
    ·
    1 天前

    Is it just you that needs access? VPN like Tailscale or Wireguard is the most secure option then, as it’s not exposing any services to the internet.

    Otherwise a reverse proxy in front of things like Traefik or Nginx, make sure things are automatically updated ASAP, and make sure auth is enabled on the services.

    • MoonlitSanguine@lemmy.oneOP
      link
      fedilink
      English
      arrow-up
      3
      ·
      13 小时前

      Thankyou. Since it’s just my devices (laptop/phone) that need access, I think WireGuard—or possibly Tailscale—seems like the best solution for me.

      • MangoPenguin@lemmy.blahaj.zone
        link
        fedilink
        English
        arrow-up
        1
        ·
        3 小时前

        Tailscale is very easy and handles everything for you but you are relying on their services, so if you want to be 100% self hosted Wireguard is the way to go.

    • tofuwabohu@slrpnk.net
      link
      fedilink
      English
      arrow-up
      9
      ·
      23 小时前

      Yeah, I feel like exposing ports 80 and 443 towards an up to date nginx/whatever is referred to as a super dangerous thing in this community and also the selfhosted subreddit. Recommending cloudflare is almost the default, which I find a bit sad given many people selfhost to escape the reliance on big monopolist companies.

      One can add different layers of security of course, but having nginx with monitoring in it’s own VM without keys to jump to another VM is enough of risk mitigation for me.

  • Shimitar@feddit.it
    link
    fedilink
    English
    arrow-up
    2
    ·
    16 小时前

    If you need also external access, because you are behind a CGNAT or in general have no public IP at all, get a VPS and setup some tunneling.

    I don’t like tailscale/cloudflare dependency so I have a different solution.

    I have documented it all here: https://wiki.gardiol.org/

  • plm00@lemmy.ml
    link
    fedilink
    English
    arrow-up
    17
    ·
    1 天前

    “Secure” and “exposed” are antonyms in this scenario, that’s the nature of the beast. I use Nginx which I have a domain pointing to. Worst case scenario, a hacker brute forces access to my container and mucks around within the confines. As I understand from a WireGuard VPN, there’s an added level of security. You have to use the VPN to get access to your home ports, and then you can access your Docker containers as configured. There’s an added layer of security.

    Some things to consider:

    • Do you have a target on your back?
    • Does your container contain sensitive data?
    • If so, does your container have access to external directories?
    • Does your project have security options like Geo Blocking, rate limiting, etc?

    I’ve been running some local servers for a few years only behind Nginx. So far nothing bad has happened. But that doesn’t mean something bad couldn’t happen later.

    • MoonlitSanguine@lemmy.oneOP
      link
      fedilink
      English
      arrow-up
      1
      ·
      13 小时前

      Thanks for the info.

      Do you have a target on your back?

      No.

      Does your container contain sensitive data?

      No.

      If so, does your container have access to external directories?

      I have a hard drive mounted to the media folder that Jellyfin can access, and also a config folder. Omnivore/Overseer will probably be similar once I add them. Could this be a problem?

        - '/home/${USER}/server/configs/jellyfin:/config'
        - '/home/${USER}/server/media:/data/media'
      

      Does your project have security options like Geo Blocking, rate limiting, etc?

      That is a good idea. Thankyou

      • plm00@lemmy.ml
        link
        fedilink
        English
        arrow-up
        2
        ·
        7 小时前

        What I was referring to is called a Bind Mount, where host directories are exposed to the docker container. You may be fine if it’s an external hard drive. I use bind mounts because they’re easier to back up, but I acknowledge they are less safe.

        You may be perfectly fine as you are now. My (and others) suggestions are for added security. As it stands, if there’s no target on your bind, the only bad traffic you’ll get are from bots trying to pick away at your domain and sub domains. Generally they’re not a problem. But being extra safe costs nothing but time.

  • Evkob (they/them)@lemmy.ca
    link
    fedilink
    English
    arrow-up
    8
    ·
    1 天前

    It depends on if you want to access it from anywhere (or give others access), or if you’re only accessing your server from specific devices.

    Since I only ever access my server from my phone or my desktop, I use Wireguard via wg-easy. You set it up as a docker container on your server and it gives you a neat web UI (defaults to port 51821) from which to add Wireguard clients. Once connected through Wireguard, you can access your services as if you’re on the server’s local network.

    Note, you’ll of course have to open up a port for Wireguard on your router for this to work, the default being 51820.

  • gdog05@lemmy.world
    link
    fedilink
    English
    arrow-up
    9
    ·
    1 天前

    My preference is just Cloudflare with or without nginx. Not sure if you’re using a hypervisor or not but it makes things exceedingly easy and I feel plenty safe enough inside of a Cloudflare tunnel. I stream a lot of data from Jellyfin. All day long, several streams to several people for over a year now with no problems. Last I knew, Cloudflare removed the language about video streaming from their TOS. Not sure if that’s changed but functionality on my end hasn’t.

    I am using Unraid but I’ve installed the Cloudflare tunnel in docker containers and TrueNAS without many issues. Takes a bit of copying/pasting to get set up but it’s not terrible and everything is very responsive to make sure you’re doing things correctly.

    • Stupidmanager@lemmy.world
      link
      fedilink
      English
      arrow-up
      1
      ·
      8 小时前

      +1 for cloudflare. But I don’t use their tunnel products, I just expose my ports to only their known IPs. With cloudflare you have a nice “free” waf in front with tls that points to a secure(nginx proxy) or unsecured docker container. Audiobookshelf is a great example. Is best to use their dns product too, for easy management of your public facing sites.

  • Fuzzypyro@lemmy.world
    link
    fedilink
    English
    arrow-up
    7
    ·
    1 天前

    Networking is fun because there are literally infinite potential options. There really isn’t a best option. It’s just what do you prefer. In my case I like to write a docker compose and write a tailscale container into it. I then set the service I want to expose either to my own tailnet or to the internet through funnel or though this other implementation I came up with a while back that I still need to do a write up on. Either way here is a guide i wrote with some docs as reference on my forgejo (git alternative). Docs are kinda a mess but hopefully it makes sense enough to help you out.

    Tailscale docker compose examples

    • MoonlitSanguine@lemmy.oneOP
      link
      fedilink
      English
      arrow-up
      1
      ·
      13 小时前

      I’ve noticed 🥲, which hopefully means there’s no horribly wrong choice. I am leaning towards Tailscale, or maybe WireGuard. Thanks for the docs

    • nfms@lemmy.ml
      link
      fedilink
      English
      arrow-up
      3
      ·
      1 天前

      I just installed tailscape and it works for my needs. Will read up on your docs. Thx

  • isgleas@lemmy.ml
    link
    fedilink
    English
    arrow-up
    6
    ·
    1 天前

    Depending on your level of paranioia. First, you don’t expose your containers, but their port(s).

    With a reverse proxy, you will likely expose only 1 port, 443, no matter how many apps/containers/ports it will be pointing internally. For this, having a proper dns setup will be key, and a service like cloudflare dns (not tunnel), which additionally you can proxy your proxy. Also, you will need certificates (letsencrypt) for your traffic to be encrypted. Here, everybody will potentially have access to your services.

    Another option is a zero trust tunnel, but as you had seen streaming may break tos. It will be likely enforced if you stream a lot, but I seriously doubt you’ll get any problem by having sporadic one or two users.

    Tailscale, you need to add all the devices you need to access your services into the mesh, and you’ll need to re-authenticate every one again every few months.

    Setting up a VPN (selfhosted) will require your devices to sign into it when accessing your services, and it seems to me the best approach as this way you will nave the most control over your setting.

    Don’t forget to mention that, for this to work, your ISP should provide you with public IP, because if on CGNAT you will have to go with something like tunnels or tailscale.

  • MSids@lemmy.world
    link
    fedilink
    English
    arrow-up
    3
    ·
    1 天前

    Lots of great ideas in this thread. It sounds like you prefer Jellyfin, but I always encourage people to consider Plex. Plex is excellent, and even if you prefer the features or interface of Jellyfin, you should never expose any application (Plex, Jellyfin, or otherwise) directly to the Internet. This should be non-negotiable. Plex uniquely solves for external access with the mobile/desktop apps and app.plex.tv by brokering client connections into your network without a NAT/PAT on your router or firewall. Plex also supports Google logins, which means that you can now have 2fa and potentially phishing-resistant 2fa if you secure your Google account with a passkey.

    At my company we only expose our applications behind a WAF and firewall, and I see that some folks here have recommended Cloudflare. For those who may not know, it is no longer enough to simply rely on a firewall. When your application is built with components that may become vulnerable over time, it’s critical to use a WAF.