Git Product home page Git Product logo

draupnir's Introduction

Draupnir

A Matrix moderation bot. Visit #draupnir:matrix.org in your client and come say hi.

Features

Draupnir has two main functions, the first is to synchronise bans for users and servers across all of the matrix rooms that you moderate. The second is to protect your community by applying policies from community curated policy lists, for example the community moderation effort, to your rooms around the clock. This means that communities can warn and protect each other of known threats

Draupnir also includes a series of protections that can be enabled that might help you in some scenarios.

By default Draupnir includes support for user bans, redactions and server ACLs.

Some support is also provided for server administrative functions, such as reviewing abuse reports, deactivating user accounts and shutting down rooms.

Differences from Mjolnir

I offer you the ring, which was burned, laid upon the pyre of Baldr by Odin.

Draupnir started as a fork of Mjolnir, and is a continuation of Mjolnir. However, large sections of the the code base are now very distinct and much of Draupnir was rewritten into a library called the matrix-protection-suite.

The main difference from Mjolnir is that it is no longer necessary to use commands for some functions. Banning a user in a protected room from your Matrix client will cause Draupnir to show a prompt in the management room, which will offer to add the ban to a policy list1.

A demo showing a propagation prompt

You can also unban users the same way, and Draupnir will prompt you to unban them without any confusing hiccups. If you do still wish to use the ban command, please note that users and other entities that are being banned are now the first argument to the ban command. It is now also possible to provide only the entity to Draupnir and have Draupnir prompt you for the policy list and the ban reason.

A demo showing the ban command

In general, all commands have been migrated to a new interface which feature better error messages for common problems and allow admins to trace the cause of unexpected errors much more easily.

Status

The UX and code base of Draupnir is being overhauled and Draupnir is slowly moving towards a 2.0.0 release.

As Draupnir heads towards v2.0.0, releases will appear here. Until v2.0.0 there will be frequent changes to commands but all of these will be noted in the changes for that release.

For the latest stable release, see v1.87.0, the documentation for which can be found here.

Migration

Migrating from Mjolnir is straightforward and requires no manual steps, migration for your setup is likely as simple as changing your server config to pull the latest Draupnir docker image instead of a mjolnir one. Draupnir remains backwards compatible so that it is possible to try Draupnir and still have the option to switch back to Mjolnir.

Any problems with migration should be reported to our support room.

Setting up

See the setup documentation for first-time setup documentation.

See the configuration sample with documentation for detailed information about Draupnir's configuration.

See the synapse module documentation for information on how to setup Draupnir's accompanying Synapse Module.

Quickstart guide

After your bot is up and running, you'll want to run a couple commands to get everything set up:

  1. !draupnir list create coc code-of-conduct-ban-list - This will create a new ban list with the shortcode coc and an alias of #code-of-conduct-ban-list:example.org. You will be invited to the room it creates automatically where you can change settings such as the visibility of the room.
  2. !draupnir default coc - This sets the default ban list to the list we just created to help with the ban commands later on.
  3. Review the Moderator's Guide.
  4. Review !draupnir help to see what else the bot can do.

Enabling readable abuse reports

Since version 1.2, Draupnir offers the ability to replace the Matrix endpoint used to report abuse and display it into a room, instead of requiring you to request this data from an admin API.

This requires two configuration steps:

  1. In your Draupnir configuration file, typically /etc/draupnir/config/production.yaml, copy and paste the web section from default.yaml, if you don't have it yet (it appears with version 1.20) and set enabled: true for both web and abuseReporting.
  2. Setup a reverse proxy that will redirect requests from ^/_matrix/client/(r0|v3)/rooms/([^/]*)/report/(.*)$ to http://host:port/api/1/report/$2/$3, where host is the host where you run Draupnir, and port is the port you configured in production.yaml. For an example nginx configuration, see test/nginx.conf. It's the confirmation we use during runtime testing.

Security note

This mechanism can extract some information from unencrypted rooms. We have taken precautions to ensure that this cannot be abused: the only case in which this feature will publish information from room foo is:

  1. If it is used by a member of room foo; AND
  2. If said member did witness the event; AND
  3. If the event was unencrypted; AND
  4. If the event was not redacted/removed/...

Essentially, this is a more restricted variant of the Admin APIs available on homeservers.

However, if you are uncomfortable with this, please do not activate this feature. Also, you should probably setup your production.yaml to ensure that the web server can only receive requests from your reverse proxy (e.g. localhost).

Contributing & Opening Issues

Draupnir wants to be yours as much as it is ours. Please see or contributing document, but do not worry too much about following the guidance to the letter. And keep that in mind throughout.

Footnotes

  1. Yes, i know they don't align horizontally, you are welcome to suggest how this should be fixed.

draupnir's People

Contributors

alch-emi avatar avdb13 avatar clokep avatar cremesk avatar dbkr avatar dependabot[bot] avatar fsg-cat avatar gnuxie avatar grahamc avatar half-shot avatar jae1911 avatar jaywink avatar jesopo avatar jojosch avatar jokergermany avatar jryans avatar julianfoad avatar mahdi1234 avatar maranda avatar mikaela avatar mtrnord avatar neilmiddleton avatar no-realm avatar pre-commit-ci[bot] avatar progval avatar reivilibre avatar shadowjonathan avatar thearcanebrony avatar turt2live avatar yoric avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

draupnir's Issues

Keywords interacting badly with prompt-for-accept

If you use !mjolnir unban @whoever:wherever --true then --true is given to the command executor as the policy list rather than the result of the prompt. As an aside, i don't think we need to use --true with unban anyway?

See the screenshot in #201 for an example of this.

The dependence on client formatting for user mentions.

The behaviour of clients formatting mention pills is making the bot unusable to some users, who don't have the knowledge to distinguish between a displayname, pill, mxid. So they become very confused and frustrated.

For example schildichat and element both format mention pills (ie [Meow (Backup)](@meow:example.com)) in the body by just printing their displayname.

  "content": {
    "body": "!ban Meow (Backup) coc",
    "format": "org.matrix.custom.html",
    "formatted_body": "!ban <a href=\"https://matrix.to/#/@meow:example.com\">Meow (Backup)</a> coc",
    "msgtype": "m.text"
  }

This is actually behaviour that is encouraged by the specification (not mandated), which as of v1.8 states:

When linking to users, use the user’s potentially ambiguous display name for the anchor’s text. If the user does not have a display name, use the user’s ID.

The text component of the anchor should be used in the event’s body where the link would normally be represented, as shown in the example above.

Unfortunately, this makes it impossible for a bot to parse. A bot cannot safely resolve a displayname back to an MXID even if it were possible to parse the displayname in the first place. So it is unclear how we should proceed.

Depending on intentional mentions doesn't fix this problem either, since we still can't tell where in the message the mentions are.


Additionally we see that the behaviour for the room is the opposite

When linking to rooms, use the canonical alias for the room. If the room does not have a canonical alias, prefer one of the aliases listed on the room. If no alias can be found, fall back to the room ID. In all cases, use the alias/room ID being linked to as the anchor’s text.

Instead of printing the title of the room, clients are encouraged to print the room ID or alias.

So we can actually use this.

  "content": {
    "body": "!ban @meow:matrix.org #policy-list:example.org  ",
    "format": "org.matrix.custom.html",
    "formatted_body": "!ban @meow:example.org <a href=\"https://matrix.to/#/#policy-list:example.org\">#policy-list:example.org</a>",
    "msgtype": "m.text"
  }

Can add trusted MXID twice

using https://github.com/spantaleev/matrix-docker-ansible-deploy/tree/a573619330767085af220715e66840d01a71bed5

  1. create coordination room
  2. draupnir has PL = 0
  3. !draupnir config add TrustedReporters.mxids @trusteduser:example.com
  4. Draupnir says Failed to set setting: M_FORBIDDEN: You don't have permission to post that to the room. user_level (0) < send_level (50) - it is unclear who "You" is. This message could be improved
  5. repeat 3.
  6. check !draupnir config get TrustedReporters
  7. User is now doubly trusted: TrustedReporters.mxids: @trusteduser:example.com,@trusteduser:example.com

One issue seems to be missing documentation around draupnir being able to write state to the coordination room. That includes downstreams such as https://docs.draupnir.midnightthoughts.space (@MTRNord) and https://github.com/spantaleev/matrix-docker-ansible-deploy.

Another issue would be the dupe check/constraint on the TrustedReporters.mxids.

Member updates are sometimes lost

This came up in d4all and I am not sure what exactly caused it. It might have been Synapse omitting it or draupnir not properly updating it's cache.

Specifically it didn't recognise it was admin even after reload/restart.

AppService intent management

Originally matrix-org/mjolnir#412

There should be some way to emulate a syncing matrix-bot-sdk client with a matrix-appservice-bridge MatrixIntent. This should preferably be implemented as something that can be contributed to matrix-appservice-bridge or as another package.

MTRNord's TODO/Wishlist

(This is an informal list of things I want to work on, or I am working on. Hence, a grouped Issue. Feel free to extract tasks and work on them, though. Tick means work is happening already.)

  • Yara Rules (#139)
  • MSC1929 (#150)
  • Updating the rest of the commands to the new system
  • Updating the synapse module
  • bot-sdk crypto (#145)
  • Adding the policy list system to protections
  • Extending the documentation especially for protections
  • Improving tests
  • Improving code quality where sensible

The legacy of `ErrorCache`: What if there are situations where errors persist?

A remaining unmitigated reason for why ErrorCache was added was because if Mjolnir had been offline and is unable to ban a bunch of new members when it comes back up (receiving lots of join events from sync) it will spam the exact errors for every member event). The management room also reports the errors because Draupnir forcibly verifies permissions at startup and performs a full sync.

This problem really is "find some way to classify whether these errors are the same errors sorts of errors as before, ie is it the same problem and do i already know about it?"
We could be lucky and this is a problem people have to solve all the time and is well documented.

Follow up from #85

Feature Request: Integrated Man style help functionality.

Todays help command in upstream atleast only gives out a massive text block with little information.

It would be better to if not replace this whole function extend it where you can invoke help command and get documentation for that command. For example if you invoke it for ban you could get told about the fact you can target servers for ACL bans and their implecations and target users and the other relevant documentation. The idea is that it would give you access to all the information you might want but do it on matrix instead of having to push you to support channels or online docs.

[chore] migrate to eslint

(This might be a good item for new contributors to tackle.)

Draupnir needs eslint applied and any issues it rustles up should be resolved. Going forward all new code should probably pass the linter, confirming existing code may take longer.

Knocked and invited members will not be banned by Draupnir

Currently Draupnir configurations are encouraged to use /joined_members (via fasterMembershipChecks) to check the room members before applying bans to a room. This means that invited users and knocked users will not be banned for the majority of deployments. They can choose to rely on a query to the room state by disabling fasterMembershipChecks, but it can come at a great performance cost for large rooms (in the region of a couple of seconds all the way to thirty depending on the size of the room and deployment setup of both Draupnir and Synapse). This has been a neglected issue for some time, but has become more important and will remain important as more rooms move to using a knock policy. As any number of users can knock on a room and appear in the members list to be reviewed by moderators with their chosen display name and avatar.

A script has been created to help guage the response times for each method of fetching room members. Would be interesting to see other people's results or improvements to the test.

Include the last message(s) of the banned person, when not banned by draupnir

We get in our control room this message:

The user was banned in <room-id/room-alias> by for .
Would you like to add the ban to a policy list?

This don't really help me, because i only set someone on a ban list, when I am sure its a severe thing.
e.G. As a room admin I can be more strict then when this would have effects for hundreds of rooms.
=> I don't do anything.

Would be cool if the last message(s) would be send with the report
Design Idea:

  • perhaps as a thread
  • make it configurable how many messages should be included

Add a propagation prompt for redactions

It makes sense that redacting a message from a user should offer a prompt to do so for all rooms. This should really require an extra confirmation prompt so it's not used accidentally. E.g. Redacting an active user's message because it didn't have a cw or something, getting the prompt and another moderator clicking on it.

Be able to search in the ban reason

Not a Issue with a high priority for me.
It's a pitty that you can't search in a ban-list-room.

I like the !mjolnir rules matching command where you can search if room/server/person is already banned.

Sometimes it could be handy beeing able to search in the ban reason, too.
(Yes it looks like I am one of the seldom people who make custom ban reasons^^)

Example:
Sometimes you have person who create multiple accounts and we ban them with a comment like "alternative account of "
If I see a person again and think: Wasn't this the person who made several accounts?

Check when redactions are applied

mahdi has reported that users aren't being redacted automatically until draupnir is manually synced with the sync command. in their setup, server ACL is disabled. There is a queue that users get added to to be redacted once all rooms have been synced. I suspect that this queue is not being popped for some reason when membership changes force a sync within a single room

Support Node 20 for building

Hi! It appears Draupnir does not support Node 20 for building as trying to run yarn install on a host with Node 20 installed errors with:

$ yarn install
yarn install v1.22.19
[1/5] Validating package.json...
[2/5] Resolving packages...
[3/5] Fetching packages...
error [email protected]: The engine "node" is incompatible with this module. Expected version ">=14 <=18". Got "20.5.0"
error Found incompatible module.
info Visit https://yarnpkg.com/en/docs/cli/install for documentation about this command.

matrix-appservice-bridge in Draupnir's package.json, which uses matrix-appservice, is on 8.1.1 even though the latest version is 9.0.1 (https://github.com/matrix-org/matrix-appservice-bridge/releases/latest) which does add support for Node 20 and drops Node 16 support which Draupnir also recently did: matrix-org/matrix-appservice-bridge@d5ab312

I'm not sure how much needs to be done to make Node 20 work, but I was able to just update matrix-appservice-bridge in my package.json and it seems to work?

Constructed server ACLs collapsed

"Constructed server ACL:" message can be very long (hundreds of ACLs), it would add to readability of control room if it was collapsed by default like help command does.

Collapsey boxes for the help command

Can the top level help command gain collapsey boxes per generic section so that it doesn't fill scroll history on mobile with 3-4 pages of commands?

"You don't have permission to post that to the room. user_level (50) < send_level (99)" is not shown in chat

When trying to add a rule without permission (for example a list where normal rules are allowed but ACLs are not for the bot) the message:

There was an unexpected error when processing this command:
Unknown Unexpected Error
Details can be found by providing the reference 0c250e35-ed81-4b12-ba04-dd1167d183bfto an administrator.

is shown. Instead, it probably makes sense to just say that the bot has no permission to add this rule to the list.

Draupnir fails to start up at all when can't join a policy list or protected room

PolicyListManager.start() hard-fails and prevents Draupnir start-up, when it tries to join each watched and protected room, if it fails to join any of the rooms.

I understand this is by design, in its basic form: because we don't want Draupnir taking drastic actions (like banning) based on missing info.

This happened to me when I thought I'll just delete this unwanted empty policy-list room in synadm but it was still listed in the bot's account data.

In the management room I got only the generic message, "‼ | Startup failed due to error - see console". (As I'm running it as a developer I can see the console logs, but I'm thinking someone other than the developer/installer/sysadmin will run into this sooner or later.)

Work-around:

  • manually edit the bot's matrix account data to remove the references to the nonexistent room. (In org.matrix.mjolnir.watched_lists and/or org.matrix.mjolnir.protected_rooms.)

Desired behaviour (minimal):

  • Log a more specific diagnostic in the management room.

Desired behaviour (optimal, "stretch goal"):

  • start-up continues, recording the failure states;
  • Draupnir is put into "dry-run" mode as we don't want it taking actions based on missing info;
  • the failure to join one or more rooms is noted and made clear to the moderator (in the admin room);
  • moderator is able to use normal Draupnir commands to see which room(s) it failed to join, to delete those room(s) from its watching/protecting lists, and/or add replacement room(s);
  • moderator is able to tell Draupnir to check everything is OK now and switch out of "dry-run" mode.

I acknowledge the latter may be too big, too much work to take on at this stage, but wanted to write it down anyway.

Prompt for accept and interaction.

  • Can we allow the defaults for commands to be configurable?
  • If there is only one suggestion, can it be offered as a default?
  • Can we allow the prompt flows to be configurable? e.g. confirm default VS just filling in the a default silently
  • For the suggestion lists, should we use emoji or just plain numbers for reaction keys?

onlookers: Do not take eyes off the prize, which presentation types + commands being specified in the Matrix spec NOT gimmicks to enable interaction. The major benefit of having presentation types + commands being specified is that it allows for most prompts and interaction to take place within the client without needing to for a trip to the bot and back.

Channel keeps getting set to invite only.

We deploy Draupnir through matrix-docker-ansible-deploy, migrated from a previous install of Mjolnir.

Current version: v1.83.0

One of the protected channels (and only one) keeps getting set to private from time to time.

Example event:

{
  "content": {
    "join_rule": "invite"
  },
  "origin_server_ts": 1692574292625,
  "room_id": "!aPqEsAdWuysydZNCic:matrix.org",
  "sender": "@nickcalyx:matrix.org",
  "state_key": "",
  "type": "m.room.join_rules",
  "unsigned": {
    "replaces_state": "$xbLTAhmv9EXBxYgs7w-zdAtEfI2fU9bq1iIX3zQqw-A",
    "prev_content": {
      "join_rule": "invite"
    },
    "prev_sender": "@bot.mjolnir:calyx.dev",
    "age": 45597433
  },
  "event_id": "$YGWMm0WXP3-aV11wMP9egt6Z2Ww9Q6egaIQYqXk4Y-I",
  "user_id": "@nickcalyx:matrix.org",
  "age": 45597433,
  "replaces_state": "$xbLTAhmv9EXBxYgs7w-zdAtEfI2fU9bq1iIX3zQqw-A",
  "prev_content": {
    "join_rule": "invite"
  }
}

The thing to note here is prev_sender and prev_content, where it shows the bot setting the channel as invite only.

We've set it to public again after this, but from time to time we find that it gets set to private, and we see a similar event like the above.

The JoinWaveShortCircuit protection has been disabled for a while. It was briefly enabled a long time ago. Mentioned because that's the only place in the code here where I see join_rules being touched.

redactions should.be checked at the end of every sync

currently when a redact command or policy matching.redact reasons is issued, draupnir checks the most.recent messages sent to all rooms for.that user, and not all.users who have been marked for redaction previously. When it could redact all marked users

feature req: way to disable warnings about lack of ACL permission

We have a bunch of rooms where draupnir doesn't have permission to set ACLs, and we don't need it to do that. It would be nice if we could disable the spam about it that happens at startup and when setting bans.

Disabling the ACL feature entirely would also work for us, but wouldn't support use cases where people want ACLs but only in certain rooms.

Somewhat related: #57

redactions should be a policy

getting reasons for automatically redact for reasons configured is silly, there should just be a policy for redacting recent or new messages. Also even if we donmt have ways to manage who.you trust to do.this yet, the situation.is already that someone.can guess your automatic redact reasons if you trust them to follow.their list

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.