I run a self-hosted server at home on which I have run a bunch of personal stuff (like nextcloud etc.). To prevent pointing DNS servers at my home router, I run a reverse proxy on a VPS that I rent (from Scaleway FWIW).

Today I was trying to figure to what extent that exposes my data to my VPS provider and whether I can do something about it. Disclaimer: this is just a hobby exercise. I’m not paranoid, I just want to learn for my own self how to improve security of my setup.

My reverse proxy terminates the SSL connection and then proxies the connection over a wireguard connection to my home server. This means that (a) data is decrypted in the RAM of the VPS and (b) the certificates live unencrypted in the storage of the VPS. This means that the VPS provider, if they want to, can read all the traffic unencrypted to and from my home server.

I was thinking that I can solve both problems by using Nginx’s SSL pass-through feature. This would allow me to not terminate SSL on the VPS solving (a) and to move the certificates to my home server solving (b).

But just as I was playing around with it, I realised that SSL pass-through would not solve the problem of trying to protect my data from the VPS provider. As long as my DNS records point at the VPS provider’s servers, the VPS provider can always get their own certificates for my domains and do a MitM attack. Therefore, I might as well keep the certificates on the VPS since I still have to trust them not to make their own behind my back.

In the end I concluded that as long as I use a VPS provider to route my traffic to my home server, there is no fool-proof way to secure my data from them. Intuitively it makes sense, the data crosses their hardware physically and thus they will have access to it. The only way to stop it would be to update the DNS records to point directly at my home server which I don’t want to do.

Is this correct thinking or is there some way to prevent the VPS provider from seeing my data?

Again, I’m trying to solve this problem as a hobby exercise. The most sensitive data that I have is stored encrypted at the filesystem level and I only decrypt it locally on my own machine to work on it. Therefore, the actually sensitive data that would be cost me a lot if compromised is never available unencrypted on the VPS. Due to the overhead of this encryption and other complications, I don’t do this for all my files.

  • GreenDot 💚@le.fduck.net
    link
    fedilink
    arrow-up
    7
    ·
    1 year ago

    No problem. I’ll just go with a oversimplification.

    The idea is that you just take whatever traffic hits port 443 and use iptables rules to route the traffic elsewhere, or in this case

    Client --> [port 443] --> [iptables] --> [ port 443 home server]

    So, it’s basically just traffic forwarding from the VPS directly to your home server, being directly to your ISP IP address, or via wireguard IP address.

    So all the traffic you are sending back from the VPS is in its original state, and the actual processing happens on your local/home server.

    On the home server you have a Web Server of your choice listening on port 443 with, loaded with your SSL certificates. So, request is made to the VPS IP address, iptables just forward the packets to your home server, and there is where the SSL/TLS termination happens. The client negotiates the TLS connection directly with your home server, and web server on your home server then sends the request where you tell it to ( reverse proxy to a docker container, or it serves the content directly).

    With this, you basically turn the VPS into a passtrough for traffic.

    Here’s a quick test I did… the two servers are connected with Wireguard mesh.

    On the VPS you need have net.ipv4.ip_forward=1 .

    net.ipv4.ip_forward=1
    

    Your iptables rules should be. Obviously on the home server you can run the webserver on any port you like, doesn’t have to be 443. But let’s keep it 443 for the sake of argument.

    iptables -t nat -A PREROUTING -p tcp --dport 443 -j DNAT --to-destination HOME_SERVER_IP:443
    iptables -t nat -A POSTROUTING -j MASQUERADE
    

    If you want to drop the rules:

    iptables -t nat -F
    
    • MigratingtoLemmy@lemmy.world
      link
      fedilink
      arrow-up
      1
      ·
      1 year ago

      Thank you for the answer. I was hoping that I could implement a DNAT on the VPS box and then have HAProxy on my router do the SSL termination and serve requests. Just to be sure, that would be possible, yes? I understood how the system works, thanks a bunch!

      • GreenDot 💚@le.fduck.net
        link
        fedilink
        arrow-up
        2
        ·
        edit-2
        1 year ago

        Yes, that would be possible with this setup. Port on which HAProxy listens just needs to be publicly accessible, and just DNAT traffic from the VPS to your $IP:$PORT .

        Technically everything is possible, I just don’t have context if you have a static IP with your ISP or it changes every so often (daily, weekly, every n months). If it’s not, you might consider using a VPN connection between VPS and your router to keep the connection open at all times, and also not exposing HAProxy directly to the live internet.

        • MigratingtoLemmy@lemmy.world
          link
          fedilink
          arrow-up
          1
          ·
          1 year ago

          Hi, I’m behind CGNAT. I’m definitely going to connect my router to my VPS instance using Wireguard.

          I will be using a domain name for my VPS to connect to it via Wireguard.

          Just to summarise: hold SSL certificates within HAProxy, and use DNAT on the VPS to direct traffic towards the Wireguard tunnel. When traffic reaches my router, it is passed into HAProxy, which terminates SSL and sends the traffic to my applications.

          Did I get it right?

          • GreenDot 💚@le.fduck.net
            link
            fedilink
            arrow-up
            1
            ·
            1 year ago

            Yes, thats exactly it. Make sure your HAProxy is listening on the wireguard interface as well. Once you have the wireguard tunnel working, do a quick test, like curl -H "Host: domain.tld" https://router_wireguard_ip/ and if that works, add in the iptables roules and you should be all set.