stop-abuse.py 3.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. import dns.resolver
  2. from django.conf import settings
  3. from django.core.management import BaseCommand
  4. from django.db.models import Q
  5. from desecapi.models import BlockedSubnet, Domain, RR, RRset, User
  6. from desecapi.pdns_change_tracker import PDNSChangeTracker
  7. class Command(BaseCommand):
  8. help = (
  9. "Removes all DNS records from domains given either by name or by email address of their owner. "
  10. "Locks all implicated user accounts."
  11. )
  12. def add_arguments(self, parser):
  13. parser.add_argument(
  14. "names",
  15. nargs="*",
  16. help="Domain(s) and User(s) to truncate and disable identified by name and email addresses",
  17. )
  18. def handle(self, *args, **options):
  19. with PDNSChangeTracker():
  20. # domains to truncate: all domains given and all domains belonging to a user given
  21. domains = Domain.objects.filter(
  22. Q(name__in=options["names"]) | Q(owner__email__in=options["names"])
  23. )
  24. domain_names = domains.distinct().values_list("name", flat=True)
  25. # users to lock: all associated with any of the domains and all given
  26. users = User.objects.filter(
  27. Q(domains__name__in=options["names"]) | Q(email__in=options["names"])
  28. )
  29. user_emails = users.distinct().values_list("email", flat=True)
  30. # rrsets to delete: all belonging to (all domains given and all domains belonging to a user given)
  31. rrsets = RRset.objects.filter(
  32. Q(domain__name__in=options["names"])
  33. | Q(domain__owner__email__in=options["names"])
  34. )
  35. blocked_subnets = []
  36. for rr in RR.objects.filter(rrset__in=rrsets.filter(type="A")):
  37. if not BlockedSubnet.objects.filter(
  38. subnet__net_contains=rr.content
  39. ).exists():
  40. try:
  41. blocked_subnet = BlockedSubnet.from_ip(rr.content)
  42. except dns.resolver.NXDOMAIN: # for unallocated IP addresses
  43. continue
  44. blocked_subnet.save()
  45. blocked_subnets.append(blocked_subnet)
  46. # Print summary
  47. print(
  48. f"Deleting {rrsets.distinct().count()} RRset(s) from {domains.distinct().count()} domain(s); "
  49. f"disabling {users.distinct().count()} associated user account(s). {len(blocked_subnets)} subnets:"
  50. )
  51. if blocked_subnets:
  52. row_format = "{:>11} {:>18} {:>8} {}"
  53. print(row_format.format("ASN", "Subnet", "Country", "Registry"))
  54. for bs in blocked_subnets:
  55. print(
  56. row_format.format(
  57. bs.asn, str(bs.subnet), bs.country, bs.registry
  58. )
  59. )
  60. # Print details
  61. for d in domain_names:
  62. print(f"Truncating domain {d}")
  63. for e in user_emails:
  64. print(f"Locking user {e}")
  65. # delete rrsets and create default NS records
  66. rrsets.delete()
  67. for d in domains:
  68. RRset.objects.create(
  69. domain=d,
  70. subname="",
  71. type="NS",
  72. ttl=3600,
  73. contents=settings.DEFAULT_NS,
  74. )
  75. # lock users
  76. users.update(is_active=False)