前面的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。