I have a nextcloud instance being hosted from my home network. The URL associated with it points directly at my home’s IP. I don’t want to host the instance on a VPS because disk space is expensive. So, instead, I want to point the URL at the VPS, and then somehow route the connection to my home’s nextcloud instance without leaking my home’s ip.

How might I go about doing this? Can this be achieved with nginx?

EDIT: Actually, not leaking my home’s IP is not essential. It is acceptable if it is possible to determine the IP with some effort. What I really want is to be able to host multiple websites with my single home IP without those websites being obviously connected, and to avoid automatic bots constantly looking for vulnerabilities in my home network.

  • dleewee@beehaw.org
    link
    fedilink
    English
    arrow-up
    5
    ·
    1 year ago

    I have done this before by setting up a Wireguard VPN link between my home server and a VPS, and then running a reverse proxy (such as Caddy) on the VPS, which basically forwarded web requests to my home server. This works well for most things, although there was a definite performance hit by routing traffic through the extra hop.

    By using the VPN connection, you wouldn’t even need to open a port on your home network which is a great starting point for security as well.

    • Max@mander.xyzOP
      link
      fedilink
      English
      arrow-up
      1
      ·
      1 year ago

      Thank you!

      By using the VPN connection, you wouldn’t even need to open a port on your home network which is a great starting point for security as well.

      Hmm, what do you mean with this? I would need to at least open one port to route the connection to the nextcloud instance in my home network - right?

      • dleewee@beehaw.org
        link
        fedilink
        English
        arrow-up
        1
        ·
        1 year ago

        Only the host acting as the VPN “server” needs to have an open port. In my setup, I made the VPS the server and my home server a client. Thus I had no open ports on my home network, only on the VPS.

    • Max@mander.xyzOP
      link
      fedilink
      English
      arrow-up
      2
      ·
      1 year ago

      Is there something that would make caddy better at this than nginx? I have only used nginx in the past, I am looking at how to use proxy_pass to connect from the VPS to my home network.

      • bigkahuna1986
        link
        fedilink
        English
        arrow-up
        1
        ·
        1 year ago

        Sorry it took so long to get back to you.

        Caddy usually has a simpler reverse proxy configuration, but it also has http/2 and http/3 on by default. Plus it creates and manages http certificates. As far as performance it’s the same as Nginx. Just in my experience it’s simpler to configure and manage.

  • boothin@kbin.social
    link
    fedilink
    arrow-up
    3
    ·
    edit-2
    1 year ago

    If all you’re wanting to do is hide your home ip, could you just put it behind cloudflare?

    • Max@mander.xyzOP
      link
      fedilink
      arrow-up
      1
      ·
      1 year ago

      I am looking into that too! But I do want to understand the foundations of how to route network traffic, and I feel like this must be a straight-forward thing to do once I understand how to do it, if you know what I mean.

  • samn
    link
    fedilink
    English
    arrow-up
    3
    ·
    1 year ago

    At the basic level, you could do a reverse ssh tunnel to forward the port from your home server to the VPS, although there’s some efficiency issues doing this iirc, and you’ve got the issue of it failing if the tunnel ever breaks

    • Max@mander.xyzOP
      link
      fedilink
      English
      arrow-up
      2
      ·
      1 year ago

      Reverse SSH… I’ll look into it. What I am thinking is that I may be able to run the reverse proxy on the VPS directly, and then direct it towards the nextcloud port in my home network.

    • Max@mander.xyzOP
      link
      fedilink
      English
      arrow-up
      2
      ·
      1 year ago

      From what I have learned today, I think that Wireguard Tunnel is what I want!

      First I was able to use nginx as a reverse proxy to route the information from my home network through the VPS. But with this approach the client would do the SSL handshake with the VPS, and then the VPS fetches information from my home network via HTTP. Since there is no encryption layer between my VPS and my home network, I suppose that the flow of information between my home server and the VPS is insecure.

      Then, I need to establish some form of encrypted connection between my home server and the VPS… And that is where the Wireguard Tunnel comes in! This tunnel allows me to transfer the information with encryption.

      I am still reading and setting it up, but yeah, I’m liking this, thanks!

      • poVoq@slrpnk.net
        link
        fedilink
        English
        arrow-up
        3
        ·
        edit-2
        1 year ago

        Nginx can also do something called SNI routing that would allow to keep the connection between your VPS and your homeserver encrypted, but overall I think a Wireguard tunnel is probably more flexible.

        • Max@mander.xyzOP
          link
          fedilink
          English
          arrow-up
          2
          ·
          1 year ago

          Oh, cool! I have managed to do it with the Wireguard tunnel! I set up a tunnel and use the nginx proxy_pass to redirect through the tunnel. It is pretty nifty that I don’t even need to port-forward!

          My next step is: in my current configuration, the SSL handshake occurs between the VPS and connecting client. So the VPS has access to everything that goes through… I need to figure out how to hand-shake through the tunnel such that the VPS does not get the SSL keys.

          Thanks a lot for your suggestion!

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

    You can set up nginx to do reverse proxy to your home IP, and then limit the traffic on your home IP to the VPS IP.

    You can also setup a wireguard VPN between VPS and your home machine, so the traffic between VPS and your home machine is encrypted.

    For DNS you just point to the VPS, and manage connections there, and on home network allow only VPS IP to connect. Then manage your security on the VPS.

    If you put a wireguad VPN between the VPS and your home machine, you don’t have to open any ingress ports. I’m using a similar setup, where the public VM is handling the incoming connections and reverse proxying it to a small private server in my home.

    Communication is done via wireguard VPN. I’ve used Netmaker to create a VPN connections and the mesh, and have VPN profile created on the phone, so I can reach any of the services I don’t want exposed on the public internet via private VPN ( example: listening to music via Navidrome, or home Emby server so I can watch stuff when I’m on the move and it is not exposed publicly).

    • Max@mander.xyzOP
      link
      fedilink
      English
      arrow-up
      2
      ·
      1 year ago

      Thanks a lot! This is kind of the configuration that I have converged to, with nginx and WireGuard. The last thing I need to set up correctly is for the SSL handshake to occur between the client and my home server, and not between the client and the internet-facing VPS, such that the information remains encrypted and unreadable to the VPS. The two strategies that I have seen can do this is SNI routing with nginx or to use stunnel. I still have not been able to set up either!

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

        In that case, you’re better off just using the VPS machine as port forwarding port 443 to your home machine’s wireguard IP address and handle the SSL/TLS termination on the home machine.

        This way all HTTPS traffic will be passing trough the VPS and being decrypted on your home machine, and encrypted data will be sent from your home machine back to the client. Anyone gets in or sniffs traffic will see encrypted traffic. Plus it’s already sent over encrypted VPN network. To really see what’s happening, they need to get into the machine and technically could use the wireguard private keys to decrypt the traffic, but they will still see the encrypted HTTPS traffic. So you’re good, technically.

        • Max@mander.xyzOP
          link
          fedilink
          English
          arrow-up
          3
          ·
          1 year ago

          In that case, you’re better off just using the VPS machine as port forwarding port 443 to your home machine’s wireguard IP address and handle the SSL/TLS termination on the home machine.

          This is what I would like to do! I was trying to handle the SSL termination ‘automatically’ by simply forwarding the connections to 443 of my machine’s wireguard IP using nginx, but I did not manage to get it to work. That’s when I found that I need to use something like ‘stunnel’ to handle the SSL termination. But I think that you may be suggesting an even simpler method of using port-forwarding instead of the reverse proxy. I am not sure how to achieve that, I will look into it using these terms.

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

            You did kinda push me in that direction to try the same thing. Once I have bit more time, I’ll try it out and send an example. Unless you beat me to it 😂

            • Max@mander.xyzOP
              link
              fedilink
              English
              arrow-up
              2
              ·
              edit-2
              1 year ago

              After lots of testing I found a configuration that works for me! In the end it is very simple, but I am quite a newbie at this so it took some effort to figure out what works. ChatGPT helped a bit too - and also confused me a lot - but it helped.

              What I do now is:

              I set up a wireguard tunnel. The VPS in this example has the ‘wireguard’ ip of 10.222.0.1, and my home network is 10.222.0.2. These are my configs (/etc/wireguard/wg0.conf):

              VPS wireguard config:

              spoiler
              [Interface]
              Address = 10.222.0.1/24
              ListenPort = 51820
              PrivateKey = <VPS Private key>
              
              [Peer]
              PublicKey = <Home network public key>
              AllowedIPs = 10.222.0.2/32
              PersistentKeepalive = 25
              

              Home network (Respberry pi) config :

              spoiler
              [Interface]
              Address = 10.222.0.2/32
              PrivateKey = <Home network private key>
              
              [Peer]
              PublicKey = <VPS Public Key>
              Endpoint = <VPS_IP>:51820
              AllowedIPs = 10.222.0.0/16
              PersistentKeepalive = 25
              
              

              Then, I use the following iptables commands in the VPS to map requests to port 80 and 443 to the ports 80 and 443 of the tunnel. What really confused me for a while was that I did not know that I needed to include the “POSTROUTING” step so that the packets get sent back the correct way, and that I had to set net.ipv4.ip_forward=1 in /etc/sysctl.conf:

              IP tables in VPS:

              spoiler
              
              iptables -t nat -A PREROUTING -p tcp --dport 443 -j DNAT --to-destination 10.222.0.2:443
              iptables -t nat -A POSTROUTING -p tcp -d 10.222.0.2 --dport 443 -j SNAT --to-source 10.222.0.1
              iptables -t nat -A PREROUTING -p tcp --dport 80 -j DNAT --to-destination 10.222.0.2:80
              iptables -t nat -A POSTROUTING -p tcp -d 10.222.0.2 --dport 80 -j SNAT --to-source 10.222.0.1
              
              

              Then, in my home network I use the standard nginx config:

              spoiler
              server {
                server_name website.com;
                listen 80;
                location / {
                      return 301 https://$host$request_uri;
                }
              }
              
              server {
                server_name website.com;
                  listen 443;
                  location / {
                      proxy_set_header Host $host;
                      proxy_pass http://0.0.0.0:<Website Port>;
                  }
                  # certificate management here
                  ssl_certificate /etc/letsencrypt/live/website.com/fullchain.pem; # managed by Certbot
                  ssl_certificate_key /etc/letsencrypt/live/website.com/privkey.pem; # managed by Certbot
                  include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
                  ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
              }
              
              

              This configuration seems to work, and since both ports 80 and 433 are mapped you can use certbot to generate and renew the SSL certificates automatically.

              I am still learning, and this is the first thing that worked - so there might be a better way! But a lot of things I tried would not complete the SSL handshake correctly. > push m

  • Avalanched@kbin.social
    link
    fedilink
    arrow-up
    2
    ·
    1 year ago

    I currently use reverse ssh tunnels to my vps. The vps runs nginx proxy manager and through that way I can tunnel specific ports to my vps, whereas with wireguard all my internet traffic was rerouted to my vps. I didn’t like that because of bandwith limitations so that’s why I chose this aproach

    • Max@mander.xyzOP
      link
      fedilink
      arrow-up
      1
      ·
      1 year ago

      ssh tunnels

      There are so many concepts to learn about! But if the SSH tunnel improves the the available useful bandwidth compared nginx/wireguard, it might be worth looking into it too. Thanks!

        • Max@mander.xyzOP
          link
          fedilink
          arrow-up
          1
          ·
          1 year ago

          Thanks! In the end I converged to setting a WireGuard tunnel and using the iptables to route the connections to port 80 and 443. I did look into ssh tunnel, and the reason I chose not to use that is because from what I could gather (from what some people say, I don’t know enough myself to assess this) WireGuard tunnels are more optimized for performance than the ssh tunnel.

  • MetroWind@lemmy.mws.rocks
    link
    fedilink
    English
    arrow-up
    2
    ·
    edit-2
    1 year ago

    You can setup HTTP reverse proxy on your VPS. You’ll need to point the domain to your VPS for that to work.

    What I really want is to be able to host multiple websites with my single home IP without those websites being obviously connected

    That’s easy. You have two ways:

    • Host the websites under different paths in the same domain. If your websites are static this is fine, but if they are “services” this may not be feasible (and could be very complicated if it is feasible).
    • Host them under different sub-domains. The way it works is you create a bunch of NS records in your DNS, pointing the subdomains to your root domain, and setup one “virtual host” for each of them in your HTTP server. Both Apache and Nginx have the ability to match virtual host by domain name.

    to avoid automatic bots constantly looking for vulnerabilities in my home network.

    I’m not sure how you would eliminate bots by separating the websites though.

  • valkyre09@vlemmy.net
    link
    fedilink
    English
    arrow-up
    2
    ·
    1 year ago

    You could do the VPN / VPS option with a reverse proxy like nginx proxy manager. Or, you could use Cloudflare tunnels. Worth noting that from a privacy perspective you’d be putting a lot of trust in Cloudflare. The same is also true for whoever you pick as your VPS provider

    • Max@mander.xyzOP
      link
      fedilink
      English
      arrow-up
      2
      ·
      1 year ago

      Thanks! Wireguard was suggested as a VPN, and I am currently playing with that.

  • dogmuffinsM
    link
    fedilink
    English
    arrow-up
    1
    ·
    1 year ago

    These two questions are really quite different and the answers to each are completely different.

    Or… to say the same thing another way, do these “multiple websites” need to be accessible by the public?

    If not, then use wireguard. This way your home network only needs to expose a single port listening for wireguard connections. Not much of an attack surface area.

    If so, then use a reverse proxy. This way you expose a single port 443 listening for https connections, and nginx (or whatever) routes requests to the correct internal port depending on the domain used in the request. Again, not much of an attack surface area.

    No bots are going to assess your multiple websites and conclude that it’s your home network, because it will just look like any other web server on the net. Additionally even if they did conclude that it’s your home network an nginx server listening to https requests is the same surface area you would have if you were forwarding all the traffic via your VPS.

    IMO, in all cases the VPS is just added complexity for no benefit.

    • Max@mander.xyzOP
      link
      fedilink
      English
      arrow-up
      1
      ·
      1 year ago

      Thanks! That seems to come with even more protections than simply hiding the IP, so it is worth definitely worth considering!

  • sionide21
    link
    fedilink
    English
    arrow-up
    1
    ·
    1 year ago

    You can use wireguard to set up a tunnel between your home server and the VPS. Then set up nginx on the VPS to forward web requests over the tunnel.

    But make sure you keep the server up to date and it’s probably wise to put a firewall on your home server because if the VPS gets hacked, it could be used to get to your home network.