diff --git a/relay.yaml.example b/relay.yaml.example index 1a0da3d..0f7f949 100644 --- a/relay.yaml.example +++ b/relay.yaml.example @@ -20,4 +20,5 @@ ap: whitelist_enabled: false whitelist: - 'good-instance.example.com' - - 'another.good-instance.example.com' \ No newline at end of file + - 'another.good-instance.example.com' + block_relays: false diff --git a/relay/__init__.py b/relay/__init__.py index 0d9a9e5..cad19ce 100644 --- a/relay/__init__.py +++ b/relay/__init__.py @@ -23,6 +23,7 @@ def load_config(): 'port': int(yaml_file.get('port', 8080)), 'note': yaml_file.get('note', 'Make a note about your instance here.'), 'ap': { + 'block_relays': yaml_file['ap'].get('block_relays', False), 'blocked_instances': yaml_file['ap'].get('blocked_instances', []), 'host': yaml_file['ap'].get('host', 'localhost'), 'whitelist': yaml_file['ap'].get('whitelist', []), diff --git a/relay/actor.py b/relay/actor.py index eb8c51b..b304721 100644 --- a/relay/actor.py +++ b/relay/actor.py @@ -103,6 +103,12 @@ async def push_message_to_actor(actor, message, our_key_id): logging.info('Caught %r while pushing to %r.', e, inbox) +async def fetch_nodeinfo(domain): + nodeinfo_data = await fetch_actor(f'https://{domain}/nodeinfo/2.0.json') + software = nodeinfo_data.get('software') + return software.get('name') if software else None + + async def follow_remote_actor(actor_uri): actor = await fetch_actor(actor_uri) @@ -235,6 +241,7 @@ async def handle_follow(actor, data, request): following = DATABASE.get('relay-list', []) inbox = get_actor_inbox(actor) + if urlsplit(inbox).hostname in AP_CONFIG['blocked_instances']: return @@ -294,6 +301,12 @@ async def inbox(request): data = await request.json() instance = urlsplit(data['actor']).hostname + if AP_CONFIG['block_relays']: + software = await fetch_nodeinfo(instance) + + if software and 'relay' in software.lower(): + raise aiohttp.web.HTTPUnauthorized(body='relays have been blocked', content_type='text/plain') + if 'actor' not in data or not request['validated']: raise aiohttp.web.HTTPUnauthorized(body='access denied', content_type='text/plain')