migrate mjolnir to draupnir
All checks were successful
/ build (pull_request) Successful in 50s
/ Ansible Lint (pull_request) Successful in 2m53s
/ cleanup-staging (pull_request) Successful in 37s
/ build (push) Successful in 56s
/ Ansible Lint (push) Successful in 3m8s

This commit is contained in:
lilly 2026-09-06 14:40:42 +02:00
commit f7c3e2146d
Signed by: lilly
SSH key fingerprint: SHA256:y9T5GFw2A20WVklhetIxG1+kcg/Ce0shnQmbu1LQ37g
12 changed files with 60 additions and 59 deletions

View file

@ -37,7 +37,7 @@ keys:
- &host_ntfy_ansible_pull_age_key age1dkecypmfuj0tcm2cz8vnvq5drpu2ddhgnfkzxvscs7m4e79gpseqyhr9pg
- &host_spaceapiccc_ansible_pull_age_key age1mdtnk78aeqnwqadjqje5pfha04wu92d3ecchyqajjmy434kwq98qksq2wa
- &host_acmedns_ansible_pull_age_key age16pxqxdj25xz6w200sf8duc62vyk0xkhzc7y63nyhg29sm077vp8qy4sywv
- &host_mjolnir_ansible_pull_age_key age1hv7m3xypesdfm0dfzwgctde8v307g9xaunnfu2687y0lagcs5q7s3eg0kj
- &host_draupnir_ansible_pull_age_key age1hv7m3xypesdfm0dfzwgctde8v307g9xaunnfu2687y0lagcs5q7s3eg0kj
- &host_diday_staging_runner_ansible_pull_age_key age1522f3qzddm82w63j7ajdkr0khvced6ht7tzp3grvp0j3hewtvesssr5kpf
- &host_auth_dns_ansible_pull_age_key age18zgt4y2sd75hxnpe333zz39048ctxpr0q8a3uqh3jajjkyawsdrq8yg5ve
- &host_forgejo_runner_ansible_pull_age_key age1az0k6cadssk6r8qcqxfr8cyu5mndy59pwt8yqq6w065ew6au4ezsmg2vkf
@ -201,12 +201,12 @@ creation_rules:
*admin_gpg_keys
age:
- *host_spaceapiccc_ansible_pull_age_key
- path_regex: "inventories/chaosknoten/host_vars/mjolnir\\.sops\\..+"
- path_regex: "inventories/chaosknoten/host_vars/draupnir\\.sops\\..+"
key_groups:
- pgp:
*admin_gpg_keys
age:
- *host_mjolnir_ansible_pull_age_key
- *host_draupnir_ansible_pull_age_key
- path_regex: "inventories/chaosknoten/host_vars/diday-staging-runner\\.sops\\..+"
key_groups:
- pgp:

View file

@ -23,7 +23,7 @@ During moderation, we adhere to the following principles:
## How It Works
The bot account `@moderation:hamburg.ccc.de` (Mjolnir) maintains various internal lists of rules that are applied in so-called "Protected Rooms".
The bot account `@moderation:hamburg.ccc.de` (Draupnir) maintains various internal lists of rules that are applied in so-called "Protected Rooms".
These can include, for example, user bans or entire server bans.
Additionally, certain automatic monitoring measures (so-called "protections") apply in these rooms, which trigger a configured action if violated.
For example, a user is not allowed to tag too many other users in a single message, as this is considered spam and results in a kick.

View file

@ -40,14 +40,14 @@ We have now added the moderation bot to the room but this is not enough.
The bot needs to be told explicitly which rooms it should protect and the newly created one therefore needs to be added to that list.
First, note down the *Internal Room ID* which can be found in the new Rooms settings under the *Advanced* tab.
Then enter the *CCCHH Moderation Management* room and write the follogin mjolnir command while substituting the copied room id:
Then enter the *CCCHH Moderation Management* room and write the following draupnir command while substituting the copied room id:
```
!mjolnir rooms add <room-id>
!draupnir rooms add <room-id>
```
## Closing Up
You should now have a new Matrix Room under moderation protection.
To verify that everything was done correctly, you can enter `!mjolnir verify` in the *CCCHH Moderation Management* room and observe that the moderation bot does not give you an error.
To verify that everything was done correctly, you can enter `!draupnir verify` in the *CCCHH Moderation Management* room and observe that the moderation bot does not give you an error.

View file

@ -18,7 +18,7 @@ All bot actions are triggered through the *CCCHH Moderation Management* room.
## Banning a User
```
!mjolnir ban general user <glob> <reason>
!draupnir ban general user <glob> <reason>
```
- `<glob>` can be a user ID (e.g. `@example:matrix.org`) but also more sophisticated. Be careful when using actual glob syntax as whole servers can be banned even if just a single user is the intended target.
@ -27,7 +27,7 @@ All bot actions are triggered through the *CCCHH Moderation Management* room.
## Banning a Server
```
!mjolnir ban server <glob> <reason>
!draupnir ban server <glob> <reason>
```
- `<glob>` can be used to ban subdomains of a domain too, e.g. `*.example.com`. If used, an additional `--force` is required after the whole command.
@ -37,7 +37,7 @@ All bot actions are triggered through the *CCCHH Moderation Management* room.
## Redacting a single Message
```
!mjolnir redact <permalink>
!draupnir redact <permalink>
```
- `<permalink>` is **not** the message ID but the actual *https://matrix.to/#blablabla* link that can be retrieved with most clients through a *Share* or *Copy link to Message* button on an individual message.
@ -45,7 +45,7 @@ All bot actions are triggered through the *CCCHH Moderation Management* room.
## Redacting all Messages of a User
```
!mjolnir redact <user-id>
!draupnir redact <user-id>
```
- `user-id` the Matrix-ID of the user of whom all messages in all rooms should be redacted (e.g. `@bla:example.com`).

View file

@ -1,9 +1,8 @@
ansible_pull__age_private_key: ENC[AES256_GCM,data:mUKh1aFJ8hn0GqfWQw5pWSAj9qaj5wH/NrHhEp9sdOYfNCBPp1dfYIDTqFAnPNz2SLzoQ+HIuPYxSCaWNq0zS8TStBelUoEGDuE=,iv:rbVLKpUzHr2ZZsHlRZtBp9E8IX9TVAa/nJAXfnh4fJQ=,tag:wT/0Ku9yrwD9snnzMigU3g==,type:str]
secret__mjolnir_matrix_user_password: ENC[AES256_GCM,data:FDCZW5dt1HHxLDSqLi3rH5eX1Go7qKQDK9+w0q8IjpTSNFNZg91B19V4voDx+2UNv2l1OUwAngAgckEZ0mSndA==,iv:c+zW3LhoqAhuu3PWlXiyZ8r8TGgF/RnswnI+fo08EBE=,tag:lPrXolXFD+5gpoGkm4GMog==,type:str]
secret__draupnir_matrix_user_token: ENC[AES256_GCM,data:WtWZQh8Khwv4bq0U0vg2203P4PnLHNRVBTN59NqGX9PggVi2rRy3PZc=,iv:L3d+xI85IXB0DfynjQxhAjAmZ3rKLTFVWCcBcdqxzF8=,tag:qAiv4M1EbKVd+ysWhV/JIA==,type:str]
sops:
age:
- recipient: age1hv7m3xypesdfm0dfzwgctde8v307g9xaunnfu2687y0lagcs5q7s3eg0kj
enc: |
- enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB3b2MzYzFWaHJ4M3NkaDkw
cEYzVDhQSGQ4SGpJQllmZGNTUUhGSy9KZkZjCi9CY0pRVTh3SUQyK0dlckMvVGI1
@ -11,8 +10,9 @@ sops:
V09XOXY4bHBpbWxpdTNycHVwVUptdE0KsksBHnhpGmag6KZmeUjI6GzYPVvG06bw
mGhQf8hwa4m7tTtD806kVuKJ/nXhOZXFr1Gp65iWGBfT5lJk2VIayQ==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2026-02-11T01:05:26Z"
mac: ENC[AES256_GCM,data:7DdCLStFif0EhqsgthwZD50v+FPa1drUmBKUhmWw9FKtCBKmNM5LbCI5TvKGJqq8gtKiMUKpOf/pA/8qGNavfl8MdRrhm9inlkHgkwgLQwAx7/ds8uHexVBjG2gV+hMPtoNCnGRkQRHwrepz/7L6Y5L5UUhWHEUEhMuxrejzNBY=,iv:SpziMsqQ34/hAH1HkbGjqG4ZyZybcWE9Xp5xWkPADGA=,tag:eYWlsKj+OPMcpU1u1Caavg==,type:str]
recipient: age1hv7m3xypesdfm0dfzwgctde8v307g9xaunnfu2687y0lagcs5q7s3eg0kj
lastmodified: "2026-09-06T11:30:21Z"
mac: ENC[AES256_GCM,data:tTOVUVlU2BOD7Xxxmn6I6b8V+zouNgyNfet18JZKuIrAqRgag/oKadoa+lBjiH/JiCUunNueACf14wsrw5eOdpJiL1zBg8sK6kyPDrI1IRGMJWXX0x01DJSL1INNz6fKdHTA+hqI0w6lTWPiLwgTbsfyMwF+lutaJv79cANC3UU=,iv:i34JCNJHLgQwZAKGrF1dX1TZSvOnB3HqQe/BvA9HTtY=,tag:8LY0AdEtVFTVY2d0dbiuDA==,type:str]
pgp:
- created_at: "2026-05-20T02:08:45Z"
enc: |-
@ -185,4 +185,4 @@ sops:
-----END PGP MESSAGE-----
fp: 41FFAF3D519CF5C039FBD8414BCC213729AF0E49
unencrypted_suffix: _unencrypted
version: 3.11.0
version: 3.13.3

View file

@ -1,4 +1,4 @@
docker_compose__compose_file_content: "{{ lookup('ansible.builtin.file', 'resources/chaosknoten/mjolnir/docker_compose/compose.yaml') }}"
docker_compose__compose_file_content: "{{ lookup('ansible.builtin.file', 'resources/chaosknoten/draupnir/docker_compose/compose.yaml') }}"
docker_compose__configuration_files:
- name: config.yaml
content: "{{ lookup('ansible.builtin.template', 'resources/chaosknoten/mjolnir/docker_compose/config.yaml.j2') }}"
content: "{{ lookup('ansible.builtin.template', 'resources/chaosknoten/draupnir/docker_compose/config.yaml.j2') }}"

View file

@ -36,8 +36,8 @@ all:
lists:
ansible_host: lists.hamburg.ccc.de
ansible_user: chaos
mjolnir:
ansible_host: mjolnir.hosts.hamburg.ccc.de
draupnir:
ansible_host: draupnir.hosts.hamburg.ccc.de
ansible_user: chaos
ansible_ssh_common_args: -J ssh://chaos@router.hamburg.ccc.de
mumble:
@ -132,7 +132,7 @@ base_config_hosts:
sunders:
renovate:
spaceapiccc:
mjolnir:
draupnir:
auth-dns:
forgejo-runner:
forgejo-runner-external:
@ -158,7 +158,7 @@ docker_compose_hosts:
ntfy:
sunders:
spaceapiccc:
mjolnir:
draupnir:
nextcloud_hosts:
hosts:
cloud:
@ -246,7 +246,7 @@ infrastructure_authorized_keys_hosts:
sunders:
renovate:
spaceapiccc:
mjolnir:
draupnir:
auth-dns:
lists:
forgejo-runner:
@ -284,7 +284,7 @@ ansible_pull_hosts:
zammad:
ntfy:
spaceapiccc:
mjolnir:
draupnir:
auth-dns:
forgejo-runner:
forgejo-runner-external:

View file

@ -499,7 +499,8 @@ keycloak.hosts IN AAAA 2a00:14b0:42:102::6
onlyoffice.hosts IN AAAA 2a00:14b0:42:102::7
renovate.hosts IN AAAA 2a00:14b0:42:102::8
sunders.hosts IN AAAA 2a00:14b0:42:102::9
mjolnir.hosts IN AAAA 2a00:14b0:42:102::a
draupnir.hosts IN AAAA 2a00:14b0:42:102::a
mjolnir.hosts IN CNAME draupnir.hosts
netbox.hosts IN AAAA 2a00:14b0:42:102::b
tickets.hosts IN AAAA 2a00:14b0:42:102::c
zammad.hosts IN AAAA 2a00:14b0:42:102::d

View file

@ -0,0 +1,11 @@
# Links & Resources
# https://github.com/matrix-org/mjolnir/blob/main/docs/setup_docker.md
services:
draupnir:
image: ghcr.io/the-draupnir-project/draupnir:v3.1.0
command: [ "bot", "--draupnir-config", "/etc/draupnir/production.yaml" ]
restart: unless-stopped
volumes:
- ./draupnir_data:/data
- ./configs/config.yaml:/etc/draupnir/production.yaml:ro

View file

@ -0,0 +1,22 @@
# https://github.com/the-draupnir-project/Draupnir/blob/main/config/default.yaml
homeserverUrl: "https://matrix.hamburg.ccc.de"
rawHomeserverUrl: "https://matrix.hamburg.ccc.de"
accessToken: "{{ secret__draupnir_matrix_user_token }}"
dataPath: "/data/storage"
logLevel: "INFO"
recordIgnoredInvites: true
managementRoom: "#moderation-management:hamburg.ccc.de"
experimentalRustCrypto: true
automaticallyRedactForReasons:
- "spam"
- "advertising"
- "porn"
- "harassmet"
# currently not working because /_synapse is not routed via reverse proxy
pollReports: false
# this knob can turn of moderation action temporarily
noop: false

View file

@ -1,10 +0,0 @@
# Links & Resources
# https://github.com/matrix-org/mjolnir/blob/main/docs/setup_docker.md
services:
mjolnir:
image: docker.io/matrixdotorg/mjolnir:v1.12.1
restart: unless-stopped
volumes:
- ./mjolnir_data:/data
- ./configs/config.yaml:/data/config/production.yaml:ro

View file

@ -1,23 +0,0 @@
# https://github.com/matrix-org/mjolnir/blob/main/config/default.yaml
homeserverUrl: "https://matrix.hamburg.ccc.de"
rawHomeserverUrl: "https://matrix.hamburg.ccc.de"
# Mjolnir should be able to retrieve an access token itself
encryption:
use: true
username: "moderation"
password: {{ secret__mjolnir_matrix_user_password }}
dataPath: "/data/storage"
autojoinOnlyIfManager: true
recordIgnoredInvites: true
# The native encryption backend doesn't seem to support v12 rooms yet.
# https://github.com/matrix-org/mjolnir/issues/641
managementRoom: "#moderation-management-v11:hamburg.ccc.de"
forwardMentionsToManagementRoom: false
verboseLogging: false
logLevel: "INFO"
syncOnStartup: true
verifyPermissionsOnStartup: true
noop: false
fasterMembershipChecks: false
protectAllJoinedRooms: true