netutil.go 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. package netutil
  2. import (
  3. "fmt"
  4. "net"
  5. )
  6. var localCIDRs []*net.IPNet
  7. func init() {
  8. // Parsing hardcoded CIDR strings should never fail, if in case it does, let's
  9. // fail it at start.
  10. rawCIDRs := []string{
  11. // https://datatracker.ietf.org/doc/html/rfc5735:
  12. "127.0.0.0/8", // Loopback
  13. "0.0.0.0/8", // "This" network
  14. "100.64.0.0/10", // Shared address space
  15. "169.254.0.0/16", // Link local
  16. "172.16.0.0/12", // Private-use networks
  17. "192.0.0.0/24", // IETF Protocol assignments
  18. "192.0.2.0/24", // TEST-NET-1
  19. "192.88.99.0/24", // 6to4 Relay anycast
  20. "192.168.0.0/16", // Private-use networks
  21. "198.18.0.0/15", // Network interconnect
  22. "198.51.100.0/24", // TEST-NET-2
  23. "203.0.113.0/24", // TEST-NET-3
  24. "255.255.255.255/32", // Limited broadcast
  25. // https://datatracker.ietf.org/doc/html/rfc1918:
  26. "10.0.0.0/8", // Private-use networks
  27. // https://datatracker.ietf.org/doc/html/rfc6890:
  28. "::1/128", // Loopback
  29. "FC00::/7", // Unique local address
  30. "FE80::/10", // Multicast address
  31. }
  32. for _, raw := range rawCIDRs {
  33. _, cidr, err := net.ParseCIDR(raw)
  34. if err != nil {
  35. panic(fmt.Sprintf("parse CIDR %q: %v", raw, err))
  36. }
  37. localCIDRs = append(localCIDRs, cidr)
  38. }
  39. }
  40. // IsBlockedLocalHostname returns true if given hostname is resolved to a local
  41. // network address that is implicitly blocked (i.e. not exempted from the
  42. // allowlist).
  43. func IsBlockedLocalHostname(hostname string, allowlist []string) bool {
  44. for _, allow := range allowlist {
  45. if hostname == allow || allow == "*" {
  46. return false
  47. }
  48. }
  49. ips, err := net.LookupIP(hostname)
  50. if err != nil {
  51. return true
  52. }
  53. for _, ip := range ips {
  54. for _, cidr := range localCIDRs {
  55. if cidr.Contains(ip) {
  56. return true
  57. }
  58. }
  59. }
  60. return false
  61. }