(move from user specified blocklist download URLs to simply country codes with multiple providers available.)
56 lines
1.7 KiB
Go
56 lines
1.7 KiB
Go
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
// CountryData holds the resolved CIDR blocks for a single country.
|
|
type CountryData struct {
|
|
Code string // ISO 3166-1 alpha-2 country code
|
|
Name string // Display name for RouterOS comments
|
|
CIDRs []string // IPv4 CIDR blocks
|
|
}
|
|
|
|
// GenerateRSC produces a RouterOS .rsc script file that populates an address list.
|
|
// The filename includes today's date, e.g. "CountryIPBlocks-2026-05-01.rsc".
|
|
// Returns the generated filename.
|
|
func GenerateRSC(countries []CountryData, listName string) (string, error) {
|
|
now := time.Now()
|
|
datedName := fmt.Sprintf("%s-%s", listName, now.Format("2006-01-02"))
|
|
filename := fmt.Sprintf("%s.rsc", datedName)
|
|
|
|
var b strings.Builder
|
|
|
|
// Header with metadata
|
|
b.WriteString(fmt.Sprintf("# RouterOS GeoIP Address List: %s\n", datedName))
|
|
b.WriteString(fmt.Sprintf("# Generated: %s\n", now.UTC().Format(time.RFC3339)))
|
|
b.WriteString(fmt.Sprintf("# Countries: %d\n", len(countries)))
|
|
|
|
totalCIDRs := 0
|
|
for _, c := range countries {
|
|
totalCIDRs += len(c.CIDRs)
|
|
}
|
|
b.WriteString(fmt.Sprintf("# Total entries: %d\n", totalCIDRs))
|
|
b.WriteString("#\n")
|
|
|
|
// Each run creates a uniquely-named list (e.g. CountryIPBlocks-2026-05-01).
|
|
// Workflow: import this file, then atomically swap your firewall rules to
|
|
// reference the new list, then remove the old dated list.
|
|
b.WriteString("/ip firewall address-list\n")
|
|
|
|
for _, country := range countries {
|
|
for _, cidr := range country.CIDRs {
|
|
b.WriteString(fmt.Sprintf("add address=%s comment=\"%s\" list=%s\n", cidr, country.Name, datedName))
|
|
}
|
|
}
|
|
|
|
if err := os.WriteFile(filename, []byte(b.String()), os.ModePerm); err != nil {
|
|
return "", fmt.Errorf("failed to write file %q: %v", filename, err)
|
|
}
|
|
|
|
return filename, nil
|
|
}
|