nibylandia/nixos/zorigami/default.nix

543 lines
16 KiB
Nix

{ config, pkgs, lib, inputs, ... }:
{
deployment.tags = [ "reachable-everywhere" ];
imports = with inputs.self.nixosModules; [
common
secureboot
monitoring
ci-runners
inputs.simple-nixos-mailserver.nixosModule
./hardware.nix
];
boot.kernelPackages = pkgs.linuxPackages;
age.secrets.cassAuth = {
file = ../../secrets/cassAuth.age;
group = "nginx";
mode = "440";
};
age.secrets.minecraftRestic.file = ../../secrets/norkclubMinecraftRestic.age;
age.secrets.nextCloudAdmin = {
file = ../../secrets/nextCloudAdmin.age;
group = "nextcloud";
mode = "440";
};
age.secrets.wgNibylandia.file = ../../secrets/wg/nibylandia_zorigami.age;
age.secrets.arMail.file = ../../secrets/mail/ar.age;
age.secrets.apoMail.file = ../../secrets/mail/apo.age;
age.secrets.madargonMail.file = ../../secrets/mail/madargon.age;
age.secrets.enkiMail.file = ../../secrets/mail/enki.age;
age.secrets.matrixMail.file = ../../secrets/mail/matrix.age;
age.secrets.mastodonMail.file = ../../secrets/mail/mastodon.age;
age.secrets.mastodonPlainMail = {
group = "mastodon";
mode = "440";
file = ../../secrets/mail/mastodonPlain.age;
};
age.secrets.vaultwardenMail.file = ../../secrets/mail/vaultwarden.age;
age.secrets.vaultwardenPlainMail = {
group = "vaultwarden";
mode = "440";
file = ../../secrets/mail/vaultwardenPlain.age;
};
age.secrets.minifluxCredentials.file = ../../secrets/miniflux.age;
age.secrets.keycloakDatabase = {
file = ../../secrets/keycloakDatabase.age;
mode = "440";
};
age.secrets.keycloak.file = ../../secrets/mail/keycloak.age;
age.secrets.notbotEnvironment.file = ../../secrets/notbotEnvironment.age;
age.secrets.synapseExtraConfig = {
group = "matrix-synapse";
mode = "440";
file = ../../secrets/synapseExtraConfig.age;
};
nibylandia.monitoring-server = { domain = "monitoring.is-a.cat"; };
services.nginx = {
enable = true;
recommendedGzipSettings = true;
recommendedOptimisation = true;
recommendedProxySettings = true;
recommendedTlsSettings = true;
clientMaxBodySize = "4096m";
appendHttpConfig = ''
disable_symlinks off;
'';
};
security.acme.acceptTerms = true;
security.acme.defaults.email = "ar@is-a.cat";
networking.firewall.allowedTCPPorts = [ 80 443 ] ++ [ 25565 25566 ]
++ [ 113 ];
networking.firewall.allowedUDPPorts = [ 80 443 ]
++ [ 19132 19133 25565 25566 ] ++ [ 51315 ];
nix.settings.max-jobs = 1;
nix.settings.cores = 24;
services.postgresql = {
enable = true;
package = pkgs.postgresql_13;
};
services.prometheus.exporters.postgres = {
enable = true;
runAsLocalSuperUser = true;
listenAddress = "127.0.0.1";
};
systemd.services.notbot = {
wantedBy = [ "multi-user.target" ];
after = [ "network.target" ];
description = "Notbot irc bot service";
serviceConfig = {
Type = "simple";
User = "bot";
EnvironmentFile = config.age.secrets.notbotEnvironment.path;
ExecStart = ''
${pkgs.notbot}/bin/notbot -nickname "notbot" -name "notbot" -user "bot" \
-server "irc.libera.chat:6667" -password $NICKSERV_PASSWORD \
-channels $CHANNELS -jitsi.channels $JITSI_CHANNELS -spaceapi.channels $SPACEAPI_CHANNELS
'';
};
};
users.users.bot = {
isSystemUser = true;
group = "bot";
};
users.groups.bot = { };
systemd.services.cass = {
wantedBy = [ "multi-user.target" ];
after = [ "network.target" ];
description = "cass";
serviceConfig = {
Type = "simple";
User = "ar";
ExecStart = ''
${pkgs.cass}/bin/cass -listen "127.0.0.1:8000" -file-store "/srv/www/arachnist.is-a.cat/c" -url-base "https://ar.is-a.cat/c/"'';
};
};
systemd.services.minecraft-overviewer = {
script = ''
${pkgs.python3Packages.minecraft-overviewer}/bin/overviewer.py -p 12 -c "/srv/minecraft-overviewer/survival/config.py"
${pkgs.python3Packages.minecraft-overviewer}/bin/overviewer.py -p 12 -c "/srv/minecraft-overviewer/survival/config.py" --genpoi
'';
serviceConfig = {
User = "minecraft";
Group = "users";
ProtectHome = "no";
};
};
systemd.timers.minecraft-overviewer = {
wantedBy = [ "multi-user.target" ];
timerConfig = { OnCalendar = "hourly"; };
};
systemd.timers.minecraft-backup = {
wantedBy = [ "multi-user.target" ];
timerConfig = { OnCalendar = "*:0/15"; };
};
users.users.minecraft = {
isNormalUser = true;
group = "users";
openssh.authorizedKeys.keys =
config.users.users.ar.openssh.authorizedKeys.keys ++ [
"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDOHWPbzvwXTftY1r0dXcYZxT9QBnQkwepdMn8PCAPlYvYwUObEj3rgYrYRFrtCRWZVrKAdqBxnH9/6S9w631Zs7tgqEeDHJsotZNZV3qip7qGjn9IqUHXqF95MUDJV21AeBAqQ1xalefwCkwf/vYLFn8dSnsnlfO+mtlHZOuBED+SB2U1eNrWY2e45v8m7PqSyTCbCu0F3wVcHGwRFsxWA598wf85UBRVcSWVcUydE9F+PCS9sGETkXiRUDcHWnup8uygs4xLa9RADubhdGkUbQE6m6yOjvHJWZ4ov59zJh+hmpszCwfmUw/k39T2TM7tbwUWxgc68qDyaMGQr/Wzd x10a94@Celestia"
"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDeJ+LSo3YXE6Jk6pGKL5om/VOi7XE5OvHA2U73V0pJXHa1bA4ityICeNqec2w8TSWSwTihJ4oAM7YLShkERNTcd1NWNHgUYova9nJ/nItFxrxDpTQsqK315u4d7nE+go09c85cyomHbDDcNVg9kJeCUjF+dr82N7JZfYVdQystOslOROYtl94GHuFHVOQyBRGeSztmakYvK1+3WV8dby6TfYG1l6uf6qLCg7q64zR4xDDP0KgfcrsusBQ6qYnKhop1fUTaW9NtEOQP/MhFLDp2YQmTsNJDiKAQpwwYLexWq4UcziXbnRfD56CHFHbW7Hu6Ltu35cHFKR2r9y4TBwTV crendgrim@gmx.de"
];
};
systemd.services.minecraft-backup = {
script = ''
export PATH="/run/current-system/sw/bin"
/home/minecraft/minecraft-backup/backup.sh -w rcon -i /home/minecraft/survival/world -r $BACKUP_DESTINATION -s $RCON_AUTH -m -1
'';
serviceConfig = {
User = "minecraft";
Group = "users";
ProtectHome = "no";
EnvironmentFile = config.age.secrets.minecraftRestic.path;
};
};
services.nextcloud = {
enable = true;
package = pkgs.nextcloud28;
hostName = "cloud.is-a.cat";
autoUpdateApps.enable = true;
autoUpdateApps.startAt = "05:00:00";
settings.overwriteprotocol = "https";
config = {
adminuser = "admin";
adminpassFile = config.age.secrets.nextCloudAdmin.path;
dbtype = "pgsql";
dbuser = "nextcloud";
dbname = "nextcloud";
dbhost = "/run/postgresql";
};
};
services.postgresql.ensureDatabases =
[ "nextcloud" "matrix-synapse" "mastodon" ];
services.postgresql.ensureUsers = [
{
name = "nextcloud";
ensureDBOwnership = true;
}
{
name = "matrix-synapse";
ensureDBOwnership = true;
}
{
name = "mastodon";
ensureDBOwnership = true;
}
];
systemd.services."nextcloud-setup" = {
requires = [ "postgresql.service" ];
after = [ "postgresql.service" ];
};
mailserver = {
enable = true;
fqdn = "is-a.cat";
domains = [ "is-a.cat" "i.am-a.cat" "rsg.enterprises" ];
certificateScheme = "acme-nginx";
enableManageSieve = true;
fullTextSearch = {
enable = true;
memoryLimit = 2000;
};
localDnsResolver = false;
monitoring.enable = false;
borgbackup.enable = false;
backup.enable = false;
messageSizeLimit = 41943040;
loginAccounts = {
"ar@is-a.cat" = {
aliases = [
"arachnist@is-a.cat"
"letsencrypt@is-a.cat"
"gustaw.weldon@is-a.cat"
"@rsg.enterprises"
"@i.am-a.cat"
"ari@is-a.cat"
];
hashedPasswordFile = config.age.secrets.arMail.path;
};
"apo@is-a.cat".hashedPasswordFile = config.age.secrets.apoMail.path;
"madargon@is-a.cat".hashedPasswordFile =
config.age.secrets.madargonMail.path;
"enkiusz@is-a.cat".hashedPasswordFile = config.age.secrets.enkiMail.path;
"mastodon@is-a.cat".hashedPasswordFile =
config.age.secrets.mastodonMail.path;
"matrix@is-a.cat".hashedPasswordFile = config.age.secrets.matrixMail.path;
"vaultwarden@is-a.cat".hashedPasswordFile =
config.age.secrets.vaultwardenMail.path;
};
};
services.dovecot2.sieve.extensions = [ "fileinto" ];
services.matrix-synapse = {
enable = true;
settings = {
server_name = "is-a.cat";
registrations_require_3pid = [ "email" ];
allowed_local_3pids = [{
medium = "email";
pattern = "^[^@]+@is-a.cat$";
}];
enable_registration = true;
registration_requires_token = true;
withJemalloc = true;
};
extraConfigFiles = [ config.age.secrets.synapseExtraConfig.path ];
};
services.mastodon = {
enable = true;
webProcesses = 4;
streamingProcesses = 4;
localDomain = "is-a.cat";
configureNginx = true;
smtp = {
user = "mastodon@is-a.cat";
passwordFile = config.age.secrets.mastodonPlainMail.path;
fromAddress = "mastodon@is-a.cat";
host = "is-a.cat";
createLocally = false;
authenticate = true;
};
extraConfig = {
EMAIL_DOMAIN_ALLOWLIST = "is-a.cat";
MAX_TOOT_CHARS = "20000";
MAX_PINNED_TOOTS = "10";
MAX_BIO_CHARS = "2000";
MAX_PROFILE_FIELDS = "8";
MAX_POLL_OPTIONS = "10";
MAX_IMAGE_SIZE = "33554432";
MAX_VIDEO_SIZE = "167772160";
ALLOWED_PRIVATE_ADDRESSES = "127.1.33.7";
GITHUB_REPOSITORY = "arachnist/mastodon/tree/meow";
};
package = pkgs.glitchSoc;
};
services.vaultwarden = {
enable = true;
dbBackend = "postgresql";
config = {
DOMAIN = "https://vaultwarden.is-a.cat";
ROCKET_PORT = "8222";
ROCKET_ADDRESS = "127.0.0.1";
databaseUrl = "postgresql://vaultwarden@%2Frun%2Fpostgresql/vaultwarden";
smtpHost = "is-a.cat";
smtpFrom = "vaultwarden@is-a.cat";
smtpUsername = "vaultwarden@is-a.cat";
smtpSecurity = "force_tls";
signupsDomainsWhitelist = "is-a.cat";
};
environmentFile = config.age.secrets.vaultwardenPlainMail.path;
};
services.nginx.virtualHosts."vaultwarden.is-a.cat" = {
forceSSL = true;
enableACME = true;
locations."/" = {
proxyPass = "http://127.0.0.1:${
toString config.services.vaultwarden.config.ROCKET_PORT
}";
proxyWebsockets = true;
};
locations."/notifications/hub" = {
proxyPass = "http://localhost:3012";
proxyWebsockets = true;
};
locations."/notifications/hub/negotiate" = {
proxyPass = "http://localhost:8812";
proxyWebsockets = true;
};
};
# need to figure out something fancy about network configuration
networking.hostName = "zorigami";
systemd.network.wait-online.enable = false;
networking.useDHCP = false;
networking.interfaces.enp36s0f1.useDHCP = false;
networking.interfaces.enp38s0.useDHCP = false;
networking.interfaces.enp39s0.useDHCP = false;
networking.interfaces.enp42s0f3u5u3c2.useDHCP = false;
networking.tempAddresses = "disabled";
networking.interfaces.enp36s0f0 = {
useDHCP = false;
ipv4 = {
addresses = [{
address = "185.236.240.137";
prefixLength = 31;
}];
routes = [{
address = "0.0.0.0";
prefixLength = 0;
via = "185.236.240.136";
}];
};
ipv6 = {
addresses = [{
address = "2a0d:eb00:8007::10";
prefixLength = 64;
}];
routes = [{
address = "::";
prefixLength = 0;
via = "2a0d:eb00:8007::1";
}];
};
};
networking.nameservers = [
"8.8.8.8"
"8.8.4.4"
"1.1.1.1"
"2606:4700:4700::1111"
"2606:4700:4700::1001"
"2001:4860:4860::8888"
];
boot.kernel.sysctl = {
"net.ipv6.conf.all.accept_ra" = false;
"net.ipv6.conf.default.accept_ra" = false;
"net.ipv4.conf.all.forwarding" = true;
};
networking.wireguard.interfaces = {
wg-nibylandia = {
ips = [ "10.255.255.1/24" ];
privateKeyFile = config.age.secrets.wgNibylandia.path;
listenPort = 51315;
peers = [
{
publicKey = "g/XhdVYsegn7Pp58Y1HFNxp4jhmA8YjRDg8W8J6swCw=";
endpoint = "i.am-a.cat:51315";
allowedIPs =
[ "10.255.255.2/32" "192.168.20.0/24" "192.168.24.0/24" ];
persistentKeepalive = 15;
}
{
publicKey = "ubxtr3zW9F/ofjaQFnj6XpYcrOvTdOSW5wv06+VEehU=";
allowedIPs = [ "10.255.255.3/32" ];
persistentKeepalive = 15;
}
{
publicKey = "tVH3q1AJZKsitYmASdaogMCBwhMCd8oSuDY2POpiUiY=";
allowedIPs = [ "10.255.255.4/32" ];
persistentKeepalive = 15;
}
];
};
};
services.nginx.virtualHosts = {
"s.nork.club" = {
forceSSL = true;
enableACME = true;
root = "/srv/www/s.nork.club";
};
"ar.is-a.cat" = {
forceSSL = true;
enableACME = true;
locations."/" = { root = "/srv/www/arachnist.is-a.cat"; };
locations."/up" = {
proxyPass = "http://127.0.0.1:8000";
basicAuthFile = config.age.secrets.cassAuth.path;
extraConfig = ''
proxy_request_buffering off;
proxy_send_timeout "9000s";
proxy_read_timeout "9000s";
'';
};
locations."/down" = {
proxyPass = "http://127.0.0.1:8000";
basicAuthFile = config.age.secrets.cassAuth.path;
extraConfig = ''
proxy_request_buffering off;
proxy_send_timeout "9000s";
proxy_read_timeout "9000s";
'';
};
};
"arachnist.is-a.cat" = {
forceSSL = true;
enableACME = true;
locations."/" = { root = "/srv/www/arachnist.is-a.cat"; };
};
"brata.zajeba.li" = {
forceSSL = true;
enableACME = true;
locations."/" = { root = "/srv/www/brata.zajeba.li"; };
};
"irc.is-a.cat" = {
forceSSL = true;
enableACME = true;
locations."^~ /weechat" = {
proxyPass = "http://127.0.0.1:9001";
proxyWebsockets = true;
};
locations."/" = { root = pkgs.glowing-bear; };
};
"cloud.is-a.cat" = {
forceSSL = true;
enableACME = true;
};
"${config.services.matrix-synapse.settings.server_name}" = {
enableACME = true;
forceSSL = true;
locations."/_matrix" = { proxyPass = "http://127.0.0.1:8008"; };
locations."/.well-known/matrix/server" = {
return = ''
200 "{\"m.server\":\"${config.services.matrix-synapse.settings.server_name}:443\",\"m.homeserver\":{\"base_url\":\"https://${config.services.matrix-synapse.settings.server_name}\"}}"'';
};
};
"matrix.${config.services.matrix-synapse.settings.server_name}" = {
enableACME = true;
forceSSL = true;
locations."/" = {
root = pkgs.cinny.override {
conf = {
homeserverList = [
config.services.matrix-synapse.settings.server_name
"matrix.hackerspace.pl"
];
allowCustomHomeservers = false;
defaultHomeserver = 0;
};
};
};
};
"rower.zajeba.li" = {
enableACME = true;
forceSSL = true;
locations."/" = {
return = "301 https://pl.wikipedia.org/wiki/Praga-Po%C5%82udnie";
};
};
};
services.oidentd.enable = true;
programs.java = {
enable = true;
package = pkgs.openjdk17;
};
environment.systemPackages = with pkgs; [ john restic weechat ];
users.groups.erin = { gid = 1003; };
users.users.erin = {
isNormalUser = true;
uid = 1003;
group = "erin";
extraGroups = [ "users" ];
packages = with pkgs; [ borgbackup ];
openssh.authorizedKeys.keys = [
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINBebbJHzn1VmIO0GxUpERXSTvYVpGdnS4/3/JHp9NZa elia@boston-packets"
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDdILFDn3VgZfybppL5tbAGsv7KWgM+SoCBQHdtGR8zn elia@panzerbook"
];
};
users.groups.domi = { gid = 1004; };
users.users.domi = {
isNormalUser = true;
uid = 1004;
group = "domi";
extraGroups = [ "users" ];
openssh.authorizedKeys.keys = [
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEFHcfS3YKXUX4N8cD2IEF3GxHvb+IlynSSudDF1/e3U domi@kita"
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPkJRQYGIVC//ofxYrIxF3nP3D8gTDSSSMyEzG6JVQii domi@sakamoto"
"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDVJ307BmZvIkQMxFIGe3nTYOL/Qo0AeaEPmxUFG+vSASPdTaSM4PHYh6WgJIRNsKcZHCF9gCFniY0TCrC3chBJRsRxTonCZteiib3/rpn0c+jFMtfi+SId56/BhQP8S3LAw7EpciQ7U5qmwYc5f5hhhXnEFhT2SoxxA45eIBwZjTo0aE1SC1M5buzVW+VnPuV2+PYE8wQjSYUnUChrJOgZeCapbIvfz8Ml7ppX1LmFLCeLHyZHJpzhoz+6Ios7FbkuhuaCTjMU+MqmSzM4MBDRThI13e/lWsExGDh1BlSTB4FawUCvd90Z0KBp671UsA0SXzzB4UQujVSNO/yDwLYvldlV3mXkLAsB0pdmRfGFAD0C4gxe8yG5jM6FxBYV4ZLEAvKRLROr4SaWJ4OXh7cplnr78zQit0r3erqusf28xYnOvF0zTvCMvPPFBVBGqolYPPFUleClZ1HaoTnM36NDAdyO5P9/4og5y/FfRDajql3HhBNA8MV+8FN/leJ2Hfk= domi@hakase"
];
};
}