使用golang http软件包时如何限制客户端IP地址 [英] How to limit client IP address when using golang http package

查看:172
本文介绍了使用golang http软件包时如何限制客户端IP地址的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用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地址的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆