Add config flag for ACL Allow IP Literals.

This is bot wide and not exposed in the AS subset of the config because this patch is lazy. Its a simple fix to add to the AS subset later if demand materialises.
This commit is contained in:
Catalan Lover
2026-08-05 12:05:59 +02:00
parent 1c9ba49260
commit fbfef44944
7 changed files with 42 additions and 8 deletions
+5
View File
@@ -0,0 +1,5 @@
---
"draupnir": minor
---
Add the ability to change if ACLs should allow ip literals.
+6
View File
@@ -0,0 +1,6 @@
---
"@the-draupnir-project/matrix-protection-suite": minor
---
Expose ability to configure if ACLs should allow IP literals. Defaults to false
as before.
@@ -145,6 +145,7 @@ describeCapabilityContextGlue<
return capabilityProvider.factory(protectionDescription, {
stateEventSender: draupnir.clientPlatform.toRoomStateEventSender(),
protectedRoomsSet: draupnir.protectedRoomsSet,
allowIpLiterals: draupnir.config.serverAclAllowIpLiterals,
});
},
});
@@ -161,6 +162,7 @@ describeCapabilityContextGlue<
): Capability {
return capabilityProvider.factory(protectionDescription, {
protectedRoomsSet: draupnir.protectedRoomsSet,
allowIpLiterals: draupnir.config.serverAclAllowIpLiterals,
} as ServerACLSynchronisationCapabilityContext);
},
});
+3
View File
@@ -94,6 +94,8 @@ export interface IConfig {
logMutedModules: string[];
verifyPermissionsOnStartup: boolean;
disableServerACL: boolean;
/** Whether to allow ip literals in produced server ACLs (m.room.server_acl.allow_ip_literals) */
serverAclAllowIpLiterals: boolean;
noop: boolean;
automaticallyRedactForReasons: string[]; // case-insensitive globs
protectAllJoinedRooms: boolean;
@@ -217,6 +219,7 @@ const defaultConfig: IConfig = {
verifyPermissionsOnStartup: true,
noop: false,
disableServerACL: false,
serverAclAllowIpLiterals: false,
automaticallyRedactForReasons: ["spam", "advertising"],
protectAllJoinedRooms: false,
backgroundDelayMS: 500,
+5
View File
@@ -88,6 +88,11 @@ noop: false
# DO NOT change this to `true` unless you are very confident that you know what you are doing.
disableServerACL: false
# Whether or not Draupnir should allow IP literals in `m.room.server_acl` events.
# This is a security risk as it allows for much easier spam by just using a ton of throwaway IP addresses.
# Dont enable this unless you know what you are doing and have a very good reason to do so.
serverAclAllowIpLiterals: false
# A case-insensitive list of ban reasons to have the bot also automatically redact the user's messages for.
#
# If the bot sees you ban a user with a reason that is an (exact case-insensitive) match to this list,
@@ -42,7 +42,8 @@ class ServerACLQueue {
public constructor(
private readonly stateEventSender: RoomStateEventSender,
private readonly serverName: StringServerName,
private readonly protectedRoomsSet: ProtectedRoomsSet
private readonly protectedRoomsSet: ProtectedRoomsSet,
private readonly allowIpLiterals: boolean
) {
// nothing to do.
}
@@ -51,7 +52,11 @@ class ServerACLQueue {
roomID: StringRoomID,
projection: ServerBanIntentProjection
): Promise<Result<boolean>> {
const ACL = compileServerACL(this.serverName, projection.currentNode);
const ACL = compileServerACL(
this.serverName,
projection.currentNode,
this.allowIpLiterals
);
const stateRevision =
this.protectedRoomsSet.setRoomState.getRevision(roomID);
if (stateRevision === undefined) {
@@ -131,9 +136,12 @@ class ServerACLQueue {
export function compileServerACL(
ourServerName: StringServerName,
projectionNode: ServerBanIntentProjectionNode
projectionNode: ServerBanIntentProjectionNode,
allowIpLiterals = false
): ServerACLBuilder {
const builder = new ServerACLBuilder(ourServerName).denyIpAddresses();
const builder = allowIpLiterals
? new ServerACLBuilder(ourServerName).allowIpAddresses()
: new ServerACLBuilder(ourServerName).denyIpAddresses();
builder.allowServer("*");
for (const serverName of projectionNode.deny) {
builder.denyServer(serverName);
@@ -151,12 +159,14 @@ export class ServerACLSynchronisationCapability
public constructor(
stateEventSender: RoomStateEventSender,
private readonly protectedRoomsSet: ProtectedRoomsSet
private readonly protectedRoomsSet: ProtectedRoomsSet,
allowIpLiterals = false
) {
this.queue = new ServerACLQueue(
stateEventSender,
userServerName(this.protectedRoomsSet.userID),
protectedRoomsSet
protectedRoomsSet,
allowIpLiterals
);
}
@@ -207,6 +217,7 @@ export class ServerACLSynchronisationCapability
export type ServerACLSynchronisationCapabilityContext = {
stateEventSender: RoomStateEventSender;
protectedRoomsSet: ProtectedRoomsSet;
allowIpLiterals?: boolean;
};
describeCapabilityProvider({
@@ -220,7 +231,8 @@ describeCapabilityProvider({
) {
return new ServerACLSynchronisationCapability(
context.stateEventSender,
context.protectedRoomsSet
context.protectedRoomsSet,
context.allowIpLiterals ?? false
);
},
});
@@ -35,7 +35,8 @@ export class SimulatedServerBanSynchronisationCapability
public constructor(private readonly protectedRoomsSet: ProtectedRoomsSet) {
this.simulatedCapability = new ServerACLSynchronisationCapability(
FakeStateSender,
this.protectedRoomsSet
this.protectedRoomsSet,
false
);
this.outcomeFromIntentInRoom =
this.simulatedCapability.outcomeFromIntentInRoom.bind(