http - 将对 GO web 服务的访问限制为来自本地子网的客户端

标签 http go

我正在使用 GO http 包在 GO 中编写一个小型 Web 服务。我想将对 Web 服务的访问限制为本地子网(127.0.0.1、10.0.0.0/8、172.16.0.0/12、192.168.0.0/16)上的客户端。

我尝试使用子网掩码作为 ListenAndServe 的地址参数但它退出时出现“没有这样的主机”错误。

编辑:

这是我在@RickA 和@Dewy Broto 的帮助下提出的解决方案。

func JustLocal(handler http.Handler) http.Handler {
    var local_subnets []*net.IPNet
    local_subnet_s := []string{"127.0.0.1/31", "10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16"}

    for _,net_s := range local_subnet_s {
        _, n, _ := net.ParseCIDR(net_s)
        local_subnets = append(local_subnets, n)
    }

    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        fmt.Println(r.RemoteAddr)
        remote_ip := net.ParseIP(strings.Split(r.RemoteAddr, ":")[0])
        fmt.Println(remote_ip)

        local := false
        for _, local_subnet := range local_subnets {
            fmt.Println(local_subnet, remote_ip)
            if local_subnet.Contains(remote_ip) {
                local = true
                break
            }
        }
        if !local {
            http.Error(w, "go away", 403)
            return
        }
        handler.ServeHTTP(w, r)
        return
    })
}

它的边缘有点粗糙,但据我所知它是有效的。感谢所有的帮助!

最佳答案

编写一个处理程序,在委托(delegate)给另一个处理程序之前检查客户端的 IP 地址是否被允许:

type authorizationHandler struct {
    nets []*net.IPNet
    h handler
}

func (ah *authorizationHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
    ok := false
    ip := net.ParseIP(r.RemoteAddr)
    for _, n := range ah.nets {
       if n.Contains(ip) {
         ok := true
         break
       }
    }
    if !ok {
       http.Error(w, "go away", 403)
       return
    }
    ah.h(w, r)
}

使用这个处理程序来包装你的根处理程序:

err := ListenAndServe(addr, 
          &authorizationHandler{nets: allowedNets, h:rootHandler))

注意:上面的代码是我在没有编译和测试的情况下输入的。可能需要围绕解析和测试远程地址进行一些调整。

关于http - 将对 GO web 服务的访问限制为来自本地子网的客户端,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26117940/

相关文章:

firebase - Firestore 批处理 - 需要超过 1 次写入的操作

go - IntelliJ Golang 插件无法导入默认包

go - 如何模拟 gRPC api 以与 golang 进行集成测试

html - 多部分/表单数据的示例

http - RESTfully 请求表示的子部分具有特定的内容类型

python - 检查网站是否可以通过 www 或不通过 www 访问

go - 无法创建与 gorm 的外键关系,其中字段名称!= 类型名称

java - HttpURLConnection - 在 servlet 中获取普通网站而不是移动网站

json - 后端只接受纯文本,不接受 JSON,只接受名称而不是 id

go - 如何获得带有反射的自定义类型?