I have two machines running docker. A (powerful) and B (tiny vps).

All my services are hosted at home on machine A. All dns records point to A. I want to point them to B and implement split horizon dns in my local network to still directly access A. Ideally A is no longer reachable from outside without going over B.

How can I forward requests on machine B to A over a tunnel like wireguard without loosing the source ip addresses?

I tried to get this working by creating two wireguard containers. I think I only need iptable rules on the WG container A but I am not sure. I am a bit confused about the iptable rules needed to get wireguard to properly forward the request through the tunnel.

What are your solutions for such a setup? Is there a better way to do this? I would also be glad for some keywords/existing solutions.

Additional info:

  • Ideally I would like to not leave docker.
  • Split horizon dns is no problem.
  • I have a static ipv6 and ipv4 on both machines.
  • I also have spare ipv6 subnets that I can use for intermediate routing.
  • I would like to avoid cloudflare.
  • ninjan@lemmy.mildgrim.com
    link
    fedilink
    English
    arrow-up
    2
    ·
    9 months ago

    Preserve the source IP you say, why?

    The thing is that if you could (without circumventing the standards) do so then that implies that IP isn’t actually a unique identifier, which is needs to be. It would also mean circumventing whitelists / blacklists would be trivial (it’s not hard by any means but has some specific requirements).

    The correct way to do this, even if there might be some hack you could do to get the actual source IP through, is to put the source in a ‘X-Forwarded-For’ header.

    As for ready solutions I use NetBird which has open source clients for Windows, Linux and Android that I use without issues and it’s perfectly self-hostable and easy to integrate with your own IDP.

    • raldone01@lemmy.worldOP
      link
      fedilink
      English
      arrow-up
      2
      ·
      edit-2
      9 months ago

      The reason I want to preserve the IP is mostly for fancy graphana plots and tracability. X-Forwarded-For is great but only works for http/https. Also I would like to keep the https termination on machine B.

      I will check out netbird.

      • ninjan@lemmy.mildgrim.com
        link
        fedilink
        English
        arrow-up
        1
        ·
        9 months ago

        You want to group by IP in grafana and not using http traffic? Why not group on data or metadata in what is being sent which is the common approach?

      • ninjan@lemmy.mildgrim.com
        link
        fedilink
        English
        arrow-up
        1
        ·
        9 months ago

        If you can fool the Internet that traffic coming from the VPS has the source IP of your home machine what stops you from assuming another IP to bypass an IP whitelist?

        Also if you expect return communication, that would go to your VPS which has faked the IP of your home machine. That technique would be very powerful to create man in the middle attacks, i.e. intercepting traffic intended for someone else and manipulating it without leaving a trace.

        IP, by virtue of how the protocol works, needs to be a unique identifier for a machine. There are techniques, like CGNAT, that allows multiple machines to share an IP, but really it works (in simplified terms) like a proxy and thus breaks the direct connection and limits you to specific ports. It’s also added on top of the IP protocol and requires specific things and either way it’s the endpoint, in your case the VPS, which will be the presenting IP.

        • pcouy@lemmy.pierre-couy.fr
          link
          fedilink
          English
          arrow-up
          3
          ·
          9 months ago

          Each time you send a packet over the internet, several routers handle this packet without touching the source and destination IP addresses.

          There is nothing stopping him from configuring the VPS in a way that forwards packets from the home server, rewriting the destination IP (and optionally destination port as well) but leaving the source IP intact.

          For outgoing packets, the VPS should rewrite the source (homeserver) IP and port and leave the destination intact.

          With iptables, this is done with MASQUERADE rules.

          This is pretty much how any NAT, including ones behind home routers, work.

          You then configure the homeserver to use the VPS as a gateway over wireguard, which should achieve the desired result.

          • ninjan@lemmy.mildgrim.com
            link
            fedilink
            English
            arrow-up
            1
            ·
            9 months ago

            Yeah, I was just confused about the direction/flow he was asking for. He clarified and his use case is fully solvable. Just not something I’ve personally dabbled in since he wants it for non http traffic.

        • raldone01@lemmy.worldOP
          link
          fedilink
          English
          arrow-up
          1
          ·
          9 months ago

          That’s not what I want accomplish. The clients connecting to machine B should not know that their traffic was handled by machine A. I will use DNATs to accomplish my goal. It is possible because tailscale can do exactly that. Thank you for your input though.

          Maybe I am wrong we will see soon. 🙃

          • ninjan@lemmy.mildgrim.com
            link
            fedilink
            English
            arrow-up
            1
            ·
            edit-2
            9 months ago

            Well thats just a normal reverse proxy then. In my setup I use Caddy to send traffic through the NetBird managed wireguard tunnel to my home machine that runs Jellyfin but for any outside observer it look like it’s my VPS that is serving Jellyfin.

            • raldone01@lemmy.worldOP
              link
              fedilink
              English
              arrow-up
              1
              ·
              edit-2
              9 months ago

              Jes exactly but without being http/https only and without decrypting the traffic on the vps.

              That’s why the forwarded for header won’t work. It’s one layer below.