Merge pull request #142758: Add Heisenbridge module
This commit is contained in:
commit
ae040631c9
3 changed files with 217 additions and 0 deletions
|
@ -75,6 +75,13 @@
|
||||||
<link linkend="opt-services.filebeat.enable">services.filebeat</link>.
|
<link linkend="opt-services.filebeat.enable">services.filebeat</link>.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
<link xlink:href="https://github.com/hifi/heisenbridge">heisenbridge</link>,
|
||||||
|
a bouncer-style Matrix IRC bridge. Available as
|
||||||
|
<link xlink:href="options.html#opt-services.heisenbridge.enable">services.heisenbridge</link>.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
<link xlink:href="https://github.com/ngoduykhanh/PowerDNS-Admin">PowerDNS-Admin</link>,
|
<link xlink:href="https://github.com/ngoduykhanh/PowerDNS-Admin">PowerDNS-Admin</link>,
|
||||||
|
|
|
@ -25,6 +25,8 @@ In addition to numerous new and upgraded packages, this release has the followin
|
||||||
|
|
||||||
- [filebeat](https://www.elastic.co/guide/en/beats/filebeat/current/filebeat-overview.html), a lightweight shipper for forwarding and centralizing log data. Available as [services.filebeat](#opt-services.filebeat.enable).
|
- [filebeat](https://www.elastic.co/guide/en/beats/filebeat/current/filebeat-overview.html), a lightweight shipper for forwarding and centralizing log data. Available as [services.filebeat](#opt-services.filebeat.enable).
|
||||||
|
|
||||||
|
- [heisenbridge](https://github.com/hifi/heisenbridge), a bouncer-style Matrix IRC bridge. Available as [services.heisenbridge](options.html#opt-services.heisenbridge.enable).
|
||||||
|
|
||||||
- [PowerDNS-Admin](https://github.com/ngoduykhanh/PowerDNS-Admin), a web interface for the PowerDNS server. Available at [services.powerdns-admin](options.html#opt-services.powerdns-admin.enable).
|
- [PowerDNS-Admin](https://github.com/ngoduykhanh/PowerDNS-Admin), a web interface for the PowerDNS server. Available at [services.powerdns-admin](options.html#opt-services.powerdns-admin.enable).
|
||||||
|
|
||||||
- [maddy](https://maddy.email), a composable all-in-one mail server. Available as [services.maddy](options.html#opt-services.maddy.enable).
|
- [maddy](https://maddy.email), a composable all-in-one mail server. Available as [services.maddy](options.html#opt-services.maddy.enable).
|
||||||
|
|
208
nixos/modules/services/misc/heisenbridge.nix
Normal file
208
nixos/modules/services/misc/heisenbridge.nix
Normal file
|
@ -0,0 +1,208 @@
|
||||||
|
{ config, pkgs, lib, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.services.heisenbridge;
|
||||||
|
|
||||||
|
pkg = config.services.heisenbridge.package;
|
||||||
|
bin = "${pkg}/bin/heisenbridge";
|
||||||
|
|
||||||
|
jsonType = (pkgs.formats.json { }).type;
|
||||||
|
|
||||||
|
registrationFile = "/var/lib/heisenbridge/registration.yml";
|
||||||
|
# JSON is a proper subset of YAML
|
||||||
|
bridgeConfig = builtins.toFile "heisenbridge-registration.yml" (builtins.toJSON {
|
||||||
|
id = "heisenbridge";
|
||||||
|
url = cfg.registrationUrl;
|
||||||
|
# Don't specify as_token and hs_token
|
||||||
|
rate_limited = false;
|
||||||
|
sender_localpart = "heisenbridge";
|
||||||
|
namespaces = cfg.namespaces;
|
||||||
|
});
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options.services.heisenbridge = {
|
||||||
|
enable = mkEnableOption "the Matrix<->IRC bridge";
|
||||||
|
|
||||||
|
package = mkOption {
|
||||||
|
type = types.package;
|
||||||
|
default = pkgs.heisenbridge;
|
||||||
|
defaultText = "pkgs.heisenbridge";
|
||||||
|
example = "pkgs.heisenbridge.override { … = …; }";
|
||||||
|
description = ''
|
||||||
|
Package of the application to run, exposed for overriding purposes.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
homeserver = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
description = "The URL to the home server for client-server API calls";
|
||||||
|
example = "http://localhost:8008";
|
||||||
|
};
|
||||||
|
|
||||||
|
registrationUrl = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
description = ''
|
||||||
|
The URL where the application service is listening for HS requests, from the Matrix HS perspective.#
|
||||||
|
The default value assumes the bridge runs on the same host as the home server, in the same network.
|
||||||
|
'';
|
||||||
|
example = "https://matrix.example.org";
|
||||||
|
default = "http://${cfg.address}:${toString cfg.port}";
|
||||||
|
defaultText = "http://$${cfg.address}:$${toString cfg.port}";
|
||||||
|
};
|
||||||
|
|
||||||
|
address = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
description = "Address to listen on. IPv6 does not seem to be supported.";
|
||||||
|
default = "127.0.0.1";
|
||||||
|
example = "0.0.0.0";
|
||||||
|
};
|
||||||
|
|
||||||
|
port = mkOption {
|
||||||
|
type = types.port;
|
||||||
|
description = "The port to listen on";
|
||||||
|
default = 9898;
|
||||||
|
};
|
||||||
|
|
||||||
|
debug = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
description = "More verbose logging. Recommended during initial setup.";
|
||||||
|
default = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
owner = mkOption {
|
||||||
|
type = types.nullOr types.str;
|
||||||
|
description = ''
|
||||||
|
Set owner MXID otherwise first talking local user will claim the bridge
|
||||||
|
'';
|
||||||
|
default = null;
|
||||||
|
example = "@admin:example.org";
|
||||||
|
};
|
||||||
|
|
||||||
|
namespaces = mkOption {
|
||||||
|
description = "Configure the 'namespaces' section of the registration.yml for the bridge and the server";
|
||||||
|
# TODO link to Matrix documentation of the format
|
||||||
|
type = types.submodule {
|
||||||
|
freeformType = jsonType;
|
||||||
|
};
|
||||||
|
|
||||||
|
default = {
|
||||||
|
users = [
|
||||||
|
{
|
||||||
|
regex = "@irc_.*";
|
||||||
|
exclusive = true;
|
||||||
|
}
|
||||||
|
];
|
||||||
|
aliases = [ ];
|
||||||
|
rooms = [ ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
identd.enable = mkEnableOption "identd service support";
|
||||||
|
identd.port = mkOption {
|
||||||
|
type = types.port;
|
||||||
|
description = "identd listen port";
|
||||||
|
default = 113;
|
||||||
|
};
|
||||||
|
|
||||||
|
extraArgs = mkOption {
|
||||||
|
type = types.listOf types.str;
|
||||||
|
description = "Heisenbridge is configured over the command line. Append extra arguments here";
|
||||||
|
default = [ ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf cfg.enable {
|
||||||
|
systemd.services.heisenbridge = {
|
||||||
|
description = "Matrix<->IRC bridge";
|
||||||
|
before = [ "matrix-synapse.service" ]; # So the registration file can be used by Synapse
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
|
||||||
|
preStart = ''
|
||||||
|
umask 077
|
||||||
|
set -e -u -o pipefail
|
||||||
|
|
||||||
|
if ! [ -f "${registrationFile}" ]; then
|
||||||
|
# Generate registration file if not present (actually, we only care about the tokens in it)
|
||||||
|
${bin} --generate --config ${registrationFile}
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Overwrite the registration file with our generated one (the config may have changed since then),
|
||||||
|
# but keep the tokens. Two step procedure to be failure safe
|
||||||
|
${pkgs.yq}/bin/yq --slurp \
|
||||||
|
'.[0] + (.[1] | {as_token, hs_token})' \
|
||||||
|
${bridgeConfig} \
|
||||||
|
${registrationFile} \
|
||||||
|
> ${registrationFile}.new
|
||||||
|
mv -f ${registrationFile}.new ${registrationFile}
|
||||||
|
|
||||||
|
# Grant Synapse access to the registration
|
||||||
|
if ${getBin pkgs.glibc}/bin/getent group matrix-synapse > /dev/null; then
|
||||||
|
chgrp -v matrix-synapse ${registrationFile}
|
||||||
|
chmod -v g+r ${registrationFile}
|
||||||
|
fi
|
||||||
|
'';
|
||||||
|
|
||||||
|
serviceConfig = rec {
|
||||||
|
Type = "simple";
|
||||||
|
ExecStart = lib.concatStringsSep " " (
|
||||||
|
[
|
||||||
|
bin
|
||||||
|
(if cfg.debug then "-vvv" else "-v")
|
||||||
|
"--config"
|
||||||
|
registrationFile
|
||||||
|
"--listen-address"
|
||||||
|
(lib.escapeShellArg cfg.address)
|
||||||
|
"--listen-port"
|
||||||
|
(toString cfg.port)
|
||||||
|
]
|
||||||
|
++ (lib.optionals (cfg.owner != null) [
|
||||||
|
"--owner"
|
||||||
|
(lib.escapeShellArg cfg.owner)
|
||||||
|
])
|
||||||
|
++ (lib.optionals cfg.identd.enable [
|
||||||
|
"--identd"
|
||||||
|
"--identd-port"
|
||||||
|
(toString cfg.identd.port)
|
||||||
|
])
|
||||||
|
++ [
|
||||||
|
(lib.escapeShellArg cfg.homeserver)
|
||||||
|
]
|
||||||
|
++ (map (lib.escapeShellArg) cfg.extraArgs)
|
||||||
|
);
|
||||||
|
|
||||||
|
ProtectHome = true;
|
||||||
|
PrivateDevices = true;
|
||||||
|
ProtectKernelTunables = true;
|
||||||
|
ProtectKernelModules = true;
|
||||||
|
ProtectControlGroups = true;
|
||||||
|
StateDirectory = "heisenbridge";
|
||||||
|
StateDirectoryMode = "755";
|
||||||
|
|
||||||
|
User = "heisenbridge";
|
||||||
|
Group = "heisenbridge";
|
||||||
|
|
||||||
|
CapabilityBoundingSet = [ "CAP_CHOWN" ] ++ optional (cfg.port < 1024 || cfg.identd.port < 1024) "CAP_NET_BIND_SERVICE";
|
||||||
|
AmbientCapabilities = CapabilityBoundingSet;
|
||||||
|
NoNewPrivileges = true;
|
||||||
|
|
||||||
|
LockPersonality = true;
|
||||||
|
RestrictRealtime = true;
|
||||||
|
PrivateMounts = true;
|
||||||
|
SystemCallFilter = "~@aio @clock @cpu-emulation @debug @keyring @memlock @module @mount @obsolete @raw-io @setuid @swap";
|
||||||
|
SystemCallArchitectures = "native";
|
||||||
|
RestrictAddressFamilies = "AF_INET AF_INET6";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
users.groups.heisenbridge = {};
|
||||||
|
users.users.heisenbridge = {
|
||||||
|
description = "Service user for the Heisenbridge";
|
||||||
|
group = "heisenbridge";
|
||||||
|
isSystemUser = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
meta.maintainers = [ lib.maintainers.piegames ];
|
||||||
|
}
|
Loading…
Reference in a new issue