{ config, pkgs, lib, ... }: with lib; let domain = "fudo.org"; hostname = "france.${domain}"; mail-hostname = "mail.${domain}"; host_ipv4 = "208.81.3.117"; # Use a special IP for git.fudo.org, since it needs to be SSH-able git_ipv4 = "208.81.3.126"; all-hostnames = []; acme-private-key = hostname: "/var/lib/acme/${hostname}/key.pem"; acme-certificate = hostname: "/var/lib/acme/${hostname}/fullchain.pem"; acme-ca = "/etc/nixos/static/letsencryptauthorityx3.pem"; fudo-ca = "/etc/nixos/static/fudo_ca.pem"; minecraft-data-dir = "/srv/minecraft/data"; system-mail-directory = "/srv/mail"; in { boot.loader.grub = { enable = true; version = 2; device = "/dev/sda"; }; imports = [ ../hardware-configuration.nix ../defaults.nix ./france/jabber.nix ./france/backplane.nix ]; environment.systemPackages = with pkgs; [ docker lxd multipath-tools nix-prefetch-docker tshark ]; fudo.common = { # Sets some server-common settings. See /etc/nixos/fudo/profiles/... profile = "server"; # Sets some common site-specific settings: gateway, monitoring, etc. See /etc/nixos/fudo/sites/... site = "portage"; domain = domain; www-root = /srv/www; local-networks = [ "208.81.1.128/28" "208.81.3.112/28" "172.17.0.0/16" "127.0.0.0/8" ]; }; fudo.prometheus = { enable = true; hostname = "metrics.fudo.org"; service-discovery-dns = { node = [ "node._metrics._tcp.fudo.org" ]; postfix = [ "postfix._metrics._tcp.fudo.org" ]; dovecot = [ "dovecot._metrics._tcp.fudo.org" ]; rspamd = [ "rspamd._metrics._tcp.fudo.org" ]; }; }; fudo.grafana = { enable = true; hostname = "monitor.fudo.org"; smtp-username = "metrics"; smtp-password-file = "/srv/grafana/secure/smtp.passwd"; admin-password-file = "/srv/grafana/secure/admin.passwd"; secret-key-file = "/srv/grafana/secure/secret.key"; prometheus-host = "metrics.fudo.org"; database = { name = "grafana"; hostname = "localhost"; user = "grafana"; password-file = /srv/grafana/secure/db.passwd; }; }; # So that grafana waits for postgresql systemd.services.grafana.after = [ "postgresql.service" ]; fudo.postgresql = { enable = true; ssl-private-key = (acme-private-key hostname); ssl-certificate = (acme-certificate hostname); keytab = "/srv/postgres/secure/postgres.keytab"; # We allow connections from local networks. Auth is still required. Outside # of these networks, no access is allowed. # # TODO: that's probably too strict, allow kerberos connections from anywhere? local-networks = [ "208.81.1.128/28" "208.81.3.112/28" "192.168.11.1/24" "127.0.0.1/8" "172.17.0.0/16" ]; users = { fudo_git = { password-file = "/srv/git/secure/db.passwd"; databases = { fudo_git = { access = "CONNECT"; entity-access = { "ALL TABLES IN SCHEMA public" = "SELECT,INSERT,UPDATE,DELETE"; "ALL SEQUENCES IN SCHEMA public" = "SELECT,UPDATE"; }; }; }; }; grafana = { password-file = "/srv/grafana/secure/db.passwd"; databases = { grafana = { access = "CONNECT"; entity-access = { "ALL TABLES IN SCHEMA public" = "SELECT,INSERT,UPDATE,DELETE"; "ALL SEQUENCES IN SCHEMA public" = "SELECT,UPDATE"; }; }; }; }; mattermost = { password-file = "/srv/mattermost/secure/db.passwd"; databases = { mattermost = { access = "CONNECT"; entity-access = { "ALL TABLES IN SCHEMA public" = "SELECT,INSERT,UPDATE,DELETE"; "ALL SEQUENCES IN SCHEMA public" = "SELECT,UPDATE"; }; }; }; }; webmail = { password-file = "/srv/webmail/secure/db.passwd"; databases = { webmail = { access = "CONNECT"; entity-access = { "ALL TABLES IN SCHEMA public" = "SELECT,INSERT,UPDATE,DELETE"; "ALL SEQUENCES IN SCHEMA public" = "SELECT,UPDATE"; }; }; }; }; niten = {}; }; local-users = [ "niten" "fudo_git" ]; databases = { fudo_git = { users = ["niten"]; }; grafana = { users = ["niten"]; }; mattermost = { users = ["niten"]; }; webmail = { users = ["niten"]; }; }; }; # fudo.dns = { # enable = true; # dns-hosts = { # "ns1.fudo.org" = host_ipv4; # "ns2.fudo.org" = ""; # }; # listen-ips = [host_ipv4]; # domains = { # "selby.ca" = import ../fudo.org/selby.ca.nix { # inherit host_ipv4 config; # }; # }; # }; # Not all users need access to france; don't allow LDAP-user access. fudo.authentication.enable = false; # But we DO run an LDAP auth server. Should be better-named. fudo.auth = { server = { enable = true; base = "dc=fudo,dc=org"; organization = "Fudo"; rootpw-file = "/srv/ldap/secure/root.pw"; kerberos-host = "france.fudo.org"; kerberos-keytab = "/srv/ldap/secure/ldap.keytab"; sslCert = "/srv/ldap/france.fudo.org.pem"; sslKey = "/srv/ldap/secure/france.fudo.org-key.pem"; sslCACert = fudo-ca; # We're using fudo-generated certs for now, but we should move to ACME # once I can figure out how to correctly produce the ca.pem file. Until # then, the server will fail to start using these certs. See: # https://serverfault.com/a/834565 # sslCert = (acme-bare-cert hostname); # sslKey = (acme-private-key hostname); # sslCACert = acme-ca; listen-uris = [ "ldap:///" "ldaps:///" "ldapi:///" ]; users = import ../fudo/users.nix; groups = import ../fudo/groups.nix; system-users = import ../fudo/system-users.nix; }; # Heimdal Kerberos server kdc = { enable = true; database-path = "/var/heimdal/heimdal"; realm = "FUDO.ORG"; mkey-file = "/var/heimdal/m-key"; acl-file = "/etc/heimdal/kdc.acl"; bind-addresses = [ host_ipv4 "127.0.0.1" "127.0.1.1" ]; }; }; # TODO: not used yet fudo.acme.hostnames = all-hostnames; fudo.mail-server = import ../fudo/email.nix { inherit config; } // { enableContainer = true; debug = true; monitoring = true; hostname = mail-hostname; postfix.ssl-certificate = (acme-certificate mail-hostname); postfix.ssl-private-key = (acme-private-key mail-hostname); dovecot.ssl-certificate = (acme-certificate mail-hostname); dovecot.ssl-private-key = (acme-private-key mail-hostname); state-directory = "${system-mail-directory}/var"; mail-directory = "${system-mail-directory}/mailboxes"; dovecot.ldap = { reader-dn = "cn=user_db_reader,dc=fudo,dc=org"; reader-passwd = fileContents /srv/ldap/secure/user_db.passwd; # FIXME: use SSL once I can figure out Acme SSL cert CA for LDAP. server-urls = [ "ldap://france.fudo.org" ]; }; clamav.enable = true; dkim.signing = true; }; fudo.webmail = { enable = true; sites = { "webmail.fudo.link" = { title = "Fudo Link Webmail"; favicon = "/etc/nixos/static/fudo.link/favicon.ico"; mail-server = mail-hostname; domain = "fudo.link"; edit-mode = "Plain"; layout-mode = "bottom"; database = { name = "webmail"; hostname = "localhost"; user = "webmail"; password-file = "/srv/webmail/secure/db.passwd"; }; }; "webmail.test.fudo.org" = { title = "Fudo Webmail"; favicon = "/etc/nixos/static/fudo.org/favicon.ico"; mail-server = mail-hostname; domain = "fudo.org"; edit-mode = "Plain"; database = { name = "webmail"; hostname = "localhost"; user = "webmail"; password-file = "/srv/webmail/secure/db.passwd"; }; }; "webmail.fudo.org" = { title = "Fudo Webmail"; favicon = "/etc/nixos/static/fudo.org/favicon.ico"; mail-server = mail-hostname; domain = "fudo.org"; edit-mode = "Plain"; database = { name = "webmail"; hostname = "localhost"; user = "webmail"; password-file = "/srv/webmail/secure/db.passwd"; }; }; "webmail.test.selby.ca" = { title = "Selby Webmail"; favicon = "/etc/nixos/static/selby.ca/favicon.ico"; mail-server = mail-hostname; domain = "selby.ca"; database = { name = "webmail"; hostname = "localhost"; user = "webmail"; password-file = "/srv/webmail/secure/db.passwd"; }; }; "webmail.selby.ca" = { title = "Selby Webmail"; favicon = "/etc/nixos/static/selby.ca/favicon.ico"; mail-server = mail-hostname; domain = "selby.ca"; database = { name = "webmail"; hostname = "localhost"; user = "webmail"; password-file = "/srv/webmail/secure/db.passwd"; }; }; }; }; fudo.chat = { enable = true; hostname = "chat.fudo.org"; site-name = "Fudo Chat"; smtp-server = "mail.fudo.org"; smtp-user = "chat"; smtp-password-file = "/srv/mattermost/secure/smtp.passwd"; database = { name = "mattermost"; hostname = "localhost"; user = "mattermost"; password-file = "/srv/mattermost/secure/db.passwd"; }; }; fudo.git = { enable = true; hostname = "git.fudo.org"; site-name = "Fudo Git"; user = "fudo_git"; database = { user = "fudo_git"; password-file = /srv/git/secure/db.passwd; hostname = "127.0.0.1"; name = "fudo_git"; }; repository-dir = /srv/git/repo; state-dir = /srv/git/state; ssh = { listen-ip = git_ipv4; listen-port = 2222; }; }; networking = { hostName = hostname; dhcpcd.enable = false; useDHCP = false; # TODO: fix IPv6 enableIPv6 = true; # Create a bridge for VMs to use macvlans = { extif0 = { interface = "enp4s0f0"; mode = "bridge"; }; extif1 = { interface = "enp4s0f0"; mode = "bridge"; }; intif0 = { interface = "enp4s0f1"; mode = "bridge"; }; }; interfaces = { extif0 = { # result of: # echo $FQDN-extif|md5sum|sed 's/^\(..\)\(..\)\(..\)\(..\)\(..\).*$/02:\1:\2:\3:\4:\5/' macAddress = "02:d4:e8:3b:10:2f"; ipv4.addresses = [ { address = host_ipv4; prefixLength = 28; } ]; }; extif1 = { macAddress = "02:6d:e2:e1:ad:ca"; ipv4.addresses = [ { address = git_ipv4; prefixLength = 28; } ]; }; intif0 = { # result of: # echo $FQDN-intif|md5sum|sed 's/^\(..\)\(..\)\(..\)\(..\)\(..\).*$/02:\1:\2:\3:\4:\5/' macAddress = "02:ba:ba:e9:08:21"; ipv4.addresses = [ { address = "192.168.11.1"; prefixLength = 24; } ]; }; }; }; hardware.bluetooth.enable = false; virtualisation = { docker = { enable = true; enableOnBoot = true; autoPrune = { enable = true; }; }; lxd = { enable = true; }; }; fileSystems = { "/srv/archiva" = { fsType = "btrfs"; options = ["subvol=archiva"]; label = "pool0"; }; "/srv/grafana" = { fsType = "btrfs"; options = ["subvol=grafana"]; label = "pool0"; }; "${system-mail-directory}" = { fsType = "btrfs"; options = ["subvol=mail"]; label = "pool0"; }; "/srv/gitlab" = { fsType = "btrfs"; options = ["subvol=gitlab"]; label = "pool0"; }; "/var/lib/lxd/storage-pools/pool0" = { fsType = "btrfs"; label = "pool0"; device = "/dev/disk/by-label/pool0"; }; "/var/lib/lxd/storage-pools/pool1" = { fsType = "btrfs"; label = "pool1"; device = "/dev/france-user/fudo-user"; }; }; users = { extraUsers = { archiva = { isNormalUser = false; group = "nogroup"; uid = 8001; }; fudo_git = { isNormalUser = false; uid = 8006; }; }; }; security.acme.certs = { "archiva.fudo.org".email = config.fudo.common.admin-email; "git.fudo.org".email = config.fudo.common.admin-email; "mail.fudo.org".email = config.fudo.common.admin-email; }; services = { nginx = { enable = true; recommendedGzipSettings = true; recommendedOptimisation = true; recommendedTlsSettings = true; virtualHosts = { "archiva.fudo.org" = { enableACME = true; forceSSL = true; locations."/" = { proxyPass = "http://127.0.0.1:8001"; extraConfig = '' proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-By $server_addr:$server_port; proxy_set_header X-Forwarded-For $remote_addr; proxy_set_header X-Forwarded-Proto $scheme; ''; }; }; # Needed to grab a cert for the mail server. "mail.fudo.org" = { enableACME = true; # Stopped relocating all because we need /metrics/... paths to remain unforwarded locations."/" = { return = "301 https://webmail.fudo.org$request_uri"; }; }; }; }; }; docker-containers = { archiva = { image = "xetusoss/archiva"; ports = ["127.0.0.1:8001:8080"]; # Ugly: name-to-uid lookup fails. user = toString config.users.users.archiva.uid; volumes = [ "/srv/archiva:/archiva-data" ]; environment = { # Not directly connected to the world anyway SSL_ENABLED = "false"; PROXY_BASE_URL = "https://archiva.fudo.org/"; }; }; }; ### # Minecraft ### fudo.minecraft-server = { enable = true; package = pkgs.minecraft-server_1_16_2; data-dir = minecraft-data-dir; world-name = "selbyland"; motd = "Welcome to the Selby Minecraft server."; }; }