-
-
Notifications
You must be signed in to change notification settings - Fork 573
feat: iplist2rule utility command #1373
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 6 commits
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
b592aaf
feat: iplist2rule utility command
Xe 9ccfdf3
docs: update CHANGELOG
Xe 2dc0719
chore: fix spelling
Xe c5815f3
chore: fix spelling again
Xe ad41bc7
feat(iplist2rule): add comment describing how rule was generated
Xe c84a414
docs: add iplist2rule docs
Xe e05d8bd
chore: fix spelling
Xe File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -18,3 +18,7 @@ clampip | |
| pseudoprofound | ||
| reimagining | ||
| iocaine | ||
| admins | ||
| fout | ||
| iplist | ||
| NArg | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,50 @@ | ||
| --- | ||
| title: iplist2rule CLI tool | ||
| --- | ||
|
|
||
| The `iplist2rule` tool converts IP blocklists into Anubis challenge policies. It reads common IP block list formats and generates the appropriate Anubis policy file for IP address filtering. | ||
|
|
||
|
|
||
| ## Installation | ||
|
|
||
| Install directly with Go | ||
|
|
||
| ```bash | ||
| go install github.com/TecharoHQ/anubis/utils/cmd/iplist2rule@latest | ||
| ``` | ||
|
|
||
| ## Usage | ||
|
|
||
| Basic conversion from URL: | ||
|
|
||
| ```bash | ||
| iplist2rule https://raw.githubusercontent.com/7c/torfilter/refs/heads/main/lists/txt/torfilter-1m-flat.txt filter-tor.yaml | ||
| ``` | ||
|
|
||
| Explicitly allow every IP address on a list: | ||
|
|
||
| ```bash | ||
| iplist2rule --action ALLOW https://raw.githubusercontent.com/7c/torfilter/refs/heads/main/lists/txt/torfilter-1m-flat.txt filter-tor.yaml | ||
| ``` | ||
|
|
||
| Add weight to requests matching IP addresses on a list: | ||
|
|
||
| ```bash | ||
| iplist2rule --action WEIGH --weight 20 https://raw.githubusercontent.com/7c/torfilter/refs/heads/main/lists/txt/torfilter-1m-flat.txt filter-tor.yaml | ||
| ``` | ||
|
|
||
| ## Options | ||
|
|
||
| | Flag | Description | Default | | ||
| | :------------ | :----------------------------------------------------------------------------------------------- | :-------------------------------- | | ||
| | `--action` | The Anubis action to take for the IP address in question, must be in ALL CAPS. | `DENY` (forbids traffic) | | ||
| | `--rule-name` | The name for the generated Anubis rule, should be in kebab-case. | (not set, inferred from filename) | | ||
| | `--weight` | When `--action=WEIGH`, how many weight points should be added or removed from matching requests? | 0 (not set) | | ||
|
|
||
| ## Using the Generated Policy | ||
|
|
||
| Save the output and import it in your main policy file: | ||
|
|
||
| ```yaml | ||
| bots: | ||
| - import: "./filter-tor.yaml" | ||
| ``` | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,57 @@ | ||
| package main | ||
|
|
||
|
|
||
| import ( | ||
| "bufio" | ||
| "fmt" | ||
| "io" | ||
| "net/http" | ||
| "net/netip" | ||
| "strings" | ||
| ) | ||
|
|
||
| // FetchBlocklist reads the blocklist over HTTP and returns every non-commented | ||
| // line parsed as an IP address in CIDR notation. IPv4 addresses are returned as | ||
| // /32, IPv6 addresses as /128. | ||
| // | ||
| // This function was generated with GLM 4.7. | ||
| func FetchBlocklist(url string) ([]string, error) { | ||
| resp, err := http.Get(url) | ||
| if err != nil { | ||
| return nil, err | ||
| } | ||
| defer resp.Body.Close() | ||
|
|
||
| if resp.StatusCode != http.StatusOK { | ||
| return nil, fmt.Errorf("HTTP request failed with status: %s", resp.Status) | ||
| } | ||
|
|
||
| var lines []string | ||
| scanner := bufio.NewScanner(resp.Body) | ||
| for scanner.Scan() { | ||
| line := scanner.Text() | ||
| // Skip empty lines and comments (lines starting with #) | ||
| if line == "" || strings.HasPrefix(line, "#") { | ||
| continue | ||
| } | ||
|
|
||
| addr, err := netip.ParseAddr(line) | ||
| if err != nil { | ||
| // Skip lines that aren't valid IP addresses | ||
| continue | ||
| } | ||
|
|
||
| var cidr string | ||
| if addr.Is4() { | ||
| cidr = fmt.Sprintf("%s/32", addr.String()) | ||
| } else { | ||
| cidr = fmt.Sprintf("%s/128", addr.String()) | ||
| } | ||
| lines = append(lines, cidr) | ||
| } | ||
|
|
||
| if err := scanner.Err(); err != nil && err != io.EOF { | ||
| return nil, err | ||
| } | ||
|
|
||
| return lines, nil | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,103 @@ | ||
| package main | ||
|
|
||
|
|
||
| import ( | ||
| "flag" | ||
| "fmt" | ||
| "log" | ||
| "os" | ||
| "path/filepath" | ||
| "strings" | ||
| "time" | ||
|
|
||
| "github.com/TecharoHQ/anubis/lib/config" | ||
| "github.com/facebookgo/flagenv" | ||
| "sigs.k8s.io/yaml" | ||
| ) | ||
|
|
||
| type Rule struct { | ||
| Name string `yaml:"name" json:"name"` | ||
| Action config.Rule `yaml:"action" json:"action"` | ||
| RemoteAddr []string `json:"remote_addresses,omitempty" yaml:"remote_addresses,omitempty"` | ||
| Weight *config.Weight `json:"weight,omitempty" yaml:"weight,omitempty"` | ||
| } | ||
|
|
||
| func init() { | ||
| flag.Usage = func() { | ||
| fmt.Printf(`Usage of %[1]s: | ||
|
|
||
| %[1]s [flags] <blocklist-url> <filename> | ||
|
|
||
| Grabs the contents of the blocklist, converts it to an Anubis ruleset, and writes it to filename. | ||
|
|
||
| Flags: | ||
| `, filepath.Base(os.Args[0])) | ||
|
|
||
| flag.PrintDefaults() | ||
| } | ||
| } | ||
|
|
||
| var ( | ||
| action = flag.String("action", "DENY", "Anubis action to take (ALLOW / DENY / WEIGH)") | ||
| manualRuleName = flag.String("rule-name", "", "If set, prefer this name over inferring from filename") | ||
| weight = flag.Int("weight", 0, "If set to any number, add/subtract this many weight points when --action=WEIGH") | ||
| ) | ||
|
|
||
| func main() { | ||
| flagenv.Parse() | ||
| flag.Parse() | ||
|
|
||
| if flag.NArg() != 2 { | ||
|
|
||
| flag.Usage() | ||
| os.Exit(2) | ||
| } | ||
|
|
||
| blocklistURL := flag.Arg(0) | ||
| foutName := flag.Arg(1) | ||
|
|
||
| ruleName := strings.TrimSuffix(foutName, filepath.Ext(foutName)) | ||
|
|
||
|
|
||
| if *manualRuleName != "" { | ||
| ruleName = *manualRuleName | ||
| } | ||
|
|
||
| ruleAction := config.Rule(*action) | ||
| if err := ruleAction.Valid(); err != nil { | ||
| log.Fatalf("--action=%q is invalid: %v", *action, err) | ||
| } | ||
|
|
||
| result := &Rule{ | ||
| Name: ruleName, | ||
| Action: ruleAction, | ||
| } | ||
|
|
||
| if *weight != 0 { | ||
| if ruleAction != config.RuleWeigh { | ||
| log.Fatalf("used --weight=%d but --action=%s", *weight, *action) | ||
| } | ||
|
|
||
| result.Weight = &config.Weight{ | ||
| Adjust: *weight, | ||
| } | ||
| } | ||
|
|
||
| ips, err := FetchBlocklist(blocklistURL) | ||
| if err != nil { | ||
| log.Fatalf("can't fetch blocklist %s: %v", blocklistURL, err) | ||
| } | ||
|
|
||
| result.RemoteAddr = ips | ||
|
|
||
| fout, err := os.Create(foutName) | ||
|
|
||
| if err != nil { | ||
| log.Fatalf("can't create output file %q: %v", foutName, err) | ||
| } | ||
| defer fout.Close() | ||
|
|
||
| fmt.Fprintf(fout, "# Generated by %s on %s from %s\n\n", filepath.Base(os.Args[0]), time.Now().Format(time.RFC3339), blocklistURL) | ||
|
|
||
| data, err := yaml.Marshal([]*Rule{result}) | ||
| if err != nil { | ||
| log.Fatalf("can't marshal yaml") | ||
| } | ||
|
|
||
| fout.Write(data) | ||
| } | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.