snarfed / bridgy-fed

🌉 A bridge between decentralized social network protocols
https://fed.brid.gy
Creative Commons Zero v1.0 Universal
556 stars 29 forks source link

Remove old Nostr spam accounts #1193

Closed snarfed closed 2 months ago

snarfed commented 2 months ago

We have ~7k old Nostr spam accounts still lying around: https://conspirator0.substack.com/p/federation-and-political-spam . They're inert, our spam filters now apply to them, but I'd like to disable them so that they don't show up in user counts, our ATProto firehose subscriber, etc.

snarfed commented 2 months ago

Example AS1 profile object:

{
  "id": "https://momostr.pink/users/npub1pn9fm360l27t326p4u3ggv9vghmwus3rk24dk5ufrpa8up9manfsqr837s",
  "inbox": "https://momostr.pink/inbox",
  "endpoints": {
    "sharedInbox": "https://momostr.pink/inbox"
  },
  "url": "https://coracle.social/people/nprofile1qqsqej5aca8l409c4dq67g5yxzkytahwgg3m92km2wy3s7n7qja7e5cpzamhxue69uhhyetvv9ujumn0wd68ytnzv9hxgtcpzamhxue69uhhyetvv9ujuurjd9kkzmpwdejhgtcpz3mhxw309akx7cmpd35x7um58gurqvph9u36avst",
  "proxyOf": [
    {
      "protocol": "https://github.com/nostr-protocol/nostr",
      "proxied": "npub1pn9fm360l27t326p4u3ggv9vghmwus3rk24dk5ufrpa8up9manfsqr837s",
      "authoritative": true
    }
  ],
  "discoverable": true,
  "indexable": true,
  "publicKey": {
    "id": "https://momostr.pink/users/npub1pn9fm360l27t326p4u3ggv9vghmwus3rk24dk5ufrpa8up9manfsqr837s",
    "type": "Key",
    "owner": "https://momostr.pink/users/npub1pn9fm360l27t326p4u3ggv9vghmwus3rk24dk5ufrpa8up9manfsqr837s",
    "publicKeyPem": "..."
  },
  "objectType": "person",
  "displayName": "dark-star",
  "username": "npub1pn9fm360l27t326p4u3ggv9vghmwus3rk24dk5ufrpa8up9manfsqr837s"
}
snarfed commented 2 months ago

Looks like there are 5645 of these. Here's what I did:

atprepos = AtpRepo.query(AtpRepo.created >= datetime(2024, 5, 10), AtpRepo.created >= datetime(2024, 5, 12)).count()
len(atprepos)
# 9490
nostr = [r for r in atprepos if r.handles[0].startswith('npub')]
len(nostr)
# 5941
non_momostr = [n for n in nostr if not n.handles[0].endswith('.momostr.pink.ap.brid.gy')]
len(non_momostr)
# 0
nostr_profile_keys = [ActivityPub(id=f"https://momostr.pink/users/{n.handles[0].split('.')[0]}").key for n in nostr]
nostr_profiles = ndb.get_multi(nostr_profile_keys)
spammers = [n for n in nostr_profiles if re.match('^[a-z]+-[a-z]+$', n.obj.as1['displayName']) and not n.obj.as1.get('image') and not n.obj.as1.get('summary')]
len(spammers)
# 5645
blocked = [s for s in spammers if s.status == 'blocked']
len(blocked)
# 5644
spammer_names = [s.obj.as1['displayName'] for s in spammers]
print(spammer_names)

spam_dids = set(s.copies[0].uri for s in spam_users)
spam_repos = [n for n in nostr if n.key.id() in spam_dids]

from arroba.util import TOMBSTONED
for repo in spam_repos:
  repo.status = TOMBSTONED
ndb.put_multi(spam_repos)

import arroba.server
for i, repo in enumerate(spam_repos):
  print(i)
  event = arroba.server.storage.write_event(repo_did=repo.key.id(), type='tombstone')

for s in spammers:
  s.enabled_protocols = []
ndb.put_multi(spammers)
snarfed commented 1 month ago

Running this now to remove their DNS entries:

repos = AtpRepo.query(AtpRepo.updated >= datetime(2024, 7, 23, 4), AtpRepo.updated <= datetime(2024, 7, 23, 17)).fetch()
repos = [r for r in repos if r.status == 'tombstoned' and r.handles[0].startswith('npub')]
len(repos)
# 5645

with open('/tmp/npubs', 'w') as f:
  for r in repos:
    print(r.handles[0], file=f)

# edit /tmp/npubs, add _atproto. prefix to each line

# now in shell:
xargs -n 1 gcloud --project=brid-gy dns record-sets delete --type=TXT --zone=brid-gy < /tmp/npubs
snarfed commented 1 month ago

Here are the DIDs and npubs. dids.txt npubs.txt