dougong5285 2014-09-30 09:58
浏览 86
已采纳

限制来自本地子网的客户端对GO Web服务的访问

I'm writing a small web service in GO using just the GO http package. I want to restrict access to the web service to clients on the local subnets (127.0.0.1, 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16).

I tried using a subnet mask as addr argument to ListenAndServe but it exits with a "no such host" error.

EDIT:

This is the solution I came up with the help of @RickA and @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
    })
}

It's a bit raw around the edges but it works as far as I could tell. Thanks for all the help!

  • 写回答

3条回答 默认 最新

  • dtjkl42086 2014-09-30 13:48
    关注

    Write a handler that checks to see if the client's IP address is allowed before delegating to another handler:

    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)
    }
    

    Use this handler to wrap your the root handler:

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

    Note: I typed in the above code without compiling or testing it. Some tweaks are probably required around parsing and testing the remote address.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

悬赏问题

  • ¥15 maple软件,用solve求反函数出现rootof,怎么办?
  • ¥50 汇编语言除法溢出问题
  • ¥65 C++实现删除N个数据列表共有的元素
  • ¥15 Visual Studio问题
  • ¥15 state显示变量是字符串形式,但是仍然红色,无法引用,并显示类型不匹配
  • ¥20 求一个html代码,有偿
  • ¥100 关于使用MATLAB中copularnd函数的问题
  • ¥20 在虚拟机的pycharm上
  • ¥15 jupyterthemes 设置完毕后没有效果
  • ¥15 matlab图像高斯低通滤波