问题描述
我正在使用golang http
软件包.服务器如何限制客户端IP地址?
I'm using golang http
package. How could the server limit client IP address?
func (s *Worker) Run(c chan error) {
apiMux := http.NewServeMux()
apiMux.HandleFunc("/test", s.test)
apiMux.HandleFunc("/block/create", s.CreateBlock)
apiMux.HandleFunc("/block/delete", s.DeleteBlock)
apiServer := &http.Server{
Addr: "0.0.0.0:" + strconv.Itoa(s.ListenPort),
Handler: apiMux,
}
go func() {
log.Println("Worker listening on " + apiServer.Addr)
c <- apiServer.ListenAndServe()
}()
}
推荐答案
您需要做两件事:一是使用一个中间件处理程序包装您的多路复用器,该中间件处理程序可以预处理您的请求并验证IP.另一个是获取用户的真实IP,如果您位于防火墙或负载平衡器之后(导致地址始终是LB的地址),或者您的用户位于代理之后,则这非常重要.
You need to do two things: one is to wrap your mux with a middleware handler that pre-processes your requests and validates the IP. The other is get the real IP of the user, which is important if you are behind a firewall or load balancer (resulting in the address being always that of the LB), or if your user is behind a proxy.
关于包装多路复用器,这很简单:
As for wrapping your mux, it's pretty simple:
apiServer := &http.Server{
Addr: "0.0.0.0:8080",
Handler: http.HandlerFunc( func(w http.ResponseWriter, req *http.Request) {
// get the real IP of the user, see below
addr := getRealAddr(req)
// the actual vaildation - replace with whatever you want
if (addr != "1.2.3.4") {
http.Error(w, "Blocked", 401)
return
}
// pass the request to the mux
apiMux.ServeHTTP(w,req)
}),
}
我要附加getRealAddr
函数,该函数来自一个实际的项目,在该项目中我做了这样的事情:
And I'm attaching the getRealAddr
function which is from an actual project in which I did something like this:
func getRealAddr(r *http.Request) string {
remoteIP := ""
// the default is the originating ip. but we try to find better options because this is almost
// never the right IP
if parts := strings.Split(r.RemoteAddr, ":"); len(parts) == 2 {
remoteIP = parts[0]
}
// If we have a forwarded-for header, take the address from there
if xff := strings.Trim(r.Header.Get("X-Forwarded-For"), ","); len(xff) > 0 {
addrs := strings.Split(xff, ",")
lastFwd := addrs[len(addrs)-1]
if ip := net.ParseIP(lastFwd); ip != nil {
remoteIP = ip.String()
}
// parse X-Real-Ip header
} else if xri := r.Header.Get("X-Real-Ip"); len(xri) > 0 {
if ip := net.ParseIP(xri); ip != nil {
remoteIP = ip.String()
}
}
return remoteIP
}
对于过滤,它可以基于一组ips或CIDR范围,这完全取决于您.
As for the filtering, it can be based on a set of ips, or CIDR ranges, it's up to you of course.
如果您感兴趣的话,上面的代码来自我编写和使用的API构建工具箱,称为Vertex,该工具箱内置于其中: https://github.com/EverythingMe/vertex
If you're interested, the above code is from an API building toolkit I wrote and used called Vertex, which has this built in: https://github.com/EverythingMe/vertex
这篇关于使用golang http软件包时如何限制客户端IP地址的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!