Created
May 8, 2023 20:48
-
-
Save wafflecomposite/81de26f9fa1fd16f33a7496c55fd637b to your computer and use it in GitHub Desktop.
π¬πͺ Silknet DNS Incident: potential censorship against Activitypub
This file contains 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
import json | |
import csv | |
from urllib.parse import urlparse | |
# pip install requests | |
import requests | |
# pip install dnspython | |
from dns import resolver | |
from dns.exception import DNSException | |
# Quad9 dns as "ground truth" | |
# aka https://dns.quad9.net/dns-query | |
r1 = resolver.Resolver() | |
r1.nameservers = ["9.9.9.9"] | |
# GE, GEOCELL(Silknet) DNS as the subject of research | |
# aka https://maradona.silknet.com | |
r2 = resolver.Resolver() | |
r2.nameservers = ["91.151.130.117"] | |
# Get OONI global server list | |
ooni_csv = requests.get('https://raw.githubusercontent.com/citizenlab/test-lists/master/lists/global.csv') | |
ooni_servers = [urlparse(row[0] if row else "").netloc for row in csv.reader(ooni_csv.text.split("\n")[1:], delimiter=',')] | |
# Get Activitypub instances, sorted by reported activity | |
headers = {'Accept': 'application/json'} | |
r_body = {"query": "{\n nodes(status: \"1\") {\n active_users_monthly\n domain\n }\n}"} | |
ap_nodes = requests.post('https://api.fediverse.observer', headers=headers, json=r_body).json()["data"]["nodes"] # get node list | |
ap_active_nodes = [item for item in ap_nodes if item["active_users_monthly"] is not None and item["active_users_monthly"] > 3] # filter low activity nodes | |
ap_sorted_nodes = [item["domain"] for item in list(sorted(ap_active_nodes, key=lambda item: item["active_users_monthly"], reverse=True))] # sort by activity | |
print(f"AP servers len:{len(ap_sorted_nodes)}") | |
print(f"OONI servers len:{len(ooni_servers)}") | |
results = { | |
"AP": { | |
0: 0, # not available on Quad9, not checked on Silknet | |
1: 0, # available on both | |
2: 0 # available on Quad9 but not on Silknet <- This is the point of interest. | |
}, | |
"OONI": { | |
0: 0, # not available on Quad9, not checked on Silknet | |
1: 0, # available on both | |
2: 0 # available on Quad9 but not on Silknet | |
}, | |
} | |
def check_server(server): | |
resp1 = None | |
resp2 = None | |
try: | |
q = r1.resolve(server) | |
resp1 = [x.address for x in q] | |
except DNSException: | |
return 0 # not available on Quad9, no point to check further | |
try: | |
q = r2.resolve(server) | |
resp2 = [x.address for x in q] | |
except DNSException: | |
resp2 = [] | |
if resp1 and resp2: | |
return 1 # available on both | |
else: | |
return 2 # available on Quad9 but not on Silknet | |
for i in range(1000): | |
ap_res = check_server(ap_sorted_nodes[i]) | |
oomi_res = check_server(ooni_servers[i]) | |
results["AP"][ap_res] += 1 | |
results["OONI"][oomi_res] += 1 | |
print(results) | |
# 00:32 UTC+4 09.05.2023 | |
# {'AP': {0: 46, 1: 498, 2: 456}, 'OONI': {0: 19, 1: 951, 2: 30}} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment