Compare commits

...

5 commits

16 changed files with 264 additions and 60 deletions

View file

@ -6,6 +6,8 @@ let
in
{
x86_64-linux = lib.mergeAttrsList [
flake-inputs.self.nixosConfigurations.hetzner-1.config.serviceTests
{
nix = checkLib.mkLint {
name = "nix-lints";

View file

@ -1,5 +1,5 @@
{
config,
lib,
modulesPath,
flake-inputs,
...
@ -9,25 +9,11 @@
flake-inputs.disko.nixosModules.disko
flake-inputs.sops-nix.nixosModules.sops
flake-inputs.tlaternet-webserver.nixosModules.default
"${modulesPath}/profiles/minimal.nix"
(import ../modules)
./services/backups.nix
./services/battery-manager.nix
./services/conduit
./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
# ./services/starbound.nix -- Not currently used
./services/postgres.nix
../modules
./nginx
./services
];
nix = {
@ -39,49 +25,9 @@
settings.trusted-users = [ "@wheel" ];
};
# Optimization for minecraft servers, see:
# https://bugs.mojang.com/browse/MC-183518
boot.kernelParams = [
"highres=off"
"nohz=off"
];
networking = {
usePredictableInterfaceNames = false;
useDHCP = false;
firewall = {
allowedTCPPorts = [
# http
80
443
# ssh
2222
# matrix
8448
# starbound
21025
config.services.coturn.listening-port
config.services.coturn.tls-listening-port
config.services.coturn.alt-listening-port
config.services.coturn.alt-tls-listening-port
];
allowedUDPPorts = [
config.services.coturn.listening-port
config.services.coturn.tls-listening-port
config.services.coturn.alt-listening-port
config.services.coturn.alt-tls-listening-port
];
allowedUDPPortRanges = [
{
from = config.services.coturn.min-port;
to = config.services.coturn.max-port;
}
];
};
};
systemd.network.enable = true;
@ -124,7 +70,7 @@
sops.defaultSopsFile = ../keys/production.yaml;
# Remove some unneeded packages
environment.defaultPackages = [ ];
environment.defaultPackages = lib.mkForce [ ];
system.stateVersion = "20.09";
}

View file

@ -1,4 +1,10 @@
{ config, lib, ... }:
{
flake-inputs,
pkgs,
config,
lib,
...
}:
let
hostNames = lib.attrNames config.services.nginx.virtualHosts;
logPath = name: "/var/log/nginx/${name}/access.log";
@ -80,5 +86,55 @@ in
};
};
};
serviceTests =
let
testHostConfig =
{ config, ... }:
{
imports = [
./.
../../modules/serviceTests/mocks.nix
];
networking.firewall.allowedTCPPorts = [ 80 ];
services.nginx = {
domain = "testHost";
virtualHosts."${config.services.nginx.domain}".locations."/".return = "200 ok";
};
};
in
{
nginxMetricsWork = pkgs.testers.runNixOSTest {
name = "nginx-metrics-work";
node.specialArgs = { inherit flake-inputs; };
nodes = {
testHost = testHostConfig;
client =
{ pkgs, ... }:
{
environment.systemPackages = [ pkgs.curl ];
};
};
testScript = ''
import time
start_all()
testHost.wait_for_unit("nginx.service")
client.succeed("curl --max-time 10 http://testHost")
# Wait a bit for the prometheus exporter to scrape our logs
time.sleep(5)
res = testHost.succeed("curl localhost:${builtins.toString config.services.prometheus.exporters.nginxlog.port}/metrics")
assert 'nginxlog_http_response_count_total{method="GET",status="200",vhost="testHost"} 1' in res, res
'';
};
};
};
}

View file

@ -1,4 +1,5 @@
{
flake-inputs,
pkgs,
config,
lib,
@ -69,5 +70,72 @@
"porkbun/api-key".owner = "acme";
"porkbun/secret-api-key".owner = "acme";
};
serviceTests =
let
testHostConfig =
{ config, ... }:
{
imports = [
./.
../../modules/serviceTests/mocks.nix
];
networking.firewall.allowedTCPPorts = [
80
443
];
security.acme.certs."tlater.net".extraDomainNames = [ config.services.nginx.domain ];
services.nginx = {
domain = "testHost";
virtualHosts."${config.services.nginx.domain}" = {
useACMEHost = "tlater.net";
forceSSL = true;
enableHSTS = true;
locations."/".return = "200 ok";
};
};
};
in
{
hstsIsSet = pkgs.testers.runNixOSTest {
name = "hsts-is-set";
node.specialArgs = { inherit flake-inputs; };
nodes = {
testHost = testHostConfig;
client =
{ pkgs, ... }:
{
environment.systemPackages = [ pkgs.curl ];
};
};
testScript = ''
start_all()
testHost.wait_for_unit("nginx.service")
testHost.copy_from_vm("/var/lib/acme/tlater.net/", "certs")
client.copy_from_host(f"{testHost.out_dir}/certs", "/certs")
client.succeed("curl --max-time 10 http://testHost")
res = client.succeed(" ".join([
"curl",
"--show-error",
"--silent",
"--dump-header -",
"--cacert /certs/tlater.net/fullchain.pem",
"https://testHost",
"-o /dev/null"
]))
assert "strict-transport-security: max-age=15552000; includeSubDomains" in res
'';
};
};
};
}

View file

@ -17,6 +17,36 @@ in
./matrix-hookshot.nix
];
networking.firewall = {
allowedTCPPorts = [
# These are for "normal" clients
80
443
# Federation happens on 8448
8448
config.services.coturn.listening-port
config.services.coturn.tls-listening-port
config.services.coturn.alt-listening-port
config.services.coturn.alt-tls-listening-port
];
allowedUDPPorts = [
config.services.coturn.listening-port
config.services.coturn.tls-listening-port
config.services.coturn.alt-listening-port
config.services.coturn.alt-tls-listening-port
];
allowedUDPPortRanges = [
{
from = config.services.coturn.min-port;
to = config.services.coturn.max-port;
}
];
};
services = {
matrix-conduit = {
enable = true;

View file

@ -0,0 +1,18 @@
{
imports = [
./backups.nix
./battery-manager.nix
./conduit
./crowdsec.nix
./foundryvtt.nix
./gitea.nix
./immich.nix
./metrics
./minecraft.nix
./nextcloud.nix
./postgres.nix
# ./starbound.nix -- Not currently used
./webserver.nix
./wireguard.nix
];
}

View file

@ -11,6 +11,11 @@ in
{
imports = [ flake-inputs.foundryvtt.nixosModules.foundryvtt ];
networking.firewall.allowedTCPPorts = [
80
443
];
services = {
foundryvtt = {
enable = true;

View file

@ -8,6 +8,11 @@ let
domain = "gitea.${config.services.nginx.domain}";
in
{
networking.firewall.allowedTCPPorts = [
80
443
];
services = {
forgejo = {
enable = true;

View file

@ -8,6 +8,11 @@ let
hostName = "immich.${config.services.nginx.domain}";
in
{
networking.firewall.allowedTCPPorts = [
80
443
];
services = {
immich = {
enable = true;

View file

@ -3,6 +3,11 @@ let
domain = "metrics.${config.services.nginx.domain}";
in
{
networking.firewall.allowedTCPPorts = [
80
443
];
services.grafana = {
enable = true;
settings = {

View file

@ -9,6 +9,11 @@ let
hostName = "nextcloud.${config.services.nginx.domain}";
in
{
networking.firewall.allowedTCPPorts = [
80
443
];
services = {
nextcloud = {
inherit hostName;

View file

@ -8,6 +8,8 @@ let
inherit (lib) concatStringsSep;
in
{
networking.firewall.allowedTCPPorts = [ 21025 ];
# Sadly, steam-run requires some X libs
environment.noXlibs = false;

View file

@ -3,6 +3,11 @@ let
inherit (config.services.nginx) domain;
in
{
networking.firewall.allowedTCPPorts = [
80
443
];
services.tlaternet-webserver = {
enable = true;
listen = {

View file

@ -1 +1,6 @@
{ imports = [ ./crowdsec ]; }
{
imports = [
./crowdsec
./serviceTests/stub.nix
];
}

View file

@ -0,0 +1,27 @@
/**
Module containing mock definitions for service test runners.
*/
{ flake-inputs, lib, ... }:
{
imports = [
flake-inputs.sops-nix.nixosModules.sops
../.
../../configuration/services/backups.nix
];
sops.defaultSopsFile = ../../keys/staging.yaml;
environment.etc."staging.key" = {
mode = "0400";
source = ../../keys/hosts/staging.key;
};
services.openssh = {
enable = true;
hostKeys = lib.mkForce [
{
type = "rsa";
bits = 4096;
path = "/etc/staging.key";
}
];
};
}

View file

@ -0,0 +1,20 @@
/**
Module to make writing service-specific tests easy.
*/
{ lib, ... }:
let
inherit (lib) mkOption types;
in
{
options = {
serviceTests = mkOption {
type = types.attrsOf types.package;
description = ''
NixOS tests to run.
'';
default = { };
};
};
}