Compare commits
1 commit
master
...
tlater/aut
| Author | SHA1 | Date | |
|---|---|---|---|
| 80d0f8fc9f |
17 changed files with 1093 additions and 399 deletions
|
|
@ -1,45 +1,61 @@
|
|||
{ flake-inputs }:
|
||||
let
|
||||
inherit (flake-inputs.nixpkgs) lib;
|
||||
pkgs = flake-inputs.nixpkgs.legacyPackages.x86_64-linux;
|
||||
checkLib = pkgs.callPackage ./lib.nix { };
|
||||
in
|
||||
{
|
||||
x86_64-linux = lib.mergeAttrsList [
|
||||
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 =
|
||||
{
|
||||
nix = checkLib.mkLint {
|
||||
name = "nix-lints";
|
||||
fileset = lib.fileset.fileFilter (file: file.hasExt "nix") ../.;
|
||||
name,
|
||||
packages,
|
||||
check,
|
||||
}:
|
||||
pkgs.stdenvNoCC.mkDerivation {
|
||||
inherit name;
|
||||
|
||||
checkInputs = lib.attrValues {
|
||||
inherit (pkgs) deadnix nixfmt-rfc-style;
|
||||
|
||||
statix = pkgs.statix.overrideAttrs (old: {
|
||||
patches = old.patches ++ [
|
||||
(pkgs.fetchpatch {
|
||||
url = "https://github.com/oppiliappan/statix/commit/925dec39bb705acbbe77178b4d658fe1b752abbb.patch";
|
||||
hash = "sha256-0wacO6wuYJ4ufN9PGucRVJucFdFFNF+NoHYIrLXsCWs=";
|
||||
})
|
||||
];
|
||||
});
|
||||
};
|
||||
|
||||
script = ''
|
||||
statix check **/*.nix
|
||||
deadnix --fail **/*.nix
|
||||
nixfmt --check --strict **/*.nix
|
||||
'';
|
||||
src = nixpkgs.lib.cleanSourceWith {
|
||||
src = self;
|
||||
filter = nixpkgs.lib.cleanSourceFilter;
|
||||
};
|
||||
|
||||
lockfile = checkLib.mkLint {
|
||||
name = "nix-lockfile";
|
||||
fileset = ../flake.lock;
|
||||
checkInputs = lib.attrValues { inherit (flake-inputs.flint.packages.x86_64-linux) flint; };
|
||||
dontPatch = true;
|
||||
dontConfigure = true;
|
||||
dontBuild = true;
|
||||
dontInstall = true;
|
||||
dontFixup = true;
|
||||
doCheck = true;
|
||||
|
||||
script = ''
|
||||
flint --fail-if-multiple-versions
|
||||
'';
|
||||
};
|
||||
}
|
||||
];
|
||||
}
|
||||
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,35 +0,0 @@
|
|||
{ pkgs, lib, ... }:
|
||||
{
|
||||
mkLint =
|
||||
{
|
||||
name,
|
||||
fileset,
|
||||
checkInputs ? [ ],
|
||||
script,
|
||||
}:
|
||||
pkgs.stdenvNoCC.mkDerivation {
|
||||
inherit name;
|
||||
|
||||
src = lib.fileset.toSource {
|
||||
root = ../.;
|
||||
fileset = lib.fileset.difference fileset (
|
||||
lib.fileset.fileFilter (
|
||||
file: file.type != "regular" || file.name == "hardware-configuration.nix"
|
||||
) ../.
|
||||
);
|
||||
};
|
||||
|
||||
checkInputs = [ pkgs.nushell ] ++ checkInputs;
|
||||
|
||||
checkPhase = ''
|
||||
nu -c '${script}' | tee $out
|
||||
'';
|
||||
|
||||
dontPatch = true;
|
||||
dontConfigure = true;
|
||||
dontBuild = true;
|
||||
dontInstall = true;
|
||||
dontFixup = true;
|
||||
doCheck = true;
|
||||
};
|
||||
}
|
||||
|
|
@ -13,6 +13,7 @@
|
|||
"${modulesPath}/profiles/minimal.nix"
|
||||
(import ../modules)
|
||||
|
||||
./services/auth
|
||||
./services/backups.nix
|
||||
./services/battery-manager.nix
|
||||
./services/conduit
|
||||
|
|
@ -27,7 +28,7 @@
|
|||
./services/wireguard.nix
|
||||
# ./services/starbound.nix -- Not currently used
|
||||
./services/postgres.nix
|
||||
./nginx
|
||||
./nginx.nix
|
||||
./sops.nix
|
||||
];
|
||||
|
||||
|
|
|
|||
|
|
@ -48,7 +48,6 @@
|
|||
memorySize = 3941;
|
||||
cores = 2;
|
||||
graphics = false;
|
||||
diskSize = 1024 * 20;
|
||||
};
|
||||
|
||||
virtualisation.qemu = {
|
||||
|
|
|
|||
77
configuration/nginx.nix
Normal file
77
configuration/nginx.nix
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
{ config, lib, ... }:
|
||||
{
|
||||
services = {
|
||||
nginx = {
|
||||
enable = true;
|
||||
recommendedTlsSettings = true;
|
||||
recommendedOptimisation = true;
|
||||
recommendedGzipSettings = true;
|
||||
recommendedProxySettings = true;
|
||||
clientMaxBodySize = "10G";
|
||||
|
||||
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;
|
||||
};
|
||||
};
|
||||
|
||||
systemd.tmpfiles.rules = lib.mapAttrsToList (
|
||||
virtualHost: _:
|
||||
#
|
||||
"d /var/log/nginx/${virtualHost} 0750 ${config.services.nginx.user} ${config.services.nginx.group}"
|
||||
) config.services.nginx.virtualHosts;
|
||||
|
||||
security.acme = {
|
||||
defaults.email = "tm@tlater.net";
|
||||
acceptTerms = true;
|
||||
|
||||
certs."tlater.net" = {
|
||||
extraDomainNames = [
|
||||
"*.tlater.net"
|
||||
"tlater.com"
|
||||
"*.tlater.com"
|
||||
];
|
||||
dnsProvider = "porkbun";
|
||||
group = "ssl-cert";
|
||||
credentialFiles = {
|
||||
PORKBUN_API_KEY_FILE = config.sops.secrets."porkbun/api-key".path;
|
||||
PORKBUN_SECRET_API_KEY_FILE = config.sops.secrets."porkbun/secret-api-key".path;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
users.groups.ssl-cert = { };
|
||||
|
||||
systemd.services.nginx.serviceConfig.SupplementaryGroups = [
|
||||
config.security.acme.certs."tlater.net".group
|
||||
];
|
||||
}
|
||||
|
|
@ -1,22 +0,0 @@
|
|||
{ lib, ... }:
|
||||
{
|
||||
imports = [
|
||||
./logging.nix
|
||||
./ssl.nix
|
||||
];
|
||||
|
||||
options.services.nginx.domain = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
description = "The base domain name to append to virtual domain names";
|
||||
};
|
||||
|
||||
config.services.nginx = {
|
||||
enable = true;
|
||||
recommendedTlsSettings = true;
|
||||
recommendedOptimisation = true;
|
||||
recommendedGzipSettings = true;
|
||||
recommendedProxySettings = true;
|
||||
clientMaxBodySize = "10G";
|
||||
statusPage = true; # For metrics, should be accessible only from localhost
|
||||
};
|
||||
}
|
||||
|
|
@ -1,84 +0,0 @@
|
|||
{ config, lib, ... }:
|
||||
let
|
||||
hostNames = lib.attrNames config.services.nginx.virtualHosts;
|
||||
logPath = name: "/var/log/nginx/${name}/access.log";
|
||||
logFormat = lib.concatStringsSep " " [
|
||||
"$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"''
|
||||
];
|
||||
in
|
||||
{
|
||||
# Extend the default configuration for nginx virtual hosts; we'd
|
||||
# like to create log files for each of them, so that the prometheus
|
||||
# nginxlog exporter can process per-host logs.
|
||||
options.services.nginx.virtualHosts = lib.mkOption {
|
||||
type = lib.types.attrsOf (
|
||||
lib.types.submodule (
|
||||
{ name, ... }:
|
||||
{
|
||||
config.extraConfig = ''
|
||||
access_log ${logPath name} upstream_time;
|
||||
'';
|
||||
}
|
||||
)
|
||||
);
|
||||
};
|
||||
|
||||
config = {
|
||||
# Create directories for host-specific logs with systemd tmpfiles
|
||||
systemd.tmpfiles.settings."10-nginx-logs" = lib.listToAttrs (
|
||||
map (
|
||||
name:
|
||||
lib.nameValuePair "/var/log/nginx/${name}" {
|
||||
d = {
|
||||
inherit (config.services.nginx) user group;
|
||||
mode = "0750";
|
||||
};
|
||||
}
|
||||
) hostNames
|
||||
);
|
||||
|
||||
services = {
|
||||
# Set the nginx-wide log format
|
||||
nginx.commonHttpConfig = ''
|
||||
log_format upstream_time '${logFormat}';
|
||||
'';
|
||||
|
||||
# Set up nginxlog to read the file and log format defined above
|
||||
# for each virtual host
|
||||
prometheus.exporters.nginxlog = {
|
||||
enable = true;
|
||||
listenAddress = "127.0.0.1";
|
||||
group = "nginx";
|
||||
|
||||
settings.namespaces = map (name: {
|
||||
inherit name;
|
||||
metrics_override.prefix = "nginxlog";
|
||||
namespace_label = "vhost";
|
||||
format = logFormat;
|
||||
source.files = [ (logPath name) ];
|
||||
}) hostNames;
|
||||
};
|
||||
|
||||
logrotate.settings = {
|
||||
# Override the nginx module default, just keep fewer logs
|
||||
nginx.rotate = 6;
|
||||
|
||||
# Configure logrotate for host-specific logs
|
||||
nginxVirtualHosts = {
|
||||
files = map logPath hostNames;
|
||||
|
||||
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`";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
@ -1,68 +0,0 @@
|
|||
{
|
||||
pkgs,
|
||||
config,
|
||||
lib,
|
||||
...
|
||||
}:
|
||||
{
|
||||
options = {
|
||||
# Add a custom per-host option to enable HSTS
|
||||
services.nginx.virtualHosts = lib.mkOption {
|
||||
type = lib.types.attrsOf (
|
||||
lib.types.submodule (
|
||||
{ config, ... }:
|
||||
{
|
||||
options.enableHSTS = lib.mkEnableOption "HSTS";
|
||||
config.extraConfig = lib.mkIf config.enableHSTS ''
|
||||
add_header Strict-Transport-Security "max-age=15552000; includeSubDomains" always;
|
||||
'';
|
||||
}
|
||||
)
|
||||
);
|
||||
};
|
||||
};
|
||||
|
||||
config = {
|
||||
# Certificate settings
|
||||
security.acme = {
|
||||
defaults.email = "tm@tlater.net";
|
||||
acceptTerms = true;
|
||||
|
||||
certs."tlater.net" = {
|
||||
extraDomainNames = [
|
||||
"*.tlater.net"
|
||||
"tlater.com"
|
||||
"*.tlater.com"
|
||||
];
|
||||
dnsProvider = "porkbun";
|
||||
group = config.users.groups.ssl-cert.name;
|
||||
credentialFiles = {
|
||||
PORKBUN_API_KEY_FILE = config.sops.secrets."porkbun/api-key".path;
|
||||
PORKBUN_SECRET_API_KEY_FILE = config.sops.secrets."porkbun/secret-api-key".path;
|
||||
};
|
||||
};
|
||||
};
|
||||
users.groups.ssl-cert = { };
|
||||
|
||||
# Back up the SSL certificate, just in case
|
||||
services.backups.acme = {
|
||||
user = "acme";
|
||||
paths = [ "/var/lib/acme/tlater.net" ];
|
||||
};
|
||||
|
||||
systemd.services = {
|
||||
nginx.serviceConfig.SupplementaryGroups = [ config.security.acme.certs."tlater.net".group ];
|
||||
|
||||
# Don't attempt to retrieve a certificate if the domain name
|
||||
# doesn't *actually* match the cert name
|
||||
#
|
||||
# TODO(tlater): Set up pebble to retrieve certs "properly"
|
||||
# instead
|
||||
"acme-tlater.net".serviceConfig.ExecCondition =
|
||||
let
|
||||
confirm = ''[[ "tlater.net" = "${config.services.nginx.domain}" ]]'';
|
||||
in
|
||||
''${pkgs.runtimeShell} -c '${confirm}' '';
|
||||
};
|
||||
};
|
||||
}
|
||||
87
configuration/services/auth/authelia.nix
Normal file
87
configuration/services/auth/authelia.nix
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
{ config, ... }:
|
||||
let
|
||||
instanceName = config.services.authelia.instances.main.name;
|
||||
in
|
||||
{
|
||||
services.authelia.instances.main = {
|
||||
enable = true;
|
||||
|
||||
settings = {
|
||||
theme = "auto";
|
||||
default_2fa_method = "totp";
|
||||
|
||||
authentication_backend = {
|
||||
password_reset.disable = true;
|
||||
password_change.disable = true;
|
||||
|
||||
file = {
|
||||
inherit (config.sops.secrets."authelia/users") path;
|
||||
|
||||
search = {
|
||||
email = true;
|
||||
case_insensitive = false;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
storage.postgres = {
|
||||
address = "unix:///run/postgresql";
|
||||
database = "authelia";
|
||||
username = "authelia";
|
||||
};
|
||||
|
||||
session.cookies = [
|
||||
{
|
||||
domain = config.services.nginx.domain;
|
||||
authelia_url = "https://auth.${config.services.nginx.domain}";
|
||||
}
|
||||
];
|
||||
|
||||
notifier.filesystem.filename = ''{{ env "RUNTIME_DIRECTORY" }}/authelia-notifications'';
|
||||
|
||||
access_control = {
|
||||
|
||||
};
|
||||
|
||||
server = {
|
||||
# Maybe a systemd socket can be used for this in the future,
|
||||
# see:
|
||||
# https://github.com/systemd/systemd/issues/23067#issuecomment-1212232155
|
||||
address = "unix://${config.systemd.sockets."authelia-${instanceName}".socketConfig.ListenStream}";
|
||||
};
|
||||
};
|
||||
|
||||
secrets = {
|
||||
jwtSecretFile = config.sops.secrets."authelia/jwt".path;
|
||||
storageEncryptionKeyFile = config.sops.secrets."authelia/storage".path;
|
||||
};
|
||||
};
|
||||
|
||||
systemd.sockets."authelia-${instanceName}" = {
|
||||
socketConfig = {
|
||||
Accept = false;
|
||||
ListenStream = "/var/run/authelia.sock";
|
||||
SocketGroup = "authelia";
|
||||
SocketMode = "0660";
|
||||
};
|
||||
};
|
||||
|
||||
systemd.services."authelia-${instanceName}" = {
|
||||
requires = [ "authelia-${instanceName}.socket" ];
|
||||
|
||||
serviceConfig = {
|
||||
RuntimeDirectory = "authelia-${instanceName}";
|
||||
SupplementaryGroups = [ "authelia" ];
|
||||
};
|
||||
};
|
||||
|
||||
# TODO: Need to map these to systemd creds to pass them into the
|
||||
# service because user permissions
|
||||
sops.secrets = {
|
||||
"authelia/users" = { };
|
||||
"authelia/jwt" = { };
|
||||
"authelia/storage" = { };
|
||||
};
|
||||
|
||||
users.groups.authelia = { };
|
||||
}
|
||||
5
configuration/services/auth/default.nix
Normal file
5
configuration/services/auth/default.nix
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
imports = [
|
||||
./authelia.nix
|
||||
];
|
||||
}
|
||||
|
|
@ -1,4 +1,9 @@
|
|||
{ pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
pkgs,
|
||||
lib,
|
||||
...
|
||||
}:
|
||||
let
|
||||
yaml = pkgs.formats.yaml { };
|
||||
in
|
||||
|
|
@ -63,6 +68,28 @@ in
|
|||
enable = true;
|
||||
listenAddress = "127.0.0.1";
|
||||
};
|
||||
|
||||
nginxlog = {
|
||||
enable = true;
|
||||
listenAddress = "127.0.0.1";
|
||||
group = "nginx";
|
||||
|
||||
settings.namespaces = lib.mapAttrsToList (name: _: {
|
||||
inherit name;
|
||||
metrics_override.prefix = "nginxlog";
|
||||
namespace_label = "vhost";
|
||||
|
||||
format = lib.concatStringsSep " " [
|
||||
"$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"''
|
||||
];
|
||||
|
||||
source.files = [ "/var/log/nginx/${name}/access.log" ];
|
||||
}) config.services.nginx.virtualHosts;
|
||||
};
|
||||
};
|
||||
|
||||
# TODO(tlater):
|
||||
|
|
|
|||
|
|
@ -17,6 +17,10 @@
|
|||
# that operation needs to be performed manually on the system as
|
||||
# well.
|
||||
ensureUsers = [
|
||||
{
|
||||
name = "authelia";
|
||||
ensureDBOwnership = true;
|
||||
}
|
||||
{
|
||||
name = "grafana";
|
||||
ensureDBOwnership = true;
|
||||
|
|
@ -28,6 +32,7 @@
|
|||
];
|
||||
|
||||
ensureDatabases = [
|
||||
"authelia"
|
||||
"grafana"
|
||||
"nextcloud"
|
||||
];
|
||||
|
|
|
|||
860
flake.lock
generated
860
flake.lock
generated
File diff suppressed because it is too large
Load diff
46
flake.nix
46
flake.nix
|
|
@ -3,44 +3,19 @@
|
|||
|
||||
inputs = {
|
||||
nixpkgs.url = "github:nixos/nixpkgs/nixos-25.05-small";
|
||||
|
||||
## Nix/OS utilities
|
||||
|
||||
disko = {
|
||||
url = "github:nix-community/disko";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
|
||||
deploy-rs = {
|
||||
url = "github:serokell/deploy-rs";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
|
||||
deploy-rs.url = "github:serokell/deploy-rs";
|
||||
sops-nix = {
|
||||
url = "github:Mic92/sops-nix";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
|
||||
## Programs
|
||||
|
||||
flint = {
|
||||
url = "github:NotAShelf/flint";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
|
||||
## Services
|
||||
|
||||
tlaternet-webserver = {
|
||||
url = "git+https://gitea.tlater.net/tlaternet/tlaternet.git";
|
||||
inputs = {
|
||||
nixpkgs.follows = "nixpkgs";
|
||||
dream2nix.inputs = {
|
||||
nixpkgs.follows = "nixpkgs";
|
||||
purescript-overlay.inputs.flake-compat.follows = "deploy-rs/flake-compat";
|
||||
};
|
||||
};
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
|
||||
foundryvtt = {
|
||||
url = "github:reckenrode/nix-foundryvtt";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
|
|
@ -48,20 +23,7 @@
|
|||
|
||||
sonnenshift = {
|
||||
url = "git+ssh://git@github.com/sonnenshift/battery-manager";
|
||||
inputs = {
|
||||
nixpkgs.follows = "nixpkgs";
|
||||
|
||||
crate2nix.inputs = {
|
||||
nixpkgs.follows = "nixpkgs";
|
||||
flake-compat.follows = "deploy-rs/flake-compat";
|
||||
cachix.inputs.nixpkgs.follows = "nixpkgs";
|
||||
pre-commit-hooks.inputs.gitignore.follows = "sonnenshift/crate2nix/cachix/git-hooks/gitignore";
|
||||
|
||||
# Yes, they do this insanity:
|
||||
# https://github.com/nix-community/crate2nix/issues/371
|
||||
crate2nix_stable.follows = "sonnenshift/crate2nix";
|
||||
};
|
||||
};
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
};
|
||||
|
||||
|
|
@ -128,7 +90,7 @@
|
|||
#########
|
||||
# Tests #
|
||||
#########
|
||||
checks = import ./checks { flake-inputs = inputs; };
|
||||
checks.${system} = import ./checks (inputs // { inherit system; });
|
||||
|
||||
###########################
|
||||
# Garbage collection root #
|
||||
|
|
|
|||
|
|
@ -1,3 +1,7 @@
|
|||
authelia:
|
||||
users: ""
|
||||
jwt: ENC[AES256_GCM,data:oKA1B7zZAzTZL4nBdHvPENVx7M2BgbMBmNtetri0qCVB7qNFIgbnwVCJFiDvjKxxNdedqUKBZZL5QJbTlPNRxCVdFgBBMFiib3khxMP8kzqff2MgJZxumonlJt5Jmh8tVxwLRJwE/2fp/N9w2hRs0vhfmMyAA4y7RZv3R9/eaKM=,iv:2iTAwP6dipPBMskyygnBJHJ53E0nmHYcGyWDrODEs1Q=,tag:koSEZtQQzOzpbQBgUP5ZHw==,type:str]
|
||||
storage: ENC[AES256_GCM,data:bO+bHu6jRvfbLU6xIDaE2JwXpNnMK916Upv43ycg9fCb+U5hqQfqBBwC2xVEVXtCBRq1VER+gc8rs8/XDT9vZkvMUqAHj4RqXHyzX0UjwsvccBJSLfoLUiT6obk3oVLo5CY7R2TukPuyFXPbMUOrBk9gnbk7z4IWzcwNnuOKBT4=,iv:RmKIS/cgZ0tUQDFF2yfaJnfTvPaeadjG0LPXKIzYFrA=,tag:XmqDhDf3Ja1BsyrYmzTKDg==,type:str]
|
||||
porkbun:
|
||||
api-key: ENC[AES256_GCM,data:A5J1sqwq6hs=,iv:77Mar3IX7mq7z7x6s9sSeGNVYc1Wv78HptJElEC7z3Q=,tag:eM/EF9TxKu+zcbJ1SYXiuA==,type:str]
|
||||
secret-api-key: ENC[AES256_GCM,data:8Xv+jWYaWMI=,iv:li4tdY0pch5lksftMmfMVS729caAwfaacoztaQ49az0=,tag:KhfElBGzVH4ByFPfuQsdhw==,type:str]
|
||||
|
|
@ -32,8 +36,8 @@ turn:
|
|||
#ENC[AES256_GCM,data:bxhKzU5Tzezl749CDu8e8kxa7ahGuZFaPa9K3kxuD+4sg5Hi3apgDlC0n8oK0DeiK4Ks7+9Cyw==,iv:T/zVJUpNAv1rR0a9+6SDTG08ws2A1hFBs5Ia3TpT0uk=,tag:uGXb1VryM+lIJ8r0I5durA==,type:comment]
|
||||
ssl-cert: ENC[AES256_GCM,data:xHUr14CjKslgbGh/n5jYSOuCw9JRxS6YXE4fxS+aJzFcNeSeGNqoipPeuJupZGBnQP/FCqohiHY=,iv:/OEsVqRshGL9NIvntMC42EPZSNL0u6EfhtUBqgV7qog=,tag:4pxtNjuvy/ibm6nDtKdSkw==,type:str]
|
||||
sops:
|
||||
lastmodified: "2025-02-07T17:43:24Z"
|
||||
mac: ENC[AES256_GCM,data:akmD/bfgeTyFzW1quvM16cdj0fC6+CbJ8WyX9173H11yKGxvE1USQYcErpl1SHOx9Jk8LVb7f+MsUm2fjQF1MEq6xaWI74jem12lZ9CGXFaTL7e87JvfbK7pV+aKpxSBBNFyJgbYm30ibdUwxwKmNVfPb1e0HT9qwenvoV7RobM=,iv:mKqOW0ULXL711uczUbRf9NPo6uPTQoS/IbR46S+JID4=,tag:vE6NYzYLbQHDImov1XGTcg==,type:str]
|
||||
lastmodified: "2025-10-20T20:04:21Z"
|
||||
mac: ENC[AES256_GCM,data:kRrmVm3PQooRA/MoHgDb9EaRnoKY9CJxAflus9Po8NBmyQxV6Ehjf8DlI6yf7ZpPlhV+VHZJamyPD+hsHp1hSr8krvr0o52ZQdKn4MJQzSQXa4K9i3i0+glj7cNGs2SzTJnKwN9lxBywZpbVDlkXmvRQYLE9tWPWoSBdurOibjw=,iv:2iBQ1cYT85mCc7jf2GTEOjNiHBlR/F76Dvjl/k5dyLA=,tag:Z7dY2i0KWmmoVp7VJjq1Sw==,type:str]
|
||||
pgp:
|
||||
- created_at: "2025-10-03T21:38:26Z"
|
||||
enc: |-
|
||||
|
|
@ -67,4 +71,4 @@ sops:
|
|||
-----END PGP MESSAGE-----
|
||||
fp: 2f5caa73e7ceea4fcc8d2881fde587e6737d2dbc
|
||||
unencrypted_suffix: _unencrypted
|
||||
version: 3.9.2
|
||||
version: 3.11.0
|
||||
|
|
|
|||
|
|
@ -1 +1,6 @@
|
|||
{ imports = [ ./crowdsec ]; }
|
||||
{
|
||||
imports = [
|
||||
./crowdsec
|
||||
./nginxExtensions.nix
|
||||
];
|
||||
}
|
||||
|
|
|
|||
59
modules/nginxExtensions.nix
Normal file
59
modules/nginxExtensions.nix
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
{
|
||||
config,
|
||||
pkgs,
|
||||
lib,
|
||||
...
|
||||
}:
|
||||
{
|
||||
options = {
|
||||
services.nginx.domain = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
description = "The base domain name to append to virtual domain names";
|
||||
};
|
||||
|
||||
services.nginx.virtualHosts =
|
||||
let
|
||||
extraVirtualHostOptions =
|
||||
{ name, config, ... }:
|
||||
{
|
||||
options = {
|
||||
enableHSTS = lib.mkEnableOption "Enable HSTS";
|
||||
|
||||
addAccessLog = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = true;
|
||||
description = ''
|
||||
Add special logging to `/var/log/nginx/''${serverName}`
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
config = {
|
||||
extraConfig = lib.concatStringsSep "\n" [
|
||||
(lib.optionalString config.enableHSTS ''
|
||||
add_header Strict-Transport-Security "max-age=15552000; includeSubDomains" always;
|
||||
'')
|
||||
(lib.optionalString config.addAccessLog ''
|
||||
access_log /var/log/nginx/${name}/access.log upstream_time;
|
||||
'')
|
||||
];
|
||||
};
|
||||
};
|
||||
in
|
||||
lib.mkOption { type = lib.types.attrsOf (lib.types.submodule extraVirtualHostOptions); };
|
||||
};
|
||||
|
||||
config = {
|
||||
# Don't attempt to run acme if the domain name is not tlater.net
|
||||
systemd.services =
|
||||
let
|
||||
confirm = ''[[ "tlater.net" = ${config.services.nginx.domain} ]]'';
|
||||
in
|
||||
lib.mapAttrs' (
|
||||
cert: _:
|
||||
lib.nameValuePair "acme-${cert}" {
|
||||
serviceConfig.ExecCondition = ''${pkgs.runtimeShell} -c '${confirm}' '';
|
||||
}
|
||||
) config.security.acme.certs;
|
||||
};
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue