geodb.go 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. package geodb
  2. import (
  3. "net"
  4. "net/http"
  5. "strings"
  6. "github.com/oschwald/geoip2-golang"
  7. "imuslab.com/arozos/ReverseProxy/mod/database"
  8. )
  9. type Store struct {
  10. geodb *geoip2.Reader
  11. sysdb *database.Database
  12. }
  13. type CountryInfo struct {
  14. CountryIsoCode string
  15. ContinetCode string
  16. }
  17. func NewGeoDb(sysdb *database.Database, dbfile string) (*Store, error) {
  18. db, err := geoip2.Open(dbfile)
  19. if err != nil {
  20. return nil, err
  21. }
  22. err = sysdb.NewTable("blacklist-cn")
  23. if err != nil {
  24. return nil, err
  25. }
  26. err = sysdb.NewTable("blacklist-ip")
  27. if err != nil {
  28. return nil, err
  29. }
  30. return &Store{
  31. geodb: db,
  32. sysdb: sysdb,
  33. }, nil
  34. }
  35. func (s *Store) ResolveCountryCodeFromIP(ipstring string) (*CountryInfo, error) {
  36. // If you are using strings that may be invalid, check that ip is not nil
  37. ip := net.ParseIP(ipstring)
  38. record, err := s.geodb.City(ip)
  39. if err != nil {
  40. return nil, err
  41. }
  42. return &CountryInfo{
  43. record.Country.IsoCode,
  44. record.Continent.Code,
  45. }, nil
  46. }
  47. func (s *Store) Close() {
  48. s.geodb.Close()
  49. }
  50. func (s *Store) AddCountryCodeToBlackList(countryCode string) {
  51. s.sysdb.Write("blacklist-cn", countryCode, true)
  52. }
  53. func (s *Store) RemoveCountryCodeFromBlackList(countryCode string) {
  54. s.sysdb.Delete("blacklist-cn", countryCode)
  55. }
  56. func (s *Store) IsCountryCodeBlacklisted(countryCode string) bool {
  57. var isBlacklisted bool = false
  58. s.sysdb.Read("blacklist-cn", countryCode, &isBlacklisted)
  59. return isBlacklisted
  60. }
  61. func (s *Store) GetAllBlacklistedCountryCode() []string {
  62. bannedCountryCodes := []string{}
  63. entries, err := s.sysdb.ListTable("blacklist-cn")
  64. if err != nil {
  65. return bannedCountryCodes
  66. }
  67. for _, keypairs := range entries {
  68. ip := string(keypairs[0])
  69. bannedCountryCodes = append(bannedCountryCodes, ip)
  70. }
  71. return bannedCountryCodes
  72. }
  73. func (s *Store) AddIPToBlackList(ipAddr string) {
  74. s.sysdb.Write("blacklist-ip", ipAddr, true)
  75. }
  76. func (s *Store) RemoveIPFromBlackList(ipAddr string) {
  77. s.sysdb.Delete("blacklist-ip", ipAddr)
  78. }
  79. func (s *Store) IsIPBlacklisted(ipAddr string) bool {
  80. var isBlacklisted bool = false
  81. s.sysdb.Read("blacklist-ip", ipAddr, &isBlacklisted)
  82. return isBlacklisted
  83. }
  84. func (s *Store) GetAllBlacklistedIp() []string {
  85. bannedIps := []string{}
  86. entries, err := s.sysdb.ListTable("blacklist-ip")
  87. if err != nil {
  88. return bannedIps
  89. }
  90. for _, keypairs := range entries {
  91. ip := string(keypairs[0])
  92. bannedIps = append(bannedIps, ip)
  93. }
  94. return bannedIps
  95. }
  96. //Check if a IP address is blacklisted, in either country or IP blacklist
  97. func (s *Store) IsBlacklisted(ipAddr string) bool {
  98. if ipAddr == "" {
  99. //Unable to get the target IP address
  100. return false
  101. }
  102. countryCode, err := s.ResolveCountryCodeFromIP(ipAddr)
  103. if err != nil {
  104. return false
  105. }
  106. if s.IsCountryCodeBlacklisted(countryCode.CountryIsoCode) {
  107. return true
  108. }
  109. if s.IsIPBlacklisted(ipAddr) {
  110. return true
  111. }
  112. return false
  113. }
  114. //Utilities function
  115. func GetRequesterIP(r *http.Request) string {
  116. ip := r.Header.Get("X-Forwarded-For")
  117. if ip == "" {
  118. ip = r.Header.Get("X-Real-IP")
  119. if ip == "" {
  120. ip = strings.Split(r.RemoteAddr, ":")[0]
  121. }
  122. }
  123. return ip
  124. }
  125. //Match the IP address with a wildcard string
  126. func MatchIpWildcard(ipAddress, wildcard string) bool {
  127. // Split IP address and wildcard into octets
  128. ipOctets := strings.Split(ipAddress, ".")
  129. wildcardOctets := strings.Split(wildcard, ".")
  130. // Check that both have 4 octets
  131. if len(ipOctets) != 4 || len(wildcardOctets) != 4 {
  132. return false
  133. }
  134. // Check each octet to see if it matches the wildcard or is an exact match
  135. for i := 0; i < 4; i++ {
  136. if wildcardOctets[i] == "*" {
  137. continue
  138. }
  139. if ipOctets[i] != wildcardOctets[i] {
  140. return false
  141. }
  142. }
  143. return true
  144. }
  145. //Match ip address with CIDR
  146. func MatchIpCIDR(ip string, cidr string) bool {
  147. // parse the CIDR string
  148. _, cidrnet, err := net.ParseCIDR(cidr)
  149. if err != nil {
  150. return false
  151. }
  152. // parse the IP address
  153. ipAddr := net.ParseIP(ip)
  154. // check if the IP address is within the CIDR range
  155. return cidrnet.Contains(ipAddr)
  156. }