From 5a7d54058e147c1c52a434ccb814d3839d28940d Mon Sep 17 00:00:00 2001 From: Shlee Date: Tue, 26 May 2026 13:06:35 +0930 Subject: [PATCH 1/9] Update main.go --- install/main.go | 57 ++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 47 insertions(+), 10 deletions(-) diff --git a/install/main.go b/install/main.go index b3979ace9..688e58be6 100644 --- a/install/main.go +++ b/install/main.go @@ -55,7 +55,8 @@ type Config struct { TraefikBouncerKey string DoCrowdsecInstall bool EnableGeoblocking bool - Secret string + EnableASNblocking bool + Secret string IsEnterprise bool } @@ -123,15 +124,22 @@ func main() { fmt.Println("\nConfiguration files created successfully!") - // Download MaxMind database if requested + // Download MaxMind Country / ASN database if requested if config.EnableGeoblocking { - fmt.Println("\n=== Downloading MaxMind Database ===") + fmt.Println("\n=== Downloading MaxMind Country Database ===") if err := downloadMaxMindDatabase(); err != nil { - fmt.Printf("Error downloading MaxMind database: %v\n", err) + fmt.Printf("Error downloading MaxMind Country database: %v\n", err) fmt.Println("You can download it manually later if needed.") } } - + if config.EnableASNblocking { + fmt.Println("\n=== Downloading MaxMind ASN Database ===") + if err := downloadMaxMindASNDatabase(); err != nil { + fmt.Printf("Error downloading MaxMind ASN database: %v\n", err) + fmt.Println("You can download it manually later if needed.") + } + } + fmt.Println("\n=== Starting installation ===") if readBool("Would you like to install and start the containers?", true) { @@ -527,8 +535,9 @@ func collectUserInput() Config { fmt.Println("\n=== Advanced Configuration ===") config.EnableIPv6 = readBool("Is your server IPv6 capable?", true) - config.EnableGeoblocking = readBool("Do you want to download the MaxMind GeoLite2 database for geoblocking functionality?", true) - + config.EnableGeoblocking = readBool("Do you want to download the MaxMind GeoLite2 Country database for geoblocking functionality?", true) + config.EnableASNblocking = readBool("Do you want to download the MaxMind GeoLite2 ASN database for rule-blocking functionality?", true) + if config.DashboardDomain == "" { fmt.Println("Error: Dashboard Domain name is required") os.Exit(1) @@ -785,17 +794,17 @@ func downloadMaxMindDatabase() error { // Download the GeoLite2 Country database if err := run("curl", "-L", "-o", "GeoLite2-Country.tar.gz", "https://github.com/GitSquared/node-geolite2-redist/raw/refs/heads/master/redist/GeoLite2-Country.tar.gz"); err != nil { - return fmt.Errorf("failed to download GeoLite2 database: %v", err) + return fmt.Errorf("failed to download GeoLite2 Country database: %v", err) } // Extract the database if err := run("tar", "-xzf", "GeoLite2-Country.tar.gz"); err != nil { - return fmt.Errorf("failed to extract GeoLite2 database: %v", err) + return fmt.Errorf("failed to extract GeoLite2 Country database: %v", err) } // Find the .mmdb file and move it to the config directory if err := run("bash", "-c", "mv GeoLite2-Country_*/GeoLite2-Country.mmdb config/"); err != nil { - return fmt.Errorf("failed to move GeoLite2 database to config directory: %v", err) + return fmt.Errorf("failed to move GeoLite2 Country database to config directory: %v", err) } // Clean up the downloaded files @@ -806,3 +815,31 @@ func downloadMaxMindDatabase() error { fmt.Println("MaxMind GeoLite2 Country database downloaded successfully!") return nil } + +func downloadMaxMindASNDatabase() error { + fmt.Println("Downloading MaxMind GeoLite2 ASN database...") + + // Download the GeoLite2 ASN database + if err := run("curl", "-L", "-o", "GeoLite2-ASN.tar.gz", + "https://github.com/GitSquared/node-geolite2-redist/raw/refs/heads/master/redist/GeoLite2-ASN.tar.gz"); err != nil { + return fmt.Errorf("failed to download GeoLite2 ASN database: %v", err) + } + + // Extract the database + if err := run("tar", "-xzf", "GeoLite2-ASN.tar.gz"); err != nil { + return fmt.Errorf("failed to extract GeoLite2 ASN database: %v", err) + } + + // Find the .mmdb file and move it to the config directory + if err := run("bash", "-c", "mv GeoLite2-ASN*/GeoLite2-ASN.mmdb config/"); err != nil { + return fmt.Errorf("failed to move GeoLite2 ASN database to config directory: %v", err) + } + + // Clean up the downloaded files + if err := run("rm", "-rf", "GeoLite2-ASN.tar.gz", "GeoLite2-ASN*"); err != nil { + fmt.Printf("Warning: failed to clean up temporary files: %v\n", err) + } + + fmt.Println("MaxMind GeoLite2 ASN database downloaded successfully!") + return nil +} From f59fbabede2b4a8312dbc01c87cbddd41cdf99ca Mon Sep 17 00:00:00 2001 From: Shlee Date: Tue, 26 May 2026 13:12:48 +0930 Subject: [PATCH 2/9] Update main.go --- install/main.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/install/main.go b/install/main.go index 688e58be6..0316219d3 100644 --- a/install/main.go +++ b/install/main.go @@ -808,7 +808,7 @@ func downloadMaxMindDatabase() error { } // Clean up the downloaded files - if err := run("rm", "-rf", "GeoLite2-Country.tar.gz", "GeoLite2-Country_*"); err != nil { + if err := run("sh", "-c", "rm -rf GeoLite2-Country.tar.gz GeoLite2-Country_*"); err != nil { fmt.Printf("Warning: failed to clean up temporary files: %v\n", err) } @@ -831,12 +831,12 @@ func downloadMaxMindASNDatabase() error { } // Find the .mmdb file and move it to the config directory - if err := run("bash", "-c", "mv GeoLite2-ASN*/GeoLite2-ASN.mmdb config/"); err != nil { + if err := run("bash", "-c", "mv GeoLite2-ASN_*/GeoLite2-ASN.mmdb config/"); err != nil { return fmt.Errorf("failed to move GeoLite2 ASN database to config directory: %v", err) } // Clean up the downloaded files - if err := run("rm", "-rf", "GeoLite2-ASN.tar.gz", "GeoLite2-ASN*"); err != nil { + if err := run("sh", "-c", "rm -rf GeoLite2-ASN.tar.gz GeoLite2-ASN_*"); err != nil { fmt.Printf("Warning: failed to clean up temporary files: %v\n", err) } From 802a41b1bd71116ffa640ee9ff42b37bd839e430 Mon Sep 17 00:00:00 2001 From: Shlee Date: Tue, 26 May 2026 13:25:53 +0930 Subject: [PATCH 3/9] Update main.go --- install/main.go | 65 ++++++++++++++++--------------------------------- 1 file changed, 21 insertions(+), 44 deletions(-) diff --git a/install/main.go b/install/main.go index 0316219d3..fb5ac9a7f 100644 --- a/install/main.go +++ b/install/main.go @@ -54,8 +54,7 @@ type Config struct { InstallGerbil bool TraefikBouncerKey string DoCrowdsecInstall bool - EnableGeoblocking bool - EnableASNblocking bool + EnableMaxMind bool Secret string IsEnterprise bool } @@ -125,17 +124,10 @@ func main() { fmt.Println("\nConfiguration files created successfully!") // Download MaxMind Country / ASN database if requested - if config.EnableGeoblocking { - fmt.Println("\n=== Downloading MaxMind Country Database ===") + if config.EnableMaxMind { + fmt.Println("\n=== Downloading MaxMind Country and ASN Databases ===") if err := downloadMaxMindDatabase(); err != nil { - fmt.Printf("Error downloading MaxMind Country database: %v\n", err) - fmt.Println("You can download it manually later if needed.") - } - } - if config.EnableASNblocking { - fmt.Println("\n=== Downloading MaxMind ASN Database ===") - if err := downloadMaxMindASNDatabase(); err != nil { - fmt.Printf("Error downloading MaxMind ASN database: %v\n", err) + fmt.Printf("Error downloading MaxMind databases: %v\n", err) fmt.Println("You can download it manually later if needed.") } } @@ -789,57 +781,42 @@ func checkPortsAvailable(port int) error { } func downloadMaxMindDatabase() error { - fmt.Println("Downloading MaxMind GeoLite2 Country database...") + fmt.Println("Downloading MaxMind GeoLite2 Country and ASN databases...") - // Download the GeoLite2 Country database + // Download the GeoLite2 Country databases if err := run("curl", "-L", "-o", "GeoLite2-Country.tar.gz", "https://github.com/GitSquared/node-geolite2-redist/raw/refs/heads/master/redist/GeoLite2-Country.tar.gz"); err != nil { return fmt.Errorf("failed to download GeoLite2 Country database: %v", err) } - - // Extract the database - if err := run("tar", "-xzf", "GeoLite2-Country.tar.gz"); err != nil { - return fmt.Errorf("failed to extract GeoLite2 Country database: %v", err) - } - - // Find the .mmdb file and move it to the config directory - if err := run("bash", "-c", "mv GeoLite2-Country_*/GeoLite2-Country.mmdb config/"); err != nil { - return fmt.Errorf("failed to move GeoLite2 Country database to config directory: %v", err) - } - - // Clean up the downloaded files - if err := run("sh", "-c", "rm -rf GeoLite2-Country.tar.gz GeoLite2-Country_*"); err != nil { - fmt.Printf("Warning: failed to clean up temporary files: %v\n", err) - } - - fmt.Println("MaxMind GeoLite2 Country database downloaded successfully!") - return nil -} - -func downloadMaxMindASNDatabase() error { - fmt.Println("Downloading MaxMind GeoLite2 ASN database...") - - // Download the GeoLite2 ASN database if err := run("curl", "-L", "-o", "GeoLite2-ASN.tar.gz", "https://github.com/GitSquared/node-geolite2-redist/raw/refs/heads/master/redist/GeoLite2-ASN.tar.gz"); err != nil { return fmt.Errorf("failed to download GeoLite2 ASN database: %v", err) } - - // Extract the database + + // Extract the Country database + if err := run("tar", "-xzf", "GeoLite2-Country.tar.gz"); err != nil { + return fmt.Errorf("failed to extract GeoLite2 Country database: %v", err) + } if err := run("tar", "-xzf", "GeoLite2-ASN.tar.gz"); err != nil { return fmt.Errorf("failed to extract GeoLite2 ASN database: %v", err) } - + // Find the .mmdb file and move it to the config directory + if err := run("bash", "-c", "mv GeoLite2-Country_*/GeoLite2-Country.mmdb config/"); err != nil { + return fmt.Errorf("failed to move GeoLite2 Country database to config directory: %v", err) + } if err := run("bash", "-c", "mv GeoLite2-ASN_*/GeoLite2-ASN.mmdb config/"); err != nil { return fmt.Errorf("failed to move GeoLite2 ASN database to config directory: %v", err) } - + // Clean up the downloaded files + if err := run("sh", "-c", "rm -rf GeoLite2-Country.tar.gz GeoLite2-Country_*"); err != nil { + fmt.Printf("Warning: failed to clean up temporary files: %v\n", err) + } if err := run("sh", "-c", "rm -rf GeoLite2-ASN.tar.gz GeoLite2-ASN_*"); err != nil { fmt.Printf("Warning: failed to clean up temporary files: %v\n", err) } - - fmt.Println("MaxMind GeoLite2 ASN database downloaded successfully!") + + fmt.Println("MaxMind GeoLite2 Country and ASN database downloaded successfully!") return nil } From 491096109a0a6a06c59789cacd56dd6e9075f777 Mon Sep 17 00:00:00 2001 From: Shlee Date: Tue, 26 May 2026 13:31:07 +0930 Subject: [PATCH 4/9] Update main.go --- install/main.go | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/install/main.go b/install/main.go index fb5ac9a7f..1142f2967 100644 --- a/install/main.go +++ b/install/main.go @@ -188,15 +188,15 @@ func main() { fmt.Println("\n=== MaxMind Database Update ===") if _, err := os.Stat("config/GeoLite2-Country.mmdb"); err == nil { fmt.Println("MaxMind GeoLite2 Country database found.") - if readBool("Would you like to update the MaxMind database to the latest version?", false) { + if readBool("Would you like to update the MaxMind databases (Country and ASN) to the latest version?", false) { if err := downloadMaxMindDatabase(); err != nil { fmt.Printf("Error updating MaxMind database: %v\n", err) fmt.Println("You can try updating it manually later if needed.") } } } else { - fmt.Println("MaxMind GeoLite2 Country database not found.") - if readBool("Would you like to download the MaxMind GeoLite2 database for geoblocking functionality?", false) { + fmt.Println("MaxMind GeoLite2 Country and ASN databases not found.") + if readBool("Would you like to download the MaxMind GeoLite2 databases for blocking functionality?", false) { if err := downloadMaxMindDatabase(); err != nil { fmt.Printf("Error downloading MaxMind database: %v\n", err) fmt.Println("You can try downloading it manually later if needed.") @@ -204,9 +204,11 @@ func main() { // Now you need to update your config file accordingly to enable geoblocking fmt.Print("Please remember to update your config/config.yml file to enable geoblocking! \n\n") // add maxmind_db_path: "./config/GeoLite2-Country.mmdb" under server - fmt.Println("Add the following line under the 'server' section:") + // add maxmind_asn_path: "./config/GeoLite2-ASN.mmdb" under server + fmt.Println("Add the following lines under the 'server' section:") fmt.Println(" maxmind_db_path: \"./config/GeoLite2-Country.mmdb\"") - } + fmt.Println(" maxmind_asn_path: \"./config/GeoLite2-ASN.mmdb\"") + } } } From 51971c7ef262a8fec7a5a1200e4239b71d39cf98 Mon Sep 17 00:00:00 2001 From: Shlee Date: Tue, 26 May 2026 13:36:01 +0930 Subject: [PATCH 5/9] Update config.yml --- install/config/config.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/install/config/config.yml b/install/config/config.yml index 90d1bf5d5..1f50057e8 100644 --- a/install/config/config.yml +++ b/install/config/config.yml @@ -22,7 +22,8 @@ server: methods: ["GET", "POST", "PUT", "DELETE", "PATCH"] allowed_headers: ["X-CSRF-Token", "Content-Type"] credentials: false - {{if .EnableGeoblocking}}maxmind_db_path: "./config/GeoLite2-Country.mmdb"{{end}} + {{if .EnableMaxMind}}maxmind_db_path: "./config/GeoLite2-Country.mmdb"{{end}} + {{if .EnableMaxMind}}maxmind_asn_path: "./config/GeoLite2-ASN.mmdb"{{end}} {{if .EnableEmail}} email: smtp_host: "{{.EmailSMTPHost}}" From 5a53f88fd6d7031ef5793beee2243345bf9b2f80 Mon Sep 17 00:00:00 2001 From: Shlee Date: Tue, 26 May 2026 13:37:28 +0930 Subject: [PATCH 6/9] Update main.go --- install/main.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/install/main.go b/install/main.go index 1142f2967..891eb454b 100644 --- a/install/main.go +++ b/install/main.go @@ -813,10 +813,10 @@ func downloadMaxMindDatabase() error { // Clean up the downloaded files if err := run("sh", "-c", "rm -rf GeoLite2-Country.tar.gz GeoLite2-Country_*"); err != nil { - fmt.Printf("Warning: failed to clean up temporary files: %v\n", err) + fmt.Printf("Warning: failed to clean up temporary country files: %v\n", err) } if err := run("sh", "-c", "rm -rf GeoLite2-ASN.tar.gz GeoLite2-ASN_*"); err != nil { - fmt.Printf("Warning: failed to clean up temporary files: %v\n", err) + fmt.Printf("Warning: failed to clean up temporary ASN files: %v\n", err) } fmt.Println("MaxMind GeoLite2 Country and ASN database downloaded successfully!") From 32fcf90467dab8756739c104c05087898e7d6cc5 Mon Sep 17 00:00:00 2001 From: Shlee Date: Tue, 26 May 2026 13:48:00 +0930 Subject: [PATCH 7/9] Update docker-compose.yml --- install/config/docker-compose.yml | 34 ++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/install/config/docker-compose.yml b/install/config/docker-compose.yml index 505089bed..1ba966964 100644 --- a/install/config/docker-compose.yml +++ b/install/config/docker-compose.yml @@ -1,7 +1,7 @@ name: pangolin services: pangolin: - image: docker.io/fosrl/pangolin:{{if .IsEnterprise}}ee-{{end}}{{.PangolinVersion}} + image: docker.io/fosrl/pangolin:{{if .IsEnterprise}}ee-postgresql-{{end}}{{.PangolinVersion}} container_name: pangolin restart: unless-stopped deploy: @@ -60,6 +60,38 @@ services: - ./config/letsencrypt:/letsencrypt # Volume to store the Let's Encrypt certificates - ./config/traefik/logs:/var/log/traefik # Volume to store Traefik logs +{{if .IsEnterprise}} + postgres: + image: postgres:18 + container_name: postgres + restart: unless-stopped + environment: + POSTGRES_USER: pangolin + POSTGRES_PASSWORD: pangolin + volumes: + - ./config/postgres18:/var/lib/postgresql/data + healthcheck: + test: ["CMD-SHELL", "pg_isready -U postgres"] + interval: 10s + timeout: 5s + retries: 5 + + redis: + image: redis/redis:8-trixie + container_name: redis + restart: unless-stopped + environment: + REDIS_ARGS: "--save 3600 1000 --appendonly yes --requirepass pangolin" ## Save Redis to disk every hour & Write the logs to disk using AOF + volumes: + - ./redis8-data:/data + healthcheck: + test: ["CMD", "redis-cli", "ping"] + interval: 10s + timeout: 3s + retries: 3 + start_period: 10s +{{end}} + networks: default: driver: bridge From f1ec1a2fb101ffbc030833129e48c8bce60c566d Mon Sep 17 00:00:00 2001 From: Shlee Date: Tue, 26 May 2026 13:49:06 +0930 Subject: [PATCH 8/9] Update docker-compose.yml --- install/config/docker-compose.yml | 34 +------------------------------ 1 file changed, 1 insertion(+), 33 deletions(-) diff --git a/install/config/docker-compose.yml b/install/config/docker-compose.yml index 1ba966964..505089bed 100644 --- a/install/config/docker-compose.yml +++ b/install/config/docker-compose.yml @@ -1,7 +1,7 @@ name: pangolin services: pangolin: - image: docker.io/fosrl/pangolin:{{if .IsEnterprise}}ee-postgresql-{{end}}{{.PangolinVersion}} + image: docker.io/fosrl/pangolin:{{if .IsEnterprise}}ee-{{end}}{{.PangolinVersion}} container_name: pangolin restart: unless-stopped deploy: @@ -60,38 +60,6 @@ services: - ./config/letsencrypt:/letsencrypt # Volume to store the Let's Encrypt certificates - ./config/traefik/logs:/var/log/traefik # Volume to store Traefik logs -{{if .IsEnterprise}} - postgres: - image: postgres:18 - container_name: postgres - restart: unless-stopped - environment: - POSTGRES_USER: pangolin - POSTGRES_PASSWORD: pangolin - volumes: - - ./config/postgres18:/var/lib/postgresql/data - healthcheck: - test: ["CMD-SHELL", "pg_isready -U postgres"] - interval: 10s - timeout: 5s - retries: 5 - - redis: - image: redis/redis:8-trixie - container_name: redis - restart: unless-stopped - environment: - REDIS_ARGS: "--save 3600 1000 --appendonly yes --requirepass pangolin" ## Save Redis to disk every hour & Write the logs to disk using AOF - volumes: - - ./redis8-data:/data - healthcheck: - test: ["CMD", "redis-cli", "ping"] - interval: 10s - timeout: 3s - retries: 3 - start_period: 10s -{{end}} - networks: default: driver: bridge From bbf42c5802d58e12354aab038b612c8c8bfe0172 Mon Sep 17 00:00:00 2001 From: Shlee Date: Tue, 26 May 2026 17:14:06 +0930 Subject: [PATCH 9/9] Update main.go --- install/main.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/install/main.go b/install/main.go index 891eb454b..5609d8cf0 100644 --- a/install/main.go +++ b/install/main.go @@ -529,8 +529,7 @@ func collectUserInput() Config { fmt.Println("\n=== Advanced Configuration ===") config.EnableIPv6 = readBool("Is your server IPv6 capable?", true) - config.EnableGeoblocking = readBool("Do you want to download the MaxMind GeoLite2 Country database for geoblocking functionality?", true) - config.EnableASNblocking = readBool("Do you want to download the MaxMind GeoLite2 ASN database for rule-blocking functionality?", true) + config.EnableMaxMind = readBool("Do you want to download the MaxMind GeoLite2 Country and ADN databases for blocking functionality?", true) if config.DashboardDomain == "" { fmt.Println("Error: Dashboard Domain name is required")