How to properly forward the request remote address to a proxied Go service?

I have a simple go service that checks the request IP address by using Request.RemoteAddr from the standard net/http package.

This go service is deployed behind nginx with the following simple location configuration:

location /api {
    proxy_pass http://localhost:8080;
}

Obviously, when the application is deployed behind the proxy, Request.RemoteAddr now returns the localhost/server address (eg. ::1)

I know that I coud define something like:

proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

but doing so will require also modification in the go service (and some additional security checks in case the service is deployed as a standalone server because those headers could be modified by the client)

Is there a way to pass the request remote address to the go service, so that it could be returned by Request.RemoteAddr?


Side note: In php with fastcgi in this case for example, I could do something like:

fastcgi_param REMOTE_ADDR $remote_address;

Solution 1:

You've proposed the correct configuration changes to your web server. These headers are how the real IP address is generally passed from the web server to the app server, regardless of language. You should add them to your server or location block.

Then to receive this data in Go, you can use a middleware such as ProxyHeaders from gorilla/handlers, which will insert the IP address from one of those headers into Request.RemoteAddr. You could possibly use other approaches, but programming questions should be asked on Stack Overflow.

Solution 2:

Since the relevant Go libraries are open source, it was quite straightforward to check that no, there is no possibility to easily customize Request.RemoteAddr.

You could get rid of nginx and put your go service under api.example.com (a separate unproxied public IP address) instead of example.com/api.