depot/ops/nixos/clouvider-lon01/default.nix

289 lines
7.2 KiB
Nix
Raw Normal View History

2020-11-04 15:51:55 +00:00
# SPDX-FileCopyrightText: 2020 Luke Granger-Brown <depot@lukegb.com>
#
# SPDX-License-Identifier: Apache-2.0
{ depot, lib, pkgs, config, ... }:
2022-04-09 20:51:24 +00:00
{
2020-11-04 15:51:55 +00:00
imports = [
../lib/zfs.nix
../lib/bgp.nix
2021-07-01 01:48:12 +00:00
../lib/minotarproxy.nix
../lib/whitby-distributed.nix
../lib/macmini-distributed.nix
../lib/oracle-lon01-distributed.nix
2021-01-19 23:41:47 +00:00
../lib/quotes.bfob.gg.nix
2021-03-20 02:03:23 +00:00
../lib/coredns/default.nix
2020-11-04 15:51:55 +00:00
];
boot.initrd = {
availableKernelModules = [
"xhci_pci"
"ahci"
"nvme"
"usbhid"
"usb_storage"
"sd_mod"
"sr_mod"
"igb"
];
network = {
enable = true;
ssh = {
enable = true;
hostKeys = ["/persist/etc/ssh/ssh_host_ed25519_key"];
authorizedKeys = map builtins.readFile config.users.users.lukegb.openssh.authorizedKeys.keyFiles;
};
postCommands = ''
echo "zfs load-key -a; killall zfs" >> /root/.profile
'';
};
};
boot.kernelParams = [
"ip=185.198.188.29::185.198.188.28:255.255.255.254:clouvider-lon01:enp1s0f0:none"
];
boot.kernelModules = [ "kvm-intel" ];
powerManagement.cpuFreqGovernor = lib.mkDefault "performance";
fileSystems = let
zfs = device: {
device = device;
fsType = "zfs";
};
in {
"/" = zfs "tank/local/root";
"/nix" = zfs "tank/local/nix";
"/persist" = zfs "tank/safe/persist";
"/home" = zfs "tank/safe/home";
"/boot1" = {
device = "/dev/disk/by-partlabel/boota";
fsType = "vfat";
};
"/boot2" = {
device = "/dev/disk/by-partlabel/bootb";
fsType = "vfat";
};
};
nix.settings.max-jobs = lib.mkDefault 8;
2020-11-04 15:51:55 +00:00
# Use GRUB, so we can have mirrored bootloaders.
boot.loader.efi.canTouchEfiVariables = true;
boot.loader.grub = {
enable = true;
zfsSupport = true;
efiSupport = true;
mirroredBoots = map (path: {
inherit path;
devices = ["nodev"];
efiSysMountPoint = path;
}) ["/boot1" "/boot2"];
};
# Networking!
networking = {
hostName = "clouvider-lon01";
domain = "as205479.net";
hostId = "29aaa324";
nameservers = [
"2001:4860:4860::8888"
"2001:4860:4860::8844"
"8.8.8.8"
"8.8.4.4"
];
defaultGateway = {
address = "185.198.188.28";
interface = "br-ext";
};
defaultGateway6 = {
address = "2a0a:54c0:0:17::1";
interface = "br-ext";
};
bridges.br-ext.interfaces = ["enp1s0f0"];
interfaces.br-ext = {
ipv4.addresses = [{ address = "185.198.188.29"; prefixLength = 31; }];
ipv6.addresses = [{ address = "2a0a:54c0:0:17::2"; prefixLength = 126; }];
};
2020-11-04 16:41:15 +00:00
interfaces.lo = {
2021-07-01 01:48:12 +00:00
ipv4.addresses = [{ address = "127.0.0.1"; prefixLength = 8; }];
2020-11-04 16:41:15 +00:00
ipv6.addresses = [{ address = "::1"; prefixLength = 128; }];
};
firewall = {
allowPing = true;
allowedTCPPorts = [
80 443 # HTTP/nginx
2022-11-24 13:03:16 +00:00
1935 # RTMP/nginx
6697 # znc
34197 # factorio
];
allowedUDPPorts = [
34197 # factorio
];
extraCommands = ''
# Allow SSH on public interfaces.
iptables -A INPUT -p tcp --dport 22 --dst 185.198.188.29 -j ACCEPT
iptables -A INPUT -p tcp --dport 22 --dst ${config.my.ip.tailscale} -j ACCEPT
ip6tables -A INPUT -p tcp --dport 22 --dst 2a0a:54c0:0:17::2 -j ACCEPT
2022-09-01 23:22:16 +00:00
ip6tables -A INPUT -p tcp --dport 22 --dst ${config.my.ip.tailscale6} -j ACCEPT
'';
};
2020-11-04 15:51:55 +00:00
};
2020-11-04 15:53:18 +00:00
my.ip.tailscale = "100.79.173.25";
2022-09-01 23:22:16 +00:00
my.ip.tailscale6 = "fd7a:115c:a1e0:ab12:4843:cd96:624f:ad19";
my.coredns.bind = [ "br-ext" "tailscale0" "127.0.0.1" "::1" ];
2020-11-04 15:51:55 +00:00
services.openssh.openFirewall = false; # allowed by networking.firewall.extraCommands
2020-11-04 15:51:55 +00:00
services.openssh.hostKeys = [
{
path = "/persist/etc/ssh/ssh_host_ed25519_key";
type = "ed25519";
}
{
path = "/persist/etc/ssh/ssh_host_rsa_key";
type = "rsa";
bits = 4096;
}
];
users.users = {
lukegb.extraGroups = [ "bird2" ];
};
2020-11-04 16:27:46 +00:00
users.groups = {
znc-acme = {
members = [ "znc" "nginx" ];
};
};
2020-11-04 15:51:55 +00:00
services.lukegbgp = let local = {
asn = 205479;
}; in {
enable = true;
config = {
local = {
routerID = "185.198.188.29";
};
2020-11-04 16:41:15 +00:00
export = {
v4 = ["92.118.29.0/24"];
2020-11-04 16:41:15 +00:00
};
2020-11-04 15:51:55 +00:00
peering = {
clouvider = {
local = local // {
v4 = "185.198.188.29";
v6 = "2a0a:54c0:0:17::2";
};
remote = {
asn = 62240;
export_community = 3000;
routers = [{
v4 = "185.198.188.28";
v6 = "2a0a:54c0:0:17::1";
}];
};
};
};
};
};
2020-11-04 16:27:46 +00:00
services.znc = {
enable = true;
mutable = true;
dataDir = "/persist/etc/znc";
useLegacyConfig = false;
};
my.vault.acmeCertificates."znc.lukegb.com" = {
hostnames = [ "znc.lukegb.com" "akiichiro.lukegb.com" ];
2022-01-04 14:00:45 +00:00
group = "znc-acme";
2020-11-04 16:27:46 +00:00
};
services.nginx = {
enable = true;
2022-11-24 13:03:16 +00:00
package = pkgs.nginxMainline;
additionalModules = with pkgs.nginxModules; [ rtmp ];
appendConfig = ''
rtmp_auto_push on;
rtmp {
server {
listen 1935;
chunk_size 4096;
application live1 {
allow publish 213.41.69.70;
allow publish 37.26.186.120;
allow publish 94.229.74.42;
live on; record off;
}
}
}
'';
2020-11-04 16:27:46 +00:00
virtualHosts = {
"clouvider-lon01.as205479.net" = {
2021-01-19 23:41:47 +00:00
default = true;
2020-11-04 17:23:52 +00:00
listen = [
{addr = "185.198.188.29"; port = 80; ssl = false;}
{addr = "[2a0a:54c0:0:17::2]"; port = 80; ssl = false;}
];
2020-11-04 16:27:46 +00:00
locations."/.well-known/acme-challenge" = {
root = "/var/lib/acme/.challenges";
};
locations."/" = {
return = "301 https://$host$request_uri";
};
};
};
};
2020-11-24 04:50:31 +00:00
systemd.mounts = let
bindMount' = dir: {
unitConfig.RequiresMountsFor = dir;
options = "bind";
what = "/persist${dir}";
where = dir;
};
bindMountSvc = dir: svc: (bindMount' dir) // {
bindsTo = [svc];
partOf = [svc];
};
bindMountSvcDynamic = dir: svc: (bindMount' "/var/lib/private/${dir}") // {
requiredBy = [svc];
before = [svc];
wantedBy = ["multi-user.target"];
};
bindMount = dir: (bindMount' dir) // {
wantedBy = ["multi-user.target"];
};
in [
(bindMountSvcDynamic "factorio" "factorio.service")
];
services.factorio = {
2022-04-09 20:51:24 +00:00
inherit (depot.ops.secrets.factorio) username token;
2020-11-24 04:50:31 +00:00
enable = true;
package = pkgs.factorio-headless-experimental;
2022-02-05 17:52:06 +00:00
saveName = "lukegb20220131-ws";
2020-11-24 04:50:31 +00:00
game-name = "Briefcase Full of Bees";
extraSettings = {
admins = ["lukegb"];
auto_pause = true;
only_admins_can_pause_the_game = false;
2022-04-09 20:51:24 +00:00
game_password = depot.ops.secrets.factorioServerPassword;
2020-11-24 04:50:31 +00:00
non_blocking_saving = true;
autosave_only_on_server = true;
autosave_interval = 5;
autosave_slots = 60;
};
};
my.quotesdb.listen = [
"185.198.188.29"
"[2a0a:54c0:0:17::2]"
];
environment.systemPackages = [
depot.ops.factorio.multiworld
];
boot.binfmt.emulatedSystems = [ "aarch64-linux" ];
2020-11-04 15:51:55 +00:00
system.stateVersion = "20.09";
}