Home > Blockchain >  How do you retrieve the NATed IP address of an incoming HTTP request in golang?
How do you retrieve the NATed IP address of an incoming HTTP request in golang?

Time:06-03

I have a GCP cloud run service that posts data to external URLs. These outgoing requests are routed thru a NAT to ensure requests originate from a static IP address. When I post the data to https://curlmyip.org, CurlmyIP correctly identifies the static IP address.

I have another Cloud Run service that can receive the same data. However, this service is unable to retrieve the static IP address. I am using this code to try and retrieve the static IP address of the incoming request

func getIP(r *http.Request) (string, error) {
    //Get IP from the X-REAL-IP header
    ip := r.Header.Get("X-REAL-IP")
    log.Printf("X-REAL-IP: %s", ip)
    netIP := net.ParseIP(ip)
    if netIP != nil {
        return ip, nil
    }

    //Get IP from X-FORWARDED-FOR header
    ips := r.Header.Get("X-FORWARDED-FOR")
    log.Printf("X-FORWARDED-FOR: %s", ips)
    splitIps := strings.Split(ips, ",")
    for _, ip := range splitIps {
        netIP := net.ParseIP(ip)
        if netIP != nil {
            return ip, nil
        }
    }

    //Get IP from RemoteAddr
    ip, _, err := net.SplitHostPort(r.RemoteAddr)
    if err != nil {
        return "", err
    }
    log.Printf("r.RemoteAddr: %s", ip)
    netIP = net.ParseIP(ip)
    if netIP != nil {
        return ip, nil
    }
    return "", fmt.Errorf("no valid ip found")
}

The above always returns 0.0.0.0 which is in r.RemoteAddr and not the configured static IP address. I added logs to print all the headers in the incoming request and the configured IP address is nowhere to be found.

CodePudding user response:

Depending on what routers/proxies/load balancers/content delivery networks/etc. the request passes through before it gets to you (and how those boxen are configured), the header could be found in any of

  • True-Client-IP
  • X-Forwarded-For
  • X-Real-IP
  • Others?

Or it could simply not be there at all.

CodePudding user response:

In the past we use the header x-forwarded-for but we skip the gcp ip ranges via nginx module.

There are some ip blocks that we found in the web but you must include the load balancer ip too. Then extract the first non-private ip from header.

You can do with pure go. Just need to find the ip ranges to skip

  •  Tags:  
  • go
  • Related