netutil.go 1.9 KB

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