转到 - 检查IP地址是否在专用网络空间中

Ste*_*nOS 7 ip network-programming go

我有一个程序在go中接受来自客户端的URL并使用net/http包获取它们.在进行进一步处理之前,我想检查URL是否映射到私有(不可路由/ RFC1918网络)地址空间.

直接的方法是执行显式DNS请求并检查已知私有范围的地址.之后,执行URL的HTTP GET请求.

有没有更好的方法来实现这一目标?最好与http.Client集成,以便它可以作为GET请求的一部分来执行.

Bra*_*ody 20

您可能还希望包括对环回(IPv4或IPv6)和/或IPv6链路本地地址的检查.下面是一个示例,其中包含RFC1918地址加上这两个地址的列表,并对它们进行简单的检查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
  }
Run Code Online (Sandbox Code Playgroud)

  • 还有`fc00::/7` (2认同)

Von*_*onC 11

据 Go 101 报道,使用Go 1.17(2021 年第四季度,5 年后)应该更容易做到这一点:

请参阅提交 c73fcccCL 272668

net: 添加IP.IsPrivate()

添加IsPrivate()帮助程序以根据 RFC 1918 和 RFC 4193 检查 IP 是否为私有

这修复了Aaran McGuire提出的golang 问题 29146

net 包似乎有很多帮助程序来报告 IP 是什么。例如:

  • IsLoopback()
  • IsMulticast()
  • IsInterfaceLocalMulticast()

但是,没有帮助程序来报告 IP 地址是否在私有范围内(RFC 1918RFC 4193)。

  • 顺便说一句,我希望在 Go 1.17 发布后更改已接受的答案。 (3认同)