ipmatch.go 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. package netutils
  2. import (
  3. "net"
  4. "net/http"
  5. "strings"
  6. )
  7. /*
  8. MatchIP.go
  9. This script contains function for matching IP address, comparing
  10. CIDR and IPv4 / v6 validations
  11. */
  12. func GetRequesterIP(r *http.Request) string {
  13. ip := r.Header.Get("X-Real-Ip")
  14. if ip == "" {
  15. CF_Connecting_IP := r.Header.Get("CF-Connecting-IP")
  16. Fastly_Client_IP := r.Header.Get("Fastly-Client-IP")
  17. if CF_Connecting_IP != "" {
  18. //Use CF Connecting IP
  19. return CF_Connecting_IP
  20. } else if Fastly_Client_IP != "" {
  21. //Use Fastly Client IP
  22. return Fastly_Client_IP
  23. }
  24. ip = r.Header.Get("X-Forwarded-For")
  25. }
  26. if ip == "" {
  27. ip = r.RemoteAddr
  28. }
  29. /*
  30. Possible shits that might be extracted by this code
  31. 127.0.0.1:61001
  32. [15c4:cbb4:cc98:4291:ffc1:3a46:06a1:51a7]:61002
  33. 127.0.0.1
  34. 158.250.160.114,109.21.249.211
  35. [15c4:cbb4:cc98:4291:ffc1:3a46:06a1:51a7],109.21.249.211
  36. We need to extract just the first ip address
  37. */
  38. requesterRawIp := ip
  39. if strings.Contains(requesterRawIp, ",") {
  40. //Trim off all the forwarder IPs
  41. requesterRawIp = strings.Split(requesterRawIp, ",")[0]
  42. }
  43. //Trim away the port number
  44. reqHost, _, err := net.SplitHostPort(requesterRawIp)
  45. if err == nil {
  46. requesterRawIp = reqHost
  47. }
  48. if strings.HasPrefix(requesterRawIp, "[") && strings.HasSuffix(requesterRawIp, "]") {
  49. //e.g. [15c4:cbb4:cc98:4291:ffc1:3a46:06a1:51a7]
  50. requesterRawIp = requesterRawIp[1 : len(requesterRawIp)-1]
  51. }
  52. return requesterRawIp
  53. }
  54. // Match the IP address with a wildcard string
  55. func MatchIpWildcard(ipAddress, wildcard string) bool {
  56. // Split IP address and wildcard into octets
  57. ipOctets := strings.Split(ipAddress, ".")
  58. wildcardOctets := strings.Split(wildcard, ".")
  59. // Check that both have 4 octets
  60. if len(ipOctets) != 4 || len(wildcardOctets) != 4 {
  61. return false
  62. }
  63. // Check each octet to see if it matches the wildcard or is an exact match
  64. for i := 0; i < 4; i++ {
  65. if wildcardOctets[i] == "*" {
  66. continue
  67. }
  68. if ipOctets[i] != wildcardOctets[i] {
  69. return false
  70. }
  71. }
  72. return true
  73. }
  74. // Match ip address with CIDR
  75. func MatchIpCIDR(ip string, cidr string) bool {
  76. // parse the CIDR string
  77. _, cidrnet, err := net.ParseCIDR(cidr)
  78. if err != nil {
  79. return false
  80. }
  81. // parse the IP address
  82. ipAddr := net.ParseIP(ip)
  83. // check if the IP address is within the CIDR range
  84. return cidrnet.Contains(ipAddr)
  85. }
  86. // Check if a ip is private IP range
  87. func IsPrivateIP(ipStr string) bool {
  88. if ipStr == "127.0.0.1" || ipStr == "::1" {
  89. //local loopback
  90. return true
  91. }
  92. ip := net.ParseIP(ipStr)
  93. if ip == nil {
  94. return false
  95. }
  96. return ip.IsPrivate()
  97. }
  98. // Check if an Ip string is ipv6
  99. func IsIPv6(ipStr string) bool {
  100. ip := net.ParseIP(ipStr)
  101. if ip == nil {
  102. return false
  103. }
  104. return ip.To4() == nil && ip.To16() != nil
  105. }
  106. // Check if an Ip string is ipv6
  107. func IsIPv4(ipStr string) bool {
  108. ip := net.ParseIP(ipStr)
  109. if ip == nil {
  110. return false
  111. }
  112. return ip.To4() != nil
  113. }