From f7c3e2146d9288c3224fe77df01e99c88e809076 Mon Sep 17 00:00:00 2001
From: lilly
Date: Sun, 6 Sep 2026 14:40:42 +0200
Subject: [PATCH] migrate mjolnir to draupnir
---
.sops.yaml | 6 ++---
.../matrix-moderation.md | 2 +-
docs/guides/matrix-create-room.md | 6 ++---
.../guides/matrix-taking-moderation-action.md | 8 +++----
.../{mjolnir.sops.yaml => draupnir.sops.yaml} | 12 +++++-----
.../host_vars/{mjolnir.yaml => draupnir.yaml} | 4 ++--
inventories/chaosknoten/hosts.yaml | 12 +++++-----
.../auth-dns/zones/hamburg.ccc.de.zone | 3 ++-
.../draupnir/docker_compose/compose.yaml | 11 +++++++++
.../draupnir/docker_compose/config.yaml.j2 | 22 ++++++++++++++++++
.../mjolnir/docker_compose/compose.yaml | 10 --------
.../mjolnir/docker_compose/config.yaml.j2 | 23 -------------------
12 files changed, 60 insertions(+), 59 deletions(-)
rename inventories/chaosknoten/host_vars/{mjolnir.sops.yaml => draupnir.sops.yaml} (93%)
rename inventories/chaosknoten/host_vars/{mjolnir.yaml => draupnir.yaml} (58%)
create mode 100644 resources/chaosknoten/draupnir/docker_compose/compose.yaml
create mode 100644 resources/chaosknoten/draupnir/docker_compose/config.yaml.j2
delete mode 100644 resources/chaosknoten/mjolnir/docker_compose/compose.yaml
delete mode 100644 resources/chaosknoten/mjolnir/docker_compose/config.yaml.j2
diff --git a/.sops.yaml b/.sops.yaml
index 7df285b4..52d69f21 100644
--- a/.sops.yaml
+++ b/.sops.yaml
@@ -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:
diff --git a/docs/concepts-and-configurations/matrix-moderation.md b/docs/concepts-and-configurations/matrix-moderation.md
index 159fbb49..c4a31ab2 100644
--- a/docs/concepts-and-configurations/matrix-moderation.md
+++ b/docs/concepts-and-configurations/matrix-moderation.md
@@ -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.
diff --git a/docs/guides/matrix-create-room.md b/docs/guides/matrix-create-room.md
index d43f6140..582e94c1 100644
--- a/docs/guides/matrix-create-room.md
+++ b/docs/guides/matrix-create-room.md
@@ -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
+!draupnir rooms add
```
## 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.
diff --git a/docs/guides/matrix-taking-moderation-action.md b/docs/guides/matrix-taking-moderation-action.md
index b1bf69fd..90f53657 100644
--- a/docs/guides/matrix-taking-moderation-action.md
+++ b/docs/guides/matrix-taking-moderation-action.md
@@ -18,7 +18,7 @@ All bot actions are triggered through the *CCCHH Moderation Management* room.
## Banning a User
```
-!mjolnir ban general user
+!draupnir ban general user
```
- `` 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
+!draupnir ban server
```
- `` 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
+!draupnir redact
```
- `` 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
+!draupnir redact
```
- `user-id` the Matrix-ID of the user of whom all messages in all rooms should be redacted (e.g. `@bla:example.com`).
diff --git a/inventories/chaosknoten/host_vars/mjolnir.sops.yaml b/inventories/chaosknoten/host_vars/draupnir.sops.yaml
similarity index 93%
rename from inventories/chaosknoten/host_vars/mjolnir.sops.yaml
rename to inventories/chaosknoten/host_vars/draupnir.sops.yaml
index cd0972ed..36fe2cf6 100644
--- a/inventories/chaosknoten/host_vars/mjolnir.sops.yaml
+++ b/inventories/chaosknoten/host_vars/draupnir.sops.yaml
@@ -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
diff --git a/inventories/chaosknoten/host_vars/mjolnir.yaml b/inventories/chaosknoten/host_vars/draupnir.yaml
similarity index 58%
rename from inventories/chaosknoten/host_vars/mjolnir.yaml
rename to inventories/chaosknoten/host_vars/draupnir.yaml
index 7b6001af..16e8c7d0 100644
--- a/inventories/chaosknoten/host_vars/mjolnir.yaml
+++ b/inventories/chaosknoten/host_vars/draupnir.yaml
@@ -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') }}"
diff --git a/inventories/chaosknoten/hosts.yaml b/inventories/chaosknoten/hosts.yaml
index 0c841fb6..7d641ae3 100644
--- a/inventories/chaosknoten/hosts.yaml
+++ b/inventories/chaosknoten/hosts.yaml
@@ -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:
diff --git a/resources/chaosknoten/auth-dns/zones/hamburg.ccc.de.zone b/resources/chaosknoten/auth-dns/zones/hamburg.ccc.de.zone
index 96df3215..f3512af1 100644
--- a/resources/chaosknoten/auth-dns/zones/hamburg.ccc.de.zone
+++ b/resources/chaosknoten/auth-dns/zones/hamburg.ccc.de.zone
@@ -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
diff --git a/resources/chaosknoten/draupnir/docker_compose/compose.yaml b/resources/chaosknoten/draupnir/docker_compose/compose.yaml
new file mode 100644
index 00000000..42bf8fda
--- /dev/null
+++ b/resources/chaosknoten/draupnir/docker_compose/compose.yaml
@@ -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
diff --git a/resources/chaosknoten/draupnir/docker_compose/config.yaml.j2 b/resources/chaosknoten/draupnir/docker_compose/config.yaml.j2
new file mode 100644
index 00000000..20a73959
--- /dev/null
+++ b/resources/chaosknoten/draupnir/docker_compose/config.yaml.j2
@@ -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
diff --git a/resources/chaosknoten/mjolnir/docker_compose/compose.yaml b/resources/chaosknoten/mjolnir/docker_compose/compose.yaml
deleted file mode 100644
index 963c9d98..00000000
--- a/resources/chaosknoten/mjolnir/docker_compose/compose.yaml
+++ /dev/null
@@ -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
diff --git a/resources/chaosknoten/mjolnir/docker_compose/config.yaml.j2 b/resources/chaosknoten/mjolnir/docker_compose/config.yaml.j2
deleted file mode 100644
index ff6e8fa3..00000000
--- a/resources/chaosknoten/mjolnir/docker_compose/config.yaml.j2
+++ /dev/null
@@ -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