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;
};
lib = nixpkgs.lib // {
quotePotentialIpV6 = addr:
quoteListenAddr = addr:
if nixpkgs.lib.hasInfix ":" addr then "[${addr}]" else addr;
};
specialArgs = {

View file

@ -34,6 +34,7 @@ in {
./matrix.nix
./fdroid.nix
./mumble.nix
./mailserver.nix
];
system.stateVersion = "22.11";
@ -75,11 +76,7 @@ in {
path = /persist;
directories = [
{ directory = /var/www/${cfg.domainName}; }
{ directory = /var/lib/maubot; }
{ directory = /var/lib/fdroid; }
{ directory = config.mailserver.dkimKeyDirectory; }
{ directory = config.mailserver.mailDirectory; }
{ directory = /home/user; }
{ directory = /home/${config.common.mainUsername}; }
{ directory = /root; }
{ directory = /nix; }
];
@ -109,12 +106,12 @@ in {
allowedUDPPorts = [
# dns
53 853
# wireguard
# 5553
];
};
# UNBOUND
users.users.${config.common.mainUsername}.extraGroups = [ config.services.unbound.group ];
services.unbound = {
enable = true;
package = pkgs.unbound-with-systemd.override {
@ -166,8 +163,6 @@ in {
startWhenNeeded = false;
};
users.users.user.extraGroups = [ config.services.unbound.group ];
services.postgresql.enable = true;
services.postgresql.package = pkgs.postgresql_13;
@ -203,7 +198,7 @@ in {
});
services.searx.runInUwsgi = true;
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.settings = {
@ -239,9 +234,9 @@ in {
services.nginx.virtualHosts."search.${cfg.domainName}" = let inherit (config.services.searx) settings; in {
enableACME = 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 = ''
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;
'';
};
@ -295,55 +290,11 @@ in {
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
services.nginx.virtualHosts."git.${cfg.domainName}" = let inherit (config.services.gitea) settings; in {
enableACME = 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 = {
enable = true;

View file

@ -5,6 +5,9 @@
let
cfg = config.server;
in {
impermanence.directories = [
{ directory = /var/lib/fdroid; user = "fdroid"; group = "fdroid"; mode = "0755"; }
];
services.nginx.virtualHosts."${cfg.domainName}" = {
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 = {
"= /.well-known/matrix/server".extraConfig = matrixServerConfigResponse;
"= /.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" ];
services.heisenbridge = {
enable = true;
homeserver = "http://${lib.quotePotentialIpV6 matrixAddr}:${toString matrixPort}/";
homeserver = "http://${lib.quoteListenAddr matrixAddr}:${toString matrixPort}/";
};
# so synapse can read the registration
users.groups.heisenbridge.members = [ "matrix-synapse" ];

View file

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

View file

@ -33,7 +33,7 @@ in {
forceSSL = true;
globalRedirect = cfg.domainName;
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 = {

View file

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

View file

@ -10,7 +10,7 @@
workstation = mkOption {
type = types.bool;
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 {
type = types.str;