{ 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 link_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 ./france/selby-forum.nix ]; environment.systemPackages = with pkgs; [ docker lxd multipath-tools nix-prefetch-docker powerdns tshark vanilla-forum ]; 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; identity = "france.fudo.org"; nameservers = { ns1 = { ip-addresses = [ "208.81.3.117" ]; ipv6-addresses = [ "2605:e200:d200:1:5054:ff:fe8c:9738" ]; description = "Nameserver 1, france, in Winnipeg, MB, CA"; rp = "reaper reaper.rp"; }; ns2 = { ip-addresses = [ "209.117.102.102" ]; ipv6-addresses = [ "2001:470:1f16:40::2" ]; description = "Nameserver 2, musashi, in Winnipeg, MB, CA"; rp = "reaper reaper.rp"; }; ns3 = { ip-addresses = [ "104.131.53.95" ]; ipv6-addresses = [ "2604:a880:800:10::8:7001" ]; description = "Nameserver 3, ns2.henchmman21.net, in New York City, NY, US"; rp = "reaper reaper.rp"; }; ns4 = { ip-addresses = [ "204.42.254.5" ]; ipv6-addresses = [ "2001:418:3f4::5" ]; description = "Nameserver 4, puck.nether.net, in Chicago, IL, US"; rp = "reaper reaper.rp"; }; }; listen-ips = [ host_ipv4 ]; domains = { "fudo.org" = import ../fudo/fudo.org.nix { inherit 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.client.dns = { enable = true; ipv4 = true; ipv6 = true; user = "fudo-client"; external-interface = "extif0"; password-file = "/srv/client/secure/client.passwd"; }; 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 = link_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 = link_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/"; }; }; }; fudo.ipfs = { enable = true; users = [ "niten" "reaper" ]; api-address = "/ip4/${host_ipv4}/tcp/5001"; }; ### # Minecraft ### fudo.minecraft-server = { enable = true; package = pkgs.minecraft-server_1_16_4; data-dir = minecraft-data-dir; world-name = "selbyland"; motd = "Welcome to the Selby Minecraft server."; }; }