From c212465159f259662b862cdb66bab8c6e4a03bb4 Mon Sep 17 00:00:00 2001 From: John Behm Date: Sun, 10 Mar 2024 00:41:31 +0100 Subject: [PATCH] update docs & fix small bug regarding automatically added blacklists/whitelists upon startup --- cmd/root.go | 8 ++-- config/config.go | 17 ++------ docker-compose.yaml | 13 +++--- readme.md | 102 ++++++++++++++++++++++++++++---------------- sample.env | 29 ++++++------- 5 files changed, 92 insertions(+), 77 deletions(-) diff --git a/cmd/root.go b/cmd/root.go index 7cd4607..eb2dfa4 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -125,12 +125,12 @@ func (c *rootContext) PreRunE(cmd *cobra.Command) func(cmd *cobra.Command, args func (c *rootContext) RunE(cmd *cobra.Command, args []string) error { log.Println("Starting up...") - for _, file := range c.Config.Whitelists { + for _, file := range c.Config.Blacklists { file = strings.TrimSpace(file) if file == "" { continue } - log.Println("Adding whitelist file: ", file) + log.Println("Adding blacklist file: ", file) added, err := parseFileAndAddIPsToCache(c.Ctx, c.Ripr, file) if err != nil { return err @@ -138,12 +138,12 @@ func (c *rootContext) RunE(cmd *cobra.Command, args []string) error { log.Printf("Added %d ip ranges from %s\n", added, file) } - for _, file := range c.Config.Blacklists { + for _, file := range c.Config.Whitelists { file = strings.TrimSpace(file) if file == "" { continue } - log.Println("Removing blacklist file: ", file) + log.Println("Removing whitelist file: ", file) removed, err := parseFileAndRemoveIPsFromCache(c.Ctx, c.Ripr, file) if err != nil { return err diff --git a/config/config.go b/config/config.go index 8cdd24f..cc790dd 100644 --- a/config/config.go +++ b/config/config.go @@ -5,8 +5,6 @@ import ( "errors" "fmt" "net/http" - "os" - "path/filepath" "strings" "time" @@ -25,17 +23,10 @@ var ( // any call after the first one will return the config of the first call // the location of the .env file can be changed via the DefaultEnvFile variable func New() *Config { - pwd := "./" - dir, err := os.Getwd() - if err == nil { - pwd = dir - } - nutsDir := filepath.Join(pwd, "nutsdata") - return &Config{ RedisAddress: "localhost:6379", RedisDB: 15, - NutsDBDir: nutsDir, + NutsDBDir: "./nutsdata", NutsDBBucket: "whitelist", WhitelistTTL: 7 * 24 * time.Hour, @@ -72,10 +63,10 @@ type Config struct { VPNBanReason string `koanf:"vpn.ban.reason" validate:"required"` Offline bool `koanf:"offline" description:" if set to true no api calls will be made if an ip was not found in the database (= distributed ban server)"` - BanThreshold float64 `koanf:"perma.ban.threshold" validate:"required"` + BanThreshold float64 `koanf:"permaban.threshold" validate:"required" description:"how many percent of the apis must agree on the vpn status for the IP to be added permanently to the blacklist"` - Whitelist string `koanf:"ip.whitelist" description:"comma separated list of ip ranges to whitelist"` - Blacklist string `koanf:"ip.blacklist" description:"comma separated list of ip ranges to blacklist"` + Whitelist string `koanf:"ip.whitelist" description:"comma separated list of files to whitelist"` + Blacklist string `koanf:"ip.blacklist" description:"comma separated list of files to blacklist"` Whitelists []string Blacklists []string diff --git a/docker-compose.yaml b/docker-compose.yaml index fa8f0ad..ac1ef67 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -26,9 +26,9 @@ services: #build: . # uncomment if you want to build the image yourself restart: unless-stopped command: - - --add + - --ip-blacklist - /data/blacklists/blacklist.txt - - --remove + - --ip-whitelist - /data/whitelists/whitelist.txt volumes: - ./volumes/vpn-detection/blacklists/blacklist.txt:/data/blacklists/blacklist.txt @@ -45,12 +45,13 @@ services: TWVPN_REDIS_PASSWORD: ${TWVPN_REDIS_PASSWORD:?err} # optional TWVPN_IPHUB_TOKEN: ${TWVPN_IPHUB_TOKEN:-} - TWVPN_IPTEOH_ENABLED: ${TWVPN_IPTEOH_ENABLED:-false} - TWVPN_OFFLINE: ${TWVPN_OFFLINE:?false} - TWVPN_PERMA_BAN_THRESHOLD: ${TWVPN_PERMA_BAN_THRESHOLD:-0.6} TWVPN_PROXYCHECK_TOKEN: ${TWVPN_PROXYCHECK_TOKEN:-} + TWVPN_VPNAPI_TOKEN: ${TWVPN_VPNAPI_TOKEN:-} + TWVPN_OFFLINE: ${TWVPN_OFFLINE:?false} + TWVPN_PERMABAN_THRESHOLD: ${TWVPN_PERMABAN_THRESHOLD:-0.6} + TWVPN_REDIS_DB_VPN: ${TWVPN_REDIS_DB_VPN:-0} - TWVPN_VPN_BAN_DURATION: ${TWVPN_VPN_BAN_DURATION:-1h} + TWVPN_VPN_BAN_DURATION: ${TWVPN_VPN_BAN_DURATION:-24h} TWVPN_VPN_BAN_REASON: ${TWVPN_VPN_BAN_REASON:-VPN} networks: diff --git a/readme.md b/readme.md index 4e3c48f..e66ea99 100644 --- a/readme.md +++ b/readme.md @@ -7,15 +7,35 @@ The joining player's IP is then compared to the redis cache. Does the cache not contain the IP, currently three VPN detection APIs are used to determine whether the player's IP is a VPN or not. 60% of these three APIs need to detect the IP as VPN in order for the application to actually ban the player and cache his VPN IP in the redis cache as such. -## Requirements +## Usage + +If you have some predefined lists of VPN IPs, you may use `TeeworldsEconVPNDetection add` to add them to the redis database. +The same goes for whitelisted IPs with `TeeworldsEconVPNDetection remove`. +If multiple VPN detection APIs still decide to flag a player's ip, then there is no whitelisting that can save him from being banned. + +You may use either docker to run the application by providing a `.env` file with the following value: +```dotenv +TWVPN_ECON_ADDRESSES=localhost:8404,localhost:8405 +TWVPN_ECON_PASSWORDS="single password for all servers or comma separated list of passwords for each server" +TWVPN_REDIS_PASSWORD="your database password" + +TWVPN_WHITELIST_TTL=168h30m30s +TWVPN_REDIS_DB_VPN=0 # 0-15 +TWVPN_OFFLINE=false +TWVPN_IPHUB_TOKEN="N..." +TWVPN_PROXYCHECK_TOKEN="12345-1234-12345-123456" +TWVPN_VPNAPI_TOKEN="123456890abcdef" +TWVPN_PERMABAN_THRESHOLD="0.6" + +TWVPN_VPN_BAN_REASON="VPN" +TWVPN_VPN_BAN_DURATION="24h30m30s" +``` +And then start your containers using `make start` and stop them using `make stop`. -### Docker +Alternatively, you may compile the application using the Go toolchain `go build .` and run the application by using more or less the exact same `.env` file as for docker and start the application with `./TeeworldsEconVPNDetection --config ./.env`. -``` -make start +You can also set up your redis database using docker with the provided `docker-compose.yml` file or just execute `make redis`. -makes stop -``` ### Redis server for caching of IPs @@ -46,35 +66,32 @@ brew install redis go build . ``` -## Running - -You may use a `.env` config file for configuring the application. -Use `sample.env` as reference or check out the help of the application. +## Command documentation +These are all of the available commands, subcommands and configuration parameters ofthe application. - -Run the econ log parser with the VPN detection. +### Run the econ log parser with the VPN detection. ```shell $ ./TeeworldsEconVPNDetection --help Environment variables: - TWVPN_IPHUB_TOKEN api key for https://iphub.info - TWVPN_PROXYCHECK_TOKEN api key for https://proxycheck.io - TWVPN_VPNAPI_TOKEN api key for https://vpnapi.io - TWVPN_REDIS_ADDRESS (default: "localhost:6379") - TWVPN_REDIS_PASSWORD optional password for the redis database - TWVPN_REDIS_DB_VPN redis database to use for the vpn ip data (0-15) (default: "15") - TWVPN_NUTSDB_DIR directory to store the nutsdb database (default: "/Users/john/Desktop/Development/TeeworldsEconVPNDetectionGo/nutsdata") - TWVPN_NUTSDB_BUCKET bucket name for the nutsdb key value database (default: "whitelist") - TWVPN_WHITELIST_TTL time to live for whitelisted ips (default: "168h0m0s") - TWVPN_ECON_ADDRESSES comma separated list of econ addresses - TWVPN_ECON_PASSWORDS comma separated list of econ passwords - TWVPN_RECONNECT_DELAY (default: "10s") - TWVPN_RECONNECT_TIMEOUT (default: "24h0m0s") - TWVPN_VPN_BAN_DURATION (default: "5m0s") - TWVPN_VPN_BAN_REASON (default: "VPN") - TWVPN_OFFLINE if set to true no api calls will be made if an ip was not found in the database (= distributed ban server) (default: "false") - TWVPN_PERMA_BAN_THRESHOLD (default: "0.6") - TWVPN_IP_WHITELIST comma separated list of ip ranges to whitelist - TWVPN_IP_BLACKLIST comma separated list of ip ranges to blacklist + TWVPN_IPHUB_TOKEN api key for https://iphub.info + TWVPN_PROXYCHECK_TOKEN api key for https://proxycheck.io + TWVPN_VPNAPI_TOKEN api key for https://vpnapi.io + TWVPN_REDIS_ADDRESS (default: "localhost:6379") + TWVPN_REDIS_PASSWORD optional password for the redis database + TWVPN_REDIS_DB_VPN redis database to use for the vpn ip data (0-15) (default: "15") + TWVPN_NUTSDB_DIR directory to store the nutsdb database (default: "./nutsdata") + TWVPN_NUTSDB_BUCKET bucket name for the nutsdb key value database (default: "whitelist") + TWVPN_WHITELIST_TTL time to live for whitelisted ips (default: "168h0m0s") + TWVPN_ECON_ADDRESSES comma separated list of econ addresses + TWVPN_ECON_PASSWORDS comma separated list of econ passwords + TWVPN_RECONNECT_DELAY (default: "10s") + TWVPN_RECONNECT_TIMEOUT (default: "24h0m0s") + TWVPN_VPN_BAN_DURATION (default: "5m0s") + TWVPN_VPN_BAN_REASON (default: "VPN") + TWVPN_OFFLINE if set to true no api calls will be made if an ip was not found in the database (= distributed ban server) (default: "false") + TWVPN_PERMABAN_THRESHOLD how many percent of the apis must agree on the vpn status for the IP to be added permanently to the blacklist (default: "0.6") + TWVPN_IP_WHITELIST comma separated list of files to whitelist + TWVPN_IP_BLACKLIST comma separated list of files to blacklist Usage: TeeworldsEconVPNDetection [flags] @@ -91,13 +108,13 @@ Flags: --econ-addresses string comma separated list of econ addresses --econ-passwords string comma separated list of econ passwords -h, --help help for TeeworldsEconVPNDetection - --ip-blacklist string comma separated list of ip ranges to blacklist - --ip-whitelist string comma separated list of ip ranges to whitelist + --ip-blacklist string comma separated list of files to blacklist + --ip-whitelist string comma separated list of files to whitelist --iphub-token string api key for https://iphub.info --nutsdb-bucket string bucket name for the nutsdb key value database (default "whitelist") - --nutsdb-dir string directory to store the nutsdb database (default "/Users/john/Desktop/Development/TeeworldsEconVPNDetectionGo/nutsdata") + --nutsdb-dir string directory to store the nutsdb database (default "./nutsdata") --offline if set to true no api calls will be made if an ip was not found in the database (= distributed ban server) - --perma-ban-threshold float (default 0.6) + --permaban-threshold float how many percent of the apis must agree on the vpn status for the IP to be added permanently to the blacklist (default 0.6) --proxycheck-token string api key for https://proxycheck.io --reconnect-delay duration (default 10s) --reconnect-timeout duration (default 24h0m0s) @@ -112,7 +129,7 @@ Flags: Use "TeeworldsEconVPNDetection [command] --help" for more information about a command. ``` -Add ips to the database (blacklist) +### Add ips to the database (blacklist) ```shell $ ./TeeworldsEconVPNDetection add --help Environment variables: @@ -131,7 +148,7 @@ Flags: --redis-password string ``` -Remove ips from the database (whitelist) +### Remove ips from the database (whitelist) ```shell $ ./TeeworldsEconVPNDetection remove --help Environment variables: @@ -189,3 +206,14 @@ Add a `# ban reason` behind the IP or behind the IP range to add a custom ban re The Teeworlds server banned you for attempting to login too any times or for connecting too often. Possible solution is to restart the game server. This should not be an issue, as the detector attempts to reconnect to the server. + +### TODO: + +Add proxy detection (if of a different currently running server) +```dotenv +PROXY_DETECTION_ENABLED=false +PROXY_UPDATE_INTERVAL=1m +PROXY_BAN_REASON="proxy connection" +PROXY_BAN_DURATION=24h +PROXY_SERVERNAME_DISTANCE=8 +``` \ No newline at end of file diff --git a/sample.env b/sample.env index 4204054..15706e6 100644 --- a/sample.env +++ b/sample.env @@ -1,20 +1,15 @@ -# mandatory -ECON_ADDRESSES=127.0.0.1:9303,127.0.0.1:9304 -ECON_PASSWORDS=password -REDIS_PASSWORD=some_database_password +TWVPN_ECON_ADDRESSES=localhost:8404,localhost:8405 +TWVPN_ECON_PASSWORDS="single password for all servers or comma separated list of passwords for each server" +TWVPN_REDIS_PASSWORD="your database password" +TWVPN_WHITELIST_TTL=168h30m30s +TWVPN_REDIS_DB_VPN=0 # 0-15 +TWVPN_OFFLINE=false +TWVPN_IPHUB_TOKEN="N..." +TWVPN_PROXYCHECK_TOKEN="12345-1234-12345-123456" +TWVPN_VPNAPI_TOKEN="123456890abcdef" +TWVPN_PERMABAN_THRESHOLD="0.6" -OFFLINE=false -IPHUB_TOKEN= -PROXYCHECK_TOKEN= -IPTEOH_ENABLED=false # does not work -PERMABAN_THRESHOLD=0.6 +TWVPN_VPN_BAN_REASON="VPN" +TWVPN_VPN_BAN_DURATION="24h30m30s" -VPN_BAN_REASON=VPN -VPN_BAN_DURATION=1h - -PROXY_DETECTION_ENABLED=false -PROXY_UPDATE_INTERVAL=1m -PROXY_BAN_REASON=proxy connection -PROXY_BAN_DURATION=24h -PROXY_SERVERNAME_DISTANCE=8