main.go 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. package main
  2. import (
  3. "flag"
  4. "fmt"
  5. "log"
  6. "os"
  7. "path/filepath"
  8. "strings"
  9. "time"
  10. "github.com/TecharoHQ/anubis/lib/config"
  11. "github.com/facebookgo/flagenv"
  12. "sigs.k8s.io/yaml"
  13. )
  14. type Rule struct {
  15. Name string `yaml:"name" json:"name"`
  16. Action config.Rule `yaml:"action" json:"action"`
  17. RemoteAddr []string `json:"remote_addresses,omitempty" yaml:"remote_addresses,omitempty"`
  18. Weight *config.Weight `json:"weight,omitempty" yaml:"weight,omitempty"`
  19. }
  20. func init() {
  21. flag.Usage = func() {
  22. fmt.Printf(`Usage of %[1]s:
  23. %[1]s [flags] <blocklist-url> <filename>
  24. Grabs the contents of the blocklist, converts it to an Anubis ruleset, and writes it to filename.
  25. Flags:
  26. `, filepath.Base(os.Args[0]))
  27. flag.PrintDefaults()
  28. }
  29. }
  30. var (
  31. action = flag.String("action", "DENY", "Anubis action to take (ALLOW / DENY / WEIGH)")
  32. manualRuleName = flag.String("rule-name", "", "If set, prefer this name over inferring from filename")
  33. weight = flag.Int("weight", 0, "If set to any number, add/subtract this many weight points when --action=WEIGH")
  34. )
  35. func main() {
  36. flagenv.Parse()
  37. flag.Parse()
  38. if flag.NArg() != 2 {
  39. flag.Usage()
  40. os.Exit(2)
  41. }
  42. blocklistURL := flag.Arg(0)
  43. foutName := flag.Arg(1)
  44. ruleName := strings.TrimSuffix(foutName, filepath.Ext(foutName))
  45. if *manualRuleName != "" {
  46. ruleName = *manualRuleName
  47. }
  48. ruleAction := config.Rule(*action)
  49. if err := ruleAction.Valid(); err != nil {
  50. log.Fatalf("--action=%q is invalid: %v", *action, err)
  51. }
  52. result := &Rule{
  53. Name: ruleName,
  54. Action: ruleAction,
  55. }
  56. if *weight != 0 {
  57. if ruleAction != config.RuleWeigh {
  58. log.Fatalf("used --weight=%d but --action=%s", *weight, *action)
  59. }
  60. result.Weight = &config.Weight{
  61. Adjust: *weight,
  62. }
  63. }
  64. ips, err := FetchBlocklist(blocklistURL)
  65. if err != nil {
  66. log.Fatalf("can't fetch blocklist %s: %v", blocklistURL, err)
  67. }
  68. result.RemoteAddr = ips
  69. fout, err := os.Create(foutName)
  70. if err != nil {
  71. log.Fatalf("can't create output file %q: %v", foutName, err)
  72. }
  73. defer fout.Close()
  74. fmt.Fprintf(fout, "# Generated by %s on %s from %s\n\n", filepath.Base(os.Args[0]), time.Now().Format(time.RFC3339), blocklistURL)
  75. data, err := yaml.Marshal([]*Rule{result})
  76. if err != nil {
  77. log.Fatalf("can't marshal yaml")
  78. }
  79. fout.Write(data)
  80. }