Compare commits

..

2 commits

30 changed files with 728 additions and 763 deletions

View file

@ -9,6 +9,3 @@ fd138d45e6a2cad89fead6e9f246ba282070d6b7
# Switch to alejandra formatting # Switch to alejandra formatting
046a88905ddfa7f9edc3291c310dbb985dee34f9 046a88905ddfa7f9edc3291c310dbb985dee34f9
# Apply wide linting
63b3cbe00be80ccb4b221aad64eb657ae5c96d70

View file

@ -1,61 +0,0 @@
{
self,
nixpkgs,
deploy-rs,
system,
...
}:
let
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 =
{
name,
packages,
check,
}:
pkgs.stdenvNoCC.mkDerivation {
inherit name;
src = nixpkgs.lib.cleanSourceWith {
src = self;
filter = nixpkgs.lib.cleanSourceFilter;
};
dontPatch = true;
dontConfigure = true;
dontBuild = true;
dontInstall = true;
dontFixup = true;
doCheck = true;
checkInputs = nixpkgs.lib.singleton pkgs.nushell ++ packages;
checkPhase = ''
nu ${check}
'';
};
in
nixpkgs.lib.recursiveUpdate {
lints = runNuCheck {
name = "lints";
packages = [
pkgs.deadnix
pkgs.nixfmt-rfc-style
pkgs.shellcheck
statix'
];
check = ./lints.nu;
};
} (deploy-rs.lib.${system}.deployChecks self.deploy)

View file

@ -1,39 +0,0 @@
#!/usr/bin/env nu
let shell_files = ls **/*.sh | get name
let nix_files = ls **/*.nix | where name !~ "hardware-configuration.nix|_sources" | get name
let linters = [
([shellcheck] ++ $shell_files)
([nixfmt --check --strict] ++ $nix_files)
([deadnix --fail] ++ $nix_files)
([statix check] ++ $nix_files)
]
mkdir $env.out
def run-linter [linterArgs: list<string>] {
print $'Running ($linterArgs.0)...'
let exit_code = try {
^$linterArgs.0 ...($linterArgs | skip 1)
$env.LAST_EXIT_CODE
} catch {|e| $e.exit_code}
[$linterArgs.0, $exit_code]
}
let results = $linters | each {|linter| run-linter $linter}
print 'Linter results:'
let success = $results | each {|result|
match $result.1 {
0 => {print $'(ansi green)($result.0)(ansi reset)'}
_ => {print $'(ansi red)($result.0)(ansi reset)'}
}
$result.1
} | math sum
exit $success

View file

@ -1,5 +1,7 @@
{ {
config, config,
pkgs,
lib,
modulesPath, modulesPath,
flake-inputs, flake-inputs,
... ...
@ -19,8 +21,8 @@
./services/crowdsec.nix ./services/crowdsec.nix
./services/foundryvtt.nix ./services/foundryvtt.nix
./services/gitea.nix ./services/gitea.nix
./services/immich.nix
./services/metrics ./services/metrics
./services/minecraft.nix
./services/nextcloud.nix ./services/nextcloud.nix
./services/webserver.nix ./services/webserver.nix
./services/wireguard.nix ./services/wireguard.nix
@ -30,7 +32,13 @@
./sops.nix ./sops.nix
]; ];
nixpkgs.overlays = [ (_: prev: { local = import ../pkgs { pkgs = prev; }; }) ]; nixpkgs.overlays = [
(final: prev: {
local = import ../pkgs {
pkgs = prev;
};
})
];
nix = { nix = {
extraOptions = '' extraOptions = ''
@ -63,8 +71,6 @@
8448 8448
# starbound # starbound
21025 21025
# Minecraft
25565
config.services.coturn.listening-port config.services.coturn.listening-port
config.services.coturn.tls-listening-port config.services.coturn.tls-listening-port
@ -73,9 +79,6 @@
]; ];
allowedUDPPorts = [ allowedUDPPorts = [
# More minecraft
25565
config.services.coturn.listening-port config.services.coturn.listening-port
config.services.coturn.tls-listening-port config.services.coturn.tls-listening-port
config.services.coturn.alt-listening-port config.services.coturn.alt-listening-port

View file

@ -80,17 +80,6 @@
inherit mountOptions; inherit mountOptions;
mountpoint = "/var"; mountpoint = "/var";
}; };
"/volume/var/lib/private/matrix-conduit" = {
mountOptions = [
# Explicitly don't compress here, since
# conduwuit's database does compression by
# itself, and relies on being able to read the
# raw file data from disk (which is impossible
# if btrfs compresses it)
"noatime"
];
mountpoint = "/var/lib/private/matrix-conduit";
};
"/volume/nix-store" = { "/volume/nix-store" = {
inherit mountOptions; inherit mountOptions;
mountpoint = "/nix"; mountpoint = "/nix";

View file

@ -6,35 +6,26 @@
boot.kernelParams = [ "nomodeset" ]; boot.kernelParams = [ "nomodeset" ];
networking.hostName = "testvm"; networking.hostName = "testvm";
services = {
# Sets the base domain for nginx to a local domain so that we can # Sets the base domain for nginx to a local domain so that we can
# easily test locally with the VM. # easily test locally with the VM.
nginx.domain = "dev.local"; services.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 = [ "192.168.9.1" ]; gateway = [
"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.
@ -43,6 +34,14 @@
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,7 +1,6 @@
{ config, lib, ... }: { config, lib, ... }:
{ {
services = { services.nginx = {
nginx = {
enable = true; enable = true;
recommendedTlsSettings = true; recommendedTlsSettings = true;
recommendedOptimisation = true; recommendedOptimisation = true;
@ -20,7 +19,7 @@
''; '';
}; };
logrotate.settings = services.logrotate.settings =
{ {
# Override the default, just keep fewer logs # Override the default, just keep fewer logs
nginx.rotate = 6; nginx.rotate = 6;
@ -37,14 +36,6 @@
} }
) config.services.nginx.virtualHosts; ) 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: _:
# #
@ -75,4 +66,11 @@
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 (
{ name, ... }: { config, name, ... }:
{ {
options = { options = {
user = lib.mkOption { user = lib.mkOption {
@ -246,7 +246,7 @@ in
}; };
} }
// lib.mapAttrs' ( // lib.mapAttrs' (
name: _: name: backup:
lib.nameValuePair "backup-${name}" { lib.nameValuePair "backup-${name}" {
wantedBy = [ "timers.target" ]; wantedBy = [ "timers.target" ];
timerConfig = { timerConfig = {

View file

@ -1,5 +1,4 @@
{ {
pkgs,
config, config,
lib, lib,
... ...
@ -17,15 +16,12 @@ in
./matrix-hookshot.nix ./matrix-hookshot.nix
]; ];
services = { services.matrix-conduit = {
matrix-conduit = {
enable = true; enable = true;
package = pkgs.matrix-continuwuity;
settings.global = { settings.global = {
address = "127.0.0.1"; address = "127.0.0.1";
server_name = domain; server_name = domain;
new_user_displayname_suffix = "🦆"; database_backend = "rocksdb";
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
@ -48,7 +44,17 @@ in
}; };
}; };
coturn = { # Pass in the TURN secret via EnvironmentFile, not supported by
# upstream module currently.
#
# See also https://gitlab.com/famedly/conduit/-/issues/314
systemd.services.conduit.serviceConfig.EnvironmentFile = config.sops.secrets."turn/env".path;
systemd.services.coturn.serviceConfig.SupplementaryGroups = [
config.security.acme.certs."tlater.net".group
];
services.coturn = {
enable = true; enable = true;
no-cli = true; no-cli = true;
use-auth-secret = true; use-auth-secret = true;
@ -104,7 +110,7 @@ in
''; '';
}; };
nginx.virtualHosts."${domain}" = { services.nginx.virtualHosts."${domain}" = {
useACMEHost = "tlater.net"; useACMEHost = "tlater.net";
listen = [ listen = [
@ -158,25 +164,11 @@ in
}; };
}; };
backups.conduit = { services.backups.conduit = {
user = "root"; user = "root";
paths = [ "/var/lib/private/matrix-conduit/" ]; paths = [ "/var/lib/private/matrix-conduit/" ];
# Other services store their data in conduit, so no other services # Other services store their data in conduit, so no other services
# need to be shut down currently. # need to be shut down currently.
pauseServices = [ "conduit.service" ]; pauseServices = [ "conduit.service" ];
}; };
};
systemd.services.conduit.serviceConfig = {
ExecStart = lib.mkForce "${config.services.matrix-conduit.package}/bin/conduwuit";
# Pass in the TURN secret via EnvironmentFile, not supported by
# upstream module currently.
#
# See also https://gitlab.com/famedly/conduit/-/issues/314
EnvironmentFile = config.sops.secrets."turn/env".path;
};
systemd.services.coturn.serviceConfig.SupplementaryGroups = [
config.security.acme.certs."tlater.net".group
];
} }

View file

@ -29,29 +29,16 @@ let
}; };
# Encryption support # Encryption support
# TODO(tlater): Enable when extraSettings = {
# https://github.com/matrix-org/matrix-hookshot/issues/1060 is "de.sorunome.msc2409.push_ephemeral" = true;
# fixed push_ephemeral = true;
# extraSettings = { "org.matrix.msc3202" = true;
# "de.sorunome.msc2409.push_ephemeral" = true; };
# push_ephemeral = true;
# "org.matrix.msc3202" = true;
# };
runtimeRegistration = "${cfg.registrationFile}"; runtimeRegistration = "${cfg.registrationFile}";
}; };
in in
{ {
# users = {
# users.matrix-hookshot = {
# home = "/run/matrix-hookshot";
# group = "matrix-hookshot";
# isSystemUser = true;
# };
# groups.matrix-hookshot = { };
# };
systemd.services.matrix-hookshot = { systemd.services.matrix-hookshot = {
serviceConfig = { serviceConfig = {
Type = lib.mkForce "exec"; Type = lib.mkForce "exec";
@ -62,7 +49,6 @@ in
# Some library in matrix-hookshot wants a home directory # Some library in matrix-hookshot wants a home directory
Environment = [ "HOME=/run/matrix-hookshot" ]; Environment = [ "HOME=/run/matrix-hookshot" ];
# User = "matrix-hookshot";
DynamicUser = true; DynamicUser = true;
StateDirectory = "matrix-hookshot"; StateDirectory = "matrix-hookshot";
RuntimeDirectory = "matrix-hookshot"; RuntimeDirectory = "matrix-hookshot";
@ -76,11 +62,7 @@ in
ProtectKernelModules = true; ProtectKernelModules = true;
ProtectKernelLogs = true; ProtectKernelLogs = true;
ProtectControlGroups = true; ProtectControlGroups = true;
RestrictAddressFamilies = [ RestrictAddressFamilies = [ "AF_INET AF_INET6" ];
# "AF_UNIX"
"AF_INET"
"AF_INET6"
];
LockPersonality = true; LockPersonality = true;
RestrictRealtime = true; RestrictRealtime = true;
ProtectProc = "invisible"; ProtectProc = "invisible";
@ -89,15 +71,12 @@ in
}; };
}; };
# services.redis.servers.matrix-hookshot = {
# enable = true;
# user = "matrix-hookshot";
# };
services.matrix-hookshot = { services.matrix-hookshot = {
enable = true; enable = true;
serviceDependencies = [ "conduit.service" ]; serviceDependencies = [
"conduit.service"
];
registrationFile = "/run/matrix-hookshot/registration.yaml"; registrationFile = "/run/matrix-hookshot/registration.yaml";
@ -112,8 +91,6 @@ in
bot.displayname = "Hookshot"; bot.displayname = "Hookshot";
# cache.redisUri = "redis://${config.services.redis.servers.matrix-hookshot.unixSocket}";
generic = { generic = {
enabled = true; enabled = true;
outbound = false; outbound = false;
@ -123,10 +100,7 @@ in
allowJsTransformationFunctions = true; allowJsTransformationFunctions = true;
}; };
# TODO(tlater): Enable when encryption.storagePath = "/var/lib/matrix-hookshot/cryptostore";
# https://github.com/matrix-org/matrix-hookshot/issues/1060 is
# fixed
# encryption.storagePath = "/var/lib/matrix-hookshot/cryptostore";
permissions = [ permissions = [
{ {
@ -152,15 +126,19 @@ in
listeners = [ listeners = [
{ {
port = 9000; port = 9000;
resources = [ "webhooks" ]; resources = [
"webhooks"
];
} }
{ {
port = 9001; port = 9001;
resources = [ "metrics" ]; resources = [
"metrics"
];
} }
]; ];
metrics.enabled = true; metrics.enable = true;
}; };
}; };
} }

View file

@ -8,7 +8,21 @@
security.crowdsec = { security.crowdsec = {
enable = true; enable = true;
parserWhitelist = [ "10.45.249.2" ]; parserWhitelist = [
"10.45.249.2"
];
extraConfig."postoverflows/s01-whitelist/matrix-whitelist.yaml" = {
name = "tetsumaki/matrix";
description = "custom matrix whitelist";
whitelist = {
reason = "whitelist false positive for matrix";
expression = [
"evt.Overflow.Alert.Events[0].GetMeta('target_fqdn') == '${config.services.matrix-conduit.settings.global.server_name}'"
"evt.Overflow.Alert.GetScenario() in ['crowdsecurity/http-probing', 'crowdsecurity/http-crawl-non_statics']"
];
};
};
extraGroups = [ extraGroups = [
"systemd-journal" "systemd-journal"
@ -19,19 +33,25 @@
{ {
source = "journalctl"; source = "journalctl";
labels.type = "syslog"; labels.type = "syslog";
journalctl_filter = [ "SYSLOG_IDENTIFIER=Nextcloud" ]; journalctl_filter = [
"SYSLOG_IDENTIFIER=Nextcloud"
];
} }
{ {
source = "journalctl"; source = "journalctl";
labels.type = "syslog"; labels.type = "syslog";
journalctl_filter = [ "SYSLOG_IDENTIFIER=sshd-session" ]; journalctl_filter = [
"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;
@ -47,36 +67,4 @@
}; };
}; };
}; };
# Add whitelists for matrix
systemd.tmpfiles.settings."10-matrix" =
let
stateDir = config.security.crowdsec.stateDirectory;
in
{
"${stateDir}/config/postoverflows".d = {
user = "crowdsec";
group = "crowdsec";
mode = "0700";
};
"${stateDir}/config/postoverflows/s01-whitelist".d = {
user = "crowdsec";
group = "crowdsec";
mode = "0700";
};
"${stateDir}/config/postoverflows/s01-whitelist/matrix-whitelist.yaml"."L+".argument =
((pkgs.formats.yaml { }).generate "crowdsec-matrix-whitelist.yaml" {
name = "tetsumaki/matrix";
description = "custom matrix whitelist";
whitelist = {
reason = "whitelist false positive for matrix";
expression = [
"evt.Overflow.Alert.Events[0].GetMeta('target_fqdn') == '${config.services.matrix-conduit.settings.global.server_name}'"
"evt.Overflow.Alert.GetScenario() in ['crowdsecurity/http-probing', 'crowdsecurity/http-crawl-non_statics']"
];
};
}).outPath;
};
} }

View file

@ -11,17 +11,20 @@ in
{ {
imports = [ flake-inputs.foundryvtt.nixosModules.foundryvtt ]; imports = [ flake-inputs.foundryvtt.nixosModules.foundryvtt ];
services = { services.foundryvtt = {
foundryvtt = {
enable = true; enable = true;
hostName = domain; hostName = domain;
minifyStaticFiles = true; minifyStaticFiles = true;
proxySSL = true; proxySSL = true;
proxyPort = 443; proxyPort = 443;
package = flake-inputs.foundryvtt.packages.${pkgs.system}.foundryvtt_13; package = flake-inputs.foundryvtt.packages.${pkgs.system}.foundryvtt_11;
}; };
nginx.virtualHosts."${domain}" = # Want to start it manually when I need it, not have it constantly
# running
systemd.services.foundryvtt.wantedBy = lib.mkForce [ ];
services.nginx.virtualHosts."${domain}" =
let let
inherit (config.services.foundryvtt) port; inherit (config.services.foundryvtt) port;
in in
@ -36,14 +39,9 @@ in
}; };
}; };
backups.foundryvtt = { services.backups.foundryvtt = {
user = "foundryvtt"; user = "foundryvtt";
paths = [ config.services.foundryvtt.dataDir ]; paths = [ config.services.foundryvtt.dataDir ];
pauseServices = [ "foundryvtt.service" ]; pauseServices = [ "foundryvtt.service" ];
}; };
};
# Want to start it manually when I need it, not have it constantly
# running
systemd.services.foundryvtt.wantedBy = lib.mkForce [ ];
} }

View file

@ -8,8 +8,7 @@ let
domain = "gitea.${config.services.nginx.domain}"; domain = "gitea.${config.services.nginx.domain}";
in in
{ {
services = { services.forgejo = {
forgejo = {
enable = true; enable = true;
database.type = "postgres"; database.type = "postgres";
@ -30,8 +29,16 @@ in
}; };
}; };
systemd.services.forgejo.serviceConfig.ExecStartPre =
let
replaceSecretBin = "${pkgs.replace-secret}/bin/replace-secret";
secretPath = config.sops.secrets."forgejo/metrics-token".path;
runConfig = "${config.services.forgejo.customDir}/conf/app.ini";
in
[ "+${replaceSecretBin} '#metricstoken#' '${secretPath}' '${runConfig}'" ];
# Set up SSL # Set up SSL
nginx.virtualHosts."${domain}" = services.nginx.virtualHosts."${domain}" =
let let
httpAddress = config.services.forgejo.settings.server.HTTP_ADDR; httpAddress = config.services.forgejo.settings.server.HTTP_ADDR;
httpPort = config.services.forgejo.settings.server.HTTP_PORT; httpPort = config.services.forgejo.settings.server.HTTP_PORT;
@ -52,7 +59,7 @@ in
}; };
}; };
backups.forgejo = { services.backups.forgejo = {
user = "forgejo"; user = "forgejo";
paths = [ paths = [
"/var/lib/forgejo/forgejo-db.sql" "/var/lib/forgejo/forgejo-db.sql"
@ -71,13 +78,4 @@ in
}; };
pauseServices = [ "forgejo.service" ]; pauseServices = [ "forgejo.service" ];
}; };
};
systemd.services.forgejo.serviceConfig.ExecStartPre =
let
replaceSecretBin = "${pkgs.replace-secret}/bin/replace-secret";
secretPath = config.sops.secrets."forgejo/metrics-token".path;
runConfig = "${config.services.forgejo.customDir}/conf/app.ini";
in
[ "+${replaceSecretBin} '#metricstoken#' '${secretPath}' '${runConfig}'" ];
} }

View file

@ -1,67 +0,0 @@
{
pkgs,
config,
lib,
...
}:
let
hostName = "immich.${config.services.nginx.domain}";
in
{
services = {
immich = {
enable = true;
settings.server.externalDomain = "https://${hostName}";
environment.IMMICH_TELEMETRY_INCLUDE = "all";
};
nginx.virtualHosts.${hostName} =
let
local = "http://${config.services.immich.host}:${toString config.services.immich.port}";
in
{
forceSSL = true;
useACMEHost = "tlater.net";
enableHSTS = true;
locations."/" = {
proxyPass = local;
proxyWebsockets = true;
};
locations."/metrics" = {
extraConfig = ''
access_log off;
allow 127.0.0.1;
${lib.optionalString config.networking.enableIPv6 "allow ::1;"}
deny all;
'';
};
};
backups.immich =
let
db-dump = "${config.services.immich.mediaLocation}/immich-db.sql";
in
{
user = "immich";
paths = [ config.services.immich.mediaLocation ];
preparation = {
packages = [ config.services.postgresql.package ];
text = ''
pg_dump ${config.services.immich.database.name} --clean --if-exists --file=${db-dump}
'';
};
cleanup = {
packages = [ pkgs.coreutils ];
text = "rm ${db-dump}";
};
pauseServices = [
"immich-server.service"
"immich-machine-learning.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: _: { settings.namespaces = lib.mapAttrsToList (name: virtualHost: {
inherit name; inherit name;
metrics_override.prefix = "nginxlog"; metrics_override.prefix = "nginxlog";
namespace_label = "vhost"; namespace_label = "vhost";
@ -97,6 +97,4 @@ in
# - postgres (?) # - postgres (?)
# - ssl_exporter (?) # - ssl_exporter (?)
}; };
services.dbus.implementation = "broker";
} }

View file

@ -1,4 +1,9 @@
{ pkgs, config, ... }: {
pkgs,
config,
flake-inputs,
...
}:
let let
domain = "metrics.${config.services.nginx.domain}"; domain = "metrics.${config.services.nginx.domain}";
in in
@ -30,7 +35,7 @@ in
declarativePlugins = [ declarativePlugins = [
pkgs.grafanaPlugins.victoriametrics-metrics-datasource pkgs.grafanaPlugins.victoriametrics-metrics-datasource
pkgs.grafanaPlugins.victoriametrics-logs-datasource flake-inputs.nixpkgs-unstable.legacyPackages.${pkgs.system}.grafanaPlugins.victoriametrics-logs-datasource
]; ];
provision = { provision = {

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, ... }: { name, self, ... }:
{ {
options = { options = {
job_name = mkOption { job_name = mkOption {
@ -106,37 +106,35 @@ 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 = { serviceConfig.Restart = mkDefault "always";
Restart = mkDefault "always"; serviceConfig.PrivateTmp = mkDefault true;
PrivateTmp = mkDefault true; serviceConfig.WorkingDirectory = mkDefault /tmp;
WorkingDirectory = mkDefault /tmp; serviceConfig.DynamicUser = mkDefault true;
DynamicUser = mkDefault true;
# Hardening # Hardening
CapabilityBoundingSet = mkDefault [ "" ]; serviceConfig.CapabilityBoundingSet = mkDefault [ "" ];
DeviceAllow = [ "" ]; serviceConfig.DeviceAllow = [ "" ];
LockPersonality = true; serviceConfig.LockPersonality = true;
MemoryDenyWriteExecute = true; serviceConfig.MemoryDenyWriteExecute = true;
NoNewPrivileges = true; serviceConfig.NoNewPrivileges = true;
PrivateDevices = mkDefault true; serviceConfig.PrivateDevices = mkDefault true;
ProtectClock = mkDefault true; serviceConfig.ProtectClock = mkDefault true;
ProtectControlGroups = true; serviceConfig.ProtectControlGroups = true;
ProtectHome = true; serviceConfig.ProtectHome = true;
ProtectHostname = true; serviceConfig.ProtectHostname = true;
ProtectKernelLogs = true; serviceConfig.ProtectKernelLogs = true;
ProtectKernelModules = true; serviceConfig.ProtectKernelModules = true;
ProtectKernelTunables = true; serviceConfig.ProtectKernelTunables = true;
ProtectSystem = mkDefault "strict"; serviceConfig.ProtectSystem = mkDefault "strict";
RemoveIPC = true; serviceConfig.RemoveIPC = true;
RestrictAddressFamilies = [ serviceConfig.RestrictAddressFamilies = [
"AF_INET" "AF_INET"
"AF_INET6" "AF_INET6"
]; ];
RestrictNamespaces = true; serviceConfig.RestrictNamespaces = true;
RestrictRealtime = true; serviceConfig.RestrictRealtime = true;
RestrictSUIDSGID = true; serviceConfig.RestrictSUIDSGID = true;
SystemCallArchitectures = "native"; serviceConfig.SystemCallArchitectures = "native";
UMask = "0077"; serviceConfig.UMask = "0077";
};
} }
exporter.serviceOpts exporter.serviceOpts
] ]
@ -146,7 +144,7 @@ in
{ {
vmagent-scrape-exporters = vmagent-scrape-exporters =
let let
inherit (config.services.victoriametrics) listenAddress; listenAddress = 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 (
@ -155,7 +153,7 @@ in
inherit (scrape) job_name; inherit (scrape) job_name;
static_configs = static_configs =
scrape.static_configs scrape.static_configs
++ lib.optional (scrape.targets != [ ]) { inherit (scrape) targets; }; ++ lib.optional (scrape.targets != [ ]) { targets = scrape.targets; };
} scrape.extraSettings } scrape.extraSettings
) config.services.victoriametrics.scrapeConfigs; ) config.services.victoriametrics.scrapeConfigs;
}; };
@ -214,7 +212,7 @@ in
services.victoriametrics.scrapeConfigs = services.victoriametrics.scrapeConfigs =
let let
allExporters = lib.mapAttrs (_: exporter: { inherit (exporter) listenAddress port; }) ( allExporters = lib.mapAttrs (name: 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,22 +1,37 @@
{ config, lib, ... }: {
config,
pkgs,
lib,
...
}:
let let
cfg = config.services.victorialogs; cfg = config.services.victorialogs;
pkg = pkgs.victoriametrics;
dirname = "victorialogs";
in in
{ {
options.services.victorialogs.bindAddress = lib.mkOption { options.services.victorialogs =
let
inherit (lib.types) str;
in
{
listenAddress = lib.mkOption {
default = ":9428";
type = str;
};
bindAddress = lib.mkOption {
readOnly = true; readOnly = true;
type = lib.types.str; type = str;
description = '' description = ''
Final address on which victorialogs listens. Final address on which victorialogs listens.
''; '';
}; };
};
config = { config = {
services.victorialogs = { services.victorialogs.bindAddress =
enable = true;
bindAddress =
(lib.optionalString (lib.hasPrefix ":" cfg.listenAddress) "127.0.0.1") + cfg.listenAddress; (lib.optionalString (lib.hasPrefix ":" cfg.listenAddress) "127.0.0.1") + cfg.listenAddress;
};
services.journald.upload = { services.journald.upload = {
enable = true; enable = true;
@ -25,6 +40,71 @@ in
NetworkTimeoutSec = "20s"; NetworkTimeoutSec = "20s";
}; };
}; };
systemd.services."systemd-journal-upload".after = [ "victorialogs.service" ]; systemd.services."systemd-journal-upload".after = [ "victorialogs.service" ];
systemd.services.victorialogs = {
description = "VictoriaLogs log database";
wantedBy = [ "multi-user.target" ];
after = [ "network.target" ];
startLimitBurst = 5;
serviceConfig = {
ExecStart = lib.escapeShellArgs [
"${pkg}/bin/victoria-logs"
"-storageDataPath=/var/lib/${dirname}"
"-httpListenAddr=${cfg.listenAddress}"
];
DynamicUser = true;
RestartSec = 1;
Restart = "on-failure";
RuntimeDirectory = dirname;
RuntimeDirectoryMode = "0700";
StateDirectory = dirname;
StateDirectoryMode = "0700";
LimitNOFILE = 1048576;
# Hardening
DeviceAllow = [ "/dev/null rw" ];
DevicePolicy = "strict";
LockPersonality = true;
MemoryDenyWriteExecute = true;
NoNewPrivileges = true;
PrivateDevices = true;
PrivateTmp = true;
PrivateUsers = true;
ProtectClock = true;
ProtectControlGroups = true;
ProtectHome = true;
ProtectHostname = true;
ProtectKernelLogs = true;
ProtectKernelModules = true;
ProtectKernelTunables = true;
ProtectProc = "invisible";
ProtectSystem = "full";
RemoveIPC = true;
RestrictAddressFamilies = [
"AF_INET"
"AF_INET6"
"AF_UNIX"
];
RestrictNamespaces = true;
RestrictRealtime = true;
RestrictSUIDSGID = true;
SystemCallArchitectures = "native";
SystemCallFilter = [
"@system-service"
"~@privileged"
];
};
postStart = lib.mkBefore ''
until ${lib.getBin pkgs.curl}/bin/curl -s -o /dev/null http://${cfg.bindAddress}/ping; do
sleep 1;
done
'';
};
}; };
} }

View file

@ -84,16 +84,9 @@ in
in in
[ "${address}:${toString port}" ]; [ "${address}:${toString port}" ];
immich.targets = [
"127.0.0.1:8081"
"127.0.0.1:8082"
];
# Configured in the hookshot listeners, but it's hard to filter # Configured in the hookshot listeners, but it's hard to filter
# the correct values out of that config. # the correct values out of that config.
matrixHookshot.targets = [ "127.0.0.1:9001" ]; matrixHookshot.targets = [ "127.0.0.1:9001" ];
victorialogs.targets = [ config.services.victorialogs.bindAddress ];
}; };
}; };
} }

View file

@ -0,0 +1,83 @@
{
pkgs,
lib,
config,
...
}:
{
services.minecraft-server = {
enable = true;
eula = true;
# jvmOpts are set using a file for forge
# jvmOpts = "-Xmx8G -Xms8G";
openFirewall = true;
declarative = true;
whitelist = {
tlater = "140d177a-966f-41b8-a4c0-e305babd291b";
romino25 = "59cd1648-14a4-4bcf-8f5a-2e1bde678f2c";
lasi25 = "0ab6e3d1-544a-47e7-8538-2e6c248e49a4";
};
serverProperties = {
allow-flight = true;
difficulty = "hard";
motd = "tlater.net";
spawn-protection = 1;
white-list = true;
enable-query = true;
enable-status = true;
# Allows the server to write chunks without hogging the main
# thread...
sync-chunk-writes = false;
# Disables chat reporting, because we don't need any of that
# drama on a lil' friends-only server.
enforce-secure-profile = false;
};
package = pkgs.writeShellApplication {
name = "minecraft-server";
runtimeInputs = with pkgs; [ jdk17_headless ];
text = ''
exec /var/lib/minecraft/run.sh $@
'';
};
};
systemd.services.minecraft-server = {
path = with pkgs; [ jdk17_headless ];
# Since we read from our own HTTP server, we need to wait for it
# to be up
after = [ "nginx.service" ];
serviceConfig = {
# Use packwiz to install mods
ExecStartPre = [
"${pkgs.jdk17_headless}/bin/java -jar ${config.services.minecraft-server.dataDir}/packwiz-installer-bootstrap.jar -g -s server 'https://minecraft.${config.services.nginx.domain}/cobblemon-pack/pack.toml'"
];
# Forge requires some bonus JVM options, which they include in a
# little `run.sh` script
ExecStart = lib.mkForce "${config.services.minecraft-server.dataDir}/run.sh --nogui";
};
};
systemd.tmpfiles.settings."10-minecraft" = {
"/srv/minecraft".d = {
user = "nginx";
group = "minecraft";
mode = "0775";
};
};
services.nginx.virtualHosts."minecraft.${config.services.nginx.domain}" = {
forceSSL = true;
useACMEHost = "tlater.net";
enableHSTS = true;
root = "/srv/minecraft";
};
}

View file

@ -5,24 +5,23 @@
... ...
}: }:
let let
nextcloud = pkgs.nextcloud31; nextcloud = pkgs.nextcloud30;
hostName = "nextcloud.${config.services.nginx.domain}"; hostName = "nextcloud.${config.services.nginx.domain}";
in in
{ {
services = { services.nextcloud = {
nextcloud = {
inherit hostName; inherit hostName;
package = nextcloud; package = nextcloud;
phpPackage = lib.mkForce ( phpPackage = lib.mkForce (
pkgs.php.override { pkgs.php.override {
packageOverrides = _: prev: { packageOverrides = final: prev: {
extensions = prev.extensions // { extensions = prev.extensions // {
pgsql = prev.extensions.pgsql.overrideAttrs (_: { pgsql = prev.extensions.pgsql.overrideAttrs (old: {
configureFlags = [ "--with-pgsql=${lib.getDev config.services.postgresql.package.pg_config}" ]; configureFlags = [ "--with-pgsql=${lib.getDev config.services.postgresql.package}" ];
}); });
pdo_pgsql = prev.extensions.pdo_pgsql.overrideAttrs (_: { pdo_pgsql = prev.extensions.pdo_pgsql.overrideAttrs (old: {
configureFlags = [ "--with-pdo-pgsql=${lib.getDev config.services.postgresql.package.pg_config}" ]; configureFlags = [ "--with-pdo-pgsql=${lib.getDev config.services.postgresql.package}" ];
}); });
}; };
}; };
@ -61,14 +60,17 @@ in
}; };
}; };
# Ensure that this service doesn't start before postgres is ready
systemd.services.nextcloud-setup.after = [ "postgresql.service" ];
# Set up SSL # Set up SSL
nginx.virtualHosts."${hostName}" = { services.nginx.virtualHosts."${hostName}" = {
forceSSL = true; forceSSL = true;
useACMEHost = "tlater.net"; useACMEHost = "tlater.net";
# The upstream module already adds HSTS # The upstream module already adds HSTS
}; };
backups.nextcloud = { services.backups.nextcloud = {
user = "nextcloud"; user = "nextcloud";
paths = [ paths = [
"/var/lib/nextcloud/nextcloud-db.sql" "/var/lib/nextcloud/nextcloud-db.sql"
@ -96,8 +98,4 @@ in
''; '';
}; };
}; };
};
# Ensure that this service doesn't start before postgres is ready
systemd.services.nextcloud-setup.after = [ "postgresql.service" ];
} }

View file

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

45
flake.lock generated
View file

@ -300,11 +300,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1747742835, "lastModified": 1739841949,
"narHash": "sha256-kYL4GCwwznsypvsnA20oyvW8zB/Dvn6K5G/tgMjVMT4=", "narHash": "sha256-lSOXdgW/1zi/SSu7xp71v+55D5Egz8ACv0STkj7fhbs=",
"owner": "nix-community", "owner": "nix-community",
"repo": "disko", "repo": "disko",
"rev": "df522e787fdffc4f32ed3e1fca9ed0968a384d62", "rev": "15dbf8cebd8e2655a883b74547108e089f051bf0",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -595,11 +595,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1746877938, "lastModified": 1739712626,
"narHash": "sha256-N9J96pSPg4vbozV+ZZ++dwLnMIf2Le6ONNMO0kZCj1M=", "narHash": "sha256-u3m+awbdL+0BKk8IWidsWMr+R0ian3GZMUlH7623kd8=",
"owner": "reckenrode", "owner": "reckenrode",
"repo": "nix-foundryvtt", "repo": "nix-foundryvtt",
"rev": "f1b401831d796dd94cf5a11b65fd169a199d4ff0", "rev": "a7fa493ba2c623cf90e83756b62285b3b58f18d2",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -744,18 +744,34 @@
"type": "github" "type": "github"
} }
}, },
"nixpkgs_2": { "nixpkgs-unstable": {
"locked": { "locked": {
"lastModified": 1748085680, "lastModified": 1740215764,
"narHash": "sha256-XG90Q/040NiV70gAVvoYbXg1lULbiwIzfkWmwSINyGQ=", "narHash": "sha256-wzBbGGZ6i1VVBA/cDJaLfuuGYCUriD7fwsLgJJHRVRk=",
"owner": "nixos", "owner": "nixos",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "4e6eeca5ed45465087274fc9dc6bc2011254a0f3", "rev": "8465e233b0668cf162c608a92e62e8d78c1ba7e4",
"type": "github" "type": "github"
}, },
"original": { "original": {
"owner": "nixos", "owner": "nixos",
"ref": "nixos-25.05-small", "ref": "nixos-unstable-small",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs_2": {
"locked": {
"lastModified": 1740162160,
"narHash": "sha256-SSYxFhqCOb3aiPb6MmN68yEzBIltfom8IgRz7phHscM=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "11415c7ae8539d6292f2928317ee7a8410b28bb9",
"type": "github"
},
"original": {
"owner": "nixos",
"ref": "nixos-24.11-small",
"repo": "nixpkgs", "repo": "nixpkgs",
"type": "github" "type": "github"
} }
@ -1006,6 +1022,7 @@
"disko": "disko", "disko": "disko",
"foundryvtt": "foundryvtt", "foundryvtt": "foundryvtt",
"nixpkgs": "nixpkgs_2", "nixpkgs": "nixpkgs_2",
"nixpkgs-unstable": "nixpkgs-unstable",
"sonnenshift": "sonnenshift", "sonnenshift": "sonnenshift",
"sops-nix": "sops-nix", "sops-nix": "sops-nix",
"tlaternet-webserver": "tlaternet-webserver" "tlaternet-webserver": "tlaternet-webserver"
@ -1079,11 +1096,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1747603214, "lastModified": 1739262228,
"narHash": "sha256-lAblXm0VwifYCJ/ILPXJwlz0qNY07DDYdLD+9H+Wc8o=", "narHash": "sha256-7JAGezJ0Dn5qIyA2+T4Dt/xQgAbhCglh6lzCekTVMeU=",
"owner": "Mic92", "owner": "Mic92",
"repo": "sops-nix", "repo": "sops-nix",
"rev": "8d215e1c981be3aa37e47aeabd4e61bb069548fd", "rev": "07af005bb7d60c7f118d9d9f5530485da5d1e975",
"type": "github" "type": "github"
}, },
"original": { "original": {

View file

@ -2,7 +2,8 @@
description = "tlater.net host configuration"; description = "tlater.net host configuration";
inputs = { inputs = {
nixpkgs.url = "github:nixos/nixpkgs/nixos-25.05-small"; nixpkgs.url = "github:nixos/nixpkgs/nixos-24.11-small";
nixpkgs-unstable.url = "github:nixos/nixpkgs/nixos-unstable-small";
disko = { disko = {
url = "github:nix-community/disko"; url = "github:nix-community/disko";
inputs.nixpkgs.follows = "nixpkgs"; inputs.nixpkgs.follows = "nixpkgs";
@ -91,7 +92,7 @@
######### #########
# Tests # # Tests #
######### #########
checks.${system} = import ./checks (inputs // { inherit system; }); checks = builtins.mapAttrs (system: deployLib: deployLib.deployChecks self.deploy) deploy-rs.lib;
########################### ###########################
# Garbage collection root # # Garbage collection root #
@ -116,6 +117,8 @@
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

@ -31,6 +31,22 @@ let
${lib.concatMapStringsSep "\n---\n" builtins.toJSON cfg.acquisitions} ${lib.concatMapStringsSep "\n---\n" builtins.toJSON cfg.acquisitions}
--- ---
''; '';
extraConfigs = pkgs.symlinkJoin {
name = "crowdsec-extra-configs";
paths = lib.mapAttrsToList (
path: settings:
(settingsFormat.generate path settings).overrideAttrs (old: {
patchPhase = ''
mkdir -p "$out/${dirOf path}/"
out="$out/${dirOf path}/"
echo $out
exit 1
'';
})
) cfg.extraConfig;
};
in in
{ {
imports = [ ./remediations ]; imports = [ ./remediations ];
@ -38,6 +54,7 @@ in
options.security.crowdsec = options.security.crowdsec =
let let
inherit (lib.types) inherit (lib.types)
attrsOf
nullOr nullOr
listOf listOf
package package
@ -85,6 +102,16 @@ in
''; '';
}; };
extraConfig = lib.mkOption {
type = attrsOf (settingsFormat.type);
default = {
"parsers/s02-enrich/nixos-whitelist.yaml" = cfg.parserWhitelist;
};
description = ''
Set of additional configurations to install.
'';
};
acquisitions = lib.mkOption { acquisitions = lib.mkOption {
type = listOf settingsFormat.type; type = listOf settingsFormat.type;
default = [ ]; default = [ ];
@ -247,7 +274,10 @@ in
online_client = { online_client = {
# By default, we don't let crowdsec phone home, since # By default, we don't let crowdsec phone home, since
# this is usually within NixOS users' concerns. # this is usually within NixOS users' concerns.
sharing = lib.mkDefault false; #
# TODO: Enable when this option becomes available
# (1.6.4, current nixpkgs-unstable)
# sharing = lib.mkDefault false;
credentials_path = cfg.centralApiCredentials; credentials_path = cfg.centralApiCredentials;
}; };
}; };
@ -264,7 +294,9 @@ in
}; };
}; };
systemd.packages = [ cfg.package ]; systemd.packages = [
cfg.package
];
environment = { environment = {
systemPackages = [ systemPackages = [
@ -295,33 +327,6 @@ in
group = "crowdsec"; group = "crowdsec";
mode = "0700"; mode = "0700";
}; };
"${cfg.stateDirectory}/config/parsers".d = lib.mkIf (cfg.parserWhitelist != [ ]) {
user = "crowdsec";
group = "crowdsec";
mode = "0700";
};
"${cfg.stateDirectory}/config/parsers/s02-enrich".d = lib.mkIf (cfg.parserWhitelist != [ ]) {
user = "crowdsec";
group = "crowdsec";
mode = "0700";
};
"${cfg.stateDirectory}/config/parsers/s02-enrich/nixos-whitelist.yaml" =
lib.mkIf (cfg.parserWhitelist != [ ])
{
"L+".argument =
(settingsFormat.generate "crowdsec-nixos-whitelist.yaml" {
name = "nixos/parser-whitelist";
description = "Parser whitelist generated by the crowdsec NixOS module";
whitelist = {
reason = "Filtered by NixOS whitelist";
ip = lib.lists.filter (ip: !(lib.hasInfix "/" ip)) cfg.parserWhitelist;
cidr = lib.lists.filter (ip: lib.hasInfix "/" ip) cfg.parserWhitelist;
};
}).outPath;
};
}; };
services = { services = {
@ -331,6 +336,8 @@ in
description = "Crowdsec database and config preparation"; description = "Crowdsec database and config preparation";
script = '' script = ''
cp --copy-contents --recursive ${extraConfigs}/. ${cfg.stateDirectory}/config
if [ ! -e '${cfg.settings.config_paths.simulation_path}' ]; then if [ ! -e '${cfg.settings.config_paths.simulation_path}' ]; then
cp '${cfg.package}/share/crowdsec/config/simulation.yaml' '${cfg.settings.config_paths.simulation_path}' cp '${cfg.package}/share/crowdsec/config/simulation.yaml' '${cfg.settings.config_paths.simulation_path}'
fi fi

View file

@ -6,11 +6,10 @@
... ...
}: }:
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 = {
@ -32,7 +31,9 @@ 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 = [ "nixos-fw" ]; iptables_chains = [
"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.
@ -77,7 +78,9 @@ in
requiredBy = [ "crowdsec.service" ]; requiredBy = [ "crowdsec.service" ];
path = path =
lib.optionals (cfg.settings.mode == "ipset" || cfg.settings.mode == "iptables") [ pkgs.ipset ] lib.optionals (cfg.settings.mode == "ipset" || cfg.settings.mode == "iptables") [
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 +1,5 @@
{ imports = [ ./cs-firewall-bouncer.nix ]; } {
imports = [
./cs-firewall-bouncer.nix
];
}

View file

@ -21,7 +21,7 @@
}, },
"crowdsec-hub": { "crowdsec-hub": {
"cargoLocks": null, "cargoLocks": null,
"date": "2025-05-17", "date": "2025-02-22",
"extract": null, "extract": null,
"name": "crowdsec-hub", "name": "crowdsec-hub",
"passthru": null, "passthru": null,
@ -33,10 +33,10 @@
"name": null, "name": null,
"owner": "crowdsecurity", "owner": "crowdsecurity",
"repo": "hub", "repo": "hub",
"rev": "850614b9fcd4298f559b422c5ac685a69aa2e5ff", "rev": "f9883cd6c7d1913c13e4a3a69d9a0b887a7d57df",
"sha256": "sha256-96MMwFN5KongQA3YJVSuk7Kanbr1gR94CCyiflmez2k=", "sha256": "sha256-45pUln7Qj5luY9I9BE2qhzjH7kv4IbYvNoEX3/4AVVg=",
"type": "github" "type": "github"
}, },
"version": "850614b9fcd4298f559b422c5ac685a69aa2e5ff" "version": "f9883cd6c7d1913c13e4a3a69d9a0b887a7d57df"
} }
} }

View file

@ -14,14 +14,14 @@
}; };
crowdsec-hub = { crowdsec-hub = {
pname = "crowdsec-hub"; pname = "crowdsec-hub";
version = "850614b9fcd4298f559b422c5ac685a69aa2e5ff"; version = "f9883cd6c7d1913c13e4a3a69d9a0b887a7d57df";
src = fetchFromGitHub { src = fetchFromGitHub {
owner = "crowdsecurity"; owner = "crowdsecurity";
repo = "hub"; repo = "hub";
rev = "850614b9fcd4298f559b422c5ac685a69aa2e5ff"; rev = "f9883cd6c7d1913c13e4a3a69d9a0b887a7d57df";
fetchSubmodules = false; fetchSubmodules = false;
sha256 = "sha256-96MMwFN5KongQA3YJVSuk7Kanbr1gR94CCyiflmez2k="; sha256 = "sha256-45pUln7Qj5luY9I9BE2qhzjH7kv4IbYvNoEX3/4AVVg=";
}; };
date = "2025-05-17"; date = "2025-02-22";
}; };
} }

View file

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