From d944e36197b74a4f6c2cedc9406c29854ebbba8f Mon Sep 17 00:00:00 2001 From: Paul-Henri Froidmont Date: Tue, 26 Mar 2024 23:37:53 +0100 Subject: [PATCH] Finish migration to NixOS modules --- modules/binary-cache.nix | 20 +- modules/default.nix | 17 +- modules/dokuwiki.nix | 7 +- modules/grafana.nix | 316 +++++++++++------------ modules/jellyfin.nix | 59 +++-- modules/jitsi.nix | 18 +- modules/mailserver.nix | 182 ------------- modules/monero.nix | 33 +-- modules/monitoring-exporters.nix | 94 +++---- modules/murmur.nix | 14 +- modules/nextcloud.nix | 156 +++++------ modules/nginx.nix | 27 +- modules/postgresql.nix | 155 +++++------ modules/roundcube.nix | 71 ++--- modules/stb.nix | 103 ++++---- modules/synapse.nix | 333 ++++++++++++------------ modules/torrents.nix | 429 ++++++++++++++++--------------- modules/website-marie.nix | 8 - profiles/backend.nix | 76 +++--- profiles/db.nix | 10 +- profiles/storage.nix | 94 ++++++- 21 files changed, 1071 insertions(+), 1151 deletions(-) delete mode 100644 modules/mailserver.nix delete mode 100644 modules/website-marie.nix diff --git a/modules/binary-cache.nix b/modules/binary-cache.nix index f53a8fb..ae46c9d 100644 --- a/modules/binary-cache.nix +++ b/modules/binary-cache.nix @@ -1,20 +1,14 @@ { config, lib, ... }: -with lib; -let - cfg = config.custom.services.binary-cache; -in -{ +let cfg = config.custom.services.binary-cache; +in { options.custom.services.binary-cache = { - enable = mkEnableOption "binary-cache"; + enable = lib.mkEnableOption "binary-cache"; - secretKeyFile = mkOption { - type = types.path; - }; + secretKeyFile = lib.mkOption { type = lib.types.path; }; }; - - config = mkIf cfg.enable { + config = lib.mkIf cfg.enable { services.nix-serve = { enable = true; port = 1500; @@ -29,7 +23,9 @@ in forceSSL = true; locations."/".extraConfig = '' - proxy_pass http://localhost:${toString config.services.nix-serve.port}; + proxy_pass http://localhost:${ + toString config.services.nix-serve.port + }; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; diff --git a/modules/default.nix b/modules/default.nix index 8cbada4..f253d65 100644 --- a/modules/default.nix +++ b/modules/default.nix @@ -1,5 +1,4 @@ -{ config, pkgs, ... }: -{ +{ config, pkgs, ... }: { imports = [ ./backup-job.nix ./monit.nix @@ -7,5 +6,19 @@ ./openssh.nix ./murmur.nix ./mastodon.nix + ./nginx.nix + ./jellyfin.nix + ./stb.nix + ./monero.nix + ./torrents.nix + ./jitsi.nix + ./binary-cache.nix + ./grafana.nix + ./monitoring-exporters.nix + ./synapse.nix + ./nextcloud.nix + ./roundcube.nix + ./dokuwiki.nix + ./postgresql.nix ]; } diff --git a/modules/dokuwiki.nix b/modules/dokuwiki.nix index 74f63ac..d1ab539 100644 --- a/modules/dokuwiki.nix +++ b/modules/dokuwiki.nix @@ -1,5 +1,4 @@ { config, lib, pkgs, ... }: -with lib; let cfg = config.custom.services.dokuwiki; @@ -47,11 +46,11 @@ let in { options.custom.services.dokuwiki = { - enable = mkEnableOption "dokuwiki"; + enable = lib.mkEnableOption "dokuwiki"; - secretKeyFile = mkOption { type = types.path; }; + secretKeyFile = lib.mkOption { type = lib.types.path; }; }; - config = mkIf cfg.enable + config = lib.mkIf cfg.enable (lib.mkMerge [ (configureWiki "anderia") (configureWiki "arkadia") ]); } diff --git a/modules/grafana.nix b/modules/grafana.nix index 1b7c801..3aaaa00 100644 --- a/modules/grafana.nix +++ b/modules/grafana.nix @@ -1,187 +1,183 @@ -{ config, ... }: -{ +{ config, lib, ... }: +let cfg = config.custom.services.grafana; +in { + options.custom.services.grafana = { enable = lib.mkEnableOption "grafana"; }; - sops.secrets = { - grafanaAdminPassword = { - owner = config.users.users.grafana.name; - key = "grafana/admin_password"; - }; - }; - - - services.grafana = { - enable = true; - dataDir = "/nix/var/data/grafana"; - settings = { - server = { - domain = "grafana.${config.networking.domain}"; + config = lib.mkIf cfg.enable { + sops.secrets = { + grafanaAdminPassword = { + owner = config.users.users.grafana.name; + key = "grafana/admin_password"; }; - security.admin_password = "$__file{${config.sops.secrets.grafanaAdminPassword.path}}"; }; - provision = { + + services.grafana = { enable = true; - datasources.settings = { - datasources = [ - { - name = "Prometheus"; - type = "prometheus"; - url = "http://127.0.0.1:${toString config.services.prometheus.port}"; - isDefault = true; - } - { - name = "Loki"; - type = "loki"; - access = "proxy"; - url = "http://127.0.0.1:${toString config.services.loki.configuration.server.http_listen_port}"; - } - ]; + dataDir = "/nix/var/data/grafana"; + settings = { + server = { domain = "grafana.${config.networking.domain}"; }; + security.admin_password = + "$__file{${config.sops.secrets.grafanaAdminPassword.path}}"; }; - dashboards.settings.providers = [ - { + provision = { + enable = true; + datasources.settings = { + datasources = [ + { + name = "Prometheus"; + type = "prometheus"; + url = + "http://127.0.0.1:${toString config.services.prometheus.port}"; + isDefault = true; + } + { + name = "Loki"; + type = "loki"; + access = "proxy"; + url = "http://127.0.0.1:${ + toString + config.services.loki.configuration.server.http_listen_port + }"; + } + ]; + }; + dashboards.settings.providers = [{ name = "Config"; options.path = ./dashboards; + }]; + }; + }; + + services.nginx = { + virtualHosts = { + "${config.services.grafana.settings.server.domain}" = { + + enableACME = true; + forceSSL = true; + + locations."/" = { + proxyPass = "http://127.0.0.1:${ + toString config.services.grafana.settings.server.http_port + }"; + proxyWebsockets = true; + }; + }; + }; + }; + + services.prometheus = { + enable = true; + + scrapeConfigs = [ + { + job_name = "node"; + static_configs = [{ + targets = [ + "10.0.2.3:${ + toString config.services.prometheus.exporters.node.port + }" + "10.0.1.1:${ + toString config.services.prometheus.exporters.node.port + }" + "10.0.1.11:${ + toString config.services.prometheus.exporters.node.port + }" + ]; + }]; + } + { + job_name = "synapse"; + scrape_interval = "15s"; + metrics_path = "/_synapse/metrics"; + static_configs = [{ targets = [ "10.0.1.1:9000" ]; }]; + } + { + job_name = "dmarc"; + scrape_interval = "15s"; + static_configs = [{ + targets = [ + "10.0.2.3:${ + toString config.services.prometheus.exporters.dmarc.port + }" + ]; + }]; } ]; }; - }; - services.nginx = { - virtualHosts = { - "${config.services.grafana.settings.server.domain}" = { + services.loki = { + enable = true; - enableACME = true; - forceSSL = true; + dataDir = "/nix/var/data/loki"; - locations."/" = { - proxyPass = "http://127.0.0.1:${toString config.services.grafana.settings.server.http_port}"; - proxyWebsockets = true; - }; - }; - }; - }; + configuration = { + server.http_listen_port = 3100; + auth_enabled = false; - services.prometheus = { - enable = true; - - scrapeConfigs = [ - { - job_name = "node"; - static_configs = [{ - targets = [ - "10.0.2.3:${toString config.services.prometheus.exporters.node.port}" - "10.0.1.1:${toString config.services.prometheus.exporters.node.port}" - "10.0.1.11:${toString config.services.prometheus.exporters.node.port}" - ]; - }]; - } - { - job_name = "synapse"; - scrape_interval = "15s"; - metrics_path = "/_synapse/metrics"; - static_configs = [{ - targets = [ - "10.0.1.1:9000" - ]; - }]; - } - { - job_name = "dmarc"; - scrape_interval = "15s"; - static_configs = [{ - targets = [ - "10.0.2.3:${toString config.services.prometheus.exporters.dmarc.port}" - ]; - }]; - } - ]; - }; - - services.loki = { - enable = true; - - dataDir = "/nix/var/data/loki"; - - configuration = { - server.http_listen_port = 3100; - auth_enabled = false; - - ingester = { - lifecycler = { - address = "127.0.0.1"; - ring = { - kvstore = { - store = "inmemory"; + ingester = { + lifecycler = { + address = "127.0.0.1"; + ring = { + kvstore = { store = "inmemory"; }; + replication_factor = 1; }; - replication_factor = 1; + }; + chunk_idle_period = "1h"; + max_chunk_age = "1h"; + chunk_target_size = 999999; + chunk_retain_period = "30s"; + max_transfer_retries = 0; + }; + + limits_config = { ingestion_rate_mb = 16; }; + + schema_config = { + configs = [{ + from = "2022-09-15"; + store = "boltdb-shipper"; + object_store = "filesystem"; + schema = "v11"; + index = { + prefix = "index_"; + period = "24h"; + }; + }]; + }; + + storage_config = { + boltdb_shipper = { + active_index_directory = + "${config.services.loki.dataDir}/boltdb-index"; + cache_location = "${config.services.loki.dataDir}/boltdb-cache"; + cache_ttl = "24h"; + shared_store = "filesystem"; + }; + + filesystem = { + directory = "${config.services.loki.dataDir}/chunks"; }; }; - chunk_idle_period = "1h"; - max_chunk_age = "1h"; - chunk_target_size = 999999; - chunk_retain_period = "30s"; - max_transfer_retries = 0; - }; - limits_config = { - ingestion_rate_mb = 16; - }; + limits_config = { + reject_old_samples = true; + reject_old_samples_max_age = "168h"; + }; - schema_config = { - configs = [{ - from = "2022-09-15"; - store = "boltdb-shipper"; - object_store = "filesystem"; - schema = "v11"; - index = { - prefix = "index_"; - period = "24h"; - }; - }]; - }; + chunk_store_config = { max_look_back_period = "0s"; }; - storage_config = { - boltdb_shipper = { - active_index_directory = "${config.services.loki.dataDir}/boltdb-index"; - cache_location = "${config.services.loki.dataDir}/boltdb-cache"; - cache_ttl = "24h"; + table_manager = { + retention_deletes_enabled = false; + retention_period = "0s"; + }; + + compactor = { + working_directory = "${config.services.loki.dataDir}"; shared_store = "filesystem"; + compactor_ring = { kvstore = { store = "inmemory"; }; }; }; - filesystem = { - directory = "${config.services.loki.dataDir}/chunks"; - }; - }; - - limits_config = { - reject_old_samples = true; - reject_old_samples_max_age = "168h"; - }; - - chunk_store_config = { - max_look_back_period = "0s"; - }; - - table_manager = { - retention_deletes_enabled = false; - retention_period = "0s"; - }; - - compactor = { - working_directory = "${config.services.loki.dataDir}"; - shared_store = "filesystem"; - compactor_ring = { - kvstore = { - store = "inmemory"; - }; - }; - }; - - analytics = { - reporting_enabled = false; + analytics = { reporting_enabled = false; }; }; }; }; } - - - diff --git a/modules/jellyfin.nix b/modules/jellyfin.nix index 12c278b..550c338 100644 --- a/modules/jellyfin.nix +++ b/modules/jellyfin.nix @@ -1,38 +1,43 @@ -{ config, lib, pkgs, ... }: -{ - services.jellyfin = { - enable = true; +{ config, lib, ... }: +let cfg = config.custom.services.jellyfin; +in { + options.custom.services.jellyfin = { + enable = lib.mkEnableOption "jellyfin"; }; - systemd.services.jellyfin.serviceConfig.ExecStart = - lib.mkOverride 10 "${config.services.jellyfin.package}/bin/jellyfin --datadir '/nix/var/data/jellyfin' --cachedir '/var/cache/jellyfin'"; + config = lib.mkIf cfg.enable { + services.jellyfin = { enable = true; }; - services.nginx.virtualHosts."jellyfin.${config.networking.domain}" = { - enableACME = true; - forceSSL = true; + systemd.services.jellyfin.serviceConfig.ExecStart = lib.mkOverride 10 + "${config.services.jellyfin.package}/bin/jellyfin --datadir '/nix/var/data/jellyfin' --cachedir '/var/cache/jellyfin'"; - locations."= /".extraConfig = '' - return 302 https://$host/web/; - ''; + services.nginx.virtualHosts."jellyfin.${config.networking.domain}" = { + enableACME = true; + forceSSL = true; - locations."/" = { - proxyPass = "http://127.0.0.1:8096"; - extraConfig = '' - proxy_buffering off; + locations."= /".extraConfig = '' + return 302 https://$host/web/; ''; - }; - locations."= /web/" = { - proxyPass = "http://127.0.0.1:8096/web/index.html"; - }; + locations."/" = { + proxyPass = "http://127.0.0.1:8096"; + extraConfig = '' + proxy_buffering off; + ''; + }; - locations."/socket" = { - proxyPass = "http://127.0.0.1:8096"; - extraConfig = '' - proxy_http_version 1.1; - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; - ''; + locations."= /web/" = { + proxyPass = "http://127.0.0.1:8096/web/index.html"; + }; + + locations."/socket" = { + proxyPass = "http://127.0.0.1:8096"; + extraConfig = '' + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + ''; + }; }; }; } diff --git a/modules/jitsi.nix b/modules/jitsi.nix index dc1d637..1758b23 100644 --- a/modules/jitsi.nix +++ b/modules/jitsi.nix @@ -1,8 +1,14 @@ -{ pkgs, lib, config, ... }: { - services.jitsi-meet = { - enable = true; - hostName = "jitsi.froidmont.org"; - interfaceConfig = { RECENT_LIST_ENABLED = false; }; +{ pkgs, config, lib, ... }: +let cfg = config.custom.services.jitsi; +in { + options.custom.services.jitsi = { enable = lib.mkEnableOption "jitsi"; }; + + config = lib.mkIf cfg.enable { + services.jitsi-meet = { + enable = true; + hostName = "jitsi.froidmont.org"; + interfaceConfig = { RECENT_LIST_ENABLED = false; }; + }; + services.jitsi-videobridge.openFirewall = true; }; - services.jitsi-videobridge.openFirewall = true; } diff --git a/modules/mailserver.nix b/modules/mailserver.nix deleted file mode 100644 index d34d569..0000000 --- a/modules/mailserver.nix +++ /dev/null @@ -1,182 +0,0 @@ -{ config, lib, pkgs, ... }: { - - sops.secrets = { - paultrialPassword = { key = "email/accounts_passwords/paultrial"; }; - eliosPassword = { key = "email/accounts_passwords/elios"; }; - mariePassword = { key = "email/accounts_passwords/marie"; }; - alicePassword = { key = "email/accounts_passwords/alice"; }; - monitPassword = { key = "email/accounts_passwords/monit"; }; - noreplyBanditlairPassword = { - key = "email/accounts_passwords/noreply_banditlair"; - }; - noreplyFroidmontPassword = { - key = "email/accounts_passwords/noreply_froidmont"; - }; - }; - - mailserver = { - enable = true; - fqdn = "mail.banditlair.com"; - domains = [ "banditlair.com" "froidmont.org" "falbo.fr" ]; - localDnsResolver = false; - enableManageSieve = true; - mailDirectory = "/nix/var/data/vmail"; - sieveDirectory = "/nix/var/data/sieve"; - lmtpSaveToDetailMailbox = "no"; - policydSPFExtraConfig = '' - Domain_Whitelist = skynet.be - ''; - loginAccounts = { - "paultrial@banditlair.com" = { - # nix run nixpkgs.apacheHttpd -c htpasswd -nbB "" "super secret password" | cut -d: -f2 > /hashed/password/file/location - hashedPasswordFile = config.sops.secrets.paultrialPassword.path; - aliases = [ "contact@froidmont.org" "account@banditlair.com" ]; - }; - "marie-alice@froidmont.org" = { - hashedPasswordFile = config.sops.secrets.mariePassword.path; - aliases = [ - "osteopathie@froidmont.org" - "communication@froidmont.org" - "crelan.communication@froidmont.org" - "kerger.communication@froidmont.org" - "3arcs.communication@froidmont.org" - "7days.communication@froidmont.org" - "ulb.communication@froidmont.org" - "baijot.communication@froidmont.org" - "alltrails.communication@froidmont.org" - "alltricks.communication@froidmont.org" - "amazon.communication@froidmont.org" - "athletv.communication@froidmont.org" - "bebecenter.communication@froidmont.org" - "canyon.communication@froidmont.org" - "cbc.communication@froidmont.org" - "coursulb.communication@froidmont.org" - "decathlon.communication@froidmont.org" - "degiro.communication@froidmont.org" - "delogne.communication@froidmont.org" - "diagnosteo.communication@froidmont.org" - "haptis.communication@froidmont.org" - "fortis.communication@froidmont.org" - "fox.communication@froidmont.org" - "vandenborre.communication@froidmont.org" - "swissquote.communication@froidmont.org" - "belso.communication@froidmont.org" - "hibike.communication@froidmont.org" - "giromedical.communication@froidmont.org" - "gymna.communication@froidmont.org" - "hotmail.communication@froidmont.org" - "hubo.communication@froidmont.org" - "infopixel.communication@froidmont.org" - "jysk.communication@froidmont.org" - "kerger.communication@froidmont.org" - "ldlc.communication@froidmont.org" - "location.communication@froidmont.org" - "mainslibres.communication@froidmont.org" - "vistaprint.communication@froidmont.org" - "solidaris.communication@froidmont.org" - "coulon.communication@froidmont.org" - "vlan.communication@froidmont.org" - "hotel.communication@froidmont.org" - "medipost.communication@froidmont.org" - "proximus.communication@froidmont.org" - "marie.communication@froidmont.org" - "tuxedo.communication@froidmont.org" - "corine.wallaux.communication@froidmont.org" - "maziers.communication@froidmont.org" - "miliboo.communication@froidmont.org" - "nike.communication@froidmont.org" - "partena.communication@froidmont.org" - "payconiq.communication@froidmont.org" - "plumart.communication@froidmont.org" - "probikeshop.communication@froidmont.org" - "ring.communication@froidmont.org" - "teams.communication@froidmont.org" - "trail.communication@froidmont.org" - "wikiloc.communication@froidmont.org" - "udemy.communication@froidmont.org" - ]; - }; - "alice@froidmont.org" = { - hashedPasswordFile = config.sops.secrets.alicePassword.path; - }; - "elios@banditlair.com" = { - hashedPasswordFile = config.sops.secrets.eliosPassword.path; - aliases = [ - "webshit@banditlair.com" - "outlook-pascal@banditlair.com" - "nexusmods.webshit@banditlair.com" - "pizza.webshit@banditlair.com" - "fnac.webshit@banditlair.com" - "paypal.webshit@banditlair.com" - "zooplus.webshit@banditlair.com" - "event.webshit@banditlair.com" - "reservation.webshit@banditlair.com" - "netflix.webshit@banditlair.com" - "jvc.webshit@banditlair.com" - "kickstarter.webshit@banditlair.com" - "vpn.webshit@banditlair.com" - "VOO.WEBSHIT@banditlair.com" - "proximus.webshit@banditlair.com" - "post.webshit@banditlair.com" - "ikea.webshit@banditlair.com" - "microsoft.webshit@banditlair.com" - "zerotier.webshit@banditlair.com" - "athome.webshit@banditlair.com" - "nordvpn.webshit@banditlair.com" - "sncf.webshit@banditlair.com" - "paradox.webshit@banditlair.com" - "oracle.webshit@banditlair.com" - "kinepolis.webshit@banditlair.com" - "leboncoin.webshit@banditlair.com" - "wondercraft.webshit@banditlair.com" - "petitvapoteur.webshit@banditlair.com" - "ryanair.webshit@banditlair.com" - "europapark.webshit@banditlair.com" - "Tricount.webshit@banditlair.com" - "huawei.webshit@banditlair.com" - "facebook.webshit@banditlair.com" - "roll20.webshit@banditlair.com" - "drivethrurpg.webshit@banditlair.com" - "chrono24.webshit@banditlair.com" - "emby.webshit@banditlair.com" - "amazon.webshit@banditlair.com" - "steam.webshit@banditlair.com" - "tinder.webshit@banditlair.com" - ]; - }; - "monit@banditlair.com" = { - hashedPasswordFile = config.sops.secrets.monitPassword.path; - sendOnly = true; - }; - "noreply@banditlair.com" = { - hashedPasswordFile = config.sops.secrets.noreplyBanditlairPassword.path; - sendOnly = true; - }; - "noreply@froidmont.org" = { - hashedPasswordFile = config.sops.secrets.noreplyFroidmontPassword.path; - sendOnly = true; - }; - }; - extraVirtualAliases = { - "info@banditlair.com" = "paultrial@banditlair.com"; - "postmaster@banditlair.com" = "paultrial@banditlair.com"; - "abuse@banditlair.com" = "paultrial@banditlair.com"; - - "info@froidmont.org" = "paultrial@banditlair.com"; - "postmaster@froidmont.org" = "paultrial@banditlair.com"; - "abuse@froidmont.org" = "paultrial@banditlair.com"; - - "info@falbo.fr" = "paultrial@banditlair.com"; - "postmaster@falbo.fr" = "paultrial@banditlair.com"; - "abuse@falbo.fr" = "paultrial@banditlair.com"; - - #Catch all - "@banditlair.com" = "paultrial@banditlair.com"; - "@froidmont.org" = "paultrial@banditlair.com"; - "@falbo.fr" = "elios@banditlair.com"; - }; - - certificateScheme = "acme-nginx"; - }; - -} diff --git a/modules/monero.nix b/modules/monero.nix index 0bf0d65..fe13f08 100644 --- a/modules/monero.nix +++ b/modules/monero.nix @@ -1,21 +1,24 @@ -{ config, lib, pkgs, ... }: -{ +{ config, lib, ... }: +let cfg = config.custom.services.monero; +in { + options.custom.services.monero = { enable = lib.mkEnableOption "monero"; }; - services.monero = { - enable = true; - rpc.restricted = true; - }; + config = lib.mkIf cfg.enable { + services.monero = { + enable = true; + rpc.restricted = true; + }; - services.nginx.virtualHosts."monero.${config.networking.domain}" = { - forceSSL = true; - enableACME = true; + services.nginx.virtualHosts."monero.${config.networking.domain}" = { + forceSSL = true; + enableACME = true; - locations."/" = { - proxyPass = "http://127.0.0.1:18081"; - extraConfig = '' - proxy_http_version 1.1; - ''; + locations."/" = { + proxyPass = "http://127.0.0.1:18081"; + extraConfig = '' + proxy_http_version 1.1; + ''; + }; }; }; - } diff --git a/modules/monitoring-exporters.nix b/modules/monitoring-exporters.nix index 3dbea69..798dd56 100644 --- a/modules/monitoring-exporters.nix +++ b/modules/monitoring-exporters.nix @@ -1,61 +1,61 @@ { config, lib, ... }: -{ - services.prometheus = { - exporters = { - node = { - enable = true; - enabledCollectors = [ "systemd" "processes" ]; - }; - }; +let cfg = config.custom.services.monitoring-exporters; +in { + options.custom.services.monitoring-exporters = { + enable = lib.mkEnableOption "monitoring-exporters"; }; - services.promtail = { - enable = true; - configuration = { - server = { - http_listen_port = 3101; - grpc_listen_port = 0; + config = lib.mkIf cfg.enable { + services.prometheus = { + exporters = { + node = { + enable = true; + enabledCollectors = [ "systemd" "processes" ]; + }; }; - clients = [{ - url = "http://10.0.2.3:3100/loki/api/v1/push"; - }]; - scrape_configs = [ - { - job_name = "journal"; - journal = { - max_age = "12h"; - labels = { - job = "systemd-journal"; - host = "${config.networking.hostName}"; + }; + + services.promtail = { + enable = true; + configuration = { + server = { + http_listen_port = 3101; + grpc_listen_port = 0; + }; + clients = [{ url = "http://10.0.2.3:3100/loki/api/v1/push"; }]; + scrape_configs = [ + { + job_name = "journal"; + journal = { + max_age = "12h"; + labels = { + job = "systemd-journal"; + host = "${config.networking.hostName}"; + }; }; - }; - relabel_configs = [{ - source_labels = [ "__journal__systemd_unit" ]; - target_label = "unit"; - }]; - } - (lib.mkIf config.services.nginx.enable { - job_name = "nginx"; - static_configs = [ - { + relabel_configs = [{ + source_labels = [ "__journal__systemd_unit" ]; + target_label = "unit"; + }]; + } + (lib.mkIf config.services.nginx.enable { + job_name = "nginx"; + static_configs = [{ targets = [ "localhost" ]; labels = { job = "nginx"; host = "${config.networking.hostName}"; __path__ = "/var/log/nginx/*.log"; }; - } - ]; - }) - ]; + }]; + }) + ]; + }; + }; + + systemd.services.promtail.serviceConfig = { + ReadOnlyPaths = lib.mkIf config.services.nginx.enable "/var/log/nginx"; + SupplementaryGroups = lib.mkIf config.services.nginx.enable [ "nginx" ]; }; }; - - systemd.services.promtail.serviceConfig = { - ReadOnlyPaths = lib.mkIf config.services.nginx.enable "/var/log/nginx"; - SupplementaryGroups = lib.mkIf config.services.nginx.enable [ "nginx" ]; - }; } - - - diff --git a/modules/murmur.nix b/modules/murmur.nix index 74e9bb6..a5e4b3c 100644 --- a/modules/murmur.nix +++ b/modules/murmur.nix @@ -1,15 +1,9 @@ { config, lib, ... }: -with lib; -let - cfg = config.custom.services.murmur; -in -{ - options.custom.services.murmur = { - enable = mkEnableOption "murmur"; - }; +let cfg = config.custom.services.murmur; +in { + options.custom.services.murmur = { enable = lib.mkEnableOption "murmur"; }; - - config = mkIf cfg.enable { + config = lib.mkIf cfg.enable { sops.secrets.murmurEnvFile = { owner = config.systemd.services.murmur.serviceConfig.User; key = "murmur.env"; diff --git a/modules/nextcloud.nix b/modules/nextcloud.nix index 414fd79..e368af9 100644 --- a/modules/nextcloud.nix +++ b/modules/nextcloud.nix @@ -1,5 +1,6 @@ { config, lib, pkgs, ... }: let + cfg = config.custom.services.nextcloud; uidFile = pkgs.writeText "uidfile" '' nextcloud:993 ''; @@ -7,85 +8,92 @@ let nextcloud:991 ''; in { - sops.secrets = { - sshfsKey = { key = "sshfs_keys/private"; }; - nextcloudDbPassword = { - owner = config.users.users.nextcloud.name; - key = "nextcloud/db_password"; - restartUnits = [ "nextcloud-setup.service" ]; - }; - nextcloudAdminPassword = { - owner = config.users.users.nextcloud.name; - key = "nextcloud/admin_password"; - restartUnits = [ "nextcloud-setup.service" ]; - }; + options.custom.services.nextcloud = { + enable = lib.mkEnableOption "nextcloud"; }; - environment.systemPackages = with pkgs; [ sshfs ]; - - systemd.services.nextcloud-data-sshfs = { - wantedBy = [ "multi-user.target" "nextcloud-setup.service" ]; - before = [ "phpfpm-nextcloud.service" ]; - restartIfChanged = false; - serviceConfig = { - ExecStartPre = "${pkgs.coreutils}/bin/mkdir -p /var/lib/nextcloud/data"; - ExecStart = let - options = builtins.concatStringsSep "," [ - "identityfile=${config.sops.secrets.sshfsKey.path}" - "ServerAliveInterval=15" - "idmap=file" - "uidfile=${uidFile}" - "gidfile=${gidFile}" - "allow_other" - "default_permissions" - "nomap=ignore" - ]; - in "${pkgs.sshfs}/bin/mount.fuse.sshfs www-data@10.0.2.3:/nix/var/data/nextcloud/data " - + "/var/lib/nextcloud/data -o ${options}"; - ExecStopPost = "-${pkgs.fuse}/bin/fusermount -u /var/lib/nextcloud/data"; - KillMode = "process"; - }; - }; - - services.nginx.virtualHosts."${config.services.nextcloud.hostName}" = { - enableACME = true; - forceSSL = true; - }; - - services.nextcloud = { - enable = true; - package = pkgs.nextcloud28; - hostName = "cloud.${config.networking.domain}"; - https = true; - maxUploadSize = "1G"; - - config = { - dbtype = "pgsql"; - dbuser = "nextcloud"; - dbhost = "10.0.1.11"; - dbname = "nextcloud"; - dbpassFile = "${config.sops.secrets.nextcloudDbPassword.path}"; - adminpassFile = "${config.sops.secrets.nextcloudAdminPassword.path}"; - adminuser = "root"; - overwriteProtocol = "https"; - defaultPhoneRegion = "BE"; + config = lib.mkIf cfg.enable { + sops.secrets = { + sshfsKey = { key = "sshfs_keys/private"; }; + nextcloudDbPassword = { + owner = config.users.users.nextcloud.name; + key = "nextcloud/db_password"; + restartUnits = [ "nextcloud-setup.service" ]; + }; + nextcloudAdminPassword = { + owner = config.users.users.nextcloud.name; + key = "nextcloud/admin_password"; + restartUnits = [ "nextcloud-setup.service" ]; + }; }; - extraOptions = { maintenance_window_start = 1; }; + environment.systemPackages = with pkgs; [ sshfs ]; - phpOptions = { - short_open_tag = "Off"; - expose_php = "Off"; - error_reporting = "E_ALL & ~E_DEPRECATED & ~E_STRICT"; - display_errors = "stderr"; - "opcache.enable_cli" = "1"; - "opcache.interned_strings_buffer" = "12"; - "opcache.max_accelerated_files" = "10000"; - "opcache.memory_consumption" = "128"; - "opcache.revalidate_freq" = "1"; - "opcache.fast_shutdown" = "1"; - "openssl.cafile" = "/etc/ssl/certs/ca-certificates.crt"; - catch_workers_output = "yes"; + systemd.services.nextcloud-data-sshfs = { + wantedBy = [ "multi-user.target" "nextcloud-setup.service" ]; + before = [ "phpfpm-nextcloud.service" ]; + restartIfChanged = false; + serviceConfig = { + ExecStartPre = "${pkgs.coreutils}/bin/mkdir -p /var/lib/nextcloud/data"; + ExecStart = let + options = builtins.concatStringsSep "," [ + "identityfile=${config.sops.secrets.sshfsKey.path}" + "ServerAliveInterval=15" + "idmap=file" + "uidfile=${uidFile}" + "gidfile=${gidFile}" + "allow_other" + "default_permissions" + "nomap=ignore" + ]; + in "${pkgs.sshfs}/bin/mount.fuse.sshfs www-data@10.0.2.3:/nix/var/data/nextcloud/data " + + "/var/lib/nextcloud/data -o ${options}"; + ExecStopPost = + "-${pkgs.fuse}/bin/fusermount -u /var/lib/nextcloud/data"; + KillMode = "process"; + }; + }; + + services.nginx.virtualHosts."${config.services.nextcloud.hostName}" = { + enableACME = true; + forceSSL = true; + }; + + services.nextcloud = { + enable = true; + package = pkgs.nextcloud28; + hostName = "cloud.${config.networking.domain}"; + https = true; + maxUploadSize = "1G"; + + config = { + dbtype = "pgsql"; + dbuser = "nextcloud"; + dbhost = "10.0.1.11"; + dbname = "nextcloud"; + dbpassFile = "${config.sops.secrets.nextcloudDbPassword.path}"; + adminpassFile = "${config.sops.secrets.nextcloudAdminPassword.path}"; + adminuser = "root"; + overwriteProtocol = "https"; + defaultPhoneRegion = "BE"; + }; + + extraOptions = { maintenance_window_start = 1; }; + + phpOptions = { + short_open_tag = "Off"; + expose_php = "Off"; + error_reporting = "E_ALL & ~E_DEPRECATED & ~E_STRICT"; + display_errors = "stderr"; + "opcache.enable_cli" = "1"; + "opcache.interned_strings_buffer" = "12"; + "opcache.max_accelerated_files" = "10000"; + "opcache.memory_consumption" = "128"; + "opcache.revalidate_freq" = "1"; + "opcache.fast_shutdown" = "1"; + "openssl.cafile" = "/etc/ssl/certs/ca-certificates.crt"; + catch_workers_output = "yes"; + }; }; }; } diff --git a/modules/nginx.nix b/modules/nginx.nix index aa5bd01..bd06966 100644 --- a/modules/nginx.nix +++ b/modules/nginx.nix @@ -1,15 +1,20 @@ -{ pkgs, lib, config, ... }: -{ - security.acme.defaults.email = "letsencrypt.account@banditlair.com"; - security.acme.defaults.webroot = "/var/lib/acme/acme-challenge"; - security.acme.acceptTerms = true; +{ config, lib, ... }: +let cfg = config.custom.services.nginx; +in { + options.custom.services.nginx = { enable = lib.mkEnableOption "nginx"; }; - services.nginx = { - enable = true; + config = lib.mkIf cfg.enable { + security.acme.defaults.email = "letsencrypt.account@banditlair.com"; + security.acme.defaults.webroot = "/var/lib/acme/acme-challenge"; + security.acme.acceptTerms = true; - recommendedTlsSettings = true; - recommendedOptimisation = true; - recommendedGzipSettings = true; - recommendedProxySettings = true; + services.nginx = { + enable = true; + + recommendedTlsSettings = true; + recommendedOptimisation = true; + recommendedGzipSettings = true; + recommendedProxySettings = true; + }; }; } diff --git a/modules/postgresql.nix b/modules/postgresql.nix index 1997d98..3a8ba6f 100644 --- a/modules/postgresql.nix +++ b/modules/postgresql.nix @@ -1,87 +1,94 @@ -{ config, lib, pkgs, ... }: { - - services.postgresql = { - enable = true; - package = pkgs.postgresql_15; - enableTCPIP = true; - identMap = '' - root_as_others root postgres - root_as_others root synapse - root_as_others root nextcloud - root_as_others root roundcube - root_as_others root mastodon - ''; - authentication = '' - local all postgres peer - local all all peer map=root_as_others - host all all 10.0.1.0/24 md5 - ''; +{ config, lib, pkgs, ... }: +let cfg = config.custom.services.postgresql; +in { + options.custom.services.postgresql = { + enable = lib.mkEnableOption "postgresql"; }; - sops.secrets = { - synapseDbPassword = { - owner = config.services.postgresql.superUser; - key = "synapse/db_password"; - restartUnits = [ "postgresql-setup.service" ]; + config = lib.mkIf cfg.enable { + services.postgresql = { + enable = true; + package = pkgs.postgresql_15; + enableTCPIP = true; + identMap = '' + root_as_others root postgres + root_as_others root synapse + root_as_others root nextcloud + root_as_others root roundcube + root_as_others root mastodon + ''; + authentication = '' + local all postgres peer + local all all peer map=root_as_others + host all all 10.0.1.0/24 md5 + ''; }; - nextcloudDbPassword = { - owner = config.services.postgresql.superUser; - key = "nextcloud/db_password"; - restartUnits = [ "postgresql-setup.service" ]; + + sops.secrets = { + synapseDbPassword = { + owner = config.services.postgresql.superUser; + key = "synapse/db_password"; + restartUnits = [ "postgresql-setup.service" ]; + }; + nextcloudDbPassword = { + owner = config.services.postgresql.superUser; + key = "nextcloud/db_password"; + restartUnits = [ "postgresql-setup.service" ]; + }; + roundcubeDbPassword = { + owner = config.services.postgresql.superUser; + key = "roundcube/db_password"; + restartUnits = [ "postgresql-setup.service" ]; + }; + mastodonDbPassword = { + owner = config.services.postgresql.superUser; + key = "mastodon/db_password"; + restartUnits = [ "postgresql-setup.service" ]; + }; }; - roundcubeDbPassword = { - owner = config.services.postgresql.superUser; - key = "roundcube/db_password"; - restartUnits = [ "postgresql-setup.service" ]; - }; - mastodonDbPassword = { - owner = config.services.postgresql.superUser; - key = "mastodon/db_password"; - restartUnits = [ "postgresql-setup.service" ]; - }; - }; - systemd.services.postgresql-setup = let pgsql = config.services.postgresql; - in { - after = [ "postgresql.service" ]; - bindsTo = [ "postgresql.service" ]; - wantedBy = [ "postgresql.service" ]; - path = [ pgsql.package pkgs.util-linux ]; - script = '' - set -u - PSQL() { - psql --port=${toString pgsql.port} "$@" - } + systemd.services.postgresql-setup = let pgsql = config.services.postgresql; + in { + after = [ "postgresql.service" ]; + bindsTo = [ "postgresql.service" ]; + wantedBy = [ "postgresql.service" ]; + path = [ pgsql.package pkgs.util-linux ]; + script = '' + set -u + PSQL() { + psql --port=${toString pgsql.port} "$@" + } - PSQL -tAc "SELECT 1 FROM pg_roles WHERE rolname = 'synapse'" | grep -q 1 || PSQL -tAc 'CREATE ROLE "synapse"' - PSQL -tAc "SELECT 1 FROM pg_roles WHERE rolname = 'nextcloud'" | grep -q 1 || PSQL -tAc 'CREATE ROLE "nextcloud"' - PSQL -tAc "SELECT 1 FROM pg_roles WHERE rolname = 'roundcube'" | grep -q 1 || PSQL -tAc 'CREATE ROLE "roundcube"' - PSQL -tAc "SELECT 1 FROM pg_roles WHERE rolname = 'mastodon'" | grep -q 1 || PSQL -tAc 'CREATE ROLE "mastodon"' + PSQL -tAc "SELECT 1 FROM pg_roles WHERE rolname = 'synapse'" | grep -q 1 || PSQL -tAc 'CREATE ROLE "synapse"' + PSQL -tAc "SELECT 1 FROM pg_roles WHERE rolname = 'nextcloud'" | grep -q 1 || PSQL -tAc 'CREATE ROLE "nextcloud"' + PSQL -tAc "SELECT 1 FROM pg_roles WHERE rolname = 'roundcube'" | grep -q 1 || PSQL -tAc 'CREATE ROLE "roundcube"' + PSQL -tAc "SELECT 1 FROM pg_roles WHERE rolname = 'mastodon'" | grep -q 1 || PSQL -tAc 'CREATE ROLE "mastodon"' - PSQL -tAc "SELECT 1 FROM pg_database WHERE datname = 'synapse'" | grep -q 1 || PSQL -tAc 'CREATE DATABASE "synapse" OWNER "synapse" TEMPLATE template0 LC_COLLATE = "C" LC_CTYPE = "C"' - PSQL -tAc "SELECT 1 FROM pg_database WHERE datname = 'nextcloud'" | grep -q 1 || PSQL -tAc 'CREATE DATABASE "nextcloud" OWNER "nextcloud"' - PSQL -tAc "SELECT 1 FROM pg_database WHERE datname = 'roundcube'" | grep -q 1 || PSQL -tAc 'CREATE DATABASE "roundcube" OWNER "roundcube"' - PSQL -tAc "SELECT 1 FROM pg_database WHERE datname = 'mastodon'" | grep -q 1 || PSQL -tAc 'CREATE DATABASE "mastodon" OWNER "mastodon"' + PSQL -tAc "SELECT 1 FROM pg_database WHERE datname = 'synapse'" | grep -q 1 || PSQL -tAc 'CREATE DATABASE "synapse" OWNER "synapse" TEMPLATE template0 LC_COLLATE = "C" LC_CTYPE = "C"' + PSQL -tAc "SELECT 1 FROM pg_database WHERE datname = 'nextcloud'" | grep -q 1 || PSQL -tAc 'CREATE DATABASE "nextcloud" OWNER "nextcloud"' + PSQL -tAc "SELECT 1 FROM pg_database WHERE datname = 'roundcube'" | grep -q 1 || PSQL -tAc 'CREATE DATABASE "roundcube" OWNER "roundcube"' + PSQL -tAc "SELECT 1 FROM pg_database WHERE datname = 'mastodon'" | grep -q 1 || PSQL -tAc 'CREATE DATABASE "mastodon" OWNER "mastodon"' - PSQL -tAc "ALTER ROLE synapse LOGIN" - PSQL -tAc "ALTER ROLE nextcloud LOGIN" - PSQL -tAc "ALTER ROLE roundcube LOGIN" - PSQL -tAc "ALTER ROLE mastodon LOGIN" + PSQL -tAc "ALTER ROLE synapse LOGIN" + PSQL -tAc "ALTER ROLE nextcloud LOGIN" + PSQL -tAc "ALTER ROLE roundcube LOGIN" + PSQL -tAc "ALTER ROLE mastodon LOGIN" - synapse_password="$(<'${config.sops.secrets.synapseDbPassword.path}')" - PSQL -tAc "ALTER ROLE synapse WITH PASSWORD '$synapse_password'" - nextcloud_password="$(<'${config.sops.secrets.nextcloudDbPassword.path}')" - PSQL -tAc "ALTER ROLE nextcloud WITH PASSWORD '$nextcloud_password'" - roundcube_password="$(<'${config.sops.secrets.roundcubeDbPassword.path}')" - PSQL -tAc "ALTER ROLE roundcube WITH PASSWORD '$roundcube_password'" - mastodon_password="$(<'${config.sops.secrets.mastodonDbPassword.path}')" - PSQL -tAc "ALTER ROLE mastodon WITH PASSWORD '$mastodon_password'" - ''; + synapse_password="$(<'${config.sops.secrets.synapseDbPassword.path}')" + PSQL -tAc "ALTER ROLE synapse WITH PASSWORD '$synapse_password'" + nextcloud_password="$(<'${config.sops.secrets.nextcloudDbPassword.path}')" + PSQL -tAc "ALTER ROLE nextcloud WITH PASSWORD '$nextcloud_password'" + roundcube_password="$(<'${config.sops.secrets.roundcubeDbPassword.path}')" + PSQL -tAc "ALTER ROLE roundcube WITH PASSWORD '$roundcube_password'" + mastodon_password="$(<'${config.sops.secrets.mastodonDbPassword.path}')" + PSQL -tAc "ALTER ROLE mastodon WITH PASSWORD '$mastodon_password'" + ''; - serviceConfig = { - User = pgsql.superUser; - Type = "oneshot"; - RemainAfterExit = true; + serviceConfig = { + User = pgsql.superUser; + Type = "oneshot"; + RemainAfterExit = true; + }; }; }; } diff --git a/modules/roundcube.nix b/modules/roundcube.nix index ab50ff8..4ea637a 100644 --- a/modules/roundcube.nix +++ b/modules/roundcube.nix @@ -1,42 +1,47 @@ { pkgs, lib, config, ... }: -{ - - sops.secrets = { - pgPassFile = { - owner = "nginx"; - key = "roundcube/pg_pass_file"; - }; - dbPassword = { - owner = "nginx"; - key = "roundcube/db_password"; - }; +let cfg = config.custom.services.roundcube; +in { + options.custom.services.roundcube = { + enable = lib.mkEnableOption "roundcube"; }; - services.roundcube = { - enable = true; - plugins = [ "managesieve" ]; - dicts = with pkgs.aspellDicts; [ en fr de ]; - hostName = "webmail.banditlair.com"; - database = { - host = "10.0.1.11"; - username = "roundcube"; - dbname = "roundcube"; - passwordFile = config.sops.secrets.pgPassFile.path; + config = lib.mkIf cfg.enable { + sops.secrets = { + pgPassFile = { + owner = "nginx"; + key = "roundcube/pg_pass_file"; + }; + dbPassword = { + owner = "nginx"; + key = "roundcube/db_password"; + }; }; + services.roundcube = { + enable = true; + plugins = [ "managesieve" ]; + dicts = with pkgs.aspellDicts; [ en fr de ]; + hostName = "webmail.banditlair.com"; + database = { + host = "10.0.1.11"; + username = "roundcube"; + dbname = "roundcube"; + passwordFile = config.sops.secrets.pgPassFile.path; + }; - extraConfig = '' - # This override is required as a workaround for the nixpkgs config because we need a plain password instead of a pgpass file - $password = file_get_contents('${config.sops.secrets.dbPassword.path}'); - $config['db_dsnw'] = 'pgsql://roundcube:' . $password . '@10.0.1.11/roundcube'; + extraConfig = '' + # This override is required as a workaround for the nixpkgs config because we need a plain password instead of a pgpass file + $password = file_get_contents('${config.sops.secrets.dbPassword.path}'); + $config['db_dsnw'] = 'pgsql://roundcube:' . $password . '@10.0.1.11/roundcube'; - $config['default_host'] = 'ssl://mail.banditlair.com:993'; - $config['smtp_server'] = 'ssl://%h'; - $config['smtp_user'] = '%u'; - $config['smtp_pass'] = '%p'; - $config['identities_level'] = 0; - $config['managesieve_host'] = 'tls://%h'; - $config['managesieve_auth_type'] = 'PLAIN'; - ''; + $config['default_host'] = 'ssl://mail.banditlair.com:993'; + $config['smtp_server'] = 'ssl://%h'; + $config['smtp_user'] = '%u'; + $config['smtp_pass'] = '%p'; + $config['identities_level'] = 0; + $config['managesieve_host'] = 'tls://%h'; + $config['managesieve_auth_type'] = 'PLAIN'; + ''; + }; }; } diff --git a/modules/stb.nix b/modules/stb.nix index c590d52..145b4ed 100644 --- a/modules/stb.nix +++ b/modules/stb.nix @@ -1,5 +1,6 @@ -{ config, lib, pkgs, ... }: +{ pkgs, config, lib, ... }: let + cfg = config.custom.services.stb; uploadWordpressConfig = pkgs.writeText "upload.ini" '' file_uploads = On memory_limit = 64M @@ -7,62 +8,62 @@ let post_max_size = 64M max_execution_time = 600 ''; -in -{ - systemd.services.init-stb-network = { - description = "Create the network bridge stb-br for wordpress."; - after = [ "network.target" ]; - wantedBy = [ "multi-user.target" ]; +in { + options.custom.services.stb = { enable = lib.mkEnableOption "stb"; }; - serviceConfig.Type = "oneshot"; - script = - let dockercli = "${config.virtualisation.docker.package}/bin/docker"; - in - '' - # Put a true at the end to prevent getting non-zero return code, which will - # crash the whole service. - check=$(${dockercli} network ls | grep "stb-br" || true) - if [ -z "$check" ]; then - ${dockercli} network create stb-br - else - echo "stb-br already exists in docker" - fi - ''; - }; + config = lib.mkIf cfg.enable { + systemd.services.init-stb-network = { + description = "Create the network bridge stb-br for wordpress."; + after = [ "network.target" ]; + wantedBy = [ "multi-user.target" ]; - virtualisation.oci-containers.containers = { - "stb-mariadb" = { - image = "mariadb:10.7"; - environment = { - "MYSQL_ROOT_PASSWORD" = "root"; - "MYSQL_USER" = "stb"; - "MYSQL_PASSWORD" = "stb"; - "MYSQL_DATABASE" = "stb"; + serviceConfig.Type = "oneshot"; + script = + let dockercli = "${config.virtualisation.docker.package}/bin/docker"; + in '' + # Put a true at the end to prevent getting non-zero return code, which will + # crash the whole service. + check=$(${dockercli} network ls | grep "stb-br" || true) + if [ -z "$check" ]; then + ${dockercli} network create stb-br + else + echo "stb-br already exists in docker" + fi + ''; + }; + + virtualisation.oci-containers.containers = { + "stb-mariadb" = { + image = "mariadb:10.7"; + environment = { + "MYSQL_ROOT_PASSWORD" = "root"; + "MYSQL_USER" = "stb"; + "MYSQL_PASSWORD" = "stb"; + "MYSQL_DATABASE" = "stb"; + }; + volumes = [ "/var/lib/mariadb/stb:/var/lib/mysql" ]; + extraOptions = [ "--network=stb-br" ]; + autoStart = true; + }; + + "stb-wordpress" = { + image = "wordpress:5.8-php7.4-apache"; + volumes = [ + "/nix/var/data/stb-wordpress:/var/www/html" + "${uploadWordpressConfig}:/usr/local/etc/php/conf.d/uploads.ini" + ]; + ports = [ "127.0.0.1:8180:80" ]; + extraOptions = [ "--network=stb-br" ]; + autoStart = true; }; - volumes = [ "/var/lib/mariadb/stb:/var/lib/mysql" ]; - extraOptions = [ "--network=stb-br" ]; - autoStart = true; }; - "stb-wordpress" = { - image = "wordpress:5.8-php7.4-apache"; - volumes = [ - "/nix/var/data/stb-wordpress:/var/www/html" - "${uploadWordpressConfig}:/usr/local/etc/php/conf.d/uploads.ini" - ]; - ports = [ "127.0.0.1:8180:80" ]; - extraOptions = [ "--network=stb-br" ]; - autoStart = true; - }; - }; + services.nginx.virtualHosts."www.societe-de-tir-bertrix.com" = { + serverAliases = [ "societe-de-tir-bertrix.com" ]; + forceSSL = true; + enableACME = true; - services.nginx.virtualHosts."www.societe-de-tir-bertrix.com" = { - serverAliases = [ "societe-de-tir-bertrix.com" ]; - forceSSL = true; - enableACME = true; - - locations."/" = { - proxyPass = "http://127.0.0.1:8180"; + locations."/" = { proxyPass = "http://127.0.0.1:8180"; }; }; }; } diff --git a/modules/synapse.nix b/modules/synapse.nix index 234455d..f5bea6d 100644 --- a/modules/synapse.nix +++ b/modules/synapse.nix @@ -1,10 +1,10 @@ -{ pkgs, lib, config, ... }: +{ pkgs, config, lib, ... }: let - fqdn = - let - join = hostName: domain: hostName + lib.optionalString (domain != null) ".${domain}"; - in - join "matrix" config.networking.domain; + cfg = config.custom.services.synapse; + fqdn = let + join = hostName: domain: + hostName + lib.optionalString (domain != null) ".${domain}"; + in join "matrix" config.networking.domain; synapseDbConfig = pkgs.writeText "synapse-db-config.yaml" '' database: name: psycopg2 @@ -24,214 +24,211 @@ let macaroon_secret_key: "MACAROON_SECRET_KEY" turn_shared_secret: "TURN_SHARED_SECRET" ''; -in -{ - services.nginx = { - virtualHosts = { - # This host section can be placed on a different host than the rest, - # i.e. to delegate from the host being accessible as ${config.networking.domain} - # to another host actually running the Matrix homeserver. - "${config.networking.domain}" = { - enableACME = true; - forceSSL = true; - # acmeFallbackHost = "storage1.banditlair.com"; +in { + options.custom.services.synapse = { enable = lib.mkEnableOption "synapse"; }; - locations."= /.well-known/matrix/server".extraConfig = - let + config = lib.mkIf cfg.enable { + services.nginx = { + virtualHosts = { + # This host section can be placed on a different host than the rest, + # i.e. to delegate from the host being accessible as ${config.networking.domain} + # to another host actually running the Matrix homeserver. + "${config.networking.domain}" = { + enableACME = true; + forceSSL = true; + # acmeFallbackHost = "storage1.banditlair.com"; + + locations."= /.well-known/matrix/server".extraConfig = let # use 443 instead of the default 8448 port to unite # the client-server and server-server port for simplicity server = { "m.server" = "${fqdn}:443"; }; - in - '' + in '' add_header Content-Type application/json; return 200 '${builtins.toJSON server}'; ''; - locations."= /.well-known/matrix/client".extraConfig = - let + locations."= /.well-known/matrix/client".extraConfig = let client = { "m.homeserver" = { "base_url" = "https://${fqdn}"; }; "m.identity_server" = { "base_url" = "https://vector.im"; }; }; # ACAO required to allow element-web on any URL to request this json file - in - '' + in '' add_header Content-Type application/json; add_header Access-Control-Allow-Origin *; return 200 '${builtins.toJSON client}'; ''; - }; + }; - # Reverse proxy for Matrix client-server and server-server communication - ${fqdn} = { - enableACME = true; - forceSSL = true; + # Reverse proxy for Matrix client-server and server-server communication + ${fqdn} = { + enableACME = true; + forceSSL = true; - # Or do a redirect instead of the 404, or whatever is appropriate for you. - # But do not put a Matrix Web client here! See the Element web section below. - locations."/".extraConfig = '' - return 404; - ''; + # Or do a redirect instead of the 404, or whatever is appropriate for you. + # But do not put a Matrix Web client here! See the Element web section below. + locations."/".extraConfig = '' + return 404; + ''; - # forward all Matrix API calls to the synapse Matrix homeserver - locations."~ ^(/_matrix|/health)" = { - proxyPass = "http://[::1]:8008"; # without a trailing / + # forward all Matrix API calls to the synapse Matrix homeserver + locations."~ ^(/_matrix|/health)" = { + proxyPass = "http://[::1]:8008"; # without a trailing / + }; }; }; }; - }; - sops.secrets = { - synapseDbPassword = { - owner = config.systemd.services.matrix-synapse.serviceConfig.User; - key = "synapse/db_password"; - restartUnits = [ "matrix-synapse-setup" ]; + sops.secrets = { + synapseDbPassword = { + owner = config.systemd.services.matrix-synapse.serviceConfig.User; + key = "synapse/db_password"; + restartUnits = [ "matrix-synapse-setup" ]; + }; + noreplySmtpPassword = { + owner = config.systemd.services.matrix-synapse.serviceConfig.User; + key = "email/accounts_passwords/noreply_banditlair_clear"; + }; + macaroonSecretKey = { + owner = config.systemd.services.matrix-synapse.serviceConfig.User; + key = "synapse/macaroon_secret_key"; + restartUnits = [ "matrix-synapse-setup" ]; + }; + turnSharedSecret = { + owner = config.systemd.services.matrix-synapse.serviceConfig.User; + group = "turnserver"; + mode = "0440"; + key = "synapse/turn_shared_secret"; + restartUnits = [ "matrix-synapse-setup" "coturn" ]; + }; }; - noreplySmtpPassword = { - owner = config.systemd.services.matrix-synapse.serviceConfig.User; - key = "email/accounts_passwords/noreply_banditlair_clear"; + + systemd.services.matrix-synapse-setup = { + before = [ "matrix-synapse.service" ]; + + script = '' + set -euo pipefail + install -m 600 ${synapseDbConfig} /run/synapse/synapse-db-config.yaml + ${pkgs.replace-secret}/bin/replace-secret 'SYNAPSE_DB_PASSWORD' '${config.sops.secrets.synapseDbPassword.path}' /run/synapse/synapse-db-config.yaml + ${pkgs.replace-secret}/bin/replace-secret 'SMTP_PASSWORD' '${config.sops.secrets.noreplySmtpPassword.path}' /run/synapse/synapse-db-config.yaml + ${pkgs.replace-secret}/bin/replace-secret 'MACAROON_SECRET_KEY' '${config.sops.secrets.noreplySmtpPassword.path}' /run/synapse/synapse-db-config.yaml + ${pkgs.replace-secret}/bin/replace-secret 'TURN_SHARED_SECRET' '${config.sops.secrets.turnSharedSecret.path}' /run/synapse/synapse-db-config.yaml + ''; + + serviceConfig = { + User = config.systemd.services.matrix-synapse.serviceConfig.User; + Group = config.systemd.services.matrix-synapse.serviceConfig.Group; + Type = "oneshot"; + RemainAfterExit = true; + RuntimeDirectory = "synapse"; + }; }; - macaroonSecretKey = { - owner = config.systemd.services.matrix-synapse.serviceConfig.User; - key = "synapse/macaroon_secret_key"; - restartUnits = [ "matrix-synapse-setup" ]; + + systemd.services.matrix-synapse = { + after = [ "matrix-synapse-setup.service" "network.target" ]; + bindsTo = [ "matrix-synapse-setup.service" ]; }; - turnSharedSecret = { - owner = config.systemd.services.matrix-synapse.serviceConfig.User; - group = "turnserver"; - mode = "0440"; - key = "synapse/turn_shared_secret"; - restartUnits = [ "matrix-synapse-setup" "coturn" ]; - }; - }; - systemd.services.matrix-synapse-setup = { - before = [ "matrix-synapse.service" ]; + services.matrix-synapse = with config.services.coturn; { + enable = true; + settings = { + server_name = config.networking.domain; - script = '' - set -euo pipefail - install -m 600 ${synapseDbConfig} /run/synapse/synapse-db-config.yaml - ${pkgs.replace-secret}/bin/replace-secret 'SYNAPSE_DB_PASSWORD' '${config.sops.secrets.synapseDbPassword.path}' /run/synapse/synapse-db-config.yaml - ${pkgs.replace-secret}/bin/replace-secret 'SMTP_PASSWORD' '${config.sops.secrets.noreplySmtpPassword.path}' /run/synapse/synapse-db-config.yaml - ${pkgs.replace-secret}/bin/replace-secret 'MACAROON_SECRET_KEY' '${config.sops.secrets.noreplySmtpPassword.path}' /run/synapse/synapse-db-config.yaml - ${pkgs.replace-secret}/bin/replace-secret 'TURN_SHARED_SECRET' '${config.sops.secrets.turnSharedSecret.path}' /run/synapse/synapse-db-config.yaml - ''; + enable_metrics = true; - serviceConfig = { - User = config.systemd.services.matrix-synapse.serviceConfig.User; - Group = config.systemd.services.matrix-synapse.serviceConfig.Group; - Type = "oneshot"; - RemainAfterExit = true; - RuntimeDirectory = "synapse"; - }; - }; - - systemd.services.matrix-synapse = { - after = [ "matrix-synapse-setup.service" "network.target" ]; - bindsTo = [ "matrix-synapse-setup.service" ]; - }; - - services.matrix-synapse = with config.services.coturn; { - enable = true; - settings = { - server_name = config.networking.domain; - - enable_metrics = true; - - listeners = [ - { - port = 8008; - bind_addresses = [ "::1" "127.0.0.1" ]; - type = "http"; - tls = false; - x_forwarded = true; - resources = [ - { + listeners = [ + { + port = 8008; + bind_addresses = [ "::1" "127.0.0.1" ]; + type = "http"; + tls = false; + x_forwarded = true; + resources = [{ names = [ "client" "federation" ]; compress = false; - } - ]; - } - { - port = 9000; - bind_addresses = [ "0.0.0.0" ]; - type = "metrics"; - tls = false; - resources = [ ]; - } - ]; + }]; + } + { + port = 9000; + bind_addresses = [ "0.0.0.0" ]; + type = "metrics"; + tls = false; + resources = [ ]; + } + ]; - database = { - name = "psycopg2"; - args = { - host = "fake"; # This section is overriden by "extraConfigFiles" + database = { + name = "psycopg2"; + args = { + host = "fake"; # This section is overriden by "extraConfigFiles" + }; }; + + turn_uris = [ + "turn:${realm}:3478?transport=udp" + "turn:${realm}:3478?transport=tcp" + ]; + turn_user_lifetime = "1h"; }; - - turn_uris = [ "turn:${realm}:3478?transport=udp" "turn:${realm}:3478?transport=tcp" ]; - turn_user_lifetime = "1h"; + dataDir = "/nix/var/data/matrix-synapse"; + extraConfigFiles = [ "/run/synapse/synapse-db-config.yaml" ]; }; - dataDir = "/nix/var/data/matrix-synapse"; - extraConfigFiles = [ "/run/synapse/synapse-db-config.yaml" ]; - }; - services.coturn = rec { - enable = true; - no-cli = true; - no-tcp-relay = true; - min-port = 49000; - max-port = 50000; - use-auth-secret = true; - static-auth-secret-file = config.sops.secrets.turnSharedSecret.path; - realm = "turn.${config.networking.domain}"; - cert = "${config.security.acme.certs.${realm}.directory}/full.pem"; - pkey = "${config.security.acme.certs.${realm}.directory}/key.pem"; - extraConfig = '' - # for debugging - verbose - # ban private IP ranges - no-multicast-peers - denied-peer-ip=0.0.0.0-0.255.255.255 - denied-peer-ip=10.0.0.0-10.255.255.255 - denied-peer-ip=100.64.0.0-100.127.255.255 - denied-peer-ip=127.0.0.0-127.255.255.255 - denied-peer-ip=169.254.0.0-169.254.255.255 - denied-peer-ip=172.16.0.0-172.31.255.255 - denied-peer-ip=192.0.0.0-192.0.0.255 - denied-peer-ip=192.0.2.0-192.0.2.255 - denied-peer-ip=192.88.99.0-192.88.99.255 - denied-peer-ip=192.168.0.0-192.168.255.255 - denied-peer-ip=198.18.0.0-198.19.255.255 - denied-peer-ip=198.51.100.0-198.51.100.255 - denied-peer-ip=203.0.113.0-203.0.113.255 - denied-peer-ip=240.0.0.0-255.255.255.255 - denied-peer-ip=::1 - denied-peer-ip=64:ff9b::-64:ff9b::ffff:ffff - denied-peer-ip=::ffff:0.0.0.0-::ffff:255.255.255.255 - denied-peer-ip=100::-100::ffff:ffff:ffff:ffff - denied-peer-ip=2001::-2001:1ff:ffff:ffff:ffff:ffff:ffff:ffff - denied-peer-ip=2002::-2002:ffff:ffff:ffff:ffff:ffff:ffff:ffff - denied-peer-ip=fc00::-fdff:ffff:ffff:ffff:ffff:ffff:ffff:ffff - denied-peer-ip=fe80::-febf:ffff:ffff:ffff:ffff:ffff:ffff:ffff - ''; - }; + services.coturn = rec { + enable = true; + no-cli = true; + no-tcp-relay = true; + min-port = 49000; + max-port = 50000; + use-auth-secret = true; + static-auth-secret-file = config.sops.secrets.turnSharedSecret.path; + realm = "turn.${config.networking.domain}"; + cert = "${config.security.acme.certs.${realm}.directory}/full.pem"; + pkey = "${config.security.acme.certs.${realm}.directory}/key.pem"; + extraConfig = '' + # for debugging + verbose + # ban private IP ranges + no-multicast-peers + denied-peer-ip=0.0.0.0-0.255.255.255 + denied-peer-ip=10.0.0.0-10.255.255.255 + denied-peer-ip=100.64.0.0-100.127.255.255 + denied-peer-ip=127.0.0.0-127.255.255.255 + denied-peer-ip=169.254.0.0-169.254.255.255 + denied-peer-ip=172.16.0.0-172.31.255.255 + denied-peer-ip=192.0.0.0-192.0.0.255 + denied-peer-ip=192.0.2.0-192.0.2.255 + denied-peer-ip=192.88.99.0-192.88.99.255 + denied-peer-ip=192.168.0.0-192.168.255.255 + denied-peer-ip=198.18.0.0-198.19.255.255 + denied-peer-ip=198.51.100.0-198.51.100.255 + denied-peer-ip=203.0.113.0-203.0.113.255 + denied-peer-ip=240.0.0.0-255.255.255.255 + denied-peer-ip=::1 + denied-peer-ip=64:ff9b::-64:ff9b::ffff:ffff + denied-peer-ip=::ffff:0.0.0.0-::ffff:255.255.255.255 + denied-peer-ip=100::-100::ffff:ffff:ffff:ffff + denied-peer-ip=2001::-2001:1ff:ffff:ffff:ffff:ffff:ffff:ffff + denied-peer-ip=2002::-2002:ffff:ffff:ffff:ffff:ffff:ffff:ffff + denied-peer-ip=fc00::-fdff:ffff:ffff:ffff:ffff:ffff:ffff:ffff + denied-peer-ip=fe80::-febf:ffff:ffff:ffff:ffff:ffff:ffff:ffff + ''; + }; - networking.firewall = - let + networking.firewall = let range = with config.services.coturn; [{ from = min-port; to = max-port; }]; - in - { + in { allowedUDPPortRanges = range; allowedUDPPorts = [ 3478 ]; allowedTCPPortRanges = range; allowedTCPPorts = [ 3478 ]; }; - - security.acme.certs.${config.services.coturn.realm} = { - postRun = "systemctl restart coturn.service"; - group = "turnserver"; + security.acme.certs.${config.services.coturn.realm} = { + postRun = "systemctl restart coturn.service"; + group = "turnserver"; + }; }; } diff --git a/modules/torrents.nix b/modules/torrents.nix index 241d752..4c0327a 100644 --- a/modules/torrents.nix +++ b/modules/torrents.nix @@ -1,227 +1,234 @@ -{ config, lib, pkgs, ... }: { - - sops.secrets = { - vpnCredentials = { key = "openvpn/credentials"; }; - transmissionRpcCredentials = { key = "transmission/rpc_config.json"; }; +{ config, lib, pkgs, ... }: +let cfg = config.custom.services.torrents; +in { + options.custom.services.torrents = { + enable = lib.mkEnableOption "torrents"; }; - containers.torrents = { - ephemeral = true; - autoStart = true; - enableTun = true; - - privateNetwork = true; - hostAddress = "192.168.1.1"; - localAddress = "192.168.1.2"; - - bindMounts = { - "${config.sops.secrets.vpnCredentials.path}" = { - hostPath = config.sops.secrets.vpnCredentials.path; - }; - "${config.sops.secrets.transmissionRpcCredentials.path}" = { - hostPath = config.sops.secrets.transmissionRpcCredentials.path; - }; - "/nix/var/data/media" = { - hostPath = "/nix/var/data/media"; - isReadOnly = false; - }; - "/nix/var/data/jackett" = { - hostPath = "/nix/var/data/jackett"; - isReadOnly = false; - }; - "/nix/var/data/sonarr" = { - hostPath = "/nix/var/data/sonarr"; - isReadOnly = false; - }; - "/nix/var/data/radarr" = { - hostPath = "/nix/var/data/radarr"; - isReadOnly = false; - }; - "/nix/var/data/lidarr" = { - hostPath = "/nix/var/data/lidarr"; - isReadOnly = false; - }; - "/nix/var/data/transmission" = { - hostPath = "/nix/var/data/transmission"; - isReadOnly = false; - }; + config = lib.mkIf cfg.enable { + sops.secrets = { + vpnCredentials = { key = "openvpn/credentials"; }; + transmissionRpcCredentials = { key = "transmission/rpc_config.json"; }; }; - config = { - time.timeZone = "Europe/Amsterdam"; - users.users.www-data = { - uid = 993; - isSystemUser = true; - group = config.users.groups.www-data.name; - }; - users.groups.www-data = { gid = 991; }; - services.openvpn.servers.client = { - updateResolvConf = true; - config = '' - client - dev tun - resolv-retry infinite - nobind - persist-key - persist-tun - verb 3 - remote-cert-tls server - ping 10 - ping-restart 60 - sndbuf 524288 - rcvbuf 524288 - cipher AES-256-CBC - tls-cipher TLS-DHE-RSA-WITH-AES-256-GCM-SHA384:TLS-DHE-RSA-WITH-AES-256-CBC-SHA - proto udp - - -----BEGIN CERTIFICATE----- - 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 - -----END CERTIFICATE----- - - tun-ipv6 - script-security 2 - fast-io - remote-random - remote de-fra-101.mullvad.net 1194 - remote de-fra-201.mullvad.net 1194 - remote de-fra-009.mullvad.net 1194 - remote de-fra-002.mullvad.net 1194 - remote de-fra-202.mullvad.net 1194 - remote de-fra-005.mullvad.net 1194 - remote de-fra-203.mullvad.net 1194 - remote de-fra-003.mullvad.net 1194 - remote de-fra-004.mullvad.net 1194 - remote de-fra-008.mullvad.net 1194 - remote de-fra-006.mullvad.net 1194 - remote de-fra-007.mullvad.net 1194 - remote de-fra-102.mullvad.net 1194 - auth-user-pass ${config.sops.secrets.vpnCredentials.path} - ''; - }; + containers.torrents = { + ephemeral = true; + autoStart = true; + enableTun = true; - services.transmission = { - enable = true; - openRPCPort = true; - user = config.users.users.www-data.name; - group = config.users.groups.www-data.name; - credentialsFile = config.sops.secrets.transmissionRpcCredentials.path; - home = "/nix/var/data/transmission"; - settings = { - rpc-bind-address = "0.0.0.0"; - rpc-whitelist = "127.0.0.1,192.168.1.1"; - rpc-authentication-required = true; - rpc-host-whitelist-enabled = false; - incomplete-dir = "/nix/var/data/transmission/.incomplete"; - watch-dir = "/nix/var/data/transmission/watchdir"; - download-dir = "/nix/var/data/transmission/downloads"; + privateNetwork = true; + hostAddress = "192.168.1.1"; + localAddress = "192.168.1.2"; + + bindMounts = { + "${config.sops.secrets.vpnCredentials.path}" = { + hostPath = config.sops.secrets.vpnCredentials.path; + }; + "${config.sops.secrets.transmissionRpcCredentials.path}" = { + hostPath = config.sops.secrets.transmissionRpcCredentials.path; + }; + "/nix/var/data/media" = { + hostPath = "/nix/var/data/media"; + isReadOnly = false; + }; + "/nix/var/data/jackett" = { + hostPath = "/nix/var/data/jackett"; + isReadOnly = false; + }; + "/nix/var/data/sonarr" = { + hostPath = "/nix/var/data/sonarr"; + isReadOnly = false; + }; + "/nix/var/data/radarr" = { + hostPath = "/nix/var/data/radarr"; + isReadOnly = false; + }; + "/nix/var/data/lidarr" = { + hostPath = "/nix/var/data/lidarr"; + isReadOnly = false; + }; + "/nix/var/data/transmission" = { + hostPath = "/nix/var/data/transmission"; + isReadOnly = false; }; }; - systemd.services.transmission.serviceConfig.BindReadOnlyPaths = - lib.mkForce [ - builtins.storeDir - "/etc" - ]; # https://github.com/NixOS/nixpkgs/issues/258793 - services.jackett = { - enable = true; - openFirewall = true; - user = config.users.users.www-data.name; - group = config.users.groups.www-data.name; - dataDir = "/nix/var/data/jackett"; - }; - services.sonarr = { - enable = true; - openFirewall = true; - user = config.users.users.www-data.name; - group = config.users.groups.www-data.name; - dataDir = "/nix/var/data/sonarr"; - }; - services.radarr = { - enable = true; - openFirewall = true; - user = config.users.users.www-data.name; - group = config.users.groups.www-data.name; - dataDir = "/nix/var/data/radarr"; - }; - services.lidarr = { - enable = true; - openFirewall = true; - user = config.users.users.www-data.name; - group = config.users.groups.www-data.name; - dataDir = "/nix/var/data/lidarr"; - }; + config = { + time.timeZone = "Europe/Amsterdam"; + users.users.www-data = { + uid = 993; + isSystemUser = true; + group = config.users.groups.www-data.name; + }; + users.groups.www-data = { gid = 991; }; + services.openvpn.servers.client = { + updateResolvConf = true; + config = '' + client + dev tun + resolv-retry infinite + nobind + persist-key + persist-tun + verb 3 + remote-cert-tls server + ping 10 + ping-restart 60 + sndbuf 524288 + rcvbuf 524288 + cipher AES-256-CBC + tls-cipher TLS-DHE-RSA-WITH-AES-256-GCM-SHA384:TLS-DHE-RSA-WITH-AES-256-CBC-SHA + proto udp + + -----BEGIN CERTIFICATE----- + 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 + -----END CERTIFICATE----- + + tun-ipv6 + script-security 2 + fast-io + remote-random + remote de-fra-101.mullvad.net 1194 + remote de-fra-201.mullvad.net 1194 + remote de-fra-009.mullvad.net 1194 + remote de-fra-002.mullvad.net 1194 + remote de-fra-202.mullvad.net 1194 + remote de-fra-005.mullvad.net 1194 + remote de-fra-203.mullvad.net 1194 + remote de-fra-003.mullvad.net 1194 + remote de-fra-004.mullvad.net 1194 + remote de-fra-008.mullvad.net 1194 + remote de-fra-006.mullvad.net 1194 + remote de-fra-007.mullvad.net 1194 + remote de-fra-102.mullvad.net 1194 + auth-user-pass ${config.sops.secrets.vpnCredentials.path} + ''; + }; - system.stateVersion = "21.11"; - }; - }; + services.transmission = { + enable = true; + openRPCPort = true; + user = config.users.users.www-data.name; + group = config.users.groups.www-data.name; + credentialsFile = config.sops.secrets.transmissionRpcCredentials.path; + home = "/nix/var/data/transmission"; + settings = { + rpc-bind-address = "0.0.0.0"; + rpc-whitelist = "127.0.0.1,192.168.1.1"; + rpc-authentication-required = true; + rpc-host-whitelist-enabled = false; + incomplete-dir = "/nix/var/data/transmission/.incomplete"; + watch-dir = "/nix/var/data/transmission/watchdir"; + download-dir = "/nix/var/data/transmission/downloads"; + }; + }; + systemd.services.transmission.serviceConfig.BindReadOnlyPaths = + lib.mkForce [ + builtins.storeDir + "/etc" + ]; # https://github.com/NixOS/nixpkgs/issues/258793 - virtualisation.oci-containers.containers.flaresolverr = { - image = "ghcr.io/flaresolverr/flaresolverr:v3.3.11"; - environment = { - "LOG_LEVEL" = "debug"; - "CAPTCHA_SOLVER" = "hcaptcha-solver"; - }; - ports = [ "192.168.1.1:8191:8191" ]; - autoStart = true; - }; + services.jackett = { + enable = true; + openFirewall = true; + user = config.users.users.www-data.name; + group = config.users.groups.www-data.name; + dataDir = "/nix/var/data/jackett"; + }; + services.sonarr = { + enable = true; + openFirewall = true; + user = config.users.users.www-data.name; + group = config.users.groups.www-data.name; + dataDir = "/nix/var/data/sonarr"; + }; + services.radarr = { + enable = true; + openFirewall = true; + user = config.users.users.www-data.name; + group = config.users.groups.www-data.name; + dataDir = "/nix/var/data/radarr"; + }; + services.lidarr = { + enable = true; + openFirewall = true; + user = config.users.users.www-data.name; + group = config.users.groups.www-data.name; + dataDir = "/nix/var/data/lidarr"; + }; - services.nginx.virtualHosts = { - "transmission.${config.networking.domain}" = { - forceSSL = true; - enableACME = true; - locations."/" = { proxyPass = "http://192.168.1.2:9091"; }; + system.stateVersion = "21.11"; + }; }; - "jackett.${config.networking.domain}" = { - forceSSL = true; - enableACME = true; - locations."/" = { proxyPass = "http://192.168.1.2:9117"; }; + + virtualisation.oci-containers.containers.flaresolverr = { + image = "ghcr.io/flaresolverr/flaresolverr:v3.3.11"; + environment = { + "LOG_LEVEL" = "debug"; + "CAPTCHA_SOLVER" = "hcaptcha-solver"; + }; + ports = [ "192.168.1.1:8191:8191" ]; + autoStart = true; }; - "sonarr.${config.networking.domain}" = { - forceSSL = true; - enableACME = true; - locations."/" = { proxyPass = "http://192.168.1.2:8989"; }; - }; - "radarr.${config.networking.domain}" = { - forceSSL = true; - enableACME = true; - locations."/" = { proxyPass = "http://192.168.1.2:7878"; }; - }; - "lidarr.${config.networking.domain}" = { - forceSSL = true; - enableACME = true; - locations."/" = { proxyPass = "http://192.168.1.2:8686"; }; + + services.nginx.virtualHosts = { + "transmission.${config.networking.domain}" = { + forceSSL = true; + enableACME = true; + locations."/" = { proxyPass = "http://192.168.1.2:9091"; }; + }; + "jackett.${config.networking.domain}" = { + forceSSL = true; + enableACME = true; + locations."/" = { proxyPass = "http://192.168.1.2:9117"; }; + }; + "sonarr.${config.networking.domain}" = { + forceSSL = true; + enableACME = true; + locations."/" = { proxyPass = "http://192.168.1.2:8989"; }; + }; + "radarr.${config.networking.domain}" = { + forceSSL = true; + enableACME = true; + locations."/" = { proxyPass = "http://192.168.1.2:7878"; }; + }; + "lidarr.${config.networking.domain}" = { + forceSSL = true; + enableACME = true; + locations."/" = { proxyPass = "http://192.168.1.2:8686"; }; + }; }; }; } diff --git a/modules/website-marie.nix b/modules/website-marie.nix deleted file mode 100644 index 83cfcd5..0000000 --- a/modules/website-marie.nix +++ /dev/null @@ -1,8 +0,0 @@ -{ config, lib, pkgs, ... }: -{ - services.nginx.virtualHosts."osteopathie.froidmont.org" = { - enableACME = true; - forceSSL = true; - root = "/nix/var/data/website-marie"; - }; -} diff --git a/profiles/backend.nix b/profiles/backend.nix index 595f9ae..036426a 100644 --- a/profiles/backend.nix +++ b/profiles/backend.nix @@ -1,16 +1,5 @@ { config, lib, pkgs, ... }: { - imports = [ - ../environment.nix - ../hardware/hcloud.nix - ../modules - ../modules/nginx.nix - ../modules/synapse.nix - ../modules/nextcloud.nix - ../modules/dokuwiki.nix - ../modules/website-marie.nix - ../modules/roundcube.nix - ../modules/monitoring-exporters.nix - ]; + imports = [ ../environment.nix ../hardware/hcloud.nix ../modules ]; sops.secrets = { borgSshKey = { @@ -20,6 +9,7 @@ }; custom = { + services.backup-job = { enable = true; repoName = "bk1"; @@ -63,13 +53,15 @@ ''; }; + services.nginx.enable = true; services.dokuwiki.enable = true; - services.openssh.enable = true; - services.murmur.enable = true; - services.mastodon.enable = false; + services.synapse.enable = true; + services.nextcloud.enable = true; + services.roundcube.enable = true; + services.monitoring-exporters.enable = true; }; services.uptime-kuma = { @@ -77,34 +69,42 @@ settings = { PORT = "3001"; }; }; - services.nginx.virtualHosts."uptime.froidmont.org" = { - serverAliases = [ "status.${config.networking.domain}" ]; - forceSSL = true; - enableACME = true; - - locations."/" = { - proxyPass = - "http://127.0.0.1:${config.services.uptime-kuma.settings.PORT}"; - proxyWebsockets = true; + services.nginx.virtualHosts = { + "osteopathie.froidmont.org" = { + enableACME = true; + forceSSL = true; + root = "/nix/var/data/website-marie"; }; - }; - services.nginx.virtualHosts."www.fautlfer.com" = { - enableACME = true; - forceSSL = true; + "uptime.froidmont.org" = { + serverAliases = [ "status.${config.networking.domain}" ]; + forceSSL = true; + enableACME = true; - locations."= /".extraConfig = '' - return 302 https://blogz.zaclys.com/faut-l-fer/; - ''; - }; + locations."/" = { + proxyPass = + "http://127.0.0.1:${config.services.uptime-kuma.settings.PORT}"; + proxyWebsockets = true; + }; + }; - services.nginx.virtualHosts."fautlfer.com" = { - enableACME = true; - forceSSL = true; + "www.fautlfer.com" = { + enableACME = true; + forceSSL = true; - locations."= /".extraConfig = '' - return 302 https://blogz.zaclys.com/faut-l-fer/; - ''; + locations."= /".extraConfig = '' + return 302 https://blogz.zaclys.com/faut-l-fer/; + ''; + }; + + "fautlfer.com" = { + enableACME = true; + forceSSL = true; + + locations."= /".extraConfig = '' + return 302 https://blogz.zaclys.com/faut-l-fer/; + ''; + }; }; networking.firewall.allowedTCPPorts = [ 80 443 64738 ]; diff --git a/profiles/db.nix b/profiles/db.nix index a6a638d..a3d78ec 100644 --- a/profiles/db.nix +++ b/profiles/db.nix @@ -1,11 +1,5 @@ { config, lib, pkgs, ... }: { - imports = [ - ../environment.nix - ../hardware/hcloud.nix - ../modules - ../modules/postgresql.nix - ../modules/monitoring-exporters.nix - ]; + imports = [ ../environment.nix ../hardware/hcloud.nix ../modules ]; networking.firewall.interfaces."eth1".allowedTCPPorts = [ config.services.prometheus.exporters.node.port @@ -35,6 +29,8 @@ }; services.openssh.enable = true; + services.postgresql.enable = true; + services.monitoring-exporters.enable = true; }; } diff --git a/profiles/storage.nix b/profiles/storage.nix index 86f2db4..d1f12c2 100644 --- a/profiles/storage.nix +++ b/profiles/storage.nix @@ -3,17 +3,6 @@ ../environment.nix ../hardware/hetzner-dedicated-storage1.nix ../modules - ../modules/openssh.nix - ../modules/mailserver.nix - ../modules/nginx.nix - ../modules/jellyfin.nix - ../modules/stb.nix - ../modules/monero.nix - ../modules/torrents.nix - ../modules/jitsi.nix - ../modules/binary-cache.nix - ../modules/grafana.nix - ../modules/monitoring-exporters.nix ]; sops.secrets = { @@ -23,6 +12,17 @@ }; nixCacheKey = { key = "nix/cache_secret_key"; }; dmarcExporterPassword = { key = "dmarc_exporter/password"; }; + paultrialPassword = { key = "email/accounts_passwords/paultrial"; }; + eliosPassword = { key = "email/accounts_passwords/elios"; }; + mariePassword = { key = "email/accounts_passwords/marie"; }; + alicePassword = { key = "email/accounts_passwords/alice"; }; + monitPassword = { key = "email/accounts_passwords/monit"; }; + noreplyBanditlairPassword = { + key = "email/accounts_passwords/noreply_banditlair"; + }; + noreplyFroidmontPassword = { + key = "email/accounts_passwords/noreply_froidmont"; + }; }; custom = { @@ -95,8 +95,80 @@ ''; }; + services.nginx.enable = true; services.gitlab-runner.enable = true; services.openssh.enable = true; + services.jellyfin.enable = true; + services.stb.enable = true; + services.monero.enable = true; + services.torrents.enable = true; + services.jitsi.enable = true; + services.grafana.enable = true; + services.monitoring-exporters.enable = true; + }; + + mailserver = { + enable = true; + fqdn = "mail.banditlair.com"; + domains = [ "banditlair.com" "froidmont.org" "falbo.fr" ]; + localDnsResolver = false; + enableManageSieve = true; + mailDirectory = "/nix/var/data/vmail"; + sieveDirectory = "/nix/var/data/sieve"; + lmtpSaveToDetailMailbox = "no"; + policydSPFExtraConfig = '' + Domain_Whitelist = skynet.be + ''; + loginAccounts = { + "paultrial@banditlair.com" = { + # nix run nixpkgs.apacheHttpd -c htpasswd -nbB "" "super secret password" | cut -d: -f2 > /hashed/password/file/location + hashedPasswordFile = config.sops.secrets.paultrialPassword.path; + aliases = [ "contact@froidmont.org" "account@banditlair.com" ]; + }; + "marie-alice@froidmont.org" = { + hashedPasswordFile = config.sops.secrets.mariePassword.path; + aliases = [ "osteopathie@froidmont.org" "communication@froidmont.org" ]; + }; + "alice@froidmont.org" = { + hashedPasswordFile = config.sops.secrets.alicePassword.path; + }; + "elios@banditlair.com" = { + hashedPasswordFile = config.sops.secrets.eliosPassword.path; + aliases = [ "webshit@banditlair.com" "outlook-pascal@banditlair.com" ]; + }; + "monit@banditlair.com" = { + hashedPasswordFile = config.sops.secrets.monitPassword.path; + sendOnly = true; + }; + "noreply@banditlair.com" = { + hashedPasswordFile = config.sops.secrets.noreplyBanditlairPassword.path; + sendOnly = true; + }; + "noreply@froidmont.org" = { + hashedPasswordFile = config.sops.secrets.noreplyFroidmontPassword.path; + sendOnly = true; + }; + }; + extraVirtualAliases = { + "info@banditlair.com" = "paultrial@banditlair.com"; + "postmaster@banditlair.com" = "paultrial@banditlair.com"; + "abuse@banditlair.com" = "paultrial@banditlair.com"; + + "info@froidmont.org" = "paultrial@banditlair.com"; + "postmaster@froidmont.org" = "paultrial@banditlair.com"; + "abuse@froidmont.org" = "paultrial@banditlair.com"; + + "info@falbo.fr" = "paultrial@banditlair.com"; + "postmaster@falbo.fr" = "paultrial@banditlair.com"; + "abuse@falbo.fr" = "paultrial@banditlair.com"; + + #Catch all + "@banditlair.com" = "paultrial@banditlair.com"; + "@froidmont.org" = "paultrial@banditlair.com"; + "@falbo.fr" = "elios@banditlair.com"; + }; + + certificateScheme = "acme-nginx"; }; services.prometheus.exporters.dmarc = {