Compare commits
2 commits
master
...
tlater/cro
Author | SHA1 | Date | |
---|---|---|---|
5e4a945981 | |||
e1eb85d00f |
30 changed files with 728 additions and 763 deletions
.git-blame-ignore-revs
checks
configuration
flake.lockflake.nixmodules/crowdsec
pkgs/crowdsec
|
@ -9,6 +9,3 @@ fd138d45e6a2cad89fead6e9f246ba282070d6b7
|
|||
|
||||
# Switch to alejandra formatting
|
||||
046a88905ddfa7f9edc3291c310dbb985dee34f9
|
||||
|
||||
# Apply wide linting
|
||||
63b3cbe00be80ccb4b221aad64eb657ae5c96d70
|
||||
|
|
|
@ -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)
|
|
@ -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
|
|
@ -1,5 +1,7 @@
|
|||
{
|
||||
config,
|
||||
pkgs,
|
||||
lib,
|
||||
modulesPath,
|
||||
flake-inputs,
|
||||
...
|
||||
|
@ -19,8 +21,8 @@
|
|||
./services/crowdsec.nix
|
||||
./services/foundryvtt.nix
|
||||
./services/gitea.nix
|
||||
./services/immich.nix
|
||||
./services/metrics
|
||||
./services/minecraft.nix
|
||||
./services/nextcloud.nix
|
||||
./services/webserver.nix
|
||||
./services/wireguard.nix
|
||||
|
@ -30,7 +32,13 @@
|
|||
./sops.nix
|
||||
];
|
||||
|
||||
nixpkgs.overlays = [ (_: prev: { local = import ../pkgs { pkgs = prev; }; }) ];
|
||||
nixpkgs.overlays = [
|
||||
(final: prev: {
|
||||
local = import ../pkgs {
|
||||
pkgs = prev;
|
||||
};
|
||||
})
|
||||
];
|
||||
|
||||
nix = {
|
||||
extraOptions = ''
|
||||
|
@ -63,8 +71,6 @@
|
|||
8448
|
||||
# starbound
|
||||
21025
|
||||
# Minecraft
|
||||
25565
|
||||
|
||||
config.services.coturn.listening-port
|
||||
config.services.coturn.tls-listening-port
|
||||
|
@ -73,9 +79,6 @@
|
|||
];
|
||||
|
||||
allowedUDPPorts = [
|
||||
# More minecraft
|
||||
25565
|
||||
|
||||
config.services.coturn.listening-port
|
||||
config.services.coturn.tls-listening-port
|
||||
config.services.coturn.alt-listening-port
|
||||
|
|
|
@ -80,17 +80,6 @@
|
|||
inherit mountOptions;
|
||||
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" = {
|
||||
inherit mountOptions;
|
||||
mountpoint = "/nix";
|
||||
|
|
|
@ -6,35 +6,26 @@
|
|||
boot.kernelParams = [ "nomodeset" ];
|
||||
|
||||
networking.hostName = "testvm";
|
||||
|
||||
services = {
|
||||
# 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";
|
||||
}
|
||||
];
|
||||
};
|
||||
# Sets the base domain for nginx to a local domain so that we can
|
||||
# easily test locally with the VM.
|
||||
services.nginx.domain = "dev.local";
|
||||
|
||||
# Use the staging secrets
|
||||
sops.defaultSopsFile = lib.mkOverride 99 ../../keys/staging.yaml;
|
||||
|
||||
systemd.network.networks."10-eth0" = {
|
||||
matchConfig.Name = "eth0";
|
||||
gateway = [ "192.168.9.1" ];
|
||||
gateway = [
|
||||
"192.168.9.1"
|
||||
];
|
||||
networkConfig = {
|
||||
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
|
||||
# to have a static key for decrypting the sops secrets for the
|
||||
# staging env.
|
||||
|
@ -43,6 +34,14 @@
|
|||
source = ../../keys/hosts/staging.key;
|
||||
};
|
||||
|
||||
services.openssh.hostKeys = lib.mkForce [
|
||||
{
|
||||
type = "rsa";
|
||||
bits = 4096;
|
||||
path = "/etc/staging.key";
|
||||
}
|
||||
];
|
||||
|
||||
virtualisation.vmVariant = {
|
||||
virtualisation = {
|
||||
memorySize = 3941;
|
||||
|
|
|
@ -1,50 +1,41 @@
|
|||
{ config, lib, ... }:
|
||||
{
|
||||
services = {
|
||||
nginx = {
|
||||
enable = true;
|
||||
recommendedTlsSettings = true;
|
||||
recommendedOptimisation = true;
|
||||
recommendedGzipSettings = true;
|
||||
recommendedProxySettings = true;
|
||||
clientMaxBodySize = "10G";
|
||||
services.nginx = {
|
||||
enable = true;
|
||||
recommendedTlsSettings = true;
|
||||
recommendedOptimisation = true;
|
||||
recommendedGzipSettings = true;
|
||||
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 = ''
|
||||
log_format upstream_time '$remote_addr - $remote_user [$time_local] '
|
||||
'"$request" $status $body_bytes_sent '
|
||||
'"$http_referer" "$http_user_agent" '
|
||||
'rt=$request_time uct="$upstream_connect_time" '
|
||||
'uht="$upstream_header_time" urt="$upstream_response_time"';
|
||||
'';
|
||||
};
|
||||
|
||||
logrotate.settings =
|
||||
{
|
||||
# Override the default, just keep fewer logs
|
||||
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;
|
||||
|
||||
backups.acme = {
|
||||
user = "acme";
|
||||
paths = lib.mapAttrsToList (
|
||||
virtualHost: _: "/var/lib/acme/${virtualHost}"
|
||||
) config.services.nginx.virtualHosts;
|
||||
};
|
||||
commonHttpConfig = ''
|
||||
log_format upstream_time '$remote_addr - $remote_user [$time_local] '
|
||||
'"$request" $status $body_bytes_sent '
|
||||
'"$http_referer" "$http_user_agent" '
|
||||
'rt=$request_time uct="$upstream_connect_time" '
|
||||
'uht="$upstream_header_time" urt="$upstream_response_time"';
|
||||
'';
|
||||
};
|
||||
|
||||
services.logrotate.settings =
|
||||
{
|
||||
# Override the default, just keep fewer logs
|
||||
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;
|
||||
|
||||
systemd.tmpfiles.rules = lib.mapAttrsToList (
|
||||
virtualHost: _:
|
||||
#
|
||||
|
@ -75,4 +66,11 @@
|
|||
systemd.services.nginx.serviceConfig.SupplementaryGroups = [
|
||||
config.security.acme.certs."tlater.net".group
|
||||
];
|
||||
|
||||
services.backups.acme = {
|
||||
user = "acme";
|
||||
paths = lib.mapAttrsToList (
|
||||
virtualHost: _: "/var/lib/acme/${virtualHost}"
|
||||
) config.services.nginx.virtualHosts;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -57,7 +57,7 @@ in
|
|||
'';
|
||||
type = types.attrsOf (
|
||||
types.submodule (
|
||||
{ name, ... }:
|
||||
{ config, name, ... }:
|
||||
{
|
||||
options = {
|
||||
user = lib.mkOption {
|
||||
|
@ -246,7 +246,7 @@ in
|
|||
};
|
||||
}
|
||||
// lib.mapAttrs' (
|
||||
name: _:
|
||||
name: backup:
|
||||
lib.nameValuePair "backup-${name}" {
|
||||
wantedBy = [ "timers.target" ];
|
||||
timerConfig = {
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
{
|
||||
pkgs,
|
||||
config,
|
||||
lib,
|
||||
...
|
||||
|
@ -17,166 +16,159 @@ in
|
|||
./matrix-hookshot.nix
|
||||
];
|
||||
|
||||
services = {
|
||||
matrix-conduit = {
|
||||
enable = true;
|
||||
package = pkgs.matrix-continuwuity;
|
||||
settings.global = {
|
||||
address = "127.0.0.1";
|
||||
server_name = domain;
|
||||
new_user_displayname_suffix = "🦆";
|
||||
allow_check_for_updates = true;
|
||||
services.matrix-conduit = {
|
||||
enable = true;
|
||||
settings.global = {
|
||||
address = "127.0.0.1";
|
||||
server_name = domain;
|
||||
database_backend = "rocksdb";
|
||||
|
||||
# Set up delegation: https://docs.conduit.rs/delegation.html#automatic-recommended
|
||||
# This is primarily to make sliding sync work
|
||||
well_known = {
|
||||
client = "https://${domain}";
|
||||
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"
|
||||
];
|
||||
# Set up delegation: https://docs.conduit.rs/delegation.html#automatic-recommended
|
||||
# This is primarily to make sliding sync work
|
||||
well_known = {
|
||||
client = "https://${domain}";
|
||||
server = "${domain}:443";
|
||||
};
|
||||
};
|
||||
|
||||
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
|
||||
'';
|
||||
};
|
||||
|
||||
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" ];
|
||||
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"
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
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;
|
||||
};
|
||||
# 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;
|
||||
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" ];
|
||||
};
|
||||
}
|
||||
|
|
|
@ -29,29 +29,16 @@ let
|
|||
};
|
||||
|
||||
# Encryption support
|
||||
# TODO(tlater): Enable when
|
||||
# https://github.com/matrix-org/matrix-hookshot/issues/1060 is
|
||||
# fixed
|
||||
# extraSettings = {
|
||||
# "de.sorunome.msc2409.push_ephemeral" = true;
|
||||
# push_ephemeral = true;
|
||||
# "org.matrix.msc3202" = true;
|
||||
# };
|
||||
extraSettings = {
|
||||
"de.sorunome.msc2409.push_ephemeral" = true;
|
||||
push_ephemeral = true;
|
||||
"org.matrix.msc3202" = true;
|
||||
};
|
||||
|
||||
runtimeRegistration = "${cfg.registrationFile}";
|
||||
};
|
||||
in
|
||||
{
|
||||
# users = {
|
||||
# users.matrix-hookshot = {
|
||||
# home = "/run/matrix-hookshot";
|
||||
# group = "matrix-hookshot";
|
||||
# isSystemUser = true;
|
||||
# };
|
||||
|
||||
# groups.matrix-hookshot = { };
|
||||
# };
|
||||
|
||||
systemd.services.matrix-hookshot = {
|
||||
serviceConfig = {
|
||||
Type = lib.mkForce "exec";
|
||||
|
@ -62,7 +49,6 @@ in
|
|||
# Some library in matrix-hookshot wants a home directory
|
||||
Environment = [ "HOME=/run/matrix-hookshot" ];
|
||||
|
||||
# User = "matrix-hookshot";
|
||||
DynamicUser = true;
|
||||
StateDirectory = "matrix-hookshot";
|
||||
RuntimeDirectory = "matrix-hookshot";
|
||||
|
@ -76,11 +62,7 @@ in
|
|||
ProtectKernelModules = true;
|
||||
ProtectKernelLogs = true;
|
||||
ProtectControlGroups = true;
|
||||
RestrictAddressFamilies = [
|
||||
# "AF_UNIX"
|
||||
"AF_INET"
|
||||
"AF_INET6"
|
||||
];
|
||||
RestrictAddressFamilies = [ "AF_INET AF_INET6" ];
|
||||
LockPersonality = true;
|
||||
RestrictRealtime = true;
|
||||
ProtectProc = "invisible";
|
||||
|
@ -89,15 +71,12 @@ in
|
|||
};
|
||||
};
|
||||
|
||||
# services.redis.servers.matrix-hookshot = {
|
||||
# enable = true;
|
||||
# user = "matrix-hookshot";
|
||||
# };
|
||||
|
||||
services.matrix-hookshot = {
|
||||
enable = true;
|
||||
|
||||
serviceDependencies = [ "conduit.service" ];
|
||||
serviceDependencies = [
|
||||
"conduit.service"
|
||||
];
|
||||
|
||||
registrationFile = "/run/matrix-hookshot/registration.yaml";
|
||||
|
||||
|
@ -112,8 +91,6 @@ in
|
|||
|
||||
bot.displayname = "Hookshot";
|
||||
|
||||
# cache.redisUri = "redis://${config.services.redis.servers.matrix-hookshot.unixSocket}";
|
||||
|
||||
generic = {
|
||||
enabled = true;
|
||||
outbound = false;
|
||||
|
@ -123,10 +100,7 @@ in
|
|||
allowJsTransformationFunctions = true;
|
||||
};
|
||||
|
||||
# TODO(tlater): Enable when
|
||||
# https://github.com/matrix-org/matrix-hookshot/issues/1060 is
|
||||
# fixed
|
||||
# encryption.storagePath = "/var/lib/matrix-hookshot/cryptostore";
|
||||
encryption.storagePath = "/var/lib/matrix-hookshot/cryptostore";
|
||||
|
||||
permissions = [
|
||||
{
|
||||
|
@ -152,15 +126,19 @@ in
|
|||
listeners = [
|
||||
{
|
||||
port = 9000;
|
||||
resources = [ "webhooks" ];
|
||||
resources = [
|
||||
"webhooks"
|
||||
];
|
||||
}
|
||||
{
|
||||
port = 9001;
|
||||
resources = [ "metrics" ];
|
||||
resources = [
|
||||
"metrics"
|
||||
];
|
||||
}
|
||||
];
|
||||
|
||||
metrics.enabled = true;
|
||||
metrics.enable = true;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
@ -8,7 +8,21 @@
|
|||
security.crowdsec = {
|
||||
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 = [
|
||||
"systemd-journal"
|
||||
|
@ -19,19 +33,25 @@
|
|||
{
|
||||
source = "journalctl";
|
||||
labels.type = "syslog";
|
||||
journalctl_filter = [ "SYSLOG_IDENTIFIER=Nextcloud" ];
|
||||
journalctl_filter = [
|
||||
"SYSLOG_IDENTIFIER=Nextcloud"
|
||||
];
|
||||
}
|
||||
|
||||
{
|
||||
source = "journalctl";
|
||||
labels.type = "syslog";
|
||||
journalctl_filter = [ "SYSLOG_IDENTIFIER=sshd-session" ];
|
||||
journalctl_filter = [
|
||||
"SYSLOG_IDENTIFIER=sshd-session"
|
||||
];
|
||||
}
|
||||
|
||||
{
|
||||
labels.type = "nginx";
|
||||
filenames =
|
||||
[ "/var/log/nginx/*.log" ]
|
||||
[
|
||||
"/var/log/nginx/*.log"
|
||||
]
|
||||
++ lib.mapAttrsToList (
|
||||
vHost: _: "/var/log/nginx/${vHost}/access.log"
|
||||
) 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;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -11,39 +11,37 @@ in
|
|||
{
|
||||
imports = [ flake-inputs.foundryvtt.nixosModules.foundryvtt ];
|
||||
|
||||
services = {
|
||||
foundryvtt = {
|
||||
enable = true;
|
||||
hostName = domain;
|
||||
minifyStaticFiles = true;
|
||||
proxySSL = true;
|
||||
proxyPort = 443;
|
||||
package = flake-inputs.foundryvtt.packages.${pkgs.system}.foundryvtt_13;
|
||||
};
|
||||
|
||||
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" ];
|
||||
};
|
||||
services.foundryvtt = {
|
||||
enable = true;
|
||||
hostName = domain;
|
||||
minifyStaticFiles = true;
|
||||
proxySSL = true;
|
||||
proxyPort = 443;
|
||||
package = flake-inputs.foundryvtt.packages.${pkgs.system}.foundryvtt_11;
|
||||
};
|
||||
|
||||
# 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
|
||||
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" ];
|
||||
};
|
||||
}
|
||||
|
|
|
@ -8,68 +8,24 @@ let
|
|||
domain = "gitea.${config.services.nginx.domain}";
|
||||
in
|
||||
{
|
||||
services = {
|
||||
forgejo = {
|
||||
enable = true;
|
||||
database.type = "postgres";
|
||||
services.forgejo = {
|
||||
enable = true;
|
||||
database.type = "postgres";
|
||||
|
||||
settings = {
|
||||
server = {
|
||||
DOMAIN = domain;
|
||||
HTTP_ADDR = "127.0.0.1";
|
||||
ROOT_URL = "https://${domain}/";
|
||||
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;
|
||||
'';
|
||||
};
|
||||
settings = {
|
||||
server = {
|
||||
DOMAIN = domain;
|
||||
HTTP_ADDR = "127.0.0.1";
|
||||
ROOT_URL = "https://${domain}/";
|
||||
SSH_PORT = 2222;
|
||||
};
|
||||
|
||||
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";
|
||||
metrics = {
|
||||
ENABLED = true;
|
||||
TOKEN = "#metricstoken#";
|
||||
};
|
||||
cleanup = {
|
||||
packages = [ pkgs.coreutils ];
|
||||
text = "rm /var/lib/forgejo/forgejo-db.sql";
|
||||
};
|
||||
pauseServices = [ "forgejo.service" ];
|
||||
service.DISABLE_REGISTRATION = true;
|
||||
session.COOKIE_SECURE = true;
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -80,4 +36,46 @@ in
|
|||
runConfig = "${config.services.forgejo.customDir}/conf/app.ini";
|
||||
in
|
||||
[ "+${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" ];
|
||||
};
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
];
|
||||
};
|
||||
};
|
||||
}
|
|
@ -74,7 +74,7 @@ in
|
|||
listenAddress = "127.0.0.1";
|
||||
group = "nginx";
|
||||
|
||||
settings.namespaces = lib.mapAttrsToList (name: _: {
|
||||
settings.namespaces = lib.mapAttrsToList (name: virtualHost: {
|
||||
inherit name;
|
||||
metrics_override.prefix = "nginxlog";
|
||||
namespace_label = "vhost";
|
||||
|
@ -97,6 +97,4 @@ in
|
|||
# - postgres (?)
|
||||
# - ssl_exporter (?)
|
||||
};
|
||||
|
||||
services.dbus.implementation = "broker";
|
||||
}
|
||||
|
|
|
@ -1,4 +1,9 @@
|
|||
{ pkgs, config, ... }:
|
||||
{
|
||||
pkgs,
|
||||
config,
|
||||
flake-inputs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
domain = "metrics.${config.services.nginx.domain}";
|
||||
in
|
||||
|
@ -30,7 +35,7 @@ in
|
|||
|
||||
declarativePlugins = [
|
||||
pkgs.grafanaPlugins.victoriametrics-metrics-datasource
|
||||
pkgs.grafanaPlugins.victoriametrics-logs-datasource
|
||||
flake-inputs.nixpkgs-unstable.legacyPackages.${pkgs.system}.grafanaPlugins.victoriametrics-logs-datasource
|
||||
];
|
||||
|
||||
provision = {
|
||||
|
|
|
@ -38,7 +38,7 @@ in
|
|||
services.victoriametrics.scrapeConfigs = mkOption {
|
||||
type = types.attrsOf (
|
||||
types.submodule (
|
||||
{ name, ... }:
|
||||
{ name, self, ... }:
|
||||
{
|
||||
options = {
|
||||
job_name = mkOption {
|
||||
|
@ -106,37 +106,35 @@ in
|
|||
# module is an intractable mess
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
after = [ "network.target" ];
|
||||
serviceConfig = {
|
||||
Restart = mkDefault "always";
|
||||
PrivateTmp = mkDefault true;
|
||||
WorkingDirectory = mkDefault /tmp;
|
||||
DynamicUser = mkDefault true;
|
||||
# Hardening
|
||||
CapabilityBoundingSet = mkDefault [ "" ];
|
||||
DeviceAllow = [ "" ];
|
||||
LockPersonality = true;
|
||||
MemoryDenyWriteExecute = true;
|
||||
NoNewPrivileges = true;
|
||||
PrivateDevices = mkDefault true;
|
||||
ProtectClock = mkDefault true;
|
||||
ProtectControlGroups = true;
|
||||
ProtectHome = true;
|
||||
ProtectHostname = true;
|
||||
ProtectKernelLogs = true;
|
||||
ProtectKernelModules = true;
|
||||
ProtectKernelTunables = true;
|
||||
ProtectSystem = mkDefault "strict";
|
||||
RemoveIPC = true;
|
||||
RestrictAddressFamilies = [
|
||||
"AF_INET"
|
||||
"AF_INET6"
|
||||
];
|
||||
RestrictNamespaces = true;
|
||||
RestrictRealtime = true;
|
||||
RestrictSUIDSGID = true;
|
||||
SystemCallArchitectures = "native";
|
||||
UMask = "0077";
|
||||
};
|
||||
serviceConfig.Restart = mkDefault "always";
|
||||
serviceConfig.PrivateTmp = mkDefault true;
|
||||
serviceConfig.WorkingDirectory = mkDefault /tmp;
|
||||
serviceConfig.DynamicUser = mkDefault true;
|
||||
# Hardening
|
||||
serviceConfig.CapabilityBoundingSet = mkDefault [ "" ];
|
||||
serviceConfig.DeviceAllow = [ "" ];
|
||||
serviceConfig.LockPersonality = true;
|
||||
serviceConfig.MemoryDenyWriteExecute = true;
|
||||
serviceConfig.NoNewPrivileges = true;
|
||||
serviceConfig.PrivateDevices = mkDefault true;
|
||||
serviceConfig.ProtectClock = mkDefault true;
|
||||
serviceConfig.ProtectControlGroups = true;
|
||||
serviceConfig.ProtectHome = true;
|
||||
serviceConfig.ProtectHostname = true;
|
||||
serviceConfig.ProtectKernelLogs = true;
|
||||
serviceConfig.ProtectKernelModules = true;
|
||||
serviceConfig.ProtectKernelTunables = true;
|
||||
serviceConfig.ProtectSystem = mkDefault "strict";
|
||||
serviceConfig.RemoveIPC = true;
|
||||
serviceConfig.RestrictAddressFamilies = [
|
||||
"AF_INET"
|
||||
"AF_INET6"
|
||||
];
|
||||
serviceConfig.RestrictNamespaces = true;
|
||||
serviceConfig.RestrictRealtime = true;
|
||||
serviceConfig.RestrictSUIDSGID = true;
|
||||
serviceConfig.SystemCallArchitectures = "native";
|
||||
serviceConfig.UMask = "0077";
|
||||
}
|
||||
exporter.serviceOpts
|
||||
]
|
||||
|
@ -146,7 +144,7 @@ in
|
|||
{
|
||||
vmagent-scrape-exporters =
|
||||
let
|
||||
inherit (config.services.victoriametrics) listenAddress;
|
||||
listenAddress = config.services.victoriametrics.listenAddress;
|
||||
vmAddr = (lib.optionalString (lib.hasPrefix ":" listenAddress) "127.0.0.1") + listenAddress;
|
||||
promscrape = yaml.generate "prometheus.yml" {
|
||||
scrape_configs = lib.mapAttrsToList (
|
||||
|
@ -155,7 +153,7 @@ in
|
|||
inherit (scrape) job_name;
|
||||
static_configs =
|
||||
scrape.static_configs
|
||||
++ lib.optional (scrape.targets != [ ]) { inherit (scrape) targets; };
|
||||
++ lib.optional (scrape.targets != [ ]) { targets = scrape.targets; };
|
||||
} scrape.extraSettings
|
||||
) config.services.victoriametrics.scrapeConfigs;
|
||||
};
|
||||
|
@ -214,7 +212,7 @@ in
|
|||
|
||||
services.victoriametrics.scrapeConfigs =
|
||||
let
|
||||
allExporters = lib.mapAttrs (_: exporter: { inherit (exporter) listenAddress port; }) (
|
||||
allExporters = lib.mapAttrs (name: exporter: { inherit (exporter) listenAddress port; }) (
|
||||
(lib.filterAttrs (
|
||||
name: exporter:
|
||||
# A bunch of deprecated exporters that need to be ignored
|
||||
|
|
|
@ -1,22 +1,37 @@
|
|||
{ config, lib, ... }:
|
||||
{
|
||||
config,
|
||||
pkgs,
|
||||
lib,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.services.victorialogs;
|
||||
pkg = pkgs.victoriametrics;
|
||||
dirname = "victorialogs";
|
||||
in
|
||||
{
|
||||
options.services.victorialogs.bindAddress = lib.mkOption {
|
||||
readOnly = true;
|
||||
type = lib.types.str;
|
||||
description = ''
|
||||
Final address on which victorialogs listens.
|
||||
'';
|
||||
};
|
||||
options.services.victorialogs =
|
||||
let
|
||||
inherit (lib.types) str;
|
||||
in
|
||||
{
|
||||
listenAddress = lib.mkOption {
|
||||
default = ":9428";
|
||||
type = str;
|
||||
};
|
||||
|
||||
bindAddress = lib.mkOption {
|
||||
readOnly = true;
|
||||
type = str;
|
||||
description = ''
|
||||
Final address on which victorialogs listens.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
config = {
|
||||
services.victorialogs = {
|
||||
enable = true;
|
||||
bindAddress =
|
||||
(lib.optionalString (lib.hasPrefix ":" cfg.listenAddress) "127.0.0.1") + cfg.listenAddress;
|
||||
};
|
||||
services.victorialogs.bindAddress =
|
||||
(lib.optionalString (lib.hasPrefix ":" cfg.listenAddress) "127.0.0.1") + cfg.listenAddress;
|
||||
|
||||
services.journald.upload = {
|
||||
enable = true;
|
||||
|
@ -25,6 +40,71 @@ in
|
|||
NetworkTimeoutSec = "20s";
|
||||
};
|
||||
};
|
||||
|
||||
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
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
@ -84,16 +84,9 @@ in
|
|||
in
|
||||
[ "${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
|
||||
# the correct values out of that config.
|
||||
matrixHookshot.targets = [ "127.0.0.1:9001" ];
|
||||
|
||||
victorialogs.targets = [ config.services.victorialogs.bindAddress ];
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
83
configuration/services/minecraft.nix
Normal file
83
configuration/services/minecraft.nix
Normal 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";
|
||||
};
|
||||
}
|
|
@ -5,99 +5,97 @@
|
|||
...
|
||||
}:
|
||||
let
|
||||
nextcloud = pkgs.nextcloud31;
|
||||
nextcloud = pkgs.nextcloud30;
|
||||
hostName = "nextcloud.${config.services.nginx.domain}";
|
||||
in
|
||||
{
|
||||
services = {
|
||||
nextcloud = {
|
||||
inherit hostName;
|
||||
services.nextcloud = {
|
||||
inherit hostName;
|
||||
|
||||
package = nextcloud;
|
||||
phpPackage = lib.mkForce (
|
||||
pkgs.php.override {
|
||||
packageOverrides = _: prev: {
|
||||
extensions = prev.extensions // {
|
||||
pgsql = prev.extensions.pgsql.overrideAttrs (_: {
|
||||
configureFlags = [ "--with-pgsql=${lib.getDev config.services.postgresql.package.pg_config}" ];
|
||||
});
|
||||
pdo_pgsql = prev.extensions.pdo_pgsql.overrideAttrs (_: {
|
||||
configureFlags = [ "--with-pdo-pgsql=${lib.getDev config.services.postgresql.package.pg_config}" ];
|
||||
});
|
||||
};
|
||||
package = nextcloud;
|
||||
phpPackage = lib.mkForce (
|
||||
pkgs.php.override {
|
||||
packageOverrides = final: prev: {
|
||||
extensions = prev.extensions // {
|
||||
pgsql = prev.extensions.pgsql.overrideAttrs (old: {
|
||||
configureFlags = [ "--with-pgsql=${lib.getDev config.services.postgresql.package}" ];
|
||||
});
|
||||
pdo_pgsql = prev.extensions.pdo_pgsql.overrideAttrs (old: {
|
||||
configureFlags = [ "--with-pdo-pgsql=${lib.getDev config.services.postgresql.package}" ];
|
||||
});
|
||||
};
|
||||
}
|
||||
);
|
||||
enable = true;
|
||||
maxUploadSize = "2G";
|
||||
https = true;
|
||||
};
|
||||
}
|
||||
);
|
||||
enable = true;
|
||||
maxUploadSize = "2G";
|
||||
https = true;
|
||||
|
||||
configureRedis = true;
|
||||
configureRedis = true;
|
||||
|
||||
config = {
|
||||
dbtype = "pgsql";
|
||||
dbhost = "/run/postgresql";
|
||||
config = {
|
||||
dbtype = "pgsql";
|
||||
dbhost = "/run/postgresql";
|
||||
|
||||
adminuser = "tlater";
|
||||
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
|
||||
;
|
||||
};
|
||||
adminuser = "tlater";
|
||||
adminpassFile = config.sops.secrets."nextcloud/tlater".path;
|
||||
};
|
||||
|
||||
# Set up SSL
|
||||
nginx.virtualHosts."${hostName}" = {
|
||||
forceSSL = true;
|
||||
useACMEHost = "tlater.net";
|
||||
# The upstream module already adds HSTS
|
||||
settings = {
|
||||
default_phone_region = "AT";
|
||||
overwriteprotocol = "https";
|
||||
};
|
||||
|
||||
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
|
||||
'';
|
||||
};
|
||||
phpOptions = {
|
||||
"opcache.interned_strings_buffer" = "16";
|
||||
};
|
||||
|
||||
extraApps = {
|
||||
inherit (config.services.nextcloud.package.packages.apps)
|
||||
calendar
|
||||
contacts
|
||||
cookbook
|
||||
news
|
||||
;
|
||||
};
|
||||
};
|
||||
|
||||
# Ensure that this service doesn't start before postgres is ready
|
||||
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
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{ config, ... }:
|
||||
let
|
||||
inherit (config.services.nginx) domain;
|
||||
domain = config.services.nginx.domain;
|
||||
in
|
||||
{
|
||||
services.tlaternet-webserver = {
|
||||
|
|
45
flake.lock
generated
45
flake.lock
generated
|
@ -300,11 +300,11 @@
|
|||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1747742835,
|
||||
"narHash": "sha256-kYL4GCwwznsypvsnA20oyvW8zB/Dvn6K5G/tgMjVMT4=",
|
||||
"lastModified": 1739841949,
|
||||
"narHash": "sha256-lSOXdgW/1zi/SSu7xp71v+55D5Egz8ACv0STkj7fhbs=",
|
||||
"owner": "nix-community",
|
||||
"repo": "disko",
|
||||
"rev": "df522e787fdffc4f32ed3e1fca9ed0968a384d62",
|
||||
"rev": "15dbf8cebd8e2655a883b74547108e089f051bf0",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
@ -595,11 +595,11 @@
|
|||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1746877938,
|
||||
"narHash": "sha256-N9J96pSPg4vbozV+ZZ++dwLnMIf2Le6ONNMO0kZCj1M=",
|
||||
"lastModified": 1739712626,
|
||||
"narHash": "sha256-u3m+awbdL+0BKk8IWidsWMr+R0ian3GZMUlH7623kd8=",
|
||||
"owner": "reckenrode",
|
||||
"repo": "nix-foundryvtt",
|
||||
"rev": "f1b401831d796dd94cf5a11b65fd169a199d4ff0",
|
||||
"rev": "a7fa493ba2c623cf90e83756b62285b3b58f18d2",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
@ -744,18 +744,34 @@
|
|||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs_2": {
|
||||
"nixpkgs-unstable": {
|
||||
"locked": {
|
||||
"lastModified": 1748085680,
|
||||
"narHash": "sha256-XG90Q/040NiV70gAVvoYbXg1lULbiwIzfkWmwSINyGQ=",
|
||||
"lastModified": 1740215764,
|
||||
"narHash": "sha256-wzBbGGZ6i1VVBA/cDJaLfuuGYCUriD7fwsLgJJHRVRk=",
|
||||
"owner": "nixos",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "4e6eeca5ed45465087274fc9dc6bc2011254a0f3",
|
||||
"rev": "8465e233b0668cf162c608a92e62e8d78c1ba7e4",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"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",
|
||||
"type": "github"
|
||||
}
|
||||
|
@ -1006,6 +1022,7 @@
|
|||
"disko": "disko",
|
||||
"foundryvtt": "foundryvtt",
|
||||
"nixpkgs": "nixpkgs_2",
|
||||
"nixpkgs-unstable": "nixpkgs-unstable",
|
||||
"sonnenshift": "sonnenshift",
|
||||
"sops-nix": "sops-nix",
|
||||
"tlaternet-webserver": "tlaternet-webserver"
|
||||
|
@ -1079,11 +1096,11 @@
|
|||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1747603214,
|
||||
"narHash": "sha256-lAblXm0VwifYCJ/ILPXJwlz0qNY07DDYdLD+9H+Wc8o=",
|
||||
"lastModified": 1739262228,
|
||||
"narHash": "sha256-7JAGezJ0Dn5qIyA2+T4Dt/xQgAbhCglh6lzCekTVMeU=",
|
||||
"owner": "Mic92",
|
||||
"repo": "sops-nix",
|
||||
"rev": "8d215e1c981be3aa37e47aeabd4e61bb069548fd",
|
||||
"rev": "07af005bb7d60c7f118d9d9f5530485da5d1e975",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
|
|
@ -2,7 +2,8 @@
|
|||
description = "tlater.net host configuration";
|
||||
|
||||
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 = {
|
||||
url = "github:nix-community/disko";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
|
@ -91,7 +92,7 @@
|
|||
#########
|
||||
# Tests #
|
||||
#########
|
||||
checks.${system} = import ./checks (inputs // { inherit system; });
|
||||
checks = builtins.mapAttrs (system: deployLib: deployLib.deployChecks self.deploy) deploy-rs.lib;
|
||||
|
||||
###########################
|
||||
# Garbage collection root #
|
||||
|
@ -116,6 +117,8 @@
|
|||
run-vm = {
|
||||
type = "app";
|
||||
program =
|
||||
let
|
||||
in
|
||||
(pkgs.writeShellScript "" ''
|
||||
${vm.config.system.build.vm.outPath}/bin/run-testvm-vm
|
||||
'').outPath;
|
||||
|
|
|
@ -31,6 +31,22 @@ let
|
|||
${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
|
||||
{
|
||||
imports = [ ./remediations ];
|
||||
|
@ -38,6 +54,7 @@ in
|
|||
options.security.crowdsec =
|
||||
let
|
||||
inherit (lib.types)
|
||||
attrsOf
|
||||
nullOr
|
||||
listOf
|
||||
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 {
|
||||
type = listOf settingsFormat.type;
|
||||
default = [ ];
|
||||
|
@ -247,7 +274,10 @@ in
|
|||
online_client = {
|
||||
# By default, we don't let crowdsec phone home, since
|
||||
# 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;
|
||||
};
|
||||
};
|
||||
|
@ -264,7 +294,9 @@ in
|
|||
};
|
||||
};
|
||||
|
||||
systemd.packages = [ cfg.package ];
|
||||
systemd.packages = [
|
||||
cfg.package
|
||||
];
|
||||
|
||||
environment = {
|
||||
systemPackages = [
|
||||
|
@ -295,33 +327,6 @@ in
|
|||
group = "crowdsec";
|
||||
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 = {
|
||||
|
@ -331,6 +336,8 @@ in
|
|||
description = "Crowdsec database and config preparation";
|
||||
|
||||
script = ''
|
||||
cp --copy-contents --recursive ${extraConfigs}/. ${cfg.stateDirectory}/config
|
||||
|
||||
if [ ! -e '${cfg.settings.config_paths.simulation_path}' ]; then
|
||||
cp '${cfg.package}/share/crowdsec/config/simulation.yaml' '${cfg.settings.config_paths.simulation_path}'
|
||||
fi
|
||||
|
|
|
@ -6,11 +6,10 @@
|
|||
...
|
||||
}:
|
||||
let
|
||||
inherit (flake-inputs.self.packages.${pkgs.system}) crowdsec-firewall-bouncer;
|
||||
|
||||
crowdsecCfg = config.security.crowdsec;
|
||||
cfg = crowdsecCfg.remediationComponents.firewallBouncer;
|
||||
settingsFormat = pkgs.formats.yaml { };
|
||||
crowdsec-firewall-bouncer = flake-inputs.self.packages.${pkgs.system}.crowdsec-firewall-bouncer;
|
||||
in
|
||||
{
|
||||
options.security.crowdsec.remediationComponents.firewallBouncer = {
|
||||
|
@ -32,7 +31,9 @@ in
|
|||
security.crowdsec.remediationComponents.firewallBouncer.settings = {
|
||||
mode = lib.mkDefault "${if config.networking.nftables.enable then "nftables" else "iptables"}";
|
||||
log_mode = "stdout";
|
||||
iptables_chains = [ "nixos-fw" ];
|
||||
iptables_chains = [
|
||||
"nixos-fw"
|
||||
];
|
||||
|
||||
# Don't let users easily override this; unfortunately we need to
|
||||
# set up this key through substitution at runtime.
|
||||
|
@ -77,7 +78,9 @@ in
|
|||
requiredBy = [ "crowdsec.service" ];
|
||||
|
||||
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 == "nftables") pkgs.nftables;
|
||||
};
|
||||
|
|
|
@ -1 +1,5 @@
|
|||
{ imports = [ ./cs-firewall-bouncer.nix ]; }
|
||||
{
|
||||
imports = [
|
||||
./cs-firewall-bouncer.nix
|
||||
];
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
},
|
||||
"crowdsec-hub": {
|
||||
"cargoLocks": null,
|
||||
"date": "2025-05-17",
|
||||
"date": "2025-02-22",
|
||||
"extract": null,
|
||||
"name": "crowdsec-hub",
|
||||
"passthru": null,
|
||||
|
@ -33,10 +33,10 @@
|
|||
"name": null,
|
||||
"owner": "crowdsecurity",
|
||||
"repo": "hub",
|
||||
"rev": "850614b9fcd4298f559b422c5ac685a69aa2e5ff",
|
||||
"sha256": "sha256-96MMwFN5KongQA3YJVSuk7Kanbr1gR94CCyiflmez2k=",
|
||||
"rev": "f9883cd6c7d1913c13e4a3a69d9a0b887a7d57df",
|
||||
"sha256": "sha256-45pUln7Qj5luY9I9BE2qhzjH7kv4IbYvNoEX3/4AVVg=",
|
||||
"type": "github"
|
||||
},
|
||||
"version": "850614b9fcd4298f559b422c5ac685a69aa2e5ff"
|
||||
"version": "f9883cd6c7d1913c13e4a3a69d9a0b887a7d57df"
|
||||
}
|
||||
}
|
|
@ -14,14 +14,14 @@
|
|||
};
|
||||
crowdsec-hub = {
|
||||
pname = "crowdsec-hub";
|
||||
version = "850614b9fcd4298f559b422c5ac685a69aa2e5ff";
|
||||
version = "f9883cd6c7d1913c13e4a3a69d9a0b887a7d57df";
|
||||
src = fetchFromGitHub {
|
||||
owner = "crowdsecurity";
|
||||
repo = "hub";
|
||||
rev = "850614b9fcd4298f559b422c5ac685a69aa2e5ff";
|
||||
rev = "f9883cd6c7d1913c13e4a3a69d9a0b887a7d57df";
|
||||
fetchSubmodules = false;
|
||||
sha256 = "sha256-96MMwFN5KongQA3YJVSuk7Kanbr1gR94CCyiflmez2k=";
|
||||
sha256 = "sha256-45pUln7Qj5luY9I9BE2qhzjH7kv4IbYvNoEX3/4AVVg=";
|
||||
};
|
||||
date = "2025-05-17";
|
||||
date = "2025-02-22";
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1 +1,4 @@
|
|||
{ sources }: sources.crowdsec-hub.src
|
||||
{
|
||||
sources,
|
||||
}:
|
||||
sources.crowdsec-hub.src
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue