move modules to containers and move piped to sockets rather than external nginx only

This commit is contained in:
Chaos 2023-08-09 15:47:01 +01:00
parent abe8e2c156
commit e57e3089e1
No known key found for this signature in database
26 changed files with 112 additions and 194 deletions

View file

@ -74,7 +74,6 @@ in {
[ [
profiles.base profiles.base
inputs.home-manager-unstable.nixosModules.home-manager inputs.home-manager-unstable.nixosModules.home-manager
hosts.hetzner-vm.modules.mailserver
profiles.sshd profiles.sshd
@ -83,6 +82,7 @@ in {
users.root users.root
] ]
++ (with hosts.hetzner-vm.containers.mail; [ ++ (with hosts.hetzner-vm.containers.mail; [
modules.mailserver
profiles.mailserver profiles.mailserver
profiles.restic profiles.restic
]); ]);

View file

@ -98,6 +98,11 @@ in {
default = ""; default = "";
}; };
rspamd_redis_port = mkOption {
type = types.number;
default = 6380;
};
vmail_config = mkOption { vmail_config = mkOption {
type = types.submodule { type = types.submodule {
options = { options = {

View file

@ -5,8 +5,6 @@
}: let }: let
mail_config = config.mailserver; mail_config = config.mailserver;
ports = import ../../ports.nix {};
postfixCfg = config.services.postfix; postfixCfg = config.services.postfix;
rspamdCfg = config.services.rspamd; rspamdCfg = config.services.rspamd;
rspamdSocket = "rspamd.service"; rspamdSocket = "rspamd.service";
@ -23,7 +21,7 @@ in {
}; };
"redis.conf" = { "redis.conf" = {
text = '' text = ''
servers = "127.0.0.1:${toString ports.rspamd-redis}"; servers = "127.0.0.1:${toString mail_config.rspamd_redis_port}";
''; '';
}; };
"classifier-bayes.conf" = { "classifier-bayes.conf" = {
@ -84,7 +82,7 @@ in {
services.redis.servers.rspamd = { services.redis.servers.rspamd = {
enable = true; enable = true;
port = ports.rspamd-redis; port = mail_config.rspamd_redis_port;
}; };
systemd.services.rspamd = { systemd.services.rspamd = {

View file

@ -133,8 +133,8 @@ in {
}; };
services.nginx.virtualHosts."${cfg.backendDomain}" = lib.mkIf (!cfg.disableNginx) { services.nginx.virtualHosts."${cfg.backendDomain}" = lib.mkIf (!cfg.disableNginx) {
forceSSL = true; forceSSL = cfg.nginxForceSSL;
enableACME = true; enableACME = cfg.nginxEnableACME;
locations."/" = { locations."/" = {
proxyPass = "http://127.0.0.1:${toString cfg.internalBackendPort}"; proxyPass = "http://127.0.0.1:${toString cfg.internalBackendPort}";
}; };

View file

@ -21,7 +21,15 @@ in {
disableNginx = mkOption { disableNginx = mkOption {
type = types.bool; type = types.bool;
default = false; default = false;
description = "Don't run nginx to serve frontend/backend/proxy"; };
nginxForceSSL = mkOption {
type = types.bool;
default = false;
};
nginxEnableACME = mkOption {
type = types.bool;
default = false;
}; };
disableFrontend = mkOption { disableFrontend = mkOption {

View file

@ -11,8 +11,8 @@ with lib; let
in { in {
config = mkIf (cfg.enable && !cfg.disableFrontend && !cfg.disableNginx) { config = mkIf (cfg.enable && !cfg.disableFrontend && !cfg.disableNginx) {
services.nginx.virtualHosts."${cfg.frontendDomain}" = { services.nginx.virtualHosts."${cfg.frontendDomain}" = {
forceSSL = true; forceSSL = cfg.nginxForceSSL;
enableACME = true; enableACME = cfg.nginxEnableACME;
locations."/".root = "${frontend-package}/share/piped-frontend"; locations."/".root = "${frontend-package}/share/piped-frontend";
extraConfig = '' extraConfig = ''
try_files $uri $uri/ /index.html; try_files $uri $uri/ /index.html;

View file

@ -0,0 +1,11 @@
{
config,
lib,
...
}: let
cfg = config.services.piped;
in {
config = lib.mkIf (cfg.enable && !cfg.disableNginx) {
services.nginx.enable = true;
};
}

View file

@ -32,8 +32,8 @@ in {
}; };
services.nginx.virtualHosts."${cfg.proxyDomain}" = lib.mkIf (!cfg.disableNginx) { services.nginx.virtualHosts."${cfg.proxyDomain}" = lib.mkIf (!cfg.disableNginx) {
forceSSL = true; forceSSL = cfg.nginxForceSSL;
enableACME = true; enableACME = cfg.nginxEnableACME;
locations."/" = { locations."/" = {
proxyPass = "http://localhost:${toString cfg.internalProxyPort}"; proxyPass = "http://localhost:${toString cfg.internalProxyPort}";
extraConfig = extraConfig =

View file

@ -21,7 +21,7 @@
in { in {
imports = with tree; [ imports = with tree; [
# needed so can get nginx defaults for proxy # needed so can get nginx defaults for proxy
hosts.hetzner-vm.modules.piped hosts.hetzner-vm.containers.piped.modules.piped
]; ];
containers.piped = { containers.piped = {
@ -52,7 +52,6 @@ in {
[ [
profiles.base profiles.base
inputs.home-manager-unstable.nixosModules.home-manager inputs.home-manager-unstable.nixosModules.home-manager
hosts.hetzner-vm.modules.piped
profiles.sshd profiles.sshd
@ -61,6 +60,7 @@ in {
users.root users.root
] ]
++ (with hosts.hetzner-vm.containers.piped; [ ++ (with hosts.hetzner-vm.containers.piped; [
modules.piped
profiles.piped profiles.piped
profiles.restic profiles.restic
]); ]);
@ -91,21 +91,16 @@ in {
services.nginx.virtualHosts."piped.owo.monster" = { services.nginx.virtualHosts."piped.owo.monster" = {
forceSSL = true; forceSSL = true;
enableACME = true; enableACME = true;
locations."/".root = let locations."/" = {
frontend-package = pkgs.piped-frontend.override { proxyPass = "http://unix:/var/lib/nixos-containers/piped/var/sockets/piped-proxy.sock";
backendDomain = "backend.piped.owo.monster"; };
};
in "${frontend-package}/share/piped-frontend";
extraConfig = ''
try_files $uri $uri/ /index.html;
'';
}; };
services.nginx.virtualHosts."backend.piped.owo.monster" = { services.nginx.virtualHosts."backend.piped.owo.monster" = {
forceSSL = true; forceSSL = true;
enableACME = true; enableACME = true;
locations."/" = { locations."/" = {
proxyPass = "http://${containerIP}:${toString ports.piped-backend}"; proxyPass = "http://unix:/var/lib/nixos-containers/piped/var/sockets/piped-backend.sock";
}; };
}; };
@ -113,20 +108,8 @@ in {
forceSSL = true; forceSSL = true;
enableACME = true; enableACME = true;
locations."/" = { locations."/" = {
proxyPass = "http://${containerIP}:${toString ports.piped-proxy}"; proxyPass = "http://unix:/var/lib/nixos-containers/piped/var/sockets/piped-proxy.sock";
extraConfig = extraConfig = config.services.piped.proxyNginxExtraConfig;
config.services.piped.proxyNginxExtraConfig
+ ''
add_header Cache-Control "public, max-age=604800";
'';
};
locations."~ (/videoplayback|/api/v4/|/api/manifest/)" = {
proxyPass = "http://${containerIP}:${toString ports.piped-proxy}";
extraConfig =
config.services.piped.proxyNginxExtraConfig
+ ''
add_header Cache-Control private always;
'';
}; };
}; };

View file

@ -1,18 +1,37 @@
{...}: let {config, ...}: let
ports = import ../data/ports.nix {}; ports = import ../data/ports.nix {};
piped_config = config.services.piped;
in { in {
services.piped = { config.services.piped = {
enable = true; enable = true;
frontendDomain = "piped.owo.monster"; frontendDomain = "piped.owo.monster";
backendDomain = "backend.piped.owo.monster"; backendDomain = "backend.piped.owo.monster";
proxyDomain = "proxy.piped.owo.monster"; proxyDomain = "proxy.piped.owo.monster";
disableNginx = true; nginxForceSSL = false;
disableFrontend = true; nginxEnableACME = false;
# Do not set proxyNginxExtraConfig here as needs be set in outside of container # Do not set proxyNginxExtraConfig here as needs be set in outside of container
internalBackendPort = ports.piped-backend; internalBackendPort = ports.piped-backend;
internalProxyPort = ports.piped-proxy; internalProxyPort = ports.piped-proxy;
}; };
config.systemd.tmpfiles.rules = [
"d /var/sockets - nginx nginx"
];
config.systemd.services.nginx.serviceConfig.ReadWritePaths = [
"/var/sockets"
];
config.services.nginx.virtualHosts."${piped_config.frontendDomain}" = {
extraConfig = "listen unix:/var/sockets/piped-frontend.sock;";
};
config.services.nginx.virtualHosts."${piped_config.backendDomain}" = {
extraConfig = "listen unix:/var/sockets/piped-backend.sock;";
};
config.services.nginx.virtualHosts."${piped_config.proxyDomain}" = {
extraConfig = "listen unix:/var/sockets/piped-proxy.sock;";
};
} }

View file

@ -8,8 +8,6 @@
imports = with tree; [ imports = with tree; [
users.root users.root
hosts.hetzner-vm.modules.mailserver
profiles.base profiles.base
profiles.sshd profiles.sshd
profiles.nginx profiles.nginx
@ -22,8 +20,6 @@
./containers/piped/piped.nix ./containers/piped/piped.nix
./containers/mail/mail.nix ./containers/mail/mail.nix
#hosts.hetzner-vm.profiles.restic
#hosts.hetzner-vm.profiles.mailserver
hosts.hetzner-vm.profiles.gitlab-static-sites hosts.hetzner-vm.profiles.gitlab-static-sites
hosts.hetzner-vm.profiles.wireguard hosts.hetzner-vm.profiles.wireguard
hosts.hetzner-vm.profiles.nginx-misc hosts.hetzner-vm.profiles.nginx-misc

View file

@ -1,13 +0,0 @@
{}: {
piped-backend = 3012;
piped-proxy = 3013;
smtp = 25;
submission = 587;
submission_ssl = 465;
imap = 143;
imap_ssl = 993;
sieve = 4190;
rspamd-redis = 6380;
}

View file

@ -1,42 +0,0 @@
{config, ...}: let
secrets = config.services.secrets.secrets;
in {
config.mailserver = {
enable = true;
fqdn = "mail.owo.monster";
domains = ["owo.monster" "kitteh.pw"];
debug_mode = true;
extra_roundcube_config = ''
$config['session_lifetime'] = (60 * 24 * 7 * 2); # 2 Weeks
$config['product_name'] = 'Chaos Mail';
$config['username_domain'] = "owo.monster";
$config['username_domain_forced'] = true;
'';
extra_aliases_file = "${secrets.private_mail_aliases.path}";
accounts = {
"chaos@owo.monster" = {
name = "chaos@owo.monster";
passwordFile = "${secrets.chaos_mail_passwd.path}";
aliases = [
"all@owo.monster"
"chaoticryptidz@owo.monster"
# TODO: legacy - to be deprecated by 2023-01-01
"kitteh@owo.monster"
"kitteh@kitteh.pw"
];
sieveScript = null;
};
"system@owo.monster" = {
name = "system@owo.monster";
passwordFile = "${secrets.system_mail_passwd.path}";
aliases = [];
sieveScript = null;
};
};
};
}

View file

@ -7,12 +7,6 @@ in {
listenPort = 51820; listenPort = 51820;
privateKeyFile = "${secrets.wg_privkey.path}"; privateKeyFile = "${secrets.wg_privkey.path}";
peers = [ peers = [
# tablet
{
publicKey = "jXA0DeprEaL/ARQ3K81l8xWuUI5C/90DcY3bIfcIjz8=";
presharedKeyFile = "${secrets.wg_preshared_tablet.path}";
allowedIPs = ["10.69.42.2/32"];
}
# vault # vault
{ {
publicKey = "IGq+WanFM/bKNUkwjO/0AAtDhJLvtvU+mVxH27QyHTc="; publicKey = "IGq+WanFM/bKNUkwjO/0AAtDhJLvtvU+mVxH27QyHTc=";
@ -20,12 +14,6 @@ in {
endpoint = "vault.servers.genderfucked.monster:51820"; endpoint = "vault.servers.genderfucked.monster:51820";
allowedIPs = ["10.69.42.3/32"]; allowedIPs = ["10.69.42.3/32"];
} }
# storage
{
publicKey = "biNNeCkjAWi2jUVoL5+1pBtXGa3OFZi4DltB2dqGjGg=";
presharedKeyFile = "${secrets.wg_preshared_storage.path}";
allowedIPs = ["10.69.42.4/32"];
}
# iphone8 # iphone8
{ {
publicKey = "2BgT08bDKh8WlFFSeRArI9a1GpFgUyqEApvJy4KgAmw="; publicKey = "2BgT08bDKh8WlFFSeRArI9a1GpFgUyqEApvJy4KgAmw=";

View file

@ -7,24 +7,37 @@
apacheHttpd apacheHttpd
]; ];
extraFunctions = ''
replace_slash_for_sed() {
sed "s#/#\\\/#"
}
simple_get_replace_crypt() {
password=$(simple_get "$1" .password | replace_slash_for_sed)
salt=$(simple_get "$1" .salt | replace_slash_for_sed)
replace_password=''${2}_ACCOUNT
replace_salt=''${2}_KEY
sed -i "s/$replace_password/$password/" "$3"
sed -i "s/$replace_salt/$salt/" "$3"
}
'';
secrets = { secrets = {
# Used directly by server
# for fetching gitlab static sites
gitlab_env = {
user = "gitlab_artifacts_sync";
group = "gitlab_artifacts_sync";
fetchScript = ''
token=$(simple_get "/api-keys/gitlab/gitlab_pages_serve" .token)
echo "GITLAB_TOKEN=$token" > $secretFile
'';
};
# for wireguard
wg_privkey = {
fetchScript = ''
simple_get "/private-public-keys/wireguard/chaos-internal/hetzner-vm" .private > $secretFile
'';
};
wg_preshared_vault = {
path = "/secrets/wg_preshared_vault";
fetchScript = ''
simple_get "/private-public-keys/wireguard/chaos-internal/hetzner-vm" .preshared_keys.vault > $secretFile
'';
};
wg_preshared_iphone8 = {
path = "/secrets/wg_preshared_iphone8";
fetchScript = ''
simple_get "/private-public-keys/wireguard/chaos-internal/hetzner-vm" .preshared_keys.iphone8 > $secretFile
'';
};
# Container: music
mpd_control_password = { mpd_control_password = {
user = "mpd"; user = "mpd";
group = "mpd"; group = "mpd";
@ -41,6 +54,20 @@
htpasswd -bc $secretFile "$username" "$password" 2>/dev/null htpasswd -bc $secretFile "$username" "$password" 2>/dev/null
''; '';
}; };
# Container: mail
mail_restic_password = {
fetchScript = ''
simple_get "/private-public-keys/restic/Mail" .password > $secretFile
'';
};
mail_restic_env = {
fetchScript = ''
RESTIC_USERNAME=$(simple_get "/api-keys/storage/restic/Mail" .username)
RESTIC_PASSWORD=$(simple_get "/api-keys/storage/restic/Mail" .password)
echo "RESTIC_REPOSITORY=rest:https://$RESTIC_USERNAME:$RESTIC_PASSWORD@storage-restic.owo.monster/Mail" > $secretFile
'';
};
private_mail_aliases = { private_mail_aliases = {
user = "root"; user = "root";
group = "root"; group = "root";
@ -56,7 +83,6 @@
htpasswd -nbB "" "$password" 2>/dev/null | cut -d: -f2 > $secretFile htpasswd -nbB "" "$password" 2>/dev/null | cut -d: -f2 > $secretFile
''; '';
}; };
system_mail_passwd = { system_mail_passwd = {
user = "dovecot2"; user = "dovecot2";
group = "dovecot2"; group = "dovecot2";
@ -66,15 +92,7 @@
''; '';
}; };
gitlab_env = { # Container: social
user = "gitlab_artifacts_sync";
group = "gitlab_artifacts_sync";
fetchScript = ''
token=$(simple_get "/api-keys/gitlab/gitlab_pages_serve" .token)
echo "GITLAB_TOKEN=$token" > $secretFile
'';
};
social_restic_password = { social_restic_password = {
fetchScript = '' fetchScript = ''
simple_get "/private-public-keys/restic/Social" .password > $secretFile simple_get "/private-public-keys/restic/Social" .password > $secretFile
@ -88,6 +106,7 @@
''; '';
}; };
# Container: quassel
quassel_restic_password = { quassel_restic_password = {
fetchScript = '' fetchScript = ''
simple_get "/private-public-keys/restic/Quassel" .password > $secretFile simple_get "/private-public-keys/restic/Quassel" .password > $secretFile
@ -101,6 +120,7 @@
''; '';
}; };
# Container: piped
piped_restic_password = { piped_restic_password = {
fetchScript = '' fetchScript = ''
simple_get "/private-public-keys/restic/Piped" .password > $secretFile simple_get "/private-public-keys/restic/Piped" .password > $secretFile
@ -113,61 +133,6 @@
echo "RESTIC_REPOSITORY=rest:https://$RESTIC_USERNAME:$RESTIC_PASSWORD@storage-restic.owo.monster/Piped" > $secretFile echo "RESTIC_REPOSITORY=rest:https://$RESTIC_USERNAME:$RESTIC_PASSWORD@storage-restic.owo.monster/Piped" > $secretFile
''; '';
}; };
mail_restic_password = {
fetchScript = ''
simple_get "/private-public-keys/restic/Mail" .password > $secretFile
'';
};
mail_restic_env = {
fetchScript = ''
RESTIC_USERNAME=$(simple_get "/api-keys/storage/restic/Mail" .username)
RESTIC_PASSWORD=$(simple_get "/api-keys/storage/restic/Mail" .password)
echo "RESTIC_REPOSITORY=rest:https://$RESTIC_USERNAME:$RESTIC_PASSWORD@storage-restic.owo.monster/Mail" > $secretFile
'';
};
restic_password = {
fetchScript = ''
simple_get "/private-public-keys/restic/HetznerVM" .password > $secretFile
'';
};
restic_env = {
fetchScript = ''
RESTIC_USERNAME=$(simple_get "/api-keys/storage/restic/HetznerVM" .username)
RESTIC_PASSWORD=$(simple_get "/api-keys/storage/restic/HetznerVM" .password)
echo "RESTIC_REPOSITORY=rest:https://$RESTIC_USERNAME:$RESTIC_PASSWORD@storage-restic.owo.monster/HetznerVM" > $secretFile
'';
};
wg_privkey = {
fetchScript = ''
simple_get "/private-public-keys/wireguard/chaos-internal/hetzner-vm" .private > $secretFile
'';
};
wg_preshared_tablet = {
path = "/secrets/wg_preshared_tablet";
fetchScript = ''
simple_get "/private-public-keys/wireguard/chaos-internal/hetzner-vm" .preshared_keys.tablet > $secretFile
'';
};
wg_preshared_vault = {
path = "/secrets/wg_preshared_vault";
fetchScript = ''
simple_get "/private-public-keys/wireguard/chaos-internal/hetzner-vm" .preshared_keys.vault > $secretFile
'';
};
wg_preshared_storage = {
path = "/secrets/wg_preshared_storage";
fetchScript = ''
simple_get "/private-public-keys/wireguard/chaos-internal/hetzner-vm" .preshared_keys.storage > $secretFile
'';
};
wg_preshared_iphone8 = {
path = "/secrets/wg_preshared_iphone8";
fetchScript = ''
simple_get "/private-public-keys/wireguard/chaos-internal/hetzner-vm" .preshared_keys.iphone8 > $secretFile
'';
};
}; };
}; };
} }