nixos-config/hosts/france.nix

592 lines
15 KiB
Nix
Raw Normal View History

2020-01-15 09:24:11 -08:00
{ config, pkgs, lib, ... }:
2019-12-25 15:20:36 -08:00
2020-01-15 09:24:11 -08:00
with lib;
2019-12-25 15:20:36 -08:00
let
2020-02-03 17:07:46 -08:00
domain = "fudo.org";
hostname = "france.${domain}";
2020-07-26 08:22:28 -07:00
mail-hostname = "mail.${domain}";
2020-01-15 09:24:11 -08:00
host_ipv4 = "208.81.3.117";
2020-06-06 18:58:13 -07:00
# Use a special IP for git.fudo.org, since it needs to be SSH-able
2020-11-19 14:21:18 -08:00
link_ipv4 = "208.81.3.126";
all-hostnames = [ ];
2019-12-25 15:20:36 -08:00
2020-01-15 09:24:11 -08:00
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";
2019-12-25 15:20:36 -08:00
2020-01-15 09:24:11 -08:00
minecraft-data-dir = "/srv/minecraft/data";
2019-12-25 15:20:36 -08:00
2020-01-15 09:24:11 -08:00
system-mail-directory = "/srv/mail";
in {
boot.loader.grub = {
enable = true;
version = 2;
device = "/dev/sda";
};
2019-12-25 15:20:36 -08:00
imports = [
../hardware-configuration.nix
2020-01-15 09:24:11 -08:00
../defaults.nix
2020-09-29 09:08:48 -07:00
./france/jabber.nix
2020-11-17 15:29:44 -08:00
./france/backplane.nix
./france/selby-forum.nix
2020-09-29 09:08:48 -07:00
];
environment.systemPackages = with pkgs; [
docker
lxd
multipath-tools
nix-prefetch-docker
2020-11-19 14:21:18 -08:00
powerdns
2020-09-29 09:08:48 -07:00
tshark
2020-01-15 09:24:11 -08:00
];
2020-02-03 17:07:46 -08:00
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" ];
2020-02-03 17:07:46 -08:00
};
2019-12-25 15:20:36 -08:00
2020-01-15 09:24:11 -08:00
fudo.prometheus = {
2019-12-25 15:20:36 -08:00
enable = true;
2020-01-15 09:24:11 -08:00
hostname = "metrics.fudo.org";
service-discovery-dns = {
node = [ "node._metrics._tcp.fudo.org" ];
2020-01-15 09:24:11 -08:00
postfix = [ "postfix._metrics._tcp.fudo.org" ];
dovecot = [ "dovecot._metrics._tcp.fudo.org" ];
rspamd = [ "rspamd._metrics._tcp.fudo.org" ];
2020-01-15 09:24:11 -08:00
};
};
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";
2020-02-03 17:07:46 -08:00
database = {
name = "grafana";
hostname = "localhost";
user = "grafana";
password-file = /srv/grafana/secure/db.passwd;
};
2020-01-15 09:24:11 -08:00
};
# So that grafana waits for postgresql
systemd.services.grafana.after = [ "postgresql.service" ];
2020-01-15 09:24:11 -08:00
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.
#
2020-02-03 17:07:46 -08:00
# TODO: that's probably too strict, allow kerberos connections from anywhere?
2020-01-15 09:24:11 -08:00
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"
];
2020-02-03 17:07:46 -08:00
users = {
2020-06-06 18:58:13 -07:00
fudo_git = {
2020-11-17 15:29:44 -08:00
password-file = "/srv/git/secure/db.passwd";
2020-06-06 18:58:13 -07:00
databases = {
2020-11-17 15:29:44 -08:00
fudo_git = {
access = "CONNECT";
entity-access = {
"ALL TABLES IN SCHEMA public" = "SELECT,INSERT,UPDATE,DELETE";
"ALL SEQUENCES IN SCHEMA public" = "SELECT,UPDATE";
};
};
2020-06-06 18:58:13 -07:00
};
};
2020-02-03 17:07:46 -08:00
grafana = {
2020-11-17 15:29:44 -08:00
password-file = "/srv/grafana/secure/db.passwd";
2020-02-03 17:07:46 -08:00
databases = {
2020-11-17 15:29:44 -08:00
grafana = {
access = "CONNECT";
entity-access = {
"ALL TABLES IN SCHEMA public" = "SELECT,INSERT,UPDATE,DELETE";
"ALL SEQUENCES IN SCHEMA public" = "SELECT,UPDATE";
};
};
2020-02-03 17:07:46 -08:00
};
};
mattermost = {
2020-11-17 15:29:44 -08:00
password-file = "/srv/mattermost/secure/db.passwd";
2020-02-03 17:07:46 -08:00
databases = {
2020-11-17 15:29:44 -08:00
mattermost = {
access = "CONNECT";
entity-access = {
"ALL TABLES IN SCHEMA public" = "SELECT,INSERT,UPDATE,DELETE";
"ALL SEQUENCES IN SCHEMA public" = "SELECT,UPDATE";
};
};
2020-02-03 17:07:46 -08:00
};
};
webmail = {
2020-11-17 15:29:44 -08:00
password-file = "/srv/webmail/secure/db.passwd";
2020-02-03 17:07:46 -08:00
databases = {
2020-11-17 15:29:44 -08:00
webmail = {
access = "CONNECT";
entity-access = {
"ALL TABLES IN SCHEMA public" = "SELECT,INSERT,UPDATE,DELETE";
"ALL SEQUENCES IN SCHEMA public" = "SELECT,UPDATE";
};
};
2020-02-03 17:07:46 -08:00
};
};
niten = { };
2020-02-03 17:07:46 -08:00
};
local-users = [ "niten" "fudo_git" ];
2020-06-06 18:58:13 -07:00
2020-02-03 17:07:46 -08:00
databases = {
fudo_git = { users = [ "niten" ]; };
grafana = { users = [ "niten" ]; };
mattermost = { users = [ "niten" ]; };
webmail = { users = [ "niten" ]; };
2020-02-03 17:07:46 -08:00
};
2020-01-15 09:24:11 -08:00
};
fudo.dns = {
enable = true;
2020-11-17 15:29:44 -08:00
identity = "france.fudo.org";
2020-11-17 15:29:44 -08:00
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 ];
2020-11-17 15:29:44 -08:00
domains = { "fudo.org" = import ../fudo/fudo.org.nix { inherit config; }; };
};
2020-11-17 15:29:44 -08:00
2020-01-15 09:24:11 -08:00
# 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:///" ];
2020-01-15 09:24:11 -08:00
users = import ../fudo/users.nix;
groups = import ../fudo/groups.nix;
2019-12-25 15:20:36 -08:00
2020-01-15 09:24:11 -08:00
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" ];
2020-01-15 09:24:11 -08:00
};
};
# TODO: not used yet
fudo.acme.hostnames = all-hostnames;
2020-11-19 14:21:18 -08:00
fudo.client.dns = {
enable = true;
ipv4 = true;
ipv6 = true;
user = "fudo-client";
external-interface = "extif0";
password-file = "/srv/client/secure/client.passwd";
};
2020-01-15 09:24:11 -08:00
fudo.mail-server = import ../fudo/email.nix { inherit config; } // {
enableContainer = true;
debug = false;
2020-01-15 09:24:11 -08:00
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";
2019-12-25 15:20:36 -08:00
2020-07-20 23:16:30 -07:00
dovecot.ldap = {
reader-dn = "cn=user_db_reader,dc=fudo,dc=org";
reader-passwd = fileContents /srv/ldap/secure/user_db.passwd;
2019-12-25 15:20:36 -08:00
2020-07-20 23:16:30 -07:00
# FIXME: use SSL once I can figure out Acme SSL cert CA for LDAP.
server-urls = [ "ldap://france.fudo.org" ];
};
2020-01-15 09:24:11 -08:00
clamav.enable = true;
dkim.signing = true;
2019-12-25 15:20:36 -08:00
};
2020-02-03 17:07:46 -08:00
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";
2020-02-18 10:58:47 -08:00
password-file = "/srv/webmail/secure/db.passwd";
2020-02-03 17:07:46 -08:00
};
};
2020-06-06 18:58:13 -07:00
"webmail.test.fudo.org" = {
title = "Fudo Webmail";
favicon = "/etc/nixos/static/fudo.org/favicon.ico";
2020-07-26 08:22:28 -07:00
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;
2020-07-20 10:12:09 -07:00
domain = "fudo.org";
2020-06-06 18:58:13 -07:00
edit-mode = "Plain";
database = {
name = "webmail";
hostname = "localhost";
user = "webmail";
2020-07-20 23:16:30 -07:00
password-file = "/srv/webmail/secure/db.passwd";
2020-06-06 18:58:13 -07:00
};
};
"webmail.test.selby.ca" = {
title = "Selby Webmail";
favicon = "/etc/nixos/static/selby.ca/favicon.ico";
2020-07-26 08:22:28 -07:00
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;
2020-07-20 10:12:09 -07:00
domain = "selby.ca";
2020-06-06 18:58:13 -07:00
database = {
name = "webmail";
hostname = "localhost";
user = "webmail";
2020-07-20 23:16:30 -07:00
password-file = "/srv/webmail/secure/db.passwd";
2020-06-06 18:58:13 -07:00
};
};
2020-02-03 17:07:46 -08:00
};
};
fudo.chat = {
enable = true;
hostname = "chat.fudo.org";
site-name = "Fudo Chat";
2020-07-26 08:22:28 -07:00
smtp-server = "mail.fudo.org";
2020-02-03 17:07:46 -08:00
smtp-user = "chat";
2020-02-18 10:58:47 -08:00
smtp-password-file = "/srv/mattermost/secure/smtp.passwd";
2020-02-03 17:07:46 -08:00
database = {
name = "mattermost";
hostname = "localhost";
user = "mattermost";
2020-02-18 10:58:47 -08:00
password-file = "/srv/mattermost/secure/db.passwd";
2020-02-03 17:07:46 -08:00
};
};
2020-06-06 18:58:13 -07:00
fudo.git = {
enable = true;
2020-07-20 17:16:52 -07:00
hostname = "git.fudo.org";
2020-06-06 18:58:13 -07:00
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;
2020-07-20 17:16:52 -07:00
ssh = {
2020-11-19 14:21:18 -08:00
listen-ip = link_ipv4;
2020-07-20 17:16:52 -07:00
listen-port = 2222;
};
2020-06-06 18:58:13 -07:00
};
2019-12-25 15:20:36 -08:00
networking = {
hostName = hostname;
dhcpcd.enable = false;
useDHCP = false;
2020-01-15 09:24:11 -08:00
# TODO: fix IPv6
2020-09-29 09:08:48 -07:00
enableIPv6 = true;
2019-12-25 15:20:36 -08:00
# Create a bridge for VMs to use
macvlans = {
extif0 = {
interface = "enp4s0f0";
mode = "bridge";
};
2020-06-06 18:58:13 -07:00
extif1 = {
interface = "enp4s0f0";
mode = "bridge";
};
2019-12-25 15:20:36 -08:00
intif0 = {
interface = "enp4s0f1";
mode = "bridge";
};
};
interfaces = {
extif0 = {
2020-06-06 18:58:13 -07:00
# result of:
# echo $FQDN-extif|md5sum|sed 's/^\(..\)\(..\)\(..\)\(..\)\(..\).*$/02:\1:\2:\3:\4:\5/'
2019-12-25 15:20:36 -08:00
macAddress = "02:d4:e8:3b:10:2f";
ipv4.addresses = [{
address = host_ipv4;
prefixLength = 28;
}];
2019-12-25 15:20:36 -08:00
};
2020-06-06 18:58:13 -07:00
extif1 = {
macAddress = "02:6d:e2:e1:ad:ca";
ipv4.addresses = [{
address = link_ipv4;
prefixLength = 28;
}];
2020-06-06 18:58:13 -07:00
};
2019-12-25 15:20:36 -08:00
intif0 = {
2020-06-06 18:58:13 -07:00
# result of:
# echo $FQDN-intif|md5sum|sed 's/^\(..\)\(..\)\(..\)\(..\)\(..\).*$/02:\1:\2:\3:\4:\5/'
2019-12-25 15:20:36 -08:00
macAddress = "02:ba:ba:e9:08:21";
ipv4.addresses = [{
address = "192.168.11.1";
prefixLength = 24;
}];
2019-12-25 15:20:36 -08:00
};
};
};
hardware.bluetooth.enable = false;
2020-01-15 09:24:11 -08:00
virtualisation = {
docker = {
enable = true;
enableOnBoot = true;
autoPrune = { enable = true; };
2020-01-15 09:24:11 -08:00
};
2020-06-06 18:58:13 -07:00
lxd = { enable = true; };
2020-01-15 09:24:11 -08:00
};
fileSystems = {
"/srv/archiva" = {
fsType = "btrfs";
options = [ "subvol=archiva" ];
2020-01-15 09:24:11 -08:00
label = "pool0";
};
"/srv/grafana" = {
fsType = "btrfs";
options = [ "subvol=grafana" ];
2020-01-15 09:24:11 -08:00
label = "pool0";
};
"${system-mail-directory}" = {
fsType = "btrfs";
options = [ "subvol=mail" ];
2020-01-15 09:24:11 -08:00
label = "pool0";
};
"/srv/gitlab" = {
fsType = "btrfs";
options = [ "subvol=gitlab" ];
2020-01-15 09:24:11 -08:00
label = "pool0";
};
2020-02-03 17:07:46 -08:00
"/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";
};
2020-01-15 09:24:11 -08:00
};
2020-06-06 18:58:13 -07:00
users = {
extraUsers = {
archiva = {
isNormalUser = false;
group = "nogroup";
uid = 8001;
};
2020-01-15 09:24:11 -08:00
2020-06-06 18:58:13 -07:00
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;
2020-09-29 09:08:48 -07:00
"mail.fudo.org".email = config.fudo.common.admin-email;
2020-06-06 18:58:13 -07:00
};
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;
'';
2020-06-06 18:58:13 -07:00
};
};
2020-07-26 08:22:28 -07:00
# Needed to grab a cert for the mail server.
"mail.fudo.org" = {
enableACME = true;
2020-09-29 09:08:48 -07:00
# Stopped relocating all because we need /metrics/... paths to remain unforwarded
locations."/" = {
return = "301 https://webmail.fudo.org$request_uri";
};
2020-07-26 08:22:28 -07:00
};
2020-06-06 18:58:13 -07:00
};
2020-01-15 09:24:11 -08:00
};
};
docker-containers = {
archiva = {
image = "xetusoss/archiva";
ports = [ "127.0.0.1:8001:8080" ];
2020-06-06 18:58:13 -07:00
# Ugly: name-to-uid lookup fails.
user = toString config.users.users.archiva.uid;
volumes = [ "/srv/archiva:/archiva-data" ];
2020-01-15 09:24:11 -08:00
environment = {
# Not directly connected to the world anyway
SSL_ENABLED = "false";
2020-09-29 09:08:48 -07:00
PROXY_BASE_URL = "https://archiva.fudo.org/";
2020-01-15 09:24:11 -08:00
};
};
};
###
# Minecraft
###
fudo.minecraft-server = {
2019-12-25 15:20:36 -08:00
enable = true;
2020-09-29 09:08:48 -07:00
package = pkgs.minecraft-server_1_16_2;
2020-01-15 09:24:11 -08:00
data-dir = minecraft-data-dir;
world-name = "selbyland";
motd = "Welcome to the Selby Minecraft server.";
2019-12-25 15:20:36 -08:00
};
}