style(treewide): Apply linter suggestions

This commit is contained in:
Tristan Daniël Maat 2025-05-20 20:38:43 +08:00
parent 5c6b697e55
commit 63b3cbe00b
Signed by: tlater
GPG key ID: 49670FD774E43268
20 changed files with 432 additions and 450 deletions

View file

@ -8,6 +8,15 @@
let let
pkgs = nixpkgs.legacyPackages.${system}; pkgs = nixpkgs.legacyPackages.${system};
statix' = pkgs.statix.overrideAttrs (old: {
patches = old.patches ++ [
(pkgs.fetchpatch {
url = "https://github.com/oppiliappan/statix/commit/925dec39bb705acbbe77178b4d658fe1b752abbb.patch";
hash = "sha256-0wacO6wuYJ4ufN9PGucRVJucFdFFNF+NoHYIrLXsCWs=";
})
];
});
runNuCheck = runNuCheck =
{ {
name, name,
@ -44,7 +53,7 @@ nixpkgs.lib.recursiveUpdate {
pkgs.deadnix pkgs.deadnix
pkgs.nixfmt-rfc-style pkgs.nixfmt-rfc-style
pkgs.shellcheck pkgs.shellcheck
pkgs.statix statix'
]; ];
check = ./lints.nu; check = ./lints.nu;

View file

@ -1,7 +1,5 @@
{ {
config, config,
pkgs,
lib,
modulesPath, modulesPath,
flake-inputs, flake-inputs,
... ...
@ -31,13 +29,7 @@
./sops.nix ./sops.nix
]; ];
nixpkgs.overlays = [ nixpkgs.overlays = [ (_: prev: { local = import ../pkgs { pkgs = prev; }; }) ];
(final: prev: {
local = import ../pkgs {
pkgs = prev;
};
})
];
nix = { nix = {
extraOptions = '' extraOptions = ''

View file

@ -6,26 +6,35 @@
boot.kernelParams = [ "nomodeset" ]; boot.kernelParams = [ "nomodeset" ];
networking.hostName = "testvm"; networking.hostName = "testvm";
# Sets the base domain for nginx to a local domain so that we can
# easily test locally with the VM. services = {
services.nginx.domain = "dev.local"; # Sets the base domain for nginx to a local domain so that we can
# easily test locally with the VM.
nginx.domain = "dev.local";
# Don't run this
batteryManager.enable = lib.mkForce false;
openssh.hostKeys = lib.mkForce [
{
type = "rsa";
bits = 4096;
path = "/etc/staging.key";
}
];
};
# Use the staging secrets # Use the staging secrets
sops.defaultSopsFile = lib.mkOverride 99 ../../keys/staging.yaml; sops.defaultSopsFile = lib.mkOverride 99 ../../keys/staging.yaml;
systemd.network.networks."10-eth0" = { systemd.network.networks."10-eth0" = {
matchConfig.Name = "eth0"; matchConfig.Name = "eth0";
gateway = [ gateway = [ "192.168.9.1" ];
"192.168.9.1"
];
networkConfig = { networkConfig = {
Address = "192.168.9.2/24"; Address = "192.168.9.2/24";
}; };
}; };
# Don't run this
services.batteryManager.enable = lib.mkForce false;
# Both so we have a predictable key for the staging env, as well as # Both so we have a predictable key for the staging env, as well as
# to have a static key for decrypting the sops secrets for the # to have a static key for decrypting the sops secrets for the
# staging env. # staging env.
@ -34,14 +43,6 @@
source = ../../keys/hosts/staging.key; source = ../../keys/hosts/staging.key;
}; };
services.openssh.hostKeys = lib.mkForce [
{
type = "rsa";
bits = 4096;
path = "/etc/staging.key";
}
];
virtualisation.vmVariant = { virtualisation.vmVariant = {
virtualisation = { virtualisation = {
memorySize = 3941; memorySize = 3941;

View file

@ -1,40 +1,49 @@
{ config, lib, ... }: { config, lib, ... }:
{ {
services.nginx = { services = {
enable = true; nginx = {
recommendedTlsSettings = true; enable = true;
recommendedOptimisation = true; recommendedTlsSettings = true;
recommendedGzipSettings = true; recommendedOptimisation = true;
recommendedProxySettings = true; recommendedGzipSettings = true;
clientMaxBodySize = "10G"; recommendedProxySettings = true;
clientMaxBodySize = "10G";
statusPage = true; # For metrics, should be accessible only from localhost statusPage = true; # For metrics, should be accessible only from localhost
commonHttpConfig = '' commonHttpConfig = ''
log_format upstream_time '$remote_addr - $remote_user [$time_local] ' log_format upstream_time '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent ' '"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" ' '"$http_referer" "$http_user_agent" '
'rt=$request_time uct="$upstream_connect_time" ' 'rt=$request_time uct="$upstream_connect_time" '
'uht="$upstream_header_time" urt="$upstream_response_time"'; 'uht="$upstream_header_time" urt="$upstream_response_time"';
''; '';
}; };
services.logrotate.settings = logrotate.settings =
{ {
# Override the default, just keep fewer logs # Override the default, just keep fewer logs
nginx.rotate = 6; nginx.rotate = 6;
}
// lib.mapAttrs' (
virtualHost: _:
lib.nameValuePair "/var/log/nginx/${virtualHost}/access.log" {
frequency = "daily";
rotate = 2;
compress = true;
delaycompress = true;
su = "${config.services.nginx.user} ${config.services.nginx.group}";
postrotate = "[ ! -f /var/run/nginx/nginx.pid ] || kill -USR1 `cat /var/run/nginx/nginx.pid`";
} }
) config.services.nginx.virtualHosts; // lib.mapAttrs' (
virtualHost: _:
lib.nameValuePair "/var/log/nginx/${virtualHost}/access.log" {
frequency = "daily";
rotate = 2;
compress = true;
delaycompress = true;
su = "${config.services.nginx.user} ${config.services.nginx.group}";
postrotate = "[ ! -f /var/run/nginx/nginx.pid ] || kill -USR1 `cat /var/run/nginx/nginx.pid`";
}
) config.services.nginx.virtualHosts;
backups.acme = {
user = "acme";
paths = lib.mapAttrsToList (
virtualHost: _: "/var/lib/acme/${virtualHost}"
) config.services.nginx.virtualHosts;
};
};
systemd.tmpfiles.rules = lib.mapAttrsToList ( systemd.tmpfiles.rules = lib.mapAttrsToList (
virtualHost: _: virtualHost: _:
@ -66,11 +75,4 @@
systemd.services.nginx.serviceConfig.SupplementaryGroups = [ systemd.services.nginx.serviceConfig.SupplementaryGroups = [
config.security.acme.certs."tlater.net".group config.security.acme.certs."tlater.net".group
]; ];
services.backups.acme = {
user = "acme";
paths = lib.mapAttrsToList (
virtualHost: _: "/var/lib/acme/${virtualHost}"
) config.services.nginx.virtualHosts;
};
} }

View file

@ -57,7 +57,7 @@ in
''; '';
type = types.attrsOf ( type = types.attrsOf (
types.submodule ( types.submodule (
{ config, name, ... }: { name, ... }:
{ {
options = { options = {
user = lib.mkOption { user = lib.mkOption {
@ -246,7 +246,7 @@ in
}; };
} }
// lib.mapAttrs' ( // lib.mapAttrs' (
name: backup: name: _:
lib.nameValuePair "backup-${name}" { lib.nameValuePair "backup-${name}" {
wantedBy = [ "timers.target" ]; wantedBy = [ "timers.target" ];
timerConfig = { timerConfig = {

View file

@ -18,33 +18,153 @@ in
./matrix-hookshot.nix ./matrix-hookshot.nix
]; ];
services.matrix-conduit = { services = {
enable = true; matrix-conduit = {
package = flake-inputs.continuwuity.packages.${pkgs.system}.default; enable = true;
settings.global = { package = flake-inputs.continuwuity.packages.${pkgs.system}.default;
address = "127.0.0.1"; settings.global = {
server_name = domain; address = "127.0.0.1";
new_user_displayname_suffix = "🦆"; server_name = domain;
allow_check_for_updates = true; new_user_displayname_suffix = "🦆";
allow_check_for_updates = true;
# Set up delegation: https://docs.conduit.rs/delegation.html#automatic-recommended # Set up delegation: https://docs.conduit.rs/delegation.html#automatic-recommended
# This is primarily to make sliding sync work # This is primarily to make sliding sync work
well_known = { well_known = {
client = "https://${domain}"; client = "https://${domain}";
server = "${domain}:443"; server = "${domain}:443";
};
turn_uris =
let
address = "${config.services.coturn.realm}:${toString config.services.coturn.listening-port}";
tls-address = "${config.services.coturn.realm}:${toString config.services.coturn.tls-listening-port}";
in
[
"turn:${address}?transport=udp"
"turn:${address}?transport=tcp"
"turns:${tls-address}?transport=udp"
"turns:${tls-address}?transport=tcp"
];
}; };
};
turn_uris = coturn = {
let enable = true;
address = "${config.services.coturn.realm}:${toString config.services.coturn.listening-port}"; no-cli = true;
tls-address = "${config.services.coturn.realm}:${toString config.services.coturn.tls-listening-port}"; use-auth-secret = true;
in static-auth-secret-file = config.sops.secrets."turn/secret".path;
[ realm = turn-realm;
"turn:${address}?transport=udp" relay-ips = [ "116.202.158.55" ];
"turn:${address}?transport=tcp"
"turns:${tls-address}?transport=udp" # SSL config
"turns:${tls-address}?transport=tcp" pkey = "${config.security.acme.certs."tlater.net".directory}/key.pem";
]; cert = "${config.security.acme.certs."tlater.net".directory}/fullchain.pem";
# Based on suggestions from
# https://github.com/matrix-org/synapse/blob/develop/docs/turn-howto.md
# and
# https://www.foxypossibilities.com/2018/05/19/setting-up-a-turn-sever-for-matrix-on-nixos/
no-tcp-relay = true;
secure-stun = true;
extraConfig = ''
# Deny various local IP ranges, see
# https://www.rtcsec.com/article/cve-2020-26262-bypass-of-coturns-access-control-protection/
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
# *Allow* any IP addresses that we explicitly set as relay IPs
${concatMapStringsSep "\n" (ip: "allowed-peer-ip=${ip}") config.services.coturn.relay-ips}
# Various other security settings
no-tlsv1
no-tlsv1_1
# Monitoring
prometheus
'';
};
nginx.virtualHosts."${domain}" = {
useACMEHost = "tlater.net";
listen = [
{
addr = "0.0.0.0";
port = 80;
}
{
addr = "[::0]";
port = 80;
}
{
addr = "0.0.0.0";
port = 443;
ssl = true;
}
{
addr = "[::0]";
port = 443;
ssl = true;
}
{
addr = "0.0.0.0";
port = 8448;
ssl = true;
}
{
addr = "[::0]";
port = 8448;
ssl = true;
}
];
forceSSL = true;
enableHSTS = true;
extraConfig = ''
merge_slashes off;
'';
locations = {
"/_matrix" = {
proxyPass = "http://${cfg.settings.global.address}:${toString cfg.settings.global.port}";
# Recommended by conduit
extraConfig = ''
proxy_buffering off;
'';
};
"/.well-known/matrix" = {
proxyPass = "http://${cfg.settings.global.address}:${toString cfg.settings.global.port}";
};
};
};
backups.conduit = {
user = "root";
paths = [ "/var/lib/private/matrix-conduit/" ];
# Other services store their data in conduit, so no other services
# need to be shut down currently.
pauseServices = [ "conduit.service" ];
}; };
}; };
@ -60,122 +180,4 @@ in
systemd.services.coturn.serviceConfig.SupplementaryGroups = [ systemd.services.coturn.serviceConfig.SupplementaryGroups = [
config.security.acme.certs."tlater.net".group config.security.acme.certs."tlater.net".group
]; ];
services.coturn = {
enable = true;
no-cli = true;
use-auth-secret = true;
static-auth-secret-file = config.sops.secrets."turn/secret".path;
realm = turn-realm;
relay-ips = [ "116.202.158.55" ];
# SSL config
pkey = "${config.security.acme.certs."tlater.net".directory}/key.pem";
cert = "${config.security.acme.certs."tlater.net".directory}/fullchain.pem";
# Based on suggestions from
# https://github.com/matrix-org/synapse/blob/develop/docs/turn-howto.md
# and
# https://www.foxypossibilities.com/2018/05/19/setting-up-a-turn-sever-for-matrix-on-nixos/
no-tcp-relay = true;
secure-stun = true;
extraConfig = ''
# Deny various local IP ranges, see
# https://www.rtcsec.com/article/cve-2020-26262-bypass-of-coturns-access-control-protection/
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
# *Allow* any IP addresses that we explicitly set as relay IPs
${concatMapStringsSep "\n" (ip: "allowed-peer-ip=${ip}") config.services.coturn.relay-ips}
# Various other security settings
no-tlsv1
no-tlsv1_1
# Monitoring
prometheus
'';
};
services.nginx.virtualHosts."${domain}" = {
useACMEHost = "tlater.net";
listen = [
{
addr = "0.0.0.0";
port = 80;
}
{
addr = "[::0]";
port = 80;
}
{
addr = "0.0.0.0";
port = 443;
ssl = true;
}
{
addr = "[::0]";
port = 443;
ssl = true;
}
{
addr = "0.0.0.0";
port = 8448;
ssl = true;
}
{
addr = "[::0]";
port = 8448;
ssl = true;
}
];
forceSSL = true;
enableHSTS = true;
extraConfig = ''
merge_slashes off;
'';
locations = {
"/_matrix" = {
proxyPass = "http://${cfg.settings.global.address}:${toString cfg.settings.global.port}";
# Recommended by conduit
extraConfig = ''
proxy_buffering off;
'';
};
"/.well-known/matrix" = {
proxyPass = "http://${cfg.settings.global.address}:${toString cfg.settings.global.port}";
};
};
};
services.backups.conduit = {
user = "root";
paths = [ "/var/lib/private/matrix-conduit/" ];
# Other services store their data in conduit, so no other services
# need to be shut down currently.
pauseServices = [ "conduit.service" ];
};
} }

View file

@ -74,9 +74,7 @@ in
services.matrix-hookshot = { services.matrix-hookshot = {
enable = true; enable = true;
serviceDependencies = [ serviceDependencies = [ "conduit.service" ];
"conduit.service"
];
registrationFile = "/run/matrix-hookshot/registration.yaml"; registrationFile = "/run/matrix-hookshot/registration.yaml";
@ -126,15 +124,11 @@ in
listeners = [ listeners = [
{ {
port = 9000; port = 9000;
resources = [ resources = [ "webhooks" ];
"webhooks"
];
} }
{ {
port = 9001; port = 9001;
resources = [ resources = [ "metrics" ];
"metrics"
];
} }
]; ];

View file

@ -8,9 +8,7 @@
security.crowdsec = { security.crowdsec = {
enable = true; enable = true;
parserWhitelist = [ parserWhitelist = [ "10.45.249.2" ];
"10.45.249.2"
];
extraGroups = [ extraGroups = [
"systemd-journal" "systemd-journal"
@ -21,25 +19,19 @@
{ {
source = "journalctl"; source = "journalctl";
labels.type = "syslog"; labels.type = "syslog";
journalctl_filter = [ journalctl_filter = [ "SYSLOG_IDENTIFIER=Nextcloud" ];
"SYSLOG_IDENTIFIER=Nextcloud"
];
} }
{ {
source = "journalctl"; source = "journalctl";
labels.type = "syslog"; labels.type = "syslog";
journalctl_filter = [ journalctl_filter = [ "SYSLOG_IDENTIFIER=sshd-session" ];
"SYSLOG_IDENTIFIER=sshd-session"
];
} }
{ {
labels.type = "nginx"; labels.type = "nginx";
filenames = filenames =
[ [ "/var/log/nginx/*.log" ]
"/var/log/nginx/*.log"
]
++ lib.mapAttrsToList ( ++ lib.mapAttrsToList (
vHost: _: "/var/log/nginx/${vHost}/access.log" vHost: _: "/var/log/nginx/${vHost}/access.log"
) config.services.nginx.virtualHosts; ) config.services.nginx.virtualHosts;

View file

@ -11,37 +11,39 @@ in
{ {
imports = [ flake-inputs.foundryvtt.nixosModules.foundryvtt ]; imports = [ flake-inputs.foundryvtt.nixosModules.foundryvtt ];
services.foundryvtt = { services = {
enable = true; foundryvtt = {
hostName = domain; enable = true;
minifyStaticFiles = true; hostName = domain;
proxySSL = true; minifyStaticFiles = true;
proxyPort = 443; proxySSL = true;
package = flake-inputs.foundryvtt.packages.${pkgs.system}.foundryvtt_11; proxyPort = 443;
package = flake-inputs.foundryvtt.packages.${pkgs.system}.foundryvtt_11;
};
nginx.virtualHosts."${domain}" =
let
inherit (config.services.foundryvtt) port;
in
{
forceSSL = true;
useACMEHost = "tlater.net";
enableHSTS = true;
locations."/" = {
proxyWebsockets = true;
proxyPass = "http://localhost:${toString port}";
};
};
backups.foundryvtt = {
user = "foundryvtt";
paths = [ config.services.foundryvtt.dataDir ];
pauseServices = [ "foundryvtt.service" ];
};
}; };
# Want to start it manually when I need it, not have it constantly # Want to start it manually when I need it, not have it constantly
# running # running
systemd.services.foundryvtt.wantedBy = lib.mkForce [ ]; systemd.services.foundryvtt.wantedBy = lib.mkForce [ ];
services.nginx.virtualHosts."${domain}" =
let
inherit (config.services.foundryvtt) port;
in
{
forceSSL = true;
useACMEHost = "tlater.net";
enableHSTS = true;
locations."/" = {
proxyWebsockets = true;
proxyPass = "http://localhost:${toString port}";
};
};
services.backups.foundryvtt = {
user = "foundryvtt";
paths = [ config.services.foundryvtt.dataDir ];
pauseServices = [ "foundryvtt.service" ];
};
} }

View file

@ -8,24 +8,68 @@ let
domain = "gitea.${config.services.nginx.domain}"; domain = "gitea.${config.services.nginx.domain}";
in in
{ {
services.forgejo = { services = {
enable = true; forgejo = {
database.type = "postgres"; enable = true;
database.type = "postgres";
settings = { settings = {
server = { server = {
DOMAIN = domain; DOMAIN = domain;
HTTP_ADDR = "127.0.0.1"; HTTP_ADDR = "127.0.0.1";
ROOT_URL = "https://${domain}/"; ROOT_URL = "https://${domain}/";
SSH_PORT = 2222; SSH_PORT = 2222;
};
metrics = {
ENABLED = true;
TOKEN = "#metricstoken#";
};
service.DISABLE_REGISTRATION = true;
session.COOKIE_SECURE = true;
};
};
# Set up SSL
nginx.virtualHosts."${domain}" =
let
httpAddress = config.services.forgejo.settings.server.HTTP_ADDR;
httpPort = config.services.forgejo.settings.server.HTTP_PORT;
in
{
forceSSL = true;
useACMEHost = "tlater.net";
enableHSTS = true;
locations."/".proxyPass = "http://${httpAddress}:${toString httpPort}";
locations."/metrics" = {
extraConfig = ''
access_log off;
allow 127.0.0.1;
${lib.optionalString config.networking.enableIPv6 "allow ::1;"}
deny all;
'';
};
}; };
metrics = { backups.forgejo = {
ENABLED = true; user = "forgejo";
TOKEN = "#metricstoken#"; paths = [
"/var/lib/forgejo/forgejo-db.sql"
"/var/lib/forgejo/repositories/"
"/var/lib/forgejo/data/"
"/var/lib/forgejo/custom/"
# Conf is backed up via nix
];
preparation = {
packages = [ config.services.postgresql.package ];
text = "pg_dump ${config.services.forgejo.database.name} --file=/var/lib/forgejo/forgejo-db.sql";
}; };
service.DISABLE_REGISTRATION = true; cleanup = {
session.COOKIE_SECURE = true; packages = [ pkgs.coreutils ];
text = "rm /var/lib/forgejo/forgejo-db.sql";
};
pauseServices = [ "forgejo.service" ];
}; };
}; };
@ -36,46 +80,4 @@ in
runConfig = "${config.services.forgejo.customDir}/conf/app.ini"; runConfig = "${config.services.forgejo.customDir}/conf/app.ini";
in in
[ "+${replaceSecretBin} '#metricstoken#' '${secretPath}' '${runConfig}'" ]; [ "+${replaceSecretBin} '#metricstoken#' '${secretPath}' '${runConfig}'" ];
# Set up SSL
services.nginx.virtualHosts."${domain}" =
let
httpAddress = config.services.forgejo.settings.server.HTTP_ADDR;
httpPort = config.services.forgejo.settings.server.HTTP_PORT;
in
{
forceSSL = true;
useACMEHost = "tlater.net";
enableHSTS = true;
locations."/".proxyPass = "http://${httpAddress}:${toString httpPort}";
locations."/metrics" = {
extraConfig = ''
access_log off;
allow 127.0.0.1;
${lib.optionalString config.networking.enableIPv6 "allow ::1;"}
deny all;
'';
};
};
services.backups.forgejo = {
user = "forgejo";
paths = [
"/var/lib/forgejo/forgejo-db.sql"
"/var/lib/forgejo/repositories/"
"/var/lib/forgejo/data/"
"/var/lib/forgejo/custom/"
# Conf is backed up via nix
];
preparation = {
packages = [ config.services.postgresql.package ];
text = "pg_dump ${config.services.forgejo.database.name} --file=/var/lib/forgejo/forgejo-db.sql";
};
cleanup = {
packages = [ pkgs.coreutils ];
text = "rm /var/lib/forgejo/forgejo-db.sql";
};
pauseServices = [ "forgejo.service" ];
};
} }

View file

@ -74,7 +74,7 @@ in
listenAddress = "127.0.0.1"; listenAddress = "127.0.0.1";
group = "nginx"; group = "nginx";
settings.namespaces = lib.mapAttrsToList (name: virtualHost: { settings.namespaces = lib.mapAttrsToList (name: _: {
inherit name; inherit name;
metrics_override.prefix = "nginxlog"; metrics_override.prefix = "nginxlog";
namespace_label = "vhost"; namespace_label = "vhost";

View file

@ -38,7 +38,7 @@ in
services.victoriametrics.scrapeConfigs = mkOption { services.victoriametrics.scrapeConfigs = mkOption {
type = types.attrsOf ( type = types.attrsOf (
types.submodule ( types.submodule (
{ name, self, ... }: { name, ... }:
{ {
options = { options = {
job_name = mkOption { job_name = mkOption {
@ -106,35 +106,37 @@ in
# module is an intractable mess # module is an intractable mess
wantedBy = [ "multi-user.target" ]; wantedBy = [ "multi-user.target" ];
after = [ "network.target" ]; after = [ "network.target" ];
serviceConfig.Restart = mkDefault "always"; serviceConfig = {
serviceConfig.PrivateTmp = mkDefault true; Restart = mkDefault "always";
serviceConfig.WorkingDirectory = mkDefault /tmp; PrivateTmp = mkDefault true;
serviceConfig.DynamicUser = mkDefault true; WorkingDirectory = mkDefault /tmp;
# Hardening DynamicUser = mkDefault true;
serviceConfig.CapabilityBoundingSet = mkDefault [ "" ]; # Hardening
serviceConfig.DeviceAllow = [ "" ]; CapabilityBoundingSet = mkDefault [ "" ];
serviceConfig.LockPersonality = true; DeviceAllow = [ "" ];
serviceConfig.MemoryDenyWriteExecute = true; LockPersonality = true;
serviceConfig.NoNewPrivileges = true; MemoryDenyWriteExecute = true;
serviceConfig.PrivateDevices = mkDefault true; NoNewPrivileges = true;
serviceConfig.ProtectClock = mkDefault true; PrivateDevices = mkDefault true;
serviceConfig.ProtectControlGroups = true; ProtectClock = mkDefault true;
serviceConfig.ProtectHome = true; ProtectControlGroups = true;
serviceConfig.ProtectHostname = true; ProtectHome = true;
serviceConfig.ProtectKernelLogs = true; ProtectHostname = true;
serviceConfig.ProtectKernelModules = true; ProtectKernelLogs = true;
serviceConfig.ProtectKernelTunables = true; ProtectKernelModules = true;
serviceConfig.ProtectSystem = mkDefault "strict"; ProtectKernelTunables = true;
serviceConfig.RemoveIPC = true; ProtectSystem = mkDefault "strict";
serviceConfig.RestrictAddressFamilies = [ RemoveIPC = true;
"AF_INET" RestrictAddressFamilies = [
"AF_INET6" "AF_INET"
]; "AF_INET6"
serviceConfig.RestrictNamespaces = true; ];
serviceConfig.RestrictRealtime = true; RestrictNamespaces = true;
serviceConfig.RestrictSUIDSGID = true; RestrictRealtime = true;
serviceConfig.SystemCallArchitectures = "native"; RestrictSUIDSGID = true;
serviceConfig.UMask = "0077"; SystemCallArchitectures = "native";
UMask = "0077";
};
} }
exporter.serviceOpts exporter.serviceOpts
] ]
@ -144,7 +146,7 @@ in
{ {
vmagent-scrape-exporters = vmagent-scrape-exporters =
let let
listenAddress = config.services.victoriametrics.listenAddress; inherit (config.services.victoriametrics) listenAddress;
vmAddr = (lib.optionalString (lib.hasPrefix ":" listenAddress) "127.0.0.1") + listenAddress; vmAddr = (lib.optionalString (lib.hasPrefix ":" listenAddress) "127.0.0.1") + listenAddress;
promscrape = yaml.generate "prometheus.yml" { promscrape = yaml.generate "prometheus.yml" {
scrape_configs = lib.mapAttrsToList ( scrape_configs = lib.mapAttrsToList (
@ -153,7 +155,7 @@ in
inherit (scrape) job_name; inherit (scrape) job_name;
static_configs = static_configs =
scrape.static_configs scrape.static_configs
++ lib.optional (scrape.targets != [ ]) { targets = scrape.targets; }; ++ lib.optional (scrape.targets != [ ]) { inherit (scrape) targets; };
} scrape.extraSettings } scrape.extraSettings
) config.services.victoriametrics.scrapeConfigs; ) config.services.victoriametrics.scrapeConfigs;
}; };
@ -212,7 +214,7 @@ in
services.victoriametrics.scrapeConfigs = services.victoriametrics.scrapeConfigs =
let let
allExporters = lib.mapAttrs (name: exporter: { inherit (exporter) listenAddress port; }) ( allExporters = lib.mapAttrs (_: exporter: { inherit (exporter) listenAddress port; }) (
(lib.filterAttrs ( (lib.filterAttrs (
name: exporter: name: exporter:
# A bunch of deprecated exporters that need to be ignored # A bunch of deprecated exporters that need to be ignored

View file

@ -1,8 +1,4 @@
{ { config, lib, ... }:
config,
lib,
...
}:
let let
cfg = config.services.victorialogs; cfg = config.services.victorialogs;
in in

View file

@ -9,93 +9,95 @@ let
hostName = "nextcloud.${config.services.nginx.domain}"; hostName = "nextcloud.${config.services.nginx.domain}";
in in
{ {
services.nextcloud = { services = {
inherit hostName; nextcloud = {
inherit hostName;
package = nextcloud; package = nextcloud;
phpPackage = lib.mkForce ( phpPackage = lib.mkForce (
pkgs.php.override { pkgs.php.override {
packageOverrides = final: prev: { packageOverrides = _: prev: {
extensions = prev.extensions // { extensions = prev.extensions // {
pgsql = prev.extensions.pgsql.overrideAttrs (old: { pgsql = prev.extensions.pgsql.overrideAttrs (_: {
configureFlags = [ "--with-pgsql=${lib.getDev config.services.postgresql.package}" ]; configureFlags = [ "--with-pgsql=${lib.getDev config.services.postgresql.package}" ];
}); });
pdo_pgsql = prev.extensions.pdo_pgsql.overrideAttrs (old: { pdo_pgsql = prev.extensions.pdo_pgsql.overrideAttrs (_: {
configureFlags = [ "--with-pdo-pgsql=${lib.getDev config.services.postgresql.package}" ]; configureFlags = [ "--with-pdo-pgsql=${lib.getDev config.services.postgresql.package}" ];
}); });
};
}; };
}; }
} );
); enable = true;
enable = true; maxUploadSize = "2G";
maxUploadSize = "2G"; https = true;
https = true;
configureRedis = true; configureRedis = true;
config = { config = {
dbtype = "pgsql"; dbtype = "pgsql";
dbhost = "/run/postgresql"; dbhost = "/run/postgresql";
adminuser = "tlater"; adminuser = "tlater";
adminpassFile = config.sops.secrets."nextcloud/tlater".path; adminpassFile = config.sops.secrets."nextcloud/tlater".path;
};
settings = {
default_phone_region = "AT";
overwriteprotocol = "https";
};
phpOptions = {
"opcache.interned_strings_buffer" = "16";
};
extraApps = {
inherit (config.services.nextcloud.package.packages.apps)
calendar
contacts
cookbook
news
;
};
}; };
settings = { # Set up SSL
default_phone_region = "AT"; nginx.virtualHosts."${hostName}" = {
overwriteprotocol = "https"; forceSSL = true;
useACMEHost = "tlater.net";
# The upstream module already adds HSTS
}; };
phpOptions = { backups.nextcloud = {
"opcache.interned_strings_buffer" = "16"; user = "nextcloud";
}; paths = [
"/var/lib/nextcloud/nextcloud-db.sql"
extraApps = { "/var/lib/nextcloud/data/"
inherit (config.services.nextcloud.package.packages.apps) "/var/lib/nextcloud/config/config.php"
calendar ];
contacts preparation = {
cookbook packages = [
news config.services.postgresql.package
; config.services.nextcloud.occ
];
text = ''
nextcloud-occ maintenance:mode --on
pg_dump ${config.services.nextcloud.config.dbname} --file=/var/lib/nextcloud/nextcloud-db.sql
'';
};
cleanup = {
packages = [
pkgs.coreutils
config.services.nextcloud.occ
];
text = ''
rm /var/lib/nextcloud/nextcloud-db.sql
nextcloud-occ maintenance:mode --off
'';
};
}; };
}; };
# Ensure that this service doesn't start before postgres is ready # Ensure that this service doesn't start before postgres is ready
systemd.services.nextcloud-setup.after = [ "postgresql.service" ]; systemd.services.nextcloud-setup.after = [ "postgresql.service" ];
# Set up SSL
services.nginx.virtualHosts."${hostName}" = {
forceSSL = true;
useACMEHost = "tlater.net";
# The upstream module already adds HSTS
};
services.backups.nextcloud = {
user = "nextcloud";
paths = [
"/var/lib/nextcloud/nextcloud-db.sql"
"/var/lib/nextcloud/data/"
"/var/lib/nextcloud/config/config.php"
];
preparation = {
packages = [
config.services.postgresql.package
config.services.nextcloud.occ
];
text = ''
nextcloud-occ maintenance:mode --on
pg_dump ${config.services.nextcloud.config.dbname} --file=/var/lib/nextcloud/nextcloud-db.sql
'';
};
cleanup = {
packages = [
pkgs.coreutils
config.services.nextcloud.occ
];
text = ''
rm /var/lib/nextcloud/nextcloud-db.sql
nextcloud-occ maintenance:mode --off
'';
};
};
} }

View file

@ -1,6 +1,6 @@
{ config, ... }: { config, ... }:
let let
domain = config.services.nginx.domain; inherit (config.services.nginx) domain;
in in
{ {
services.tlaternet-webserver = { services.tlaternet-webserver = {

View file

@ -121,8 +121,6 @@
run-vm = { run-vm = {
type = "app"; type = "app";
program = program =
let
in
(pkgs.writeShellScript "" '' (pkgs.writeShellScript "" ''
${vm.config.system.build.vm.outPath}/bin/run-testvm-vm ${vm.config.system.build.vm.outPath}/bin/run-testvm-vm
'').outPath; '').outPath;

View file

@ -267,9 +267,7 @@ in
}; };
}; };
systemd.packages = [ systemd.packages = [ cfg.package ];
cfg.package
];
environment = { environment = {
systemPackages = [ systemPackages = [

View file

@ -6,10 +6,11 @@
... ...
}: }:
let let
inherit (flake-inputs.self.packages.${pkgs.system}) crowdsec-firewall-bouncer;
crowdsecCfg = config.security.crowdsec; crowdsecCfg = config.security.crowdsec;
cfg = crowdsecCfg.remediationComponents.firewallBouncer; cfg = crowdsecCfg.remediationComponents.firewallBouncer;
settingsFormat = pkgs.formats.yaml { }; settingsFormat = pkgs.formats.yaml { };
crowdsec-firewall-bouncer = flake-inputs.self.packages.${pkgs.system}.crowdsec-firewall-bouncer;
in in
{ {
options.security.crowdsec.remediationComponents.firewallBouncer = { options.security.crowdsec.remediationComponents.firewallBouncer = {
@ -31,9 +32,7 @@ in
security.crowdsec.remediationComponents.firewallBouncer.settings = { security.crowdsec.remediationComponents.firewallBouncer.settings = {
mode = lib.mkDefault "${if config.networking.nftables.enable then "nftables" else "iptables"}"; mode = lib.mkDefault "${if config.networking.nftables.enable then "nftables" else "iptables"}";
log_mode = "stdout"; log_mode = "stdout";
iptables_chains = [ iptables_chains = [ "nixos-fw" ];
"nixos-fw"
];
# Don't let users easily override this; unfortunately we need to # Don't let users easily override this; unfortunately we need to
# set up this key through substitution at runtime. # set up this key through substitution at runtime.
@ -78,9 +77,7 @@ in
requiredBy = [ "crowdsec.service" ]; requiredBy = [ "crowdsec.service" ];
path = path =
lib.optionals (cfg.settings.mode == "ipset" || cfg.settings.mode == "iptables") [ lib.optionals (cfg.settings.mode == "ipset" || cfg.settings.mode == "iptables") [ pkgs.ipset ]
pkgs.ipset
]
++ lib.optional (cfg.settings.mode == "iptables") pkgs.iptables ++ lib.optional (cfg.settings.mode == "iptables") pkgs.iptables
++ lib.optional (cfg.settings.mode == "nftables") pkgs.nftables; ++ lib.optional (cfg.settings.mode == "nftables") pkgs.nftables;
}; };

View file

@ -1,5 +1 @@
{ { imports = [ ./cs-firewall-bouncer.nix ]; }
imports = [
./cs-firewall-bouncer.nix
];
}

View file

@ -1,4 +1 @@
{ { sources }: sources.crowdsec-hub.src
sources,
}:
sources.crowdsec-hub.src