Check if IP address is in private network space

前端 未结 2 1202
臣服心动
臣服心动 2021-02-15 00:43

I have a program in go which accepts URLs from clients and gets them using the net/http package. Before doing further processing, I would like to check if the URL maps to privat

相关标签:
2条回答
  • 2021-02-15 00:57

    It seems there's no better way to accomplish than the one I described. Combining code from @MichaelHausenblas with the suggestion from @JimB, my code ended up kind of like this.

    func privateIP(ip string) (bool, error) {
        var err error
        private := false
        IP := net.ParseIP(ip)
        if IP == nil {
            err = errors.New("Invalid IP")
        } else {
            _, private24BitBlock, _ := net.ParseCIDR("10.0.0.0/8")
            _, private20BitBlock, _ := net.ParseCIDR("172.16.0.0/12")
            _, private16BitBlock, _ := net.ParseCIDR("192.168.0.0/16")
            private = private24BitBlock.Contains(IP) || private20BitBlock.Contains(IP) || private16BitBlock.Contains(IP)
        }
        return private, err
    }
    
    0 讨论(0)
  • 2021-02-15 01:10

    You might also want to include checks for loopback (IPv4 or IPv6) and/or IPv6 link-local or unique-local addresses. Here is an example with a list of RFC1918 address plus these others and a simple check against them as isPrivateIP(ip net.IP):

    var privateIPBlocks []*net.IPNet
    
    func init() {
        for _, cidr := range []string{
            "127.0.0.0/8",    // IPv4 loopback
            "10.0.0.0/8",     // RFC1918
            "172.16.0.0/12",  // RFC1918
            "192.168.0.0/16", // RFC1918
            "169.254.0.0/16", // RFC3927 link-local
            "::1/128",        // IPv6 loopback
            "fe80::/10",      // IPv6 link-local
            "fc00::/7",       // IPv6 unique local addr
        } {
            _, block, err := net.ParseCIDR(cidr)
            if err != nil {
                panic(fmt.Errorf("parse error on %q: %v", cidr, err))
            }
            privateIPBlocks = append(privateIPBlocks, block)
        }
    }
    
    func isPrivateIP(ip net.IP) bool {
        if ip.IsLoopback() || ip.IsLinkLocalUnicast() || ip.IsLinkLocalMulticast() {
            return true
        }
    
        for _, block := range privateIPBlocks {
            if block.Contains(ip) {
                return true
            }
        }
        return false
      }
    
    0 讨论(0)
提交回复
热议问题