aboutsummaryrefslogtreecommitdiff
path: root/colmena/cobalt
diff options
context:
space:
mode:
authorsefidel <contact@sefidel.net>2023-02-02 18:48:45 +0900
committersefidel <contact@sefidel.net>2023-02-02 18:58:09 +0900
commit68e5d83b0b379fdca677cbd3221fa05fe5ec268f (patch)
tree9cf212cedc1b36da8366331581dc156efd39e559 /colmena/cobalt
parentc551a417940f9c66b4346c5813c2550f06269380 (diff)
downloadnixrc-68e5d83b0b379fdca677cbd3221fa05fe5ec268f.zip
feat(colmena/cobalt): configure soju & acme
Diffstat (limited to 'colmena/cobalt')
-rw-r--r--colmena/cobalt/configuration.nix3
-rw-r--r--colmena/cobalt/overlays/soju.nix132
-rw-r--r--colmena/cobalt/services/acme.nix26
-rw-r--r--colmena/cobalt/services/soju.nix27
4 files changed, 188 insertions, 0 deletions
diff --git a/colmena/cobalt/configuration.nix b/colmena/cobalt/configuration.nix
index e115859..1542def 100644
--- a/colmena/cobalt/configuration.nix
+++ b/colmena/cobalt/configuration.nix
@@ -23,6 +23,9 @@ in
imports =
[ # Include the results of the hardware scan.
./hardware-configuration.nix
+
+ ./services/acme.nix
+ ./services/soju.nix
];
boot.supportedFilesystems = [ "zfs" ];
diff --git a/colmena/cobalt/overlays/soju.nix b/colmena/cobalt/overlays/soju.nix
new file mode 100644
index 0000000..95f333e
--- /dev/null
+++ b/colmena/cobalt/overlays/soju.nix
@@ -0,0 +1,132 @@
+# Not an overlay, module replacement
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+ cfg = config.services.soju;
+ stateDir = "/var/lib/soju";
+ listenCfg = concatMapStringsSep "\n" (l: "listen ${l}") cfg.listen;
+ tlsCfg = optionalString (cfg.tlsCertificate != null)
+ "tls ${cfg.tlsCertificate} ${cfg.tlsCertificateKey}";
+ logCfg = optionalString cfg.enableMessageLogging
+ "log fs ${stateDir}/logs";
+
+ configFile = pkgs.writeText "soju.conf" ''
+ ${listenCfg}
+ hostname ${cfg.hostName}
+ ${tlsCfg}
+ db sqlite3 ${stateDir}/soju.db
+ ${logCfg}
+ http-origin ${concatStringsSep " " cfg.httpOrigins}
+ accept-proxy-ip ${concatStringsSep " " cfg.acceptProxyIP}
+
+ ${cfg.extraConfig}
+ '';
+in
+{
+ ###### interface
+
+ options.services.soju = {
+ enable = mkEnableOption (lib.mdDoc "soju");
+
+ listen = mkOption {
+ type = types.listOf types.str;
+ default = [ ":6697" ];
+ description = lib.mdDoc ''
+ Where soju should listen for incoming connections. See the
+ `listen` directive in
+ {manpage}`soju(1)`.
+ '';
+ };
+
+ hostName = mkOption {
+ type = types.str;
+ default = config.networking.hostName;
+ defaultText = literalExpression "config.networking.hostName";
+ description = lib.mdDoc "Server hostname.";
+ };
+
+ tlsCertificate = mkOption {
+ type = types.nullOr types.path;
+ default = null;
+ example = "/var/host.cert";
+ description = lib.mdDoc "Path to server TLS certificate.";
+ };
+
+ tlsCertificateKey = mkOption {
+ type = types.nullOr types.path;
+ default = null;
+ example = "/var/host.key";
+ description = lib.mdDoc "Path to server TLS certificate key.";
+ };
+
+ enableMessageLogging = mkOption {
+ type = types.bool;
+ default = true;
+ description = lib.mdDoc "Whether to enable message logging.";
+ };
+
+ httpOrigins = mkOption {
+ type = types.listOf types.str;
+ default = [];
+ description = lib.mdDoc ''
+ List of allowed HTTP origins for WebSocket listeners. The parameters are
+ interpreted as shell patterns, see
+ {manpage}`glob(7)`.
+ '';
+ };
+
+ acceptProxyIP = mkOption {
+ type = types.listOf types.str;
+ default = [];
+ description = lib.mdDoc ''
+ Allow the specified IPs to act as a proxy. Proxys have the ability to
+ overwrite the remote and local connection addresses (via the X-Forwarded-\*
+ HTTP header fields). The special name "localhost" accepts the loopback
+ addresses 127.0.0.0/8 and ::1/128. By default, all IPs are rejected.
+ '';
+ };
+
+ extraConfig = mkOption {
+ type = types.lines;
+ default = "";
+ description = lib.mdDoc "Lines added verbatim to the configuration file.";
+ };
+
+ extraGroups = mkOption {
+ type = types.listOf types.str;
+ default = [];
+ description = lib.mdDoc "Extra groups for the dynamic user.";
+ };
+ };
+
+ ###### implementation
+
+ config = mkIf cfg.enable {
+ assertions = [
+ {
+ assertion = (cfg.tlsCertificate != null) == (cfg.tlsCertificateKey != null);
+ message = ''
+ services.soju.tlsCertificate and services.soju.tlsCertificateKey
+ must both be specified to enable TLS.
+ '';
+ }
+ ];
+
+ systemd.services.soju = {
+ description = "soju IRC bouncer";
+ wantedBy = [ "multi-user.target" ];
+ after = [ "network-online.target" ];
+ serviceConfig = {
+ DynamicUser = true;
+ SupplementaryGroups = cfg.extraGroups;
+ Restart = "always";
+ ExecStart = "${pkgs.soju}/bin/soju -config ${configFile}";
+ StateDirectory = "soju";
+ };
+ };
+ };
+
+ meta.maintainers = with maintainers; [ malvo ];
+}
diff --git a/colmena/cobalt/services/acme.nix b/colmena/cobalt/services/acme.nix
new file mode 100644
index 0000000..b41ae1c
--- /dev/null
+++ b/colmena/cobalt/services/acme.nix
@@ -0,0 +1,26 @@
+let
+ poorObfuscation = y: x: "${x}@${y}";
+in
+{
+ security.acme = {
+ acceptTerms = true;
+ defaults.email = poorObfuscation "sefidel.com" "postmaster";
+ certs = {
+ "sefidel.com" = {
+ domain = "*.sefidel.com";
+ dnsProvider = "hetzner";
+ dnsPropagationCheck = true;
+ credentialsFile = "/persist/secrets/hetzner.key";
+ };
+ };
+ };
+
+ environment.persistence."/persist".directories = [
+ "/var/lib/acme"
+ ];
+
+ deployment.keys."hetzner.key" = {
+ keyCommand = [ "pass" "show" "server/hetzner-dns" ];
+ destDir = "/persist/secrets";
+ };
+}
diff --git a/colmena/cobalt/services/soju.nix b/colmena/cobalt/services/soju.nix
new file mode 100644
index 0000000..3e1e3fe
--- /dev/null
+++ b/colmena/cobalt/services/soju.nix
@@ -0,0 +1,27 @@
+{
+ services.soju = {
+ enable = true;
+ extraGroups = [ "acme" ];
+ hostName = "bouncer.sefidel.com";
+ listen = [
+ # ":6697"
+ "ircs://bouncer.sefidel.com:6697"
+ ];
+ tlsCertificate = "/var/lib/acme/sefidel.com/cert.pem";
+ tlsCertificateKey = "/var/lib/acme/sefidel.com/key.pem";
+ };
+
+ networking.firewall.allowedTCPPorts = [ 6697 ];
+
+ environment.persistence."/persist".directories = [
+ "/var/lib/private/soju"
+ ];
+
+ # TODO: remove this once merged
+ disabledModules = [ "services/networking/soju.nix" ];
+
+ imports = [
+ ./acme.nix
+ ../overlays/soju.nix
+ ];
+}