bikeshedding

This commit is contained in:
chayleaf 2023-05-17 06:29:03 +07:00
parent f77271b249
commit 5bc6d6a996
9 changed files with 80 additions and 72 deletions

View file

@ -36,7 +36,7 @@
inherit nixpkgs; inherit nixpkgs;
}; };
lib = nixpkgs.lib // { lib = nixpkgs.lib // {
quotePotentialIpV6 = addr: quoteListenAddr = addr:
if nixpkgs.lib.hasInfix ":" addr then "[${addr}]" else addr; if nixpkgs.lib.hasInfix ":" addr then "[${addr}]" else addr;
}; };
specialArgs = { specialArgs = {

View file

@ -34,6 +34,7 @@ in {
./matrix.nix ./matrix.nix
./fdroid.nix ./fdroid.nix
./mumble.nix ./mumble.nix
./mailserver.nix
]; ];
system.stateVersion = "22.11"; system.stateVersion = "22.11";
@ -75,11 +76,7 @@ in {
path = /persist; path = /persist;
directories = [ directories = [
{ directory = /var/www/${cfg.domainName}; } { directory = /var/www/${cfg.domainName}; }
{ directory = /var/lib/maubot; } { directory = /home/${config.common.mainUsername}; }
{ directory = /var/lib/fdroid; }
{ directory = config.mailserver.dkimKeyDirectory; }
{ directory = config.mailserver.mailDirectory; }
{ directory = /home/user; }
{ directory = /root; } { directory = /root; }
{ directory = /nix; } { directory = /nix; }
]; ];
@ -109,12 +106,12 @@ in {
allowedUDPPorts = [ allowedUDPPorts = [
# dns # dns
53 853 53 853
# wireguard
# 5553
]; ];
}; };
# UNBOUND # UNBOUND
users.users.${config.common.mainUsername}.extraGroups = [ config.services.unbound.group ];
services.unbound = { services.unbound = {
enable = true; enable = true;
package = pkgs.unbound-with-systemd.override { package = pkgs.unbound-with-systemd.override {
@ -166,8 +163,6 @@ in {
startWhenNeeded = false; startWhenNeeded = false;
}; };
users.users.user.extraGroups = [ config.services.unbound.group ];
services.postgresql.enable = true; services.postgresql.enable = true;
services.postgresql.package = pkgs.postgresql_13; services.postgresql.package = pkgs.postgresql_13;
@ -203,7 +198,7 @@ in {
}); });
services.searx.runInUwsgi = true; services.searx.runInUwsgi = true;
services.searx.uwsgiConfig = let inherit (config.services.searx) settings; in { services.searx.uwsgiConfig = let inherit (config.services.searx) settings; in {
socket = "${lib.quotePotentialIpV6 settings.server.bind_address}:${toString settings.server.port}"; socket = "${lib.quoteListenAddr settings.server.bind_address}:${toString settings.server.port}";
}; };
services.searx.environmentFile = /var/lib/searx/searx.env; services.searx.environmentFile = /var/lib/searx/searx.env;
services.searx.settings = { services.searx.settings = {
@ -239,9 +234,9 @@ in {
services.nginx.virtualHosts."search.${cfg.domainName}" = let inherit (config.services.searx) settings; in { services.nginx.virtualHosts."search.${cfg.domainName}" = let inherit (config.services.searx) settings; in {
enableACME = true; enableACME = true;
forceSSL = true; forceSSL = true;
# locations."/".proxyPass = "http://${lib.quotePotentialIpV6 settings.server.bind_address}:${toString settings.server.port}"; # locations."/".proxyPass = "http://${lib.quoteListenAddr settings.server.bind_address}:${toString settings.server.port}";
locations."/".extraConfig = '' locations."/".extraConfig = ''
uwsgi_pass "${lib.quotePotentialIpV6 settings.server.bind_address}:${toString settings.server.port}"; uwsgi_pass "${lib.quoteListenAddr settings.server.bind_address}:${toString settings.server.port}";
include ${config.services.nginx.package}/conf/uwsgi_params; include ${config.services.nginx.package}/conf/uwsgi_params;
''; '';
}; };
@ -295,55 +290,11 @@ in {
globalRedirect = cfg.domainName; globalRedirect = cfg.domainName;
}; };
# MAILSERVER
# roundcube
services.nginx.virtualHosts."mail.${cfg.domainName}" = {
enableACME = true;
};
services.roundcube = {
enable = true;
package = pkgs.roundcube.withPlugins (plugins: [ plugins.persistent_login ]);
dicts = with pkgs.aspellDicts; [ en ru ];
hostName = "mail.${cfg.domainName}";
maxAttachmentSize = 100;
plugins = [ "persistent_login" ];
};
mailserver = {
enable = true;
fqdn = "mail.${cfg.domainName}";
domains = [ cfg.domainName ];
certificateScheme = 1;
certificateFile = config.security.acme.certs."mail.${cfg.domainName}".directory + "/fullchain.pem";
keyFile = config.security.acme.certs."mail.${cfg.domainName}".directory + "/key.pem";
localDnsResolver = false;
recipientDelimiter = "-";
lmtpSaveToDetailMailbox = "no";
hierarchySeparator = "/";
};
# Only allow local connections to noreply account
mailserver.loginAccounts."noreply@${cfg.domainName}" = {
# password is set in private.nix
hashedPassword = cfg.hashedNoreplyPassword;
sendOnly = true;
};
services.dovecot2.extraConfig =
let
passwd = builtins.toFile "dovecot2-local-passwd" ''
noreply@${cfg.domainName}:{plain}${cfg.unhashedNoreplyPassword}::::::allow_nets=local,127.0.0.0/8,::1
'';
in ''
passdb {
driver = passwd-file
args = ${passwd}
}
'';
# GITEA # GITEA
services.nginx.virtualHosts."git.${cfg.domainName}" = let inherit (config.services.gitea) settings; in { services.nginx.virtualHosts."git.${cfg.domainName}" = let inherit (config.services.gitea) settings; in {
enableACME = true; enableACME = true;
forceSSL = true; forceSSL = true;
locations."/".proxyPass = "http://${lib.quotePotentialIpV6 settings.server.HTTP_ADDR}:${toString settings.server.HTTP_PORT}"; locations."/".proxyPass = "http://${lib.quoteListenAddr settings.server.HTTP_ADDR}:${toString settings.server.HTTP_PORT}";
}; };
services.gitea = { services.gitea = {
enable = true; enable = true;

View file

@ -5,6 +5,9 @@
let let
cfg = config.server; cfg = config.server;
in { in {
impermanence.directories = [
{ directory = /var/lib/fdroid; user = "fdroid"; group = "fdroid"; mode = "0755"; }
];
services.nginx.virtualHosts."${cfg.domainName}" = { services.nginx.virtualHosts."${cfg.domainName}" = {
locations."/fdroid/".alias = "/var/lib/fdroid/repo/"; locations."/fdroid/".alias = "/var/lib/fdroid/repo/";
}; };

View file

@ -0,0 +1,56 @@
{ config
, pkgs
, ... }:
let
cfg = config.server;
in {
impermanence.directories = [
{ directory = config.mailserver.dkimKeyDirectory; user = "opendkim"; group = "opendkim"; mode = "0755"; }
{ directory = config.mailserver.mailDirectory; user = "virtualMail"; group = "virtualMail"; mode = "0700"; }
];
# roundcube
# TODO: fix sending mail via roundcube
services.nginx.virtualHosts."mail.${cfg.domainName}" = {
enableACME = true;
};
services.roundcube = {
enable = true;
package = pkgs.roundcube.withPlugins (plugins: [ plugins.persistent_login ]);
dicts = with pkgs.aspellDicts; [ en ru ];
hostName = "mail.${cfg.domainName}";
maxAttachmentSize = 100;
plugins = [ "persistent_login" ];
};
mailserver = {
enable = true;
fqdn = "mail.${cfg.domainName}";
domains = [ cfg.domainName ];
certificateScheme = 1;
certificateFile = config.security.acme.certs."mail.${cfg.domainName}".directory + "/fullchain.pem";
keyFile = config.security.acme.certs."mail.${cfg.domainName}".directory + "/key.pem";
localDnsResolver = false;
recipientDelimiter = "-";
lmtpSaveToDetailMailbox = "no";
hierarchySeparator = "/";
};
# Only allow local connections to noreply account
mailserver.loginAccounts."noreply@${cfg.domainName}" = {
# password is set in private.nix
hashedPassword = cfg.hashedNoreplyPassword;
sendOnly = true;
};
services.dovecot2.extraConfig =
let
passwd = builtins.toFile "dovecot2-local-passwd" ''
noreply@${cfg.domainName}:{plain}${cfg.unhashedNoreplyPassword}::::::allow_nets=local,127.0.0.0/8,::1
'';
in ''
passdb {
driver = passwd-file
args = ${passwd}
}
'';
}

View file

@ -39,7 +39,7 @@ in {
locations = { locations = {
"= /.well-known/matrix/server".extraConfig = matrixServerConfigResponse; "= /.well-known/matrix/server".extraConfig = matrixServerConfigResponse;
"= /.well-known/matrix/client".extraConfig = matrixClientConfigResponse; "= /.well-known/matrix/client".extraConfig = matrixClientConfigResponse;
"/".proxyPass = "http://${lib.quotePotentialIpV6 matrixAddr}:${toString matrixPort}"; "/".proxyPass = "http://${lib.quoteListenAddr matrixAddr}:${toString matrixPort}";
}; };
}; };
@ -47,7 +47,7 @@ in {
systemd.services.heisenbridge.after = [ "matrix-synapse.service" ]; systemd.services.heisenbridge.after = [ "matrix-synapse.service" ];
services.heisenbridge = { services.heisenbridge = {
enable = true; enable = true;
homeserver = "http://${lib.quotePotentialIpV6 matrixAddr}:${toString matrixPort}/"; homeserver = "http://${lib.quoteListenAddr matrixAddr}:${toString matrixPort}/";
}; };
# so synapse can read the registration # so synapse can read the registration
users.groups.heisenbridge.members = [ "matrix-synapse" ]; users.groups.heisenbridge.members = [ "matrix-synapse" ];

View file

@ -9,9 +9,12 @@ let
maubotAddr = "127.0.0.1"; maubotAddr = "127.0.0.1";
maubotPort = 29316; maubotPort = 29316;
in { in {
impermanence.directories = [
{ directory = /var/lib/maubot; user = "maubot"; group = "maubot"; mode = "0755"; }
];
services.nginx.virtualHosts."matrix.${cfg.domainName}".locations = { services.nginx.virtualHosts."matrix.${cfg.domainName}".locations = {
"/_matrix/maubot/" = { "/_matrix/maubot/" = {
proxyPass = "http://${lib.quotePotentialIpV6 maubotAddr}:${toString maubotPort}"; proxyPass = "http://${lib.quoteListenAddr maubotAddr}:${toString maubotPort}";
proxyWebsockets = true; proxyWebsockets = true;
}; };
}; };

View file

@ -33,7 +33,7 @@ in {
forceSSL = true; forceSSL = true;
globalRedirect = cfg.domainName; globalRedirect = cfg.domainName;
locations."/music".extraConfig = "return 301 https://mumble.${cfg.domainName}/music/;"; locations."/music".extraConfig = "return 301 https://mumble.${cfg.domainName}/music/;";
locations."/music/".proxyPass = "http://${lib.quotePotentialIpV6 settings.webinterface.listening_addr}:${toString settings.webinterface.listening_port}/"; locations."/music/".proxyPass = "http://${lib.quoteListenAddr settings.webinterface.listening_addr}:${toString settings.webinterface.listening_port}/";
}; };
services.botamusique = { services.botamusique = {

View file

@ -12,7 +12,7 @@
lanCidrV4 = mkOption { lanCidrV4 = mkOption {
type = types.str; type = types.str;
description = "LAN mask (IPv4)"; description = "LAN mask (IPv4)";
example = "192.168.1.0/96"; example = "192.168.1.0/24";
default = "0.0.0.0/0"; default = "0.0.0.0/0";
}; };
lanCidrV6 = mkOption { lanCidrV6 = mkOption {
@ -33,19 +33,14 @@
example = "fd01:abcd::2"; example = "fd01:abcd::2";
default = null; default = null;
}; };
noreplyPassword = mkOption {
type = types.str;
description = "noreply (only available via localhost) account password";
default = "totallysafe";
};
hashedNoreplyPassword = mkOption { hashedNoreplyPassword = mkOption {
type = types.str; type = types.str;
description = "hashed noreply password via mkpasswd -sm bcrypt"; description = "hashed noreply password via mkpasswd -sm bcrypt for external access";
}; };
unhashedNoreplyPassword = mkOption { unhashedNoreplyPassword = mkOption {
type = types.str; type = types.str;
description = "unhashed noreply password. \ description = "unhashed noreply password for internal access only. \
This should preferably be different from the password that is hashed for better security (yes, really)"; This should be different from the password that is hashed for better security";
}; };
pizzabotMagic = mkOption { pizzabotMagic = mkOption {
type = types.str; type = types.str;

View file

@ -10,7 +10,7 @@
workstation = mkOption { workstation = mkOption {
type = types.bool; type = types.bool;
default = false; default = false;
description = "whether this device is a workstation (meaning a device for personal use rather than a server)"; description = "whether this device is a workstation (meaning a device for personal use rather than a server/embedded device)";
}; };
mainUsername = mkOption { mainUsername = mkOption {
type = types.str; type = types.str;