minor ejabberd config changes, simplify DNS %NATIVE% updating

This commit is contained in:
2022-12-21 08:50:41 +00:00
parent 55e09c2dbf
commit 278cc98c6d
5 changed files with 116 additions and 50 deletions

View File

@@ -44,14 +44,18 @@
users.users.ejabberd.extraGroups = [ "nginx" ]; users.users.ejabberd.extraGroups = [ "nginx" ];
security.acme.certs."uninsane.org".extraDomainNames = [ security.acme.certs."uninsane.org".extraDomainNames = [
"conference.xmpp.uninsane.org" "xmpp.uninsane.org"
"muc.xmpp.uninsane.org"
"pubsub.xmpp.uninsane.org" "pubsub.xmpp.uninsane.org"
"upload.xmpp.uninsane.org" "upload.xmpp.uninsane.org"
"vjid.xmpp.uninsane.org" "vjid.xmpp.uninsane.org"
]; ];
# exists so the XMPP server's cert can obtain altNames for all its resources # exists so the XMPP server's cert can obtain altNames for all its resources
services.nginx.virtualHosts."conference.xmpp.uninsane.org" = { services.nginx.virtualHosts."xmpp.uninsane.org" = {
useACMEHost = "uninsane.org";
};
services.nginx.virtualHosts."muc.xmpp.uninsane.org" = {
useACMEHost = "uninsane.org"; useACMEHost = "uninsane.org";
}; };
services.nginx.virtualHosts."pubsub.xmpp.uninsane.org" = { services.nginx.virtualHosts."pubsub.xmpp.uninsane.org" = {
@@ -65,22 +69,29 @@
}; };
sane.services.trust-dns.zones."uninsane.org".inet = { sane.services.trust-dns.zones."uninsane.org".inet = {
# XXX: toplevel xmpp might not actually be used/needed. # XXX: SRV records have to point to something with a A/AAAA record; no CNAMEs
CNAME."xmpp" = [ "native" ]; A."xmpp" = [ "%NATIVE%" ];
CNAME."conference.xmpp" = [ "native" ]; CNAME."muc.xmpp" = [ "xmpp" ];
CNAME."pubsub.xmpp" = [ "native" ]; CNAME."pubsub.xmpp" = [ "xmpp" ];
CNAME."upload.xmpp" = [ "native" ]; CNAME."upload.xmpp" = [ "xmpp" ];
CNAME."vjid.xmpp" = [ "native" ]; CNAME."vjid.xmpp" = [ "xmpp" ];
# _Service._Proto.Name TTL Class SRV Priority Weight Port Target # _Service._Proto.Name TTL Class SRV Priority Weight Port Target
SRV."_xmpp-client._tcp" = [ "0 0 5222 native" ]; # - <https://xmpp.org/extensions/xep-0368.html>
SRV."_xmpp-server._tcp" = [ "0 0 5269 native" ]; # something's requesting the SRV records for muc.xmpp, so let's include it
SRV."_stun._udp" = [ "0 0 3478 native" ]; # nothing seems to request XMPP SRVs for the other records (except @)
SRV."_stun._tcp" = [ "0 0 3478 native" ]; SRV."_xmpp-client._tcp.muc.xmpp" = [ "0 0 5222 xmpp" ];
SRV."_stuns._tcp" = [ "0 0 5349 native" ]; SRV."_xmpp-server._tcp.muc.xmpp" = [ "0 0 5269 xmpp" ];
SRV."_turn._udp" = [ "0 0 3478 native" ];
SRV."_turn._tcp" = [ "0 0 3478 native" ]; SRV."_xmpp-client._tcp" = [ "0 0 5222 xmpp" ];
SRV."_turns._tcp" = [ "0 0 5349 native" ]; SRV."_xmpp-server._tcp" = [ "0 0 5269 xmpp" ];
SRV."_stun._udp" = [ "0 0 3478 xmpp" ];
SRV."_stun._tcp" = [ "0 0 3478 xmpp" ];
SRV."_stuns._tcp" = [ "0 0 5349 xmpp" ];
SRV."_turn._udp" = [ "0 0 3478 xmpp" ];
SRV."_turn._tcp" = [ "0 0 3478 xmpp" ];
SRV."_turns._tcp" = [ "0 0 5349 xmpp" ];
}; };
# TODO: allocate UIDs/GIDs ? # TODO: allocate UIDs/GIDs ?
@@ -95,11 +106,14 @@
# none | emergency | alert | critical | error | warning | notice | info | debug # none | emergency | alert | critical | error | warning | notice | info | debug
loglevel: debug loglevel: debug
# loglevel: info
# loglevel: notice
acme: acme:
auto: false auto: false
certfiles: certfiles:
- /var/lib/acme/uninsane.org/full.pem - /var/lib/acme/uninsane.org/full.pem
# ca_file: ${pkgs.cacert.unbundled}/etc/ssl/certs/
# ca_file: ${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt # ca_file: ${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt
pam_userinfotype: jid pam_userinfotype: jid
@@ -127,7 +141,7 @@
muc_create: muc_create:
allow: local allow: local
pubsub_createnode_access: pubsub_createnode_access:
allow: local allow: all
trusted_network: trusted_network:
allow: loopback allow: loopback
@@ -277,9 +291,9 @@
access_mam: access_mam:
- allow - allow
history_size: 100 # messages to show new participants history_size: 100 # messages to show new participants
host: conference.xmpp.uninsane.org host: muc.xmpp.uninsane.org
hosts: hosts:
- conference.xmpp.uninsane.org - muc.xmpp.uninsane.org
default_room_options: default_room_options:
anonymous: false anonymous: false
lang: en lang: en
@@ -295,7 +309,9 @@
mod_roster: mod_roster:
versioning: true versioning: true
# docs: <https://docs.ejabberd.im/admin/configuration/modules/#mod-s2s-dialback> # docs: <https://docs.ejabberd.im/admin/configuration/modules/#mod-s2s-dialback>
# mod_s2s_dialback: {} # XXX: MIGHT need to enable this to federate with some servers # s2s dialback to verify inbound messages
# unclear to what degree the XMPP network requires this
mod_s2s_dialback: {}
mod_shared_roster: {} # creates groups for @all, @online, and anything manually administered? mod_shared_roster: {} # creates groups for @all, @online, and anything manually administered?
mod_stream_mgmt: mod_stream_mgmt:
resend_on_timeout: if_offline # resend undelivered messages if the origin client is offline resend_on_timeout: if_offline # resend undelivered messages if the origin client is offline
@@ -318,14 +334,19 @@
host: pubsub.xmpp.uninsane.org host: pubsub.xmpp.uninsane.org
hosts: hosts:
- pubsub.xmpp.uninsane.org - pubsub.xmpp.uninsane.org
ignore_pep_from_offline: false
last_item_cache: true
plugins: plugins:
- pep - pep
# - flat - flat
force_node_config: force_node_config:
# avoid buggy clients to make their bookmarks public # ensure client bookmarks are private
# XXX: not sure if this is necessary: copying config from examples
storage:bookmarks: storage:bookmarks:
access_model: whitelist access_model: whitelist
urn:xmpp:avatar:data:
access_model: open
urn:xmpp:avatar:metadata:
access_model: open
mod_version: {} mod_version: {}
''; '';
}; };

View File

@@ -128,6 +128,28 @@ in
{ user = "colin"; group = "users"; directory = "/var/www/sites"; } { user = "colin"; group = "users"; directory = "/var/www/sites"; }
]; ];
# let's encrypt default chain looks like:
# - End-entity certificate ← R3 ← ISRG Root X1 ← DST Root CA X3
# - <https://community.letsencrypt.org/t/production-chain-changes/150739>
# DST Root CA X3 expired in 2021 (?)
# the alternative chain is:
# - End-entity certificate ← R3 ← ISRG Root X1 (self-signed)
# using this alternative chain grants more compatibility for services like ejabberd
# but might decrease compatibility with very old clients that don't get updates (e.g. old android, iphone <= 4).
# security.acme.defaults.extraLegoFlags = [
security.acme.certs."uninsane.org" = rec {
# ISRG Root X1 results in lets encrypt sending the same chain as default,
# just without the final ISRG Root X1 ← DST Root CA X3 link.
# i.e. we could alternative clip the last item and achieve the exact same thing.
extraLegoRunFlags = [
"--preferred-chain" "ISRG Root X1"
];
extraLegoRenewFlags = extraLegoRunFlags;
};
# TODO: alternatively, we could clip the last cert IF it's expired,
# optionally outputting that to a new cert file.
# security.acme.defaults.postRun = "";
# create a self-signed SSL certificate for use with literally any domain. # create a self-signed SSL certificate for use with literally any domain.
# browsers will reject this, but proxies and local testing tools can be configured # browsers will reject this, but proxies and local testing tools can be configured
# to accept it. # to accept it.

View File

@@ -23,21 +23,23 @@
sane.services.trust-dns.zones."uninsane.org".inet = { sane.services.trust-dns.zones."uninsane.org".inet = {
SOA."@" = ['' SOA."@" = [''
ns1.uninsane.org. admin-dns.uninsane.org. ( ns1.uninsane.org. admin-dns.uninsane.org. (
2022121601 ; Serial 2022122001 ; Serial
4h ; Refresh 4h ; Refresh
30m ; Retry 30m ; Retry
7d ; Expire 7d ; Expire
5m) ; Negative response TTL 5m) ; Negative response TTL
'']; ''];
TXT."rev" = [ "2022121801" ]; TXT."rev" = [ "2022122001" ];
# XXX NS records must also not be CNAME # XXX NS records must also not be CNAME
# it's best that we keep this identical, or a superset of, what org. lists as our NS. # it's best that we keep this identical, or a superset of, what org. lists as our NS.
# so, org. can specify ns2/ns3 as being to the VPN, with no mention of ns1. we provide ns1 here. # so, org. can specify ns2/ns3 as being to the VPN, with no mention of ns1. we provide ns1 here.
# A."ns1" = [ "%NATIVE%" ]; A."ns1" = [ "%NATIVE%" ];
A."ns2" = [ "185.157.162.178" ]; A."ns2" = [ "185.157.162.178" ];
A."ns3" = [ "185.157.162.178" ]; A."ns3" = [ "185.157.162.178" ];
A."ovpns" = [ "185.157.162.178" ]; A."ovpns" = [ "185.157.162.178" ];
A."native" = [ "%NATIVE%" ];
A."@" = [ "%NATIVE%" ];
NS."@" = [ NS."@" = [
"ns1.uninsane.org." "ns1.uninsane.org."
"ns2.uninsane.org." "ns2.uninsane.org."
@@ -45,19 +47,14 @@
]; ];
}; };
sane.services.trust-dns.zones."uninsane.org".include = [ sane.services.trust-dns.zones."uninsane.org".file =
"/var/lib/trust-dns/native.uninsane.org.zone" "/var/lib/trust-dns/uninsane.org.zone";
];
systemd.services.trust-dns.preStart = let systemd.services.trust-dns.preStart = let
sed = "${pkgs.gnused}/bin/sed"; sed = "${pkgs.gnused}/bin/sed";
zone-dir = "/var/lib/trust-dns"; zone-dir = "/var/lib/trust-dns";
zone-out = "${zone-dir}/native.uninsane.org.zone"; zone-out = "${zone-dir}/uninsane.org.zone";
zone-template = pkgs.writeText "native.uninsane.org.zone.in" '' zone-template = pkgs.writeText "uninsane.org.zone.in" config.sane.services.trust-dns.generatedZones."uninsane.org";
@ A %NATIVE%
ns1 A %NATIVE%
native A %NATIVE%
'';
in '' in ''
# make WAN records available to trust-dns # make WAN records available to trust-dns
mkdir -p ${zone-dir} mkdir -p ${zone-dir}

View File

@@ -187,6 +187,7 @@ let
# (specifically: root, in case of rescue) # (specifically: root, in case of rescue)
systemPkgs = [ systemPkgs = [
btrfs-progs btrfs-progs
cacert.unbundled # some services require unbundled /etc/ssl/certs
cryptsetup cryptsetup
dig dig
efibootmgr efibootmgr
@@ -283,5 +284,7 @@ in
config = { config = {
environment.systemPackages = mkIf cfg.enableSystemPkgs systemPkgs; environment.systemPackages = mkIf cfg.enableSystemPkgs systemPkgs;
# XXX: this might not be necessary. try removing this and cacert.unbundled?
environment.etc."ssl/certs".source = mkIf cfg.enableSystemPkgs "${pkgs.cacert.unbundled}/etc/ssl/certs/*";
}; };
} }

View File

@@ -22,24 +22,30 @@ let
fmtIncludes = paths: concatStringsSep fmtIncludes = paths: concatStringsSep
"\n" "\n"
(map (path: "$INCLUDE ${path}") paths); (map (path: "$INCLUDE ${path}") paths);
genZone = zcfg: ''
$TTL ${toString zcfg.TTL}
${fmtRecordAttrs "IN" "SOA" zcfg.inet.SOA}
${fmtRecordAttrs "IN" "A" zcfg.inet.A}
${fmtRecordAttrs "IN" "CNAME" zcfg.inet.CNAME}
${fmtRecordAttrs "IN" "MX" zcfg.inet.MX}
${fmtRecordAttrs "IN" "NS" zcfg.inet.NS}
${fmtRecordAttrs "IN" "SRV" zcfg.inet.SRV}
${fmtRecordAttrs "IN" "TXT" zcfg.inet.TXT}
${fmtIncludes zcfg.include}
${zcfg.extraConfig}
'';
configFile = toml.generate "trust-dns.toml" { configFile = toml.generate "trust-dns.toml" {
listen_addrs_ipv4 = cfg.listenAddrsIPv4; listen_addrs_ipv4 = cfg.listenAddrsIPv4;
zones = attrValues ( zones = attrValues (
mapAttrs (zone: zcfg: { mapAttrs (zname: zcfg: rec {
inherit zone; zone = if zcfg.name == null then zname else zcfg.name;
zone_type = "Primary"; zone_type = "Primary";
file = pkgs.writeText "${zone}.zone" '' file = if zcfg.file == null then
$TTL ${toString zcfg.TTL} pkgs.writeText "${zone}.zone" (genZone zcfg)
${fmtRecordAttrs "IN" "SOA" zcfg.inet.SOA} else
${fmtRecordAttrs "IN" "A" zcfg.inet.A} zcfg.file;
${fmtRecordAttrs "IN" "CNAME" zcfg.inet.CNAME}
${fmtRecordAttrs "IN" "MX" zcfg.inet.MX}
${fmtRecordAttrs "IN" "NS" zcfg.inet.NS}
${fmtRecordAttrs "IN" "SRV" zcfg.inet.SRV}
${fmtRecordAttrs "IN" "TXT" zcfg.inet.TXT}
${fmtIncludes zcfg.include}
${zcfg.extraConfig}
'';
}) cfg.zones }) cfg.zones
); );
}; };
@@ -60,6 +66,11 @@ in
zones = mkOption { zones = mkOption {
type = types.attrsOf (types.submodule { type = types.attrsOf (types.submodule {
options = { options = {
name = mkOption {
type = types.nullOr types.str;
description = "zone name. defaults to the attribute name in zones";
default = null;
};
TTL = mkOption { TTL = mkOption {
type = types.int; type = types.int;
description = "default TTL"; description = "default TTL";
@@ -112,15 +123,27 @@ in
default = {}; default = {};
}; };
}; };
file = mkOption {
type = types.nullOr types.str;
default = null;
description = "instead of using the generated zone file, use the specified path";
};
}; };
}); });
default = {}; default = {};
description = "Declarative zone config"; description = "Declarative zone config";
}; };
generatedZones = mkOption {
type = types.attrsOf types.str;
description = "generated zone text for each zone";
};
}; };
}; };
config = mkIf cfg.enable { config = mkIf cfg.enable {
sane.services.trust-dns.generatedZones = mapAttrs (zone: zcfg: genZone zcfg) cfg.zones;
networking.firewall.allowedTCPPorts = [ 53 ]; networking.firewall.allowedTCPPorts = [ 53 ];
networking.firewall.allowedUDPPorts = [ 53 ]; networking.firewall.allowedUDPPorts = [ 53 ];