mirror of
https://github.com/tobychui/zoraxy.git
synced 2025-06-06 07:37:21 +02:00

+ Added reverse proxy TLS skip verification + Added basic auth + Edit proxy settings + Whitelist + TCP Proxy (experimental) + Info (Utilities page)
356 lines
7.6 KiB
Go
356 lines
7.6 KiB
Go
package geodb
|
|
|
|
import (
|
|
_ "embed"
|
|
"log"
|
|
"net/http"
|
|
"strings"
|
|
|
|
"imuslab.com/zoraxy/mod/database"
|
|
)
|
|
|
|
//go:embed geoipv4.csv
|
|
var geoipv4 []byte //Geodb dataset for ipv4
|
|
|
|
//go:embed geoipv6.csv
|
|
var geoipv6 []byte //Geodb dataset for ipv6
|
|
|
|
type Store struct {
|
|
BlacklistEnabled bool
|
|
WhitelistEnabled bool
|
|
geodb [][]string //Parsed geodb list
|
|
geodbIpv6 [][]string //Parsed geodb list for ipv6
|
|
|
|
geotrie *trie
|
|
geotrieIpv6 *trie
|
|
|
|
//geoipCache sync.Map
|
|
|
|
sysdb *database.Database
|
|
}
|
|
|
|
type CountryInfo struct {
|
|
CountryIsoCode string
|
|
ContinetCode string
|
|
}
|
|
|
|
func NewGeoDb(sysdb *database.Database) (*Store, error) {
|
|
parsedGeoData, err := parseCSV(geoipv4)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
parsedGeoDataIpv6, err := parseCSV(geoipv6)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
blacklistEnabled := false
|
|
whitelistEnabled := false
|
|
if sysdb != nil {
|
|
err = sysdb.NewTable("blacklist-cn")
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
err = sysdb.NewTable("blacklist-ip")
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
err = sysdb.NewTable("whitelist-cn")
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
err = sysdb.NewTable("whitelist-ip")
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
err = sysdb.NewTable("blackwhitelist")
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
sysdb.Read("blackwhitelist", "blacklistEnabled", &blacklistEnabled)
|
|
sysdb.Read("blackwhitelist", "whitelistEnabled", &whitelistEnabled)
|
|
} else {
|
|
log.Println("Database pointer set to nil: Entering debug mode")
|
|
}
|
|
|
|
return &Store{
|
|
BlacklistEnabled: blacklistEnabled,
|
|
WhitelistEnabled: whitelistEnabled,
|
|
geodb: parsedGeoData,
|
|
geotrie: constrctTrieTree(parsedGeoData),
|
|
geodbIpv6: parsedGeoDataIpv6,
|
|
geotrieIpv6: constrctTrieTree(parsedGeoDataIpv6),
|
|
sysdb: sysdb,
|
|
}, nil
|
|
}
|
|
|
|
func (s *Store) ToggleBlacklist(enabled bool) {
|
|
s.sysdb.Write("blackwhitelist", "blacklistEnabled", enabled)
|
|
s.BlacklistEnabled = enabled
|
|
}
|
|
|
|
func (s *Store) ToggleWhitelist(enabled bool) {
|
|
s.sysdb.Write("blackwhitelist", "whitelistEnabled", enabled)
|
|
s.WhitelistEnabled = enabled
|
|
}
|
|
|
|
func (s *Store) ResolveCountryCodeFromIP(ipstring string) (*CountryInfo, error) {
|
|
cc := s.search(ipstring)
|
|
return &CountryInfo{
|
|
CountryIsoCode: cc,
|
|
ContinetCode: "",
|
|
}, nil
|
|
}
|
|
|
|
func (s *Store) Close() {
|
|
|
|
}
|
|
|
|
/*
|
|
Country code based black / white list
|
|
*/
|
|
|
|
func (s *Store) AddCountryCodeToBlackList(countryCode string) {
|
|
countryCode = strings.ToLower(countryCode)
|
|
s.sysdb.Write("blacklist-cn", countryCode, true)
|
|
}
|
|
|
|
func (s *Store) RemoveCountryCodeFromBlackList(countryCode string) {
|
|
countryCode = strings.ToLower(countryCode)
|
|
s.sysdb.Delete("blacklist-cn", countryCode)
|
|
}
|
|
|
|
func (s *Store) AddCountryCodeToWhitelist(countryCode string) {
|
|
countryCode = strings.ToLower(countryCode)
|
|
s.sysdb.Write("whitelist-cn", countryCode, true)
|
|
}
|
|
|
|
func (s *Store) RemoveCountryCodeFromWhitelist(countryCode string) {
|
|
countryCode = strings.ToLower(countryCode)
|
|
s.sysdb.Delete("whitelist-cn", countryCode)
|
|
}
|
|
|
|
func (s *Store) IsCountryCodeBlacklisted(countryCode string) bool {
|
|
countryCode = strings.ToLower(countryCode)
|
|
var isBlacklisted bool = false
|
|
s.sysdb.Read("blacklist-cn", countryCode, &isBlacklisted)
|
|
return isBlacklisted
|
|
}
|
|
|
|
func (s *Store) IsCountryCodeWhitelisted(countryCode string) bool {
|
|
countryCode = strings.ToLower(countryCode)
|
|
var isWhitelisted bool = false
|
|
s.sysdb.Read("whitelist-cn", countryCode, &isWhitelisted)
|
|
return isWhitelisted
|
|
}
|
|
|
|
func (s *Store) GetAllBlacklistedCountryCode() []string {
|
|
bannedCountryCodes := []string{}
|
|
entries, err := s.sysdb.ListTable("blacklist-cn")
|
|
if err != nil {
|
|
return bannedCountryCodes
|
|
}
|
|
for _, keypairs := range entries {
|
|
ip := string(keypairs[0])
|
|
bannedCountryCodes = append(bannedCountryCodes, ip)
|
|
}
|
|
|
|
return bannedCountryCodes
|
|
}
|
|
|
|
func (s *Store) GetAllWhitelistedCountryCode() []string {
|
|
whitelistedCountryCode := []string{}
|
|
entries, err := s.sysdb.ListTable("whitelist-cn")
|
|
if err != nil {
|
|
return whitelistedCountryCode
|
|
}
|
|
for _, keypairs := range entries {
|
|
ip := string(keypairs[0])
|
|
whitelistedCountryCode = append(whitelistedCountryCode, ip)
|
|
}
|
|
|
|
return whitelistedCountryCode
|
|
}
|
|
|
|
/*
|
|
IP based black / whitelist
|
|
*/
|
|
|
|
func (s *Store) AddIPToBlackList(ipAddr string) {
|
|
s.sysdb.Write("blacklist-ip", ipAddr, true)
|
|
}
|
|
|
|
func (s *Store) RemoveIPFromBlackList(ipAddr string) {
|
|
s.sysdb.Delete("blacklist-ip", ipAddr)
|
|
}
|
|
|
|
func (s *Store) AddIPToWhiteList(ipAddr string) {
|
|
s.sysdb.Write("whitelist-ip", ipAddr, true)
|
|
}
|
|
|
|
func (s *Store) RemoveIPFromWhiteList(ipAddr string) {
|
|
s.sysdb.Delete("whitelist-ip", ipAddr)
|
|
}
|
|
|
|
func (s *Store) IsIPBlacklisted(ipAddr string) bool {
|
|
var isBlacklisted bool = false
|
|
s.sysdb.Read("blacklist-ip", ipAddr, &isBlacklisted)
|
|
if isBlacklisted {
|
|
return true
|
|
}
|
|
|
|
//Check for IP wildcard and CIRD rules
|
|
AllBlacklistedIps := s.GetAllBlacklistedIp()
|
|
for _, blacklistRule := range AllBlacklistedIps {
|
|
wildcardMatch := MatchIpWildcard(ipAddr, blacklistRule)
|
|
if wildcardMatch {
|
|
return true
|
|
}
|
|
|
|
cidrMatch := MatchIpCIDR(ipAddr, blacklistRule)
|
|
if cidrMatch {
|
|
return true
|
|
}
|
|
}
|
|
|
|
return false
|
|
}
|
|
|
|
func (s *Store) IsIPWhitelisted(ipAddr string) bool {
|
|
var isBlacklisted bool = false
|
|
s.sysdb.Read("whitelist-ip", ipAddr, &isBlacklisted)
|
|
if isBlacklisted {
|
|
return true
|
|
}
|
|
|
|
//Check for IP wildcard and CIRD rules
|
|
AllBlacklistedIps := s.GetAllBlacklistedIp()
|
|
for _, blacklistRule := range AllBlacklistedIps {
|
|
wildcardMatch := MatchIpWildcard(ipAddr, blacklistRule)
|
|
if wildcardMatch {
|
|
return true
|
|
}
|
|
|
|
cidrMatch := MatchIpCIDR(ipAddr, blacklistRule)
|
|
if cidrMatch {
|
|
return true
|
|
}
|
|
}
|
|
|
|
return false
|
|
}
|
|
|
|
func (s *Store) GetAllBlacklistedIp() []string {
|
|
bannedIps := []string{}
|
|
entries, err := s.sysdb.ListTable("blacklist-ip")
|
|
if err != nil {
|
|
return bannedIps
|
|
}
|
|
|
|
for _, keypairs := range entries {
|
|
ip := string(keypairs[0])
|
|
bannedIps = append(bannedIps, ip)
|
|
}
|
|
|
|
return bannedIps
|
|
}
|
|
|
|
func (s *Store) GetAllWhitelistedIp() []string {
|
|
whitelistedIp := []string{}
|
|
entries, err := s.sysdb.ListTable("whitelist-ip")
|
|
if err != nil {
|
|
return whitelistedIp
|
|
}
|
|
|
|
for _, keypairs := range entries {
|
|
ip := string(keypairs[0])
|
|
whitelistedIp = append(whitelistedIp, ip)
|
|
}
|
|
|
|
return whitelistedIp
|
|
}
|
|
|
|
/*
|
|
Check if a IP address is blacklisted, in either country or IP blacklist
|
|
IsBlacklisted default return is false (allow access)
|
|
*/
|
|
func (s *Store) IsBlacklisted(ipAddr string) bool {
|
|
if !s.BlacklistEnabled {
|
|
//Blacklist not enabled. Always return false
|
|
return false
|
|
}
|
|
|
|
if ipAddr == "" {
|
|
//Unable to get the target IP address
|
|
return false
|
|
}
|
|
|
|
countryCode, err := s.ResolveCountryCodeFromIP(ipAddr)
|
|
if err != nil {
|
|
return false
|
|
}
|
|
|
|
if s.IsCountryCodeBlacklisted(countryCode.CountryIsoCode) {
|
|
return true
|
|
}
|
|
|
|
if s.IsIPBlacklisted(ipAddr) {
|
|
return true
|
|
}
|
|
|
|
return false
|
|
}
|
|
|
|
/*
|
|
IsWhitelisted check if a given IP address is in the current
|
|
server's white list.
|
|
|
|
Note that the Whitelist default result is true even
|
|
when encountered error
|
|
*/
|
|
func (s *Store) IsWhitelisted(ipAddr string) bool {
|
|
if !s.WhitelistEnabled {
|
|
//Whitelist not enabled. Always return true (allow access)
|
|
return true
|
|
}
|
|
|
|
if ipAddr == "" {
|
|
//Unable to get the target IP address, assume ok
|
|
return true
|
|
}
|
|
|
|
countryCode, err := s.ResolveCountryCodeFromIP(ipAddr)
|
|
if err != nil {
|
|
return true
|
|
}
|
|
|
|
if s.IsCountryCodeWhitelisted(countryCode.CountryIsoCode) {
|
|
return true
|
|
}
|
|
|
|
if s.IsIPWhitelisted(ipAddr) {
|
|
return true
|
|
}
|
|
|
|
return false
|
|
}
|
|
|
|
func (s *Store) GetRequesterCountryISOCode(r *http.Request) string {
|
|
ipAddr := GetRequesterIP(r)
|
|
if ipAddr == "" {
|
|
return ""
|
|
}
|
|
countryCode, err := s.ResolveCountryCodeFromIP(ipAddr)
|
|
if err != nil {
|
|
return ""
|
|
}
|
|
|
|
return countryCode.CountryIsoCode
|
|
}
|