前面的Python版本据说有安全风险,而且Go程序都说是网络性能更高,所以也找了一个Go版本

# cat ip4u.go 
package main

import (
    "fmt"
    "net"
    "net/http"
    "strings"
)

func main() {
    handlerFunc := http.HandlerFunc(handleRequest)
    http.Handle("/", handlerFunc)
    http.ListenAndServe("127.0.0.1:9088", nil)
}

func handleRequest(w http.ResponseWriter, r *http.Request) {
    ip, err := getIP(r)
    if err != nil {
        w.WriteHeader(400)
        w.Write([]byte("No valid ip"))
    }
    w.WriteHeader(200)
    w.Write([]byte(ip))
}

func getIP(r *http.Request) (string, error) {
    //Get IP from the X-REAL-IP header
    ip := r.Header.Get("X-REAL-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")
    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
    }
    netIP = net.ParseIP(ip)
    if netIP != nil {
        return ip, nil
    }
    return "", fmt.Errorf("No valid ip found")
}

实际的代码基本就是 https://www.cnblogs.com/GaiHeiluKamei/p/13731791.html  文后的参考文章里的代码,不做任何修改就可以直接使用。源代码里很多地方都没做错误预处理,生产使用的话需要自己把握。

Nginx的相关配置如下:

server {
        listen       9080;
        listen       [::]:9080;
        server_name  _;
        root         /usr/share/nginx/html;
        set_real_ip_from 172.28.0.0/12;
        real_ip_header X-Forwarded-For;


        location / {
                proxy_set_header Host $http_host;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header HTTP_X_REAL_IP $remote_addr;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_pass http://127.0.0.1:9088;
        }
}

这样不管是直接运行,还是在Nginx后面,甚至Nginx前面还有AWS ALB都能正常工作。172.28是我aws vpc的cidr。