add redlight alert bot, to send alerts to redlight client administrators
This commit is contained in:
parent
f1978e09c8
commit
b0cfe7dd0a
38
redlight_bot.py
Normal file
38
redlight_bot.py
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
import logging
|
||||||
|
import requests
|
||||||
|
|
||||||
|
# Setting up logging:
|
||||||
|
file_handler = logging.FileHandler('/var/log/matrix-synapse/redlight.log')
|
||||||
|
file_handler.setLevel(logging.INFO)
|
||||||
|
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
|
||||||
|
file_handler.setFormatter(formatter)
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
logger.setLevel(logging.INFO)
|
||||||
|
logger.addHandler(file_handler)
|
||||||
|
|
||||||
|
# Prevent logger's messages from propagating to the root logger.
|
||||||
|
logger.propagate = False
|
||||||
|
|
||||||
|
class RedlightBot:
|
||||||
|
def __init__(self, homeserver, access_token):
|
||||||
|
self.homeserver = homeserver
|
||||||
|
self.access_token = access_token
|
||||||
|
self.headers = {
|
||||||
|
"Authorization": f"Bearer {self.access_token}",
|
||||||
|
"Content-Type": "application/json"
|
||||||
|
}
|
||||||
|
|
||||||
|
def send_alert_message(self, room_id, message):
|
||||||
|
endpoint = f"{self.homeserver}/_matrix/client/r0/rooms/{room_id}/send/m.room.message"
|
||||||
|
payload = {
|
||||||
|
"msgtype": "m.text",
|
||||||
|
"body": message
|
||||||
|
}
|
||||||
|
response = requests.post(endpoint, headers=self.headers, json=payload)
|
||||||
|
|
||||||
|
# Check if the request was successful
|
||||||
|
if response.status_code == 200:
|
||||||
|
logger.info("Alert message sent successfully!")
|
||||||
|
else:
|
||||||
|
logger.info(f"Failed to send allert message. Status code: {response.status_code}, Response: {response.text}")
|
@ -1,6 +1,7 @@
|
|||||||
import logging
|
import logging
|
||||||
import hashlib
|
import hashlib
|
||||||
import json
|
import json
|
||||||
|
import asyncio
|
||||||
from typing import Union
|
from typing import Union
|
||||||
from synapse.module_api import ModuleApi, NOT_SPAM
|
from synapse.module_api import ModuleApi, NOT_SPAM
|
||||||
from synapse.api.errors import AuthError
|
from synapse.api.errors import AuthError
|
||||||
@ -11,6 +12,7 @@ from twisted.internet import reactor
|
|||||||
from twisted.internet import defer
|
from twisted.internet import defer
|
||||||
from twisted.web.iweb import IBodyProducer
|
from twisted.web.iweb import IBodyProducer
|
||||||
from zope.interface import implementer
|
from zope.interface import implementer
|
||||||
|
from redlight_bot import RedlightBot
|
||||||
|
|
||||||
# Setting up logging:
|
# Setting up logging:
|
||||||
file_handler = logging.FileHandler('/var/log/matrix-synapse/redlight.log')
|
file_handler = logging.FileHandler('/var/log/matrix-synapse/redlight.log')
|
||||||
@ -46,12 +48,23 @@ class _JsonProducer:
|
|||||||
class RedlightClientModule:
|
class RedlightClientModule:
|
||||||
def __init__(self, config: dict, api: ModuleApi):
|
def __init__(self, config: dict, api: ModuleApi):
|
||||||
self._api = api
|
self._api = api
|
||||||
# URL where we'll check if the room/user combination is allowed.
|
# Your homeserver's URL
|
||||||
self._redlight_url = config.get("redlight_url", "http://127.0.0.1:8008/_matrix/loj/v1/abuse_lookup")
|
self._homeserver_url = "https://" + config.get("homeserver_url", "127.0.0.1:8008")
|
||||||
|
# The API token of your redlight bot user
|
||||||
|
self._redlight_bot_user = config.get("redlight_bot_token", "")
|
||||||
|
# The alert room your redlight bot will post too
|
||||||
|
self._redlight_alert_room = config.get("redlight_alert_room", "")
|
||||||
|
# Redlight server endpoint, where we'll check if the room/user combination is allowed.
|
||||||
|
self._redlight_endpoint = "https://" + config.get("redlight_server", "127.0.0.1:8008") + "/_matrix/loj/v1/abuse_lookup"
|
||||||
self._agent = Agent(reactor) # Twisted agent for making HTTP requests.
|
self._agent = Agent(reactor) # Twisted agent for making HTTP requests.
|
||||||
|
|
||||||
|
# Create an instance of the RedlightBot
|
||||||
|
self.bot = RedlightBot(self._homeserver_url, self._redlight_bot_user) # Adjust the homeserver and token as required
|
||||||
|
|
||||||
logger.info("RedLightClientModule initialized.")
|
logger.info("RedLightClientModule initialized.")
|
||||||
logger.info(f"Redlight Server URL set to: {self._redlight_url}")
|
logger.info(f"Redlight bot user token: {self._redlight_bot_user}")
|
||||||
|
logger.info(f"Redlight alert room: {self._redlight_alert_room}")
|
||||||
|
logger.info(f"Redlight server endpoint set to: {self._redlight_endpoint}")
|
||||||
|
|
||||||
# Register the user_may_join_room function to be called by Synapse before a user joins a room.
|
# Register the user_may_join_room function to be called by Synapse before a user joins a room.
|
||||||
api.register_spam_checker_callbacks(
|
api.register_spam_checker_callbacks(
|
||||||
@ -84,7 +97,7 @@ class RedlightClientModule:
|
|||||||
# Make the HTTP request to our redlight server.
|
# Make the HTTP request to our redlight server.
|
||||||
response = await self._agent.request(
|
response = await self._agent.request(
|
||||||
b"PUT",
|
b"PUT",
|
||||||
self._redlight_url.encode(),
|
self._redlight_endpoint.encode(),
|
||||||
Headers({'Content-Type': [b'application/json']}),
|
Headers({'Content-Type': [b'application/json']}),
|
||||||
body
|
body
|
||||||
)
|
)
|
||||||
@ -105,7 +118,13 @@ class RedlightClientModule:
|
|||||||
# Handle the response based on its HTTP status code.
|
# Handle the response based on its HTTP status code.
|
||||||
if response.code == 200:
|
if response.code == 200:
|
||||||
logger.warn(f"User {user} not allowed to join room {room}.")
|
logger.warn(f"User {user} not allowed to join room {room}.")
|
||||||
raise AuthError(403, "User not allowed to join this room.")
|
# Create the alert message
|
||||||
|
alert_message = f"WARNING: Incident detected! User {user} was attempting to access this restricted room: {room}"
|
||||||
|
# Start the synchronous send_alert_message method in a thread but don't await it
|
||||||
|
loop = asyncio.get_event_loop()
|
||||||
|
loop.run_in_executor(None, self.bot.send_alert_message, self._redlight_alert_room, alert_message)
|
||||||
|
# Throw a 403 error that the user will see
|
||||||
|
raise AuthError(403, "PERMISSION DENIED - This room violates server policy.")
|
||||||
elif response.code == 204:
|
elif response.code == 204:
|
||||||
logger.info(f"User {user} allowed to join room {room}.")
|
logger.info(f"User {user} allowed to join room {room}.")
|
||||||
return NOT_SPAM # Allow the user to join.
|
return NOT_SPAM # Allow the user to join.
|
||||||
|
@ -117,4 +117,6 @@ More then 10 join requests in a minute might seem suspicious... (What about bots
|
|||||||
|
|
||||||
- What other methods (besides IP) could be used to restrict requests from redlight client homeservers?
|
- What other methods (besides IP) could be used to restrict requests from redlight client homeservers?
|
||||||
|
|
||||||
|
API tokens, certificate-based authentication, or domain whitelisting?
|
||||||
|
|
||||||
- What other methods could be used to secure the source list and prevent interception/leaking?
|
- What other methods could be used to secure the source list and prevent interception/leaking?
|
||||||
|
Loading…
Reference in New Issue
Block a user