1
0

geodb.go 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. package geodb
  2. import (
  3. _ "embed"
  4. "log"
  5. "net"
  6. "net/http"
  7. "imuslab.com/zoraxy/mod/database"
  8. )
  9. //go:embed geoipv4.csv
  10. var geoipv4 []byte //Geodb dataset for ipv4
  11. //go:embed geoipv6.csv
  12. var geoipv6 []byte //Geodb dataset for ipv6
  13. type Store struct {
  14. BlacklistEnabled bool
  15. WhitelistEnabled bool
  16. geodb [][]string //Parsed geodb list
  17. geodbIpv6 [][]string //Parsed geodb list for ipv6
  18. geotrie *trie
  19. geotrieIpv6 *trie
  20. //geoipCache sync.Map
  21. sysdb *database.Database
  22. }
  23. type CountryInfo struct {
  24. CountryIsoCode string
  25. ContinetCode string
  26. }
  27. func NewGeoDb(sysdb *database.Database) (*Store, error) {
  28. parsedGeoData, err := parseCSV(geoipv4)
  29. if err != nil {
  30. return nil, err
  31. }
  32. parsedGeoDataIpv6, err := parseCSV(geoipv6)
  33. if err != nil {
  34. return nil, err
  35. }
  36. blacklistEnabled := false
  37. whitelistEnabled := false
  38. if sysdb != nil {
  39. err = sysdb.NewTable("blacklist-cn")
  40. if err != nil {
  41. return nil, err
  42. }
  43. err = sysdb.NewTable("blacklist-ip")
  44. if err != nil {
  45. return nil, err
  46. }
  47. err = sysdb.NewTable("whitelist-cn")
  48. if err != nil {
  49. return nil, err
  50. }
  51. err = sysdb.NewTable("whitelist-ip")
  52. if err != nil {
  53. return nil, err
  54. }
  55. err = sysdb.NewTable("blackwhitelist")
  56. if err != nil {
  57. return nil, err
  58. }
  59. sysdb.Read("blackwhitelist", "blacklistEnabled", &blacklistEnabled)
  60. sysdb.Read("blackwhitelist", "whitelistEnabled", &whitelistEnabled)
  61. } else {
  62. log.Println("Database pointer set to nil: Entering debug mode")
  63. }
  64. return &Store{
  65. BlacklistEnabled: blacklistEnabled,
  66. WhitelistEnabled: whitelistEnabled,
  67. geodb: parsedGeoData,
  68. geotrie: constrctTrieTree(parsedGeoData),
  69. geodbIpv6: parsedGeoDataIpv6,
  70. geotrieIpv6: constrctTrieTree(parsedGeoDataIpv6),
  71. sysdb: sysdb,
  72. }, nil
  73. }
  74. func (s *Store) ToggleBlacklist(enabled bool) {
  75. s.sysdb.Write("blackwhitelist", "blacklistEnabled", enabled)
  76. s.BlacklistEnabled = enabled
  77. }
  78. func (s *Store) ToggleWhitelist(enabled bool) {
  79. s.sysdb.Write("blackwhitelist", "whitelistEnabled", enabled)
  80. s.WhitelistEnabled = enabled
  81. }
  82. func (s *Store) ResolveCountryCodeFromIP(ipstring string) (*CountryInfo, error) {
  83. cc := s.search(ipstring)
  84. return &CountryInfo{
  85. CountryIsoCode: cc,
  86. ContinetCode: "",
  87. }, nil
  88. }
  89. func (s *Store) Close() {
  90. }
  91. /*
  92. Check if a IP address is blacklisted, in either country or IP blacklist
  93. IsBlacklisted default return is false (allow access)
  94. */
  95. func (s *Store) IsBlacklisted(ipAddr string) bool {
  96. if !s.BlacklistEnabled {
  97. //Blacklist not enabled. Always return false
  98. return false
  99. }
  100. if ipAddr == "" {
  101. //Unable to get the target IP address
  102. return false
  103. }
  104. countryCode, err := s.ResolveCountryCodeFromIP(ipAddr)
  105. if err != nil {
  106. return false
  107. }
  108. if s.IsCountryCodeBlacklisted(countryCode.CountryIsoCode) {
  109. return true
  110. }
  111. if s.IsIPBlacklisted(ipAddr) {
  112. return true
  113. }
  114. return false
  115. }
  116. /*
  117. IsWhitelisted check if a given IP address is in the current
  118. server's white list.
  119. Note that the Whitelist default result is true even
  120. when encountered error
  121. */
  122. func (s *Store) IsWhitelisted(ipAddr string) bool {
  123. if !s.WhitelistEnabled {
  124. //Whitelist not enabled. Always return true (allow access)
  125. return true
  126. }
  127. if ipAddr == "" {
  128. //Unable to get the target IP address, assume ok
  129. return true
  130. }
  131. countryCode, err := s.ResolveCountryCodeFromIP(ipAddr)
  132. if err != nil {
  133. return true
  134. }
  135. if s.IsCountryCodeWhitelisted(countryCode.CountryIsoCode) {
  136. return true
  137. }
  138. if s.IsIPWhitelisted(ipAddr) {
  139. return true
  140. }
  141. return false
  142. }
  143. // A helper function that check both blacklist and whitelist for access
  144. // for both geoIP and ip / CIDR ranges
  145. func (s *Store) AllowIpAccess(ipaddr string) bool {
  146. if s.IsBlacklisted(ipaddr) {
  147. return false
  148. }
  149. return s.IsWhitelisted(ipaddr)
  150. }
  151. func (s *Store) AllowConnectionAccess(conn net.Conn) bool {
  152. if addr, ok := conn.RemoteAddr().(*net.TCPAddr); ok {
  153. return s.AllowIpAccess(addr.IP.String())
  154. }
  155. return true
  156. }
  157. func (s *Store) GetRequesterCountryISOCode(r *http.Request) string {
  158. ipAddr := GetRequesterIP(r)
  159. if ipAddr == "" {
  160. return ""
  161. }
  162. countryCode, err := s.ResolveCountryCodeFromIP(ipAddr)
  163. if err != nil {
  164. return ""
  165. }
  166. return countryCode.CountryIsoCode
  167. }