this post was submitted on 17 Jul 2023
24 points (92.9% liked)

Selfhosted

39964 readers
298 users here now

A place to share alternatives to popular online services that can be self-hosted without giving up privacy or locking you into a service you don't control.

Rules:

  1. Be civil: we're here to support and learn from one another. Insults won't be tolerated. Flame wars are frowned upon.

  2. No spam posting.

  3. Posts have to be centered around self-hosting. There are other communities for discussing hardware or home computing. If it's not obvious why your post topic revolves around selfhosting, please include details to make it clear.

  4. Don't duplicate the full text of your blog or github here. Just post the link for folks to click.

  5. Submission headline should match the article title (don’t cherry-pick information from the title to fit your agenda).

  6. No trolling.

Resources:

Any issues on the community? Report it using the report flag.

Questions? DM the mods!

founded 1 year ago
MODERATORS
 

Simple question, difficult solution. I can't work it out. I have a server at home with a site-to-site VPN to a server in the cloud. The server in the cloud has a public IP.

I want people to access server in the cloud and it should forward traffic through the VPN. I have tried this and it works. I've tried with nginx streams, frp and also HAProxy. They all work, but, in the server at home logs I can only see that people are connecting from the site-to-site VPN, not their actual source IP.

Is there any solution (program/Docker image) that will take a port, forward it to another host (or maybe another program listening on the host) that then modifies the traffic to contain the real source IP. The whole idea is that in the server logs I want to see people's real IP addresses, not the server in the cloud private VPN IP.

you are viewing a single comment's thread
view the rest of the comments
[–] [email protected] 6 points 1 year ago* (last edited 1 year ago) (1 children)

Short answer: Don't bother, it's too complex to setup (unless your app is HTTP or supports the PROXY protocol). You better read your proxy logs instead.

Long answer: What you want is called "IP transparency" and require your proxy to "spoof" the IP address of the client when forwarding packets to the remote server. Some proxies do it (Nginx plus, Avi Vantage, Fortinet) but are paid services. I don't know for free solutions as I only ever implemented it with those listed above.

This require a fairly complex setup though:

0. IP address spoofing

The proxy must rewrite all downstream request to spoof the client IP address, making it look like the traffic originates from the client at the TCP layer.

1. Backend server routing

As the packet will most likely originate from random IP on the internet, your backend server must have a way to route back the traffic to the proxy, instead of it's default gateway. Otherwise you'd implement what is called "Direct Server Return*, which won't work in your case (packet will be dropped by the client as originating from your backend server directly, and not from the proxy).

You have two solutions here:

  • set your default gateway to the proxy over its VPN interface (don't do that unless you truly understand all the implications of such a setup)
  • use packet tagging and VRF on the backend server to route back all traffic coming from the VPN, back to the VPN interface (I'm not even sure this would work with an IPsec VPN though because of ACL...)

3. Intercept and route back return traffic

The proxy must be aware that it must intercept this traffic targeted at the destination IP of the client as part of a proxied request. This require a proxy that can bind on an IP that is not configured on the system.

So yeah, don't do that unless you NEED to do that (trust me as I had to do it, and hated setting it up).

Edit: apparently haproxy supports this feature, which they call transparent mode

[–] [email protected] 1 points 1 year ago (1 children)

I think this is right but to make it work you'd need to do one of two things to pull it off. First off, if you're doing it just for Web the nginx proxy putting original ip in the header and unpacking on the other side is the smart move. Otherwise.

1: route all your traffic on your side via the vpn, and have the routing on the vpn side forward the packets to the intranet ip on your side not do dnat on it.

2: if you want to route normal traffic over your normal link then you could do it with source routing on the router. You would need two subnets, one for your normal Internet and one for the vpn traffic. Setup source routing to route packets with the vpn ip addresses go via vpn and the rest nat the normal way then the same as before, vpn on cloud forwards not nat to your side of the vpn.

In both cases snat should be done on the cloud side.

It's a fiddly setup just to get the ip addresses though.

[–] [email protected] 1 points 1 year ago (1 children)

I think you meant to reply to another comment. I never talked about setting up NAT rules, neither source, nor destination.

The proxy is responsible for responding with the correct IP address as it terminates the connection. Setting up NAT rules is not needed.

[–] [email protected] 1 points 1 year ago

Well, I was replying to OP through your reply since it was pretty much spot on. Except I was giving some idea of other ways to bring the original IP through a VPN using the linux ip stack features. Whatever way they go about it, it's a lot of effort for not that much upside though.