This commit is contained in:
Grimmauld 2024-05-08 21:50:08 +02:00
parent f4615cbae9
commit a7734d312b
Signed by: Grimmauld
GPG key ID: C2946668769F91FB
25 changed files with 328 additions and 222 deletions

View file

@ -56,9 +56,7 @@ in
}; };
boot = { boot = {
kernelParams = [ kernelParams = [ "quiet" ];
"quiet"
];
loader.efi.canTouchEfiVariables = true; loader.efi.canTouchEfiVariables = true;
initrd.availableKernelModules = [ initrd.availableKernelModules = [
"xhci_pci" "xhci_pci"

View file

@ -83,9 +83,7 @@ in
services.power-profiles-daemon.enable = false; services.power-profiles-daemon.enable = false;
services.upower.enable = true; services.upower.enable = true;
boot.extraModulePackages = [ boot.extraModulePackages = [ cpupower ] ++ optional enable_perf_policy x86_energy_perf_policy;
cpupower
] ++ optional enable_perf_policy x86_energy_perf_policy;
services.tlp = { services.tlp = {
enable = true; enable = true;

View file

@ -17,7 +17,11 @@ in
programs.xonsh = { programs.xonsh = {
enable = true; enable = true;
config = lib.concatLines (lib.mapAttrsToList (name: value: ''aliases["${name}"] = "${value}"'') config.environment.shellAliases); config = lib.concatLines (
lib.mapAttrsToList (
name: value: ''aliases["${name}"] = "${value}"''
) config.environment.shellAliases
);
package = pkgs.xonsh.override { package = pkgs.xonsh.override {
extraPackages = extraPackages =
ps: with ps; [ ps: with ps; [

View file

@ -9,12 +9,17 @@ let
nivSources = import ./nix/sources.nix; nivSources = import ./nix/sources.nix;
asGithubRef = src: "github:${src.owner}/${src.repo}/${src.rev}"; asGithubRef = src: "github:${src.owner}/${src.repo}/${src.rev}";
build_target = let env_host = builtins.getEnv "NIXOS_TARGET_HOST"; in if env_host != "" then env_host else builtins.replaceStrings ["\n"] [""] (lib.toLower (builtins.readFile /proc/sys/kernel/hostname)); build_target =
let
env_host = builtins.getEnv "NIXOS_TARGET_HOST";
in
if env_host != "" then
env_host
else
builtins.replaceStrings [ "\n" ] [ "" ] (lib.toLower (builtins.readFile /proc/sys/kernel/hostname));
host_modules = { host_modules = {
grimmauld-nixos = [ grimmauld-nixos = [ ./specific/grimm-nixos-laptop/configuration.nix ];
./specific/grimm-nixos-laptop/configuration.nix
];
grimmauld-nixos-server = [ grimmauld-nixos-server = [
./specific/grimmauld-nixos-server/configuration.nix ./specific/grimmauld-nixos-server/configuration.nix
@ -49,11 +54,11 @@ in
"${nivSources.nixos-mailserver}/default.nix" "${nivSources.nixos-mailserver}/default.nix"
"${nivSources.nixos-matrix-modules}/module.nix" "${nivSources.nixos-matrix-modules}/module.nix"
# fixme: ideally we'd not rely on the flake syntax to load the module # fixme: ideally we'd not rely on the flake syntax to load the module
(builtins.getFlake (asGithubRef nivSources.chaotic)).nixosModules.default (builtins.getFlake (asGithubRef nivSources.chaotic)).nixosModules.default
# (builtins.getFlake (asGithubRef nivSources.nixos-matrix-modules)).nixosModules.default # (builtins.getFlake (asGithubRef nivSources.nixos-matrix-modules)).nixosModules.default
# (builtins.getFlake "git+${nivSources.nixos-mailserver.repo}").nixosModules.default # (builtins.getFlake "git+${nivSources.nixos-mailserver.repo}").nixosModules.default
] ++ lib.optionals (builtins.hasAttr build_target host_modules) host_modules.${build_target}; ] ++ lib.optionals (builtins.hasAttr build_target host_modules) host_modules.${build_target};
nixpkgs.hostPlatform = system; nixpkgs.hostPlatform = system;

View file

@ -1,22 +1,40 @@
{ config, lib, pkgs, ...}: let {
config,
lib,
pkgs,
...
}:
let
bridge_port = 9005; # netstat -nlp | grep 9005 bridge_port = 9005; # netstat -nlp | grep 9005
in { in
nixpkgs.overlays = [ (final: prev: { matrix-appservice-discord = prev.matrix-appservice-discord.overrideAttrs (old: { {
src = pkgs.fetchFromGitHub { nixpkgs.overlays = [
owner = "t2bot"; (final: prev: {
repo = "matrix-appservice-discord"; matrix-appservice-discord = prev.matrix-appservice-discord.overrideAttrs (old: {
rev = "8361ca6121bf1f0902154baa538cb6d5766e477f"; src = pkgs.fetchFromGitHub {
hash = "sha256-oXon6pFJgqQ1uBLtsSVNH7XSOpxxJYqpW2n9cFrs3sU="; owner = "t2bot";
}; repo = "matrix-appservice-discord";
patches = (let oldPatches = old.patches or []; in if oldPatches == null then [] else oldPatches) ++ [ ./patch_bridge_perms.patch ]; rev = "8361ca6121bf1f0902154baa538cb6d5766e477f";
doCheck = false; hash = "sha256-oXon6pFJgqQ1uBLtsSVNH7XSOpxxJYqpW2n9cFrs3sU=";
});}) };
patches =
(
let
oldPatches = old.patches or [ ];
in
if oldPatches == null then [ ] else oldPatches
)
++ [ ./patch_bridge_perms.patch ];
doCheck = false;
});
})
]; ];
age.secrets.matrix_discord_bridge_token.file = ../secrets/matrix_discord_bridge_token.age; age.secrets.matrix_discord_bridge_token.file = ../secrets/matrix_discord_bridge_token.age;
services.matrix-synapse-next.settings.app_service_config_files = [ "/var/lib/matrix-synapse/discord-registration.yaml" ]; services.matrix-synapse-next.settings.app_service_config_files = [
"/var/lib/matrix-synapse/discord-registration.yaml"
];
services.matrix-appservice-discord = { services.matrix-appservice-discord = {
enable = true; enable = true;
@ -31,13 +49,12 @@ in {
disablePresence = true; disablePresence = true;
disableTypingNotifications = true; disableTypingNotifications = true;
}; };
# logging.console = "silly"; # logging.console = "silly";
}; };
serviceDependencies = ["matrix-synapse.target"]; serviceDependencies = [ "matrix-synapse.target" ];
port = bridge_port; port = bridge_port;
localpart = "_discord_"; localpart = "_discord_";
package = pkgs.matrix-appservice-discord; package = pkgs.matrix-appservice-discord;
environmentFile = config.age.secrets.matrix_discord_bridge_token.path; environmentFile = config.age.secrets.matrix_discord_bridge_token.path;
}; };
} }

View file

@ -2,10 +2,11 @@
let let
inherit (config.networking) domain; inherit (config.networking) domain;
mail_host = "mail.${domain}"; mail_host = "mail.${domain}";
in { in
{
security.acme.certs."${domain}".extraDomainNames = [ mail_host ]; security.acme.certs."${domain}".extraDomainNames = [ mail_host ];
# services.dovecot2.sieve.extensions = [ "fileinto" ]; # sives break without this for some reason # services.dovecot2.sieve.extensions = [ "fileinto" ]; # sives break without this for some reason
mailserver = { mailserver = {
enable = true; enable = true;
fqdn = mail_host; fqdn = mail_host;
@ -16,7 +17,7 @@ in {
loginAccounts = { loginAccounts = {
"contact@${domain}" = { "contact@${domain}" = {
hashedPasswordFile = ./mailpass/contact; hashedPasswordFile = ./mailpass/contact;
aliases = ["kontakt@${domain}"]; aliases = [ "kontakt@${domain}" ];
}; };
"admin@${domain}" = { "admin@${domain}" = {
hashedPasswordFile = ./mailpass/admin; hashedPasswordFile = ./mailpass/admin;
@ -33,9 +34,10 @@ in {
keyFile = "/var/lib/acme/${domain}/key.pem"; keyFile = "/var/lib/acme/${domain}/key.pem";
}; };
services.nginx = { services.nginx = {
enable = true; enable = true;
virtualHosts."${mail_host}" = { # you should NOT be here from a browser :P virtualHosts."${mail_host}" = {
# you should NOT be here from a browser :P
serverName = mail_host; serverName = mail_host;
forceSSL = true; forceSSL = true;
useACMEHost = domain; useACMEHost = domain;

View file

@ -1,10 +1,13 @@
{ ... }: { { ... }:
{
services.fail2ban = { services.fail2ban = {
enable = true; enable = true;
maxretry = 5; maxretry = 5;
ignoreIP = [ ignoreIP = [
# Whitelist some subnets # Whitelist some subnets
"10.0.0.0/8" "172.16.0.0/12" "192.168.0.0/16" "10.0.0.0/8"
"172.16.0.0/12"
"192.168.0.0/16"
"matrix.org" "matrix.org"
"app.element.io" # don't ratelimit matrix users "app.element.io" # don't ratelimit matrix users
]; ];

View file

@ -1,10 +1,17 @@
{ lib, config, inputs, pkgs, ... }: {
lib,
config,
inputs,
pkgs,
...
}:
let let
inherit (config.networking) domain; inherit (config.networking) domain;
gitea_host = "git.${domain}"; gitea_host = "git.${domain}";
gitea_port = 8081; gitea_port = 8081;
gitea_ssh_port = 2222; gitea_ssh_port = 2222;
in { in
{
services.gitea = { services.gitea = {
enable = true; enable = true;
settings = { settings = {
@ -17,22 +24,19 @@ in {
START_SSH_SERVER = true; START_SSH_SERVER = true;
BUILTIN_SSH_SERVER_USER = "git"; BUILTIN_SSH_SERVER_USER = "git";
SSH_PORT = gitea_ssh_port; SSH_PORT = gitea_ssh_port;
# SSH_LISTEN_HOST="::"; # fixme? # SSH_LISTEN_HOST="::"; # fixme?
# SSH_AUTHORIZED_PRINCIPALS_ALLOW="username"; # SSH_AUTHORIZED_PRINCIPALS_ALLOW="username";
}; };
# log.LEVEL = "Debug"; # log.LEVEL = "Debug";
"ssh.minimum_key_sizes".RSA = 2048; "ssh.minimum_key_sizes".RSA = 2048;
"git.timeout".MIGRATE = 6000; "git.timeout".MIGRATE = 6000;
}; };
lfs.enable = true; lfs.enable = true;
}; };
environment.systemPackages = with pkgs; [ environment.systemPackages = with pkgs; [ gitea ];
gitea
];
security.acme.certs."${domain}".extraDomainNames = [ gitea_host ];
security.acme.certs."${domain}".extraDomainNames = [ gitea_host];
networking.firewall.allowedTCPPorts = [ gitea_ssh_port ]; networking.firewall.allowedTCPPorts = [ gitea_ssh_port ];
services.nginx = { services.nginx = {
@ -47,4 +51,3 @@ in {
}; };
}; };
} }

View file

@ -3,7 +3,8 @@ let
inherit (config.networking) domain; inherit (config.networking) domain;
grafana_host = "grafana.${domain}"; grafana_host = "grafana.${domain}";
grafana_port = 8082; grafana_port = 8082;
in { in
{
age.secrets.grafana_admin_pass = { age.secrets.grafana_admin_pass = {
file = ../secrets/grafana_admin_pass.age; file = ../secrets/grafana_admin_pass.age;
owner = "grafana"; owner = "grafana";

View file

@ -1,8 +1,15 @@
{ lib, config, inputs, pkgs, ... }: {
lib,
config,
inputs,
pkgs,
...
}:
let let
inherit (config.networking) domain; inherit (config.networking) domain;
root_email = "contact@${domain}"; root_email = "contact@${domain}";
in { in
{
security.acme = { security.acme = {
acceptTerms = true; acceptTerms = true;
defaults.email = root_email; defaults.email = root_email;

View file

@ -1,8 +1,9 @@
{ config, ... } : { config, ... }:
let let
inherit (config.networking) domain; inherit (config.networking) domain;
mastodon_host = "mastodon.${domain}"; mastodon_host = "mastodon.${domain}";
in { in
{
security.acme.certs."${domain}".extraDomainNames = [ mastodon_host ]; security.acme.certs."${domain}".extraDomainNames = [ mastodon_host ];
services.mastodon = { services.mastodon = {
enable = true; enable = true;

View file

@ -1,9 +1,16 @@
{ lib, config, inputs, pkgs, ... }: {
lib,
config,
inputs,
pkgs,
...
}:
let let
inherit (config.networking) domain; inherit (config.networking) domain;
matrix_host = "matrix.${domain}"; matrix_host = "matrix.${domain}";
in { in
services.postgresql = { {
services.postgresql = {
enable = true; enable = true;
# CREATE DATABASE synapse ENCODING 'UTF8' LC_COLLATE='C' LC_CTYPE='C' template=template0 OWNER synapse; # CREATE DATABASE synapse ENCODING 'UTF8' LC_COLLATE='C' LC_CTYPE='C' template=template0 OWNER synapse;
ensureDatabases = [ "synapse" ]; ensureDatabases = [ "synapse" ];
@ -15,40 +22,42 @@ services.postgresql = {
} }
]; ];
authentication = pkgs.lib.mkOverride 10 '' authentication = pkgs.lib.mkOverride 10 ''
#type database DBuser auth-method #type database DBuser auth-method
local all postgres peer local all postgres peer
local all all peer local all all peer
host all all 127.0.0.1/32 md5 host all all 127.0.0.1/32 md5
host synapse matrix-synapse ::1/128 md5 host synapse matrix-synapse ::1/128 md5
host nextcloud nextcloud ::1/128 md5 host nextcloud nextcloud ::1/128 md5
host all all ::1/128 md5 host all all ::1/128 md5
local replication all peer local replication all peer
host replication all 127.0.0.1/32 md5 host replication all 127.0.0.1/32 md5
host replication all ::1/128 md5 host replication all ::1/128 md5
''; '';
identMap = '' identMap = ''
# ArbitraryMapName systemUser DBUser # ArbitraryMapName systemUser DBUser
superuser_map root postgres superuser_map root postgres
superuser_map matrix-synapse synapse superuser_map matrix-synapse synapse
superuser_map nextcloud nextcloud superuser_map nextcloud nextcloud
superuser_map postgres postgres superuser_map postgres postgres
# Let other names login as themselves # Let other names login as themselves
superuser_map /^(.*)$ \1 superuser_map /^(.*)$ \1
''; '';
}; };
systemd.services.postgresql.postStart = let systemd.services.postgresql.postStart =
password_file_path = config.age.secrets.synapse_db_pass.path; let
in '' password_file_path = config.age.secrets.synapse_db_pass.path;
$PSQL -tA <<'EOF' in
DO $$ ''
DECLARE password TEXT; $PSQL -tA <<'EOF'
BEGIN DO $$
password := trim(both from replace(pg_read_file('${password_file_path}'), E'\n', ''')); DECLARE password TEXT;
EXECUTE format('ALTER ROLE synapse WITH PASSWORD '''%s''';', password); BEGIN
END $$; password := trim(both from replace(pg_read_file('${password_file_path}'), E'\n', '''));
EOF EXECUTE format('ALTER ROLE synapse WITH PASSWORD '''%s''';', password);
''; END $$;
EOF
'';
services.matrix-synapse-next = { services.matrix-synapse-next = {
enable = true; enable = true;
@ -71,10 +80,10 @@ host replication all ::1/128 md5
enable_registration = true; enable_registration = true;
registration_requires_token = true; registration_requires_token = true;
registration_shared_secret_path = config.age.secrets.synapse_registration_shared_secret.path; registration_shared_secret_path = config.age.secrets.synapse_registration_shared_secret.path;
# enable_registration_without_verification = true; # enable_registration_without_verification = true;
# mainLogConfig = ./matrix_synapse_log_config.yaml; # mainLogConfig = ./matrix_synapse_log_config.yaml;
# registrations_require_3pid = [ "email" ]; # registrations_require_3pid = [ "email" ];
database = { database = {
name = "psycopg2"; name = "psycopg2";
@ -125,16 +134,16 @@ host replication all ::1/128 md5
locations."/.well-known/matrix/server" = { locations."/.well-known/matrix/server" = {
return = "200 '{\"m.server\":\"${matrix_host}:443\"}'"; return = "200 '{\"m.server\":\"${matrix_host}:443\"}'";
extraConfig = '' extraConfig = ''
default_type application/json; default_type application/json;
add_header Access-Control-Allow-Origin *; add_header Access-Control-Allow-Origin *;
add_header Accept-Ranges bytes;''; add_header Accept-Ranges bytes;'';
}; };
locations."/.well-known/matrix/client" = { locations."/.well-known/matrix/client" = {
return = "200 '{\"m.homeserver\": {\"base_url\": \"https://${matrix_host}\"}}'"; return = "200 '{\"m.homeserver\": {\"base_url\": \"https://${matrix_host}\"}}'";
extraConfig = '' extraConfig = ''
add_header Access-Control-Allow-Origin *; add_header Access-Control-Allow-Origin *;
default_type application/json; default_type application/json;
''; '';
}; };
locations."/_matrix" = { locations."/_matrix" = {
proxyPass = "http://$synapse_backend"; proxyPass = "http://$synapse_backend";
@ -171,5 +180,5 @@ default_type application/json;
}; };
}; };
}; };
# networking.firewall.allowedTCPPorts = [ 8448 8008 ]; # networking.firewall.allowedTCPPorts = [ 8448 8008 ];
} }

View file

@ -1,7 +1,7 @@
{ config, ... } : { config, ... }:
let let
in
in { {
age.secrets = { age.secrets = {
matrix_mjolnir_pass = { matrix_mjolnir_pass = {
file = ../secrets/matrix_mjolnir_pass.age; file = ../secrets/matrix_mjolnir_pass.age;
@ -14,7 +14,7 @@ in {
file = ../secrets/matrix_mjolnir_tle_pass.age; file = ../secrets/matrix_mjolnir_tle_pass.age;
owner = "mjolnir"; owner = "mjolnir";
group = "mjolnir"; group = "mjolnir";
mode = "0777"; # not ideal, but containers are weird mode = "0777"; # not ideal, but containers are weird
}; };
}; };
@ -22,9 +22,7 @@ in {
services.mjolnir = { services.mjolnir = {
enable = true; enable = true;
homeserverUrl = config.services.matrix-synapse-next.settings.public_baseurl; homeserverUrl = config.services.matrix-synapse-next.settings.public_baseurl;
protectedRooms = [ protectedRooms = [ "https://matrix.to/#/!zDkrFrfuMIKbqYFbFv:grimmauld.de" ];
"https://matrix.to/#/!zDkrFrfuMIKbqYFbFv:grimmauld.de"
];
managementRoom = "!kgfXXqEYHGgToIwhMP:grimmauld.de"; managementRoom = "!kgfXXqEYHGgToIwhMP:grimmauld.de";
pantalaimon = { pantalaimon = {
enable = true; enable = true;
@ -37,33 +35,35 @@ in {
}; };
services.logrotate.checkConfig = false; # needed or this explodes services.logrotate.checkConfig = false; # needed or this explodes
containers.mjolnirtle = let containers.mjolnirtle =
baseurl = config.services.matrix-synapse-next.settings.public_baseurl; let
pass_file = config.age.secrets.matrix_mjolnir_tle_pass.path; baseurl = config.services.matrix-synapse-next.settings.public_baseurl;
in { pass_file = config.age.secrets.matrix_mjolnir_tle_pass.path;
privateNetwork = false; # don't want nat in
autoStart = true; {
bindMounts."${pass_file}".isReadOnly = true; privateNetwork = false; # don't want nat
config = { config, ... }: { autoStart = true;
system.stateVersion = "unstable"; bindMounts."${pass_file}".isReadOnly = true;
# tle mjolnir config =
services.logrotate.checkConfig = false; { config, ... }:
services.mjolnir = { {
enable = true; system.stateVersion = "unstable";
homeserverUrl = baseurl; # tle mjolnir
protectedRooms = [ services.logrotate.checkConfig = false;
"https://matrix.to/#/!BgDBnHgMgilMMnPMyp:grimmauld.de" services.mjolnir = {
]; enable = true;
managementRoom = "!NQedmlMeoQErGgAwxm:grimmauld.de"; homeserverUrl = baseurl;
pantalaimon = { protectedRooms = [ "https://matrix.to/#/!BgDBnHgMgilMMnPMyp:grimmauld.de" ];
enable = true; managementRoom = "!NQedmlMeoQErGgAwxm:grimmauld.de";
username = "mjolnir_tle"; pantalaimon = {
options = { enable = true;
homeserver = baseurl; username = "mjolnir_tle";
}; options = {
passwordFile = pass_file; homeserver = baseurl;
};
passwordFile = pass_file;
};
};
};
}; };
};
};
};
} }

View file

@ -1,9 +1,15 @@
{ lib, pkgs, config, ...} : {
lib,
pkgs,
config,
...
}:
let let
inherit (config.networking) domain; inherit (config.networking) domain;
nextcloud_host = "cloud.${domain}"; nextcloud_host = "cloud.${domain}";
nextcloud_port = 8083; nextcloud_port = 8083;
in { in
{
services.postgresql = { services.postgresql = {
enable = true; enable = true;
ensureDatabases = [ "nextcloud" ]; ensureDatabases = [ "nextcloud" ];
@ -46,13 +52,13 @@ in {
package = pkgs.nextcloud28; package = pkgs.nextcloud28;
caching.redis = true; caching.redis = true;
# extraApps = with config.services.nextcloud.package.packages.apps; [ # extraApps = with config.services.nextcloud.package.packages.apps; [
# news contacts calendar tasks; # news contacts calendar tasks;
# ]; # ];
config = { config = {
adminpassFile = config.age.secrets.nextcloud_admin_pass.path; adminpassFile = config.age.secrets.nextcloud_admin_pass.path;
dbuser = "nextcloud"; dbuser = "nextcloud";
dbhost= "localhost:${builtins.toString config.services.postgresql.settings.port}"; dbhost = "localhost:${builtins.toString config.services.postgresql.settings.port}";
dbtype = "pgsql"; dbtype = "pgsql";
}; };
settings = { settings = {
@ -64,7 +70,6 @@ in {
port = 6379; port = 6379;
timeout = 0.0; timeout = 0.0;
}; };
}; };
phpOptions = { phpOptions = {
"opcache.interned_strings_buffer" = "12"; "opcache.interned_strings_buffer" = "12";

View file

@ -1,10 +1,11 @@
{ config, ... } : { config, ... }:
let let
inherit (config.networking) domain; inherit (config.networking) domain;
prometheus_host = "prometheus.${domain}"; prometheus_host = "prometheus.${domain}";
prometheus_port = 9090; # netstat -nlp | grep 9090 prometheus_port = 9090; # netstat -nlp | grep 9090
in { in
security.acme.certs."${domain}".extraDomainNames = [ prometheus_host]; {
security.acme.certs."${domain}".extraDomainNames = [ prometheus_host ];
services.prometheus = { services.prometheus = {
enable = true; enable = true;
@ -13,13 +14,15 @@ in {
scrapeConfigs = [ scrapeConfigs = [
{ {
job_name = "chrysalis"; job_name = "chrysalis";
static_configs = [{ static_configs = [
targets = [ {
"127.0.0.1:${toString config.services.prometheus.exporters.node.port}" targets = [
"127.0.0.1:${toString config.services.prometheus.exporters.nginx.port}" "127.0.0.1:${toString config.services.prometheus.exporters.node.port}"
"127.0.0.1:${toString config.services.prometheus.exporters.postgres.port}" "127.0.0.1:${toString config.services.prometheus.exporters.nginx.port}"
]; "127.0.0.1:${toString config.services.prometheus.exporters.postgres.port}"
}]; ];
}
];
} }
]; ];
exporters = { exporters = {
@ -44,7 +47,7 @@ in {
forceSSL = true; forceSSL = true;
useACMEHost = domain; useACMEHost = domain;
locations."/" = { locations."/" = {
# proxyPass = "http://127.0.0.1:${builtins.toString config.services.prometheus.port}"; # proxyPass = "http://127.0.0.1:${builtins.toString config.services.prometheus.port}";
return = "307 https://${domain}"; # nuh uh, no raw prometheus access for you! return = "307 https://${domain}"; # nuh uh, no raw prometheus access for you!
}; };
}; };

View file

@ -1,4 +1,5 @@
{config, pkgs, ...}: let { config, pkgs, ... }:
let
inherit (config.networking) domain; inherit (config.networking) domain;
root_email = "contact@${domain}"; root_email = "contact@${domain}";
ptero_host = "ptero.${domain}"; ptero_host = "ptero.${domain}";
@ -7,13 +8,14 @@
local_bridge = "ptero-local-br"; local_bridge = "ptero-local-br";
ptero_ver = "1.11.5"; ptero_ver = "1.11.5";
ptero_port = "8042"; ptero_port = "8042";
in { in
{
users.users.${panel_user} = { users.users.${panel_user} = {
isSystemUser = true; isSystemUser = true;
extraGroups = ["docker"]; extraGroups = [ "docker" ];
group = panel_user; group = panel_user;
}; };
users.groups.${panel_user} = {}; users.groups.${panel_user} = { };
age.secrets.ptero_env = { age.secrets.ptero_env = {
file = ../secrets/ptero_env.age; file = ../secrets/ptero_env.age;
@ -24,15 +26,15 @@ in {
wantedBy = [ "multi-user.target" ]; wantedBy = [ "multi-user.target" ];
serviceConfig.Type = "oneshot"; serviceConfig.Type = "oneshot";
script ='' script = ''
mkdir -p ${DATA_DIR}/database mkdir -p ${DATA_DIR}/database
mkdir -p ${DATA_DIR}/cache mkdir -p ${DATA_DIR}/cache
mkdir -p ${DATA_DIR}/panel/var mkdir -p ${DATA_DIR}/panel/var
mkdir -p ${DATA_DIR}/panel/logs mkdir -p ${DATA_DIR}/panel/logs
mkdir -p ${DATA_DIR}/panel/nginx mkdir -p ${DATA_DIR}/panel/nginx
chown ${panel_user}:${panel_user} -R ${DATA_DIR} chown ${panel_user}:${panel_user} -R ${DATA_DIR}
chmod +777 -R ${DATA_DIR} chmod +777 -R ${DATA_DIR}
''; '';
}; };
virtualisation.oci-containers.backend = "podman"; virtualisation.oci-containers.backend = "podman";
@ -43,18 +45,20 @@ chmod +777 -R ${DATA_DIR}
wantedBy = [ "multi-user.target" ]; wantedBy = [ "multi-user.target" ];
serviceConfig.Type = "oneshot"; serviceConfig.Type = "oneshot";
script = let podmancli = "${config.virtualisation.podman.package}/bin/podman"; script =
in '' let
check=$(${podmancli} pod ls | grep "ptero" || true) podmancli = "${config.virtualisation.podman.package}/bin/podman";
if [ -z "$check" ]; then in
${podmancli} pod create -p "${ptero_port}:80" ptero ''
else check=$(${podmancli} pod ls | grep "ptero" || true)
echo "ptero pod already exists" if [ -z "$check" ]; then
fi ${podmancli} pod create -p "${ptero_port}:80" ptero
''; else
echo "ptero pod already exists"
fi
'';
}; };
virtualisation.oci-containers.containers."ptero-mysql" = { virtualisation.oci-containers.containers."ptero-mysql" = {
image = "library/mysql:8.0"; image = "library/mysql:8.0";
workdir = "${DATA_DIR}/database"; workdir = "${DATA_DIR}/database";
@ -64,14 +68,17 @@ chmod +777 -R ${DATA_DIR}
"MYSQL_DATABASE" = "panel"; "MYSQL_DATABASE" = "panel";
}; };
environmentFiles = [ config.age.secrets.ptero_env.path ]; environmentFiles = [ config.age.secrets.ptero_env.path ];
volumes = ["${DATA_DIR}/database:/var/lib/mysql" "${DATA_DIR}/database:${DATA_DIR}/database"]; volumes = [
cmd=["--default-authentication-plugin=mysql_native_password"]; "${DATA_DIR}/database:/var/lib/mysql"
"${DATA_DIR}/database:${DATA_DIR}/database"
];
cmd = [ "--default-authentication-plugin=mysql_native_password" ];
}; };
virtualisation.oci-containers.containers."ptero-cache" = { virtualisation.oci-containers.containers."ptero-cache" = {
image = "redis:alpine"; image = "redis:alpine";
workdir = "${DATA_DIR}/cache"; workdir = "${DATA_DIR}/cache";
volumes = ["${DATA_DIR}/cache:${DATA_DIR}/cache"]; volumes = [ "${DATA_DIR}/cache:${DATA_DIR}/cache" ];
extraOptions = [ "--pod=ptero" ]; extraOptions = [ "--pod=ptero" ];
}; };
@ -85,7 +92,7 @@ chmod +777 -R ${DATA_DIR}
extraOptions = [ "--pod=ptero" ]; extraOptions = [ "--pod=ptero" ];
environment = { environment = {
"APP_URL" = "https://${ptero_host}"; "APP_URL" = "https://${ptero_host}";
"APP_TIMEZONE" = "Europe/Berlin"; "APP_TIMEZONE" = "Europe/Berlin";
"APP_SERVICE_AUTHOR" = root_email; "APP_SERVICE_AUTHOR" = root_email;
"MAIL_FROM" = "noreply@${domain}"; "MAIL_FROM" = "noreply@${domain}";
@ -96,8 +103,8 @@ chmod +777 -R ${DATA_DIR}
"MAIL_PASSWORD" = ""; "MAIL_PASSWORD" = "";
"MAIL_ENCRYPTION" = "true"; "MAIL_ENCRYPTION" = "true";
"APP_ENV"= "production"; "APP_ENV" = "production";
"APP_ENVIRONMENT_ONLY"= "false"; "APP_ENVIRONMENT_ONLY" = "false";
"CACHE_DRIVER" = "redis"; "CACHE_DRIVER" = "redis";
"SESSION_DRIVER" = "redis"; "SESSION_DRIVER" = "redis";
"QUEUE_DRIVER" = "redis"; "QUEUE_DRIVER" = "redis";
@ -106,7 +113,7 @@ chmod +777 -R ${DATA_DIR}
"TRUSTED_PROXIES" = "*"; "TRUSTED_PROXIES" = "*";
}; };
labels = { labels = {
"traefik.http.routers.pterodactyl_panel.entrypoints"="web"; "traefik.http.routers.pterodactyl_panel.entrypoints" = "web";
}; };
environmentFiles = [ config.age.secrets.ptero_env.path ]; environmentFiles = [ config.age.secrets.ptero_env.path ];
}; };

View file

@ -1,4 +1,10 @@
{ lib, config, inputs, pkgs, ... }: {
lib,
config,
inputs,
pkgs,
...
}:
let let
inherit (config.networking) domain; inherit (config.networking) domain;
puffer_port = 8080; puffer_port = 8080;
@ -6,14 +12,15 @@ let
puffer_host = "puffer.${domain}"; puffer_host = "puffer.${domain}";
tlemap_host = "tlemap.${domain}"; tlemap_host = "tlemap.${domain}";
tlemap_port = 8100; tlemap_port = 8100;
in { in
{
services.pufferpanel = { services.pufferpanel = {
enable = true; enable = true;
environment = { environment = {
PUFFER_WEB_HOST = ":${builtins.toString puffer_port}"; PUFFER_WEB_HOST = ":${builtins.toString puffer_port}";
PUFFER_DAEMON_SFTP_HOST = ":${builtins.toString puffer_sftp_port}"; PUFFER_DAEMON_SFTP_HOST = ":${builtins.toString puffer_sftp_port}";
}; };
extraPackages = with pkgs; []; extraPackages = with pkgs; [ ];
extraGroups = [ "docker" ]; extraGroups = [ "docker" ];
}; };
@ -35,12 +42,21 @@ in {
proxyPass = "http://127.0.0.1:${builtins.toString tlemap_port}"; proxyPass = "http://127.0.0.1:${builtins.toString tlemap_port}";
}; };
}; };
}; };
security.acme.certs."${domain}".extraDomainNames = [ puffer_host tlemap_host ]; security.acme.certs."${domain}".extraDomainNames = [
networking.firewall.allowedTCPPorts = [ puffer_sftp_port 25565 25566 25567 25568 7270 ]; puffer_host
tlemap_host
];
networking.firewall.allowedTCPPorts = [
puffer_sftp_port
25565
25566
25567
25568
7270
];
# virtualisation.podman.enable = true; # virtualisation.podman.enable = true;
virtualisation.docker.enable = true; virtualisation.docker.enable = true;
environment.systemPackages = with pkgs; [ environment.systemPackages = with pkgs; [

View file

@ -1,6 +1,8 @@
{config, pkgs, ...}: let { config, pkgs, ... }:
let
git_user = "Grimmauld"; git_user = "Grimmauld";
in { in
{
environment.systemPackages = with pkgs; [ environment.systemPackages = with pkgs; [
(writeShellScriptBin "silent-add" "git add --intent-to-add $@ ; git update-index --assume-unchanged $@") (writeShellScriptBin "silent-add" "git add --intent-to-add $@ ; git update-index --assume-unchanged $@")
(writeShellScriptBin "systemd-owner" "systemctl show -pUser,UID $@") (writeShellScriptBin "systemd-owner" "systemctl show -pUser,UID $@")
@ -36,10 +38,15 @@ in {
set number set number
set hidden set hidden
set nocompatible set nocompatible
''; '';
packages.myVimPackage = with pkgs.vimPlugins; { packages.myVimPackage = with pkgs.vimPlugins; {
# loaded on launch # loaded on launch
start = [ vim-nix vim-scala fugitive autoclose-nvim ]; start = [
vim-nix
vim-scala
fugitive
autoclose-nvim
];
# manually loadable by calling `:packadd $plugin-name` # manually loadable by calling `:packadd $plugin-name`
opt = [ ]; opt = [ ];
}; };

View file

@ -2,13 +2,16 @@ let
laptop_pub = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCy7X5ByG4/9y2XkQSnXcpMGnV5WPGUd+B6FaYCDNmPQ7xIZEteS+kCpu9oiMP6C/H/FT+i9DZvCflkzgdFAyujYLKRYaZbZ3K6F60qN0rkJ0z/ZO5c6rqwIwR6BEoB7dq5inkyH9fZ8/SI+PXxELmeWF9ehT7kkQC+o9Ujpcjd7ZuZllbAz4UQZFRbbpwdVJCEDenu9/63yuYbvMupgGk0edaTiFT0Q9MSzs/3pNP8xlAxmmZ3HzSjeF7gUzBF7CaIroTeguiUjSVybUEx48P8fy878t7dUZf4anEno9MS0B3aqfZvCKuuPdAUdeBfCbFHRqN7GuCylFIXGPe95Mxl grimmauld@grimmauld-nixos"; laptop_pub = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCy7X5ByG4/9y2XkQSnXcpMGnV5WPGUd+B6FaYCDNmPQ7xIZEteS+kCpu9oiMP6C/H/FT+i9DZvCflkzgdFAyujYLKRYaZbZ3K6F60qN0rkJ0z/ZO5c6rqwIwR6BEoB7dq5inkyH9fZ8/SI+PXxELmeWF9ehT7kkQC+o9Ujpcjd7ZuZllbAz4UQZFRbbpwdVJCEDenu9/63yuYbvMupgGk0edaTiFT0Q9MSzs/3pNP8xlAxmmZ3HzSjeF7gUzBF7CaIroTeguiUjSVybUEx48P8fy878t7dUZf4anEno9MS0B3aqfZvCKuuPdAUdeBfCbFHRqN7GuCylFIXGPe95Mxl grimmauld@grimmauld-nixos";
laptop_pub_ed = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJhM1Fk5ix4OZAdlfCxL891KxeEKpyIFrP5yYkC9mg7E grimmauld@grimmauld-nixos"; laptop_pub_ed = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJhM1Fk5ix4OZAdlfCxL891KxeEKpyIFrP5yYkC9mg7E grimmauld@grimmauld-nixos";
# obtained with `ssh-keyscan [ip]` # obtained with `ssh-keyscan [ip]`
contabo_nix_pub = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDCCsCsjhJleQCBm0gwnUj5R7zewC0SoRvth1qhXtUCeWM3KHkX+CjiHvVaHs+ftYE9uCe5jwVMB+b4UPkNU8EfQeL99iOYtkcn+fEQqjUJe/x/Pn0NxfS1DCvFpI6s3485ysDmagi640XN9S+eIiiMZIqWTsIlUtkEwGF0wuv+xqzbBOlUtIkL2AMpMeFCFovOcpu2JwEAIpDUiW+FanAFImw6rvNmpAtaaFGheYOGJwnpVfdaIeRPqEN3fqtIRBIQVgxt25BGYX83vaIH3Y/OaEKMGUa/4Fe/PRpGJyhCtdae6kcVfx57hs0e7/HezjgfS90HTu2cy6BrJOvGUspCjCbdElddfboE9wtBeNYsgjUOdU926m2M1tTn7Ex6ZMOQRKRlVFac6Yo+CedRTe4u6lkrWcsDdmnajel7uxoW8VMEre/CBCtK+ZlGaDwJjIVNCn7J3KZBKeaB/t/1iSr7/buaXYh5VV1Q0gv0mtvx+D7YLngaTv3sLFpLV8Wk1mgXt9R2hHxcRBKGJYx5RWa8aMHK62RP1GRc5yCzREj2Mc5qUJyd8oirnQYms/BsaDybUJde9IL4REeMzIBYyi/MG/+OAIUSAtdYygABWco+Swv4jP52UODHikcmyejHdFhRngsb4IYzGZXbS5pobkCyqCMJ20v5BG3WNFmujAlXRw=="; contabo_nix_pub = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDCCsCsjhJleQCBm0gwnUj5R7zewC0SoRvth1qhXtUCeWM3KHkX+CjiHvVaHs+ftYE9uCe5jwVMB+b4UPkNU8EfQeL99iOYtkcn+fEQqjUJe/x/Pn0NxfS1DCvFpI6s3485ysDmagi640XN9S+eIiiMZIqWTsIlUtkEwGF0wuv+xqzbBOlUtIkL2AMpMeFCFovOcpu2JwEAIpDUiW+FanAFImw6rvNmpAtaaFGheYOGJwnpVfdaIeRPqEN3fqtIRBIQVgxt25BGYX83vaIH3Y/OaEKMGUa/4Fe/PRpGJyhCtdae6kcVfx57hs0e7/HezjgfS90HTu2cy6BrJOvGUspCjCbdElddfboE9wtBeNYsgjUOdU926m2M1tTn7Ex6ZMOQRKRlVFac6Yo+CedRTe4u6lkrWcsDdmnajel7uxoW8VMEre/CBCtK+ZlGaDwJjIVNCn7J3KZBKeaB/t/1iSr7/buaXYh5VV1Q0gv0mtvx+D7YLngaTv3sLFpLV8Wk1mgXt9R2hHxcRBKGJYx5RWa8aMHK62RP1GRc5yCzREj2Mc5qUJyd8oirnQYms/BsaDybUJde9IL4REeMzIBYyi/MG/+OAIUSAtdYygABWco+Swv4jP52UODHikcmyejHdFhRngsb4IYzGZXbS5pobkCyqCMJ20v5BG3WNFmujAlXRw==";
in in
{ {
"nextcloud_pass.age".publicKeys = [ laptop_pub laptop_pub_ed ]; "nextcloud_pass.age".publicKeys = [
laptop_pub
laptop_pub_ed
];
# "duckdns_token.age".publicKeys = [ contabo_nix_pub ]; # "duckdns_token.age".publicKeys = [ contabo_nix_pub ];
"synapse_db_pass.age".publicKeys = [ contabo_nix_pub ]; "synapse_db_pass.age".publicKeys = [ contabo_nix_pub ];
"synapse_db_pass_prepared.age".publicKeys = [ contabo_nix_pub ]; "synapse_db_pass_prepared.age".publicKeys = [ contabo_nix_pub ];
"grafana_admin_pass.age".publicKeys = [ contabo_nix_pub ]; "grafana_admin_pass.age".publicKeys = [ contabo_nix_pub ];

View file

@ -1,12 +1,20 @@
{ lib, config, inputs, pkgs, ... }: {
lib,
config,
inputs,
pkgs,
...
}:
let let
inherit (config.networking) domain; inherit (config.networking) domain;
in { in
imports = [ {
./hardware-configuration.nix imports = [ ./hardware-configuration.nix ];
];
networking.firewall.allowedTCPPorts = [ 80 443 ]; networking.firewall.allowedTCPPorts = [
80
443
];
networking.hostName = "grimmauld-nixos-server"; networking.hostName = "grimmauld-nixos-server";
networking.domain = "grimmauld.de"; networking.domain = "grimmauld.de";
services.openssh.enable = true; services.openssh.enable = true;
@ -26,7 +34,7 @@ in {
enableACME = lib.mkForce false; # use the correct cert, not some weird one that matrix-synapse module supplies enableACME = lib.mkForce false; # use the correct cert, not some weird one that matrix-synapse module supplies
useACMEHost = domain; useACMEHost = domain;
locations."/" = { locations."/" = {
root = "/var/www/${domain}"; root = "/var/www/${domain}";
}; };
}; };
}; };

View file

@ -2,12 +2,19 @@
{ {
imports = [ (modulesPath + "/profiles/qemu-guest.nix") ]; imports = [ (modulesPath + "/profiles/qemu-guest.nix") ];
boot.loader.grub.device = "/dev/sda"; boot.loader.grub.device = "/dev/sda";
boot.initrd.availableKernelModules = [ "ata_piix" "uhci_hcd" "xen_blkfront" "vmw_pvscsi" ]; boot.initrd.availableKernelModules = [
"ata_piix"
"uhci_hcd"
"xen_blkfront"
"vmw_pvscsi"
];
boot.initrd.kernelModules = [ "nvme" ]; boot.initrd.kernelModules = [ "nvme" ];
fileSystems."/" = { device = "/dev/sda3"; fsType = "ext4"; }; fileSystems."/" = {
device = "/dev/sda3";
fsType = "ext4";
};
environment.sessionVariables = { environment.sessionVariables = {
OMP_NUM_THREADS = "8"; OMP_NUM_THREADS = "8";
}; };
} }

View file

@ -35,13 +35,15 @@
{ remote = "Videos"; } { remote = "Videos"; }
]; ];
packages = with pkgs; lib.optionals config.grimmShared.graphical [ packages =
webcord with pkgs;
discord lib.optionals config.grimmShared.graphical [
obs-studio webcord
element-desktop discord
ghidra obs-studio
# rmview element-desktop
]; ghidra
# rmview
];
}; };
} }