bikeshedding
This commit is contained in:
parent
f77271b249
commit
5bc6d6a996
|
@ -36,7 +36,7 @@
|
|||
inherit nixpkgs;
|
||||
};
|
||||
lib = nixpkgs.lib // {
|
||||
quotePotentialIpV6 = addr:
|
||||
quoteListenAddr = addr:
|
||||
if nixpkgs.lib.hasInfix ":" addr then "[${addr}]" else addr;
|
||||
};
|
||||
specialArgs = {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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/";
|
||||
};
|
||||
|
|
56
system/hosts/nixserver/mailserver.nix
Normal file
56
system/hosts/nixserver/mailserver.nix
Normal 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}
|
||||
}
|
||||
'';
|
||||
}
|
|
@ -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" ];
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
};
|
||||
|
|
|
@ -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 = {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue