Merge pull request 'Add NixOS config for nachtigall' (#4) from nachtigall into main

Reviewed-on: pub-solar/infra-new#4
This commit is contained in:
b12f 2023-10-28 00:58:23 +02:00
commit 6cf680a2df
Signed by: pub.solar gitea
GPG key ID: F0332B04B7054873
11 changed files with 424 additions and 62 deletions

View file

@ -32,6 +32,42 @@
"type": "github" "type": "github"
} }
}, },
"deploy-rs": {
"inputs": {
"flake-compat": "flake-compat",
"nixpkgs": "nixpkgs",
"utils": "utils"
},
"locked": {
"lastModified": 1695052866,
"narHash": "sha256-agn7F9Oww4oU6nPiw+YiYI9Xb4vOOE73w8PAoBRP4AA=",
"owner": "serokell",
"repo": "deploy-rs",
"rev": "e3f41832680801d0ee9e2ed33eb63af398b090e9",
"type": "github"
},
"original": {
"owner": "serokell",
"repo": "deploy-rs",
"type": "github"
}
},
"flake-compat": {
"flake": false,
"locked": {
"lastModified": 1668681692,
"narHash": "sha256-Ht91NGdewz8IQLtWZ9LCeNXMSXHUss+9COoqu6JLmXU=",
"owner": "edolstra",
"repo": "flake-compat",
"rev": "009399224d5e398d03b22badca40a37ac85412a1",
"type": "github"
},
"original": {
"owner": "edolstra",
"repo": "flake-compat",
"type": "github"
}
},
"flake-parts": { "flake-parts": {
"inputs": { "inputs": {
"nixpkgs-lib": "nixpkgs-lib" "nixpkgs-lib": "nixpkgs-lib"
@ -123,16 +159,16 @@
}, },
"nixpkgs": { "nixpkgs": {
"locked": { "locked": {
"lastModified": 1690548937, "lastModified": 1671417167,
"narHash": "sha256-x3ZOPGLvtC0/+iFAg9Kvqm/8hTAIkGjc634SqtgaXTA=", "narHash": "sha256-JkHam6WQOwZN1t2C2sbp1TqMv3TVRjzrdoejqfefwrM=",
"owner": "nixos", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "2a9d660ff0f7ffde9d73be328ee6e6f10ef66b28", "rev": "bb31220cca6d044baa6dc2715b07497a2a7c4bc7",
"type": "github" "type": "github"
}, },
"original": { "original": {
"owner": "nixos", "owner": "NixOS",
"ref": "nixos-unstable", "ref": "nixpkgs-unstable",
"repo": "nixpkgs", "repo": "nixpkgs",
"type": "github" "type": "github"
} }
@ -156,6 +192,22 @@
} }
}, },
"nixpkgs_2": { "nixpkgs_2": {
"locked": {
"lastModified": 1690548937,
"narHash": "sha256-x3ZOPGLvtC0/+iFAg9Kvqm/8hTAIkGjc634SqtgaXTA=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "2a9d660ff0f7ffde9d73be328ee6e6f10ef66b28",
"type": "github"
},
"original": {
"owner": "nixos",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs_3": {
"locked": { "locked": {
"lastModified": 1636823747, "lastModified": 1636823747,
"narHash": "sha256-oWo1nElRAOZqEf90Yek2ixdHyjD+gqtS/pAgwaQ9UhQ=", "narHash": "sha256-oWo1nElRAOZqEf90Yek2ixdHyjD+gqtS/pAgwaQ9UhQ=",
@ -172,11 +224,12 @@
}, },
"root": { "root": {
"inputs": { "inputs": {
"deploy-rs": "deploy-rs",
"flake-parts": "flake-parts", "flake-parts": "flake-parts",
"home-manager": "home-manager", "home-manager": "home-manager",
"nix-darwin": "nix-darwin", "nix-darwin": "nix-darwin",
"nixos-flake": "nixos-flake", "nixos-flake": "nixos-flake",
"nixpkgs": "nixpkgs", "nixpkgs": "nixpkgs_2",
"terranix": "terranix" "terranix": "terranix"
} }
}, },
@ -185,7 +238,7 @@
"bats-assert": "bats-assert", "bats-assert": "bats-assert",
"bats-support": "bats-support", "bats-support": "bats-support",
"flake-utils": "flake-utils", "flake-utils": "flake-utils",
"nixpkgs": "nixpkgs_2", "nixpkgs": "nixpkgs_3",
"terranix-examples": "terranix-examples" "terranix-examples": "terranix-examples"
}, },
"locked": { "locked": {
@ -216,6 +269,21 @@
"repo": "terranix-examples", "repo": "terranix-examples",
"type": "github" "type": "github"
} }
},
"utils": {
"locked": {
"lastModified": 1667395993,
"narHash": "sha256-nuEHfE/LcWyuSWnS8t12N1wc105Qtau+/OdUAjtQ0rA=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "5aed5285a952e0b949eb3ba02c12fa4fcfef535f",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
} }
}, },
"root": "root", "root": "root",

102
flake.nix
View file

@ -11,6 +11,8 @@
nixos-flake.url = "github:srid/nixos-flake"; nixos-flake.url = "github:srid/nixos-flake";
terranix.url = "github:terranix/terranix"; terranix.url = "github:terranix/terranix";
deploy-rs.url = "github:serokell/deploy-rs";
}; };
outputs = inputs@{ self, terranix, ... }: outputs = inputs@{ self, terranix, ... }:
@ -19,78 +21,62 @@
imports = [ imports = [
inputs.nixos-flake.flakeModule inputs.nixos-flake.flakeModule
./terraform.nix # ./terraform.nix
./public-keys
./lib
]; ];
perSystem = { config, ... }: { }; perSystem = { config, ... }: { };
flake = flake =
let let
# TODO: Change username username = "barkeeper";
myUserName = "john";
system = "x86_64-linux"; system = "x86_64-linux";
in in {
{
# Configurations for Linux (NixOS) machines
nixosConfigurations = { nixosConfigurations = {
# TODO: Change hostname from "example1" to something else. nachtigall = self.nixos-flake.lib.mkLinuxSystem system {
example1 = self.nixos-flake.lib.mkLinuxSystem "x86_64-linux" {
imports = [ imports = [
self.nixosModules.common # See below for "nixosModules"! self.nixosModules.common
self.nixosModules.linux ./hosts/nachtigall
./hosts/example1/default.nix self.pub-solar.lib.linux.unlockZFSOnBoot
self.nixosModules.home-manager self.nixosModules.home-manager
self.nixosModules.linux
{ {
home-manager.users.${myUserName} = { home-manager.users.${username} = {
imports = [ imports = [
self.homeModules.common # See below for "homeModules"! self.homeModules.common
self.homeModules.linux
]; ];
home.stateVersion = "22.11"; home.stateVersion = "23.05";
}; };
} }
]; ];
}; };
}; };
# Configurations for macOS machines
darwinConfigurations = {
# TODO: Change hostname from "example1" to something else.
example1 = self.nixos-flake.lib.mkMacosSystem "aarch64-darwin" {
imports = [
self.nixosModules.common # See below for "nixosModules"!
self.nixosModules.darwin
./hosts/example1/default.nix
self.darwinModules.home-manager
{
home-manager.users.${myUserName} = {
imports = [
self.homeModules.common # See below for "homeModules"!
self.homeModules.darwin
];
home.stateVersion = "22.11";
};
}
];
};
};
# All nixos/nix-darwin configurations are kept here.
nixosModules = { nixosModules = {
# Common nixos/nix-darwin configuration shared between Linux and macOS. # Common nixos/nix-darwin configuration shared between Linux and macOS.
common = { pkgs, ... }: { common = { pkgs, ... }: {
environment.systemPackages = with pkgs; [ virtualisation.docker.enable = true;
hello services.openssh.enable = true;
]; services.openssh.settings.PermitRootLogin = "prohibit-password";
}; };
# NixOS specific configuration # NixOS specific configuration
linux = { pkgs, ... }: { linux = { pkgs, ... }: {
users.users.${myUserName}.isNormalUser = true; users.users.${username} = {
services.netdata.enable = true; name = username;
}; group = username;
# nix-darwin specific configuration extraGroups = ["wheel"];
darwin = { pkgs, ... }: { isNormalUser = true;
security.pam.enableSudoTouchIdAuth = true; openssh.authorizedKeys.keys = self.publicKeys.allAdmins;
};
users.groups.${username} = {};
security.sudo.wheelNeedsPassword = false;
nix.settings.trusted-users = [ "root" username ];
# TODO: Remove when we stop locking ourselves out.
users.users.root.openssh.authorizedKeys.keys = self.publicKeys.allAdmins;
}; };
}; };
@ -101,14 +87,22 @@
programs.git.enable = true; programs.git.enable = true;
programs.starship.enable = true; programs.starship.enable = true;
programs.bash.enable = true; programs.bash.enable = true;
programs.neovim = {
enable = true;
vimAlias = true;
viAlias = true;
defaultEditor = true;
# configure = {
# packages.myVimPackages = with pkgs.vimPlugins; {
# start = [vim-nix vim-surrund rainbow];
# };
# };
};
}; };
# home-manager config specific to NixOS };
linux = { deploy.nodes = self.pub-solar.lib.deploy.mkDeployNodes self.nixosConfigurations {
xsession.enable = true; nachtigall = {
}; sshUser = username;
# home-manager config specifi to Darwin
darwin = {
targets.darwin.search = "Bing";
}; };
}; };
}; };

View file

@ -0,0 +1,94 @@
{ config, pkgs, ... }:
{
imports =
[ # Include the results of the hardware scan.
./hardware-configuration.nix
];
# Use GRUB2 as the boot loader.
# We don't use systemd-boot because Hetzner uses BIOS legacy boot.
boot.loader.systemd-boot.enable = false;
boot.loader.grub = {
enable = true;
efiSupport = false;
mirroredBoots = [
{
devices = [
"/dev/disk/by-id/nvme-SAMSUNG_MZVL21T0HCLR-00B00_S676NF0R517371"
];
path = "/boot1";
}
{
devices = [
"/dev/disk/by-id/nvme-KXG60ZNV1T02_TOSHIBA_Z9NF704ZF9ZL"
];
path = "/boot2";
}
];
copyKernels = true;
};
boot.supportedFilesystems = [ "zfs" ];
boot.kernelParams = [
"boot.shell_on_fail=1"
"ip=138.201.80.102::138.201.80.65:255.255.255.192:nachtigall::off"
];
boot.initrd.availableKernelModules = [ "igb" ];
networking.hostName = "nachtigall";
networking.domain = "pub.solar";
networking.hostId = "00000001";
# enable flakes by default
nix = {
package = pkgs.nixFlakes;
extraOptions = ''
experimental-features = nix-command flakes
'';
};
# Set your time zone.
time.timeZone = "Etc/UTC";
environment = {
# just a couple of packages to make our lives easier
systemPackages = with pkgs; [ vim ];
};
# Network (Hetzner uses static IP assignments, and we don't use DHCP here)
networking.useDHCP = false;
networking.interfaces."enp35s0".ipv4.addresses = [
{
address = "138.201.80.102";
prefixLength = 26;
}
];
networking.interfaces."enp35s0".ipv6.addresses = [
{
address = "2a01:4f8:172:1c25::1";
prefixLength = 64;
}
];
networking.defaultGateway = "138.201.80.65";
networking.defaultGateway6 = { address = "fe80::1"; interface = "enp35s0"; };
services.resolved = {
enable = true;
extraConfig = ''
DNS=9.9.9.9#dns.quad9.net 149.112.112.112#dns.quad9.net 2620:fe::fe#dns.quad9.net 2620:fe::9#dns.quad9.net 193.110.81.0#dns0.eu 185.253.5.0#dns0.eu 2a0f:fc80::#dns0.eu 2a0f:fc81::#dns0.eu
FallbackDNS=5.1.66.255#dot.ffmuc.net 185.150.99.255#dot.ffmuc.net 2001:678:e68:f000::#dot.ffmuc.net 2001:678:ed0:f000::#dot.ffmuc.net
Domains=~.
DNSOverTLS=yes
'';
};
users.users.root.initialHashedPassword = "$y$j9T$bIN6GjQkmPMllOcQsq52K0$q0Z5B5.KW/uxXK9fItB8H6HO79RYAcI/ZZdB0Djke32";
# This value determines the NixOS release with which your system is to be
# compatible, in order to avoid breaking some software such as database
# servers. You should change this only after NixOS release notes say you
# should.
system.stateVersion = "23.05"; # Did you read the comment?
}

View file

@ -0,0 +1,48 @@
# Do not modify this file! It was generated by nixos-generate-config
# and may be overwritten by future invocations. Please make changes
# to /etc/nixos/configuration.nix instead.
{ config, lib, pkgs, modulesPath, ... }:
{
imports =
[ (modulesPath + "/installer/scan/not-detected.nix")
];
boot.initrd.availableKernelModules = [ "ahci" "nvme" ];
boot.initrd.kernelModules = [ ];
boot.kernelModules = [ "kvm-amd" ];
boot.extraModulePackages = [ ];
fileSystems."/" =
{ device = "root_pool/root";
fsType = "zfs";
};
fileSystems."/var/lib/postgresql" =
{ device = "root_pool/data/postgresql";
fsType = "zfs";
};
fileSystems."/boot1" =
{ device = "/dev/disk/by-uuid/5493-EFF5";
fsType = "vfat";
};
fileSystems."/boot2" =
{ device = "/dev/disk/by-uuid/5494-BA1E";
fsType = "vfat";
};
swapDevices = [ ];
# Enables DHCP on each ethernet and wireless interface. In case of scripted networking
# (the default) this is the recommended approach. When using systemd-networkd it's
# still possible to use this option, but it's recommended to use it in conjunction
# with explicit per-interface declarations with `networking.interfaces.<interface>.useDHCP`.
networking.useDHCP = lib.mkDefault true;
# networking.interfaces.eth0.useDHCP = lib.mkDefault true;
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
powerManagement.cpuFreqGovernor = lib.mkDefault "ondemand";
hardware.cpu.amd.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
}

21
lib/compat/default.nix Normal file
View file

@ -0,0 +1,21 @@
let
lock = builtins.fromJSON (builtins.readFile builtins.path {
path = ../../flake.lock;
name = "lockPath";
});
flake =
import
(
fetchTarball {
url = "https://github.com/edolstra/flake-compat/archive/${lock.nodes.flake-compat.locked.rev}.tar.gz";
sha256 = lock.nodes.flake-compat.locked.narHash;
}
)
{
src = builtins.path {
path = ../../.;
name = "projectRoot";
};
};
in
flake

View file

@ -0,0 +1,9 @@
{...}: let
inherit (default.inputs.nixos) lib;
host = configs.${hostname} or configs.PubSolarOS;
configs = default.nixosConfigurations;
default = (import ../.).defaultNix;
hostname = lib.fileContents /etc/hostname;
in
host

20
lib/default.nix Normal file
View file

@ -0,0 +1,20 @@
{ self, lib, inputs, ... }: {
# Configuration common to all Linux systems
flake = {
pub-solar.lib = let
callLibs = file: import file {inherit lib;};
in rec {
## Define your own library functions here!
#id = x: x;
## Or in files, containing functions that take {lib}
#foo = callLibs ./foo.nix;
## In configs, they can be used under "lib.our"
deploy = import ./deploy.nix { inherit inputs lib; };
linux = {
unlockZFSOnBoot = import ./unlock-zfs-on-boot.nix {publicKeys = self.publicKeys.allAdmins;};
};
};
};
}

62
lib/deploy.nix Normal file
View file

@ -0,0 +1,62 @@
/*
* The contents of this file are adapted from digga
* https://github.com/divnix/digga
*
* Licensed under the MIT license
*/
{ lib, inputs }: let
getFqdn = c: let
net = c.config.networking;
fqdn =
if (net ? domain) && (net.domain != null)
then "${net.hostName}.${net.domain}"
else net.hostName;
in
fqdn;
in {
mkDeployNodes = systemConfigurations: extraConfig:
/*
*
Synopsis: mkNodes _systemConfigurations_ _extraConfig_
Generate the `nodes` attribute expected by deploy-rs
where _systemConfigurations_ are `nodes`.
_systemConfigurations_ should take the form of a flake's
_nixosConfigurations_. Note that deploy-rs does not currently support
deploying to darwin hosts.
_extraConfig_, if specified, will be merged into each of the
nodes' configurations.
Example _systemConfigurations_ input:
```
{
hostname-1 = {
fastConnection = true;
sshOpts = [ "-p" "25" ];
};
hostname-2 = {
sshOpts = [ "-p" "19999" ];
sshUser = "root";
};
}
```
*
*/
lib.recursiveUpdate
(lib.mapAttrs
(
_: c: {
hostname = getFqdn c;
profiles.system = {
user = "root";
path = inputs.deploy-rs.lib.${c.pkgs.stdenv.hostPlatform.system}.activate.nixos c;
};
}
)
systemConfigurations)
extraConfig;
}

View file

@ -0,0 +1,29 @@
{publicKeys}: {
# From https://nixos.wiki/wiki/ZFS#Unlock_encrypted_zfs_via_ssh_on_boot
boot.initrd.network = {
enable = true;
ssh = {
enable = true;
# To prevent ssh clients from freaking out because a different host key is used,
# a different port for ssh is useful (assuming the same host has also a regular sshd running)
port = 2222;
# Please create this manually the first time.
hostKeys = [ "/etc/secrets/initrd/ssh_host_ed25519_key" ];
authorizedKeys = publicKeys;
};
# this will automatically load the zfs password prompt on login
# and kill the other prompt so boot can continue
postCommands = ''
cat <<EOF > /root/.profile
if pgrep -x "zfs" > /dev/null
then
zfs load-key -a
killall zfs
else
echo "zfs not running -- maybe the pool is taking some time to load for some unforseen reason."
fi
EOF
'';
};
}

9
public-keys/admins.nix Normal file
View file

@ -0,0 +1,9 @@
{
axeman-1 = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMNeQYLFauAbzDyIbKC86NUh9yZfiyBm/BtIdkcpZnSU axeman@tuxnix";
b12f-1 = "ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBHx4A8rLYmFgTOp1fDGbbONN8SOT0l5wWrUSYFUcVzMPTyfdT23ZVIdVD5yZCySgi/7PSh5mVmyLIZVIXlNrZJg= @b12f Yubi Main";
b12f-2 = "ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBEST9eyAY3nzGYNnqDYfWHu+89LZsOjyKHMqCFvtP7vrgB7F7JbbECjdjAXEOfPDSCVwtMMpq8JJXeRMjpsD0rw= @b12f Yubi Backup";
hensoko-1 = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEbaQdxp7Flz6ttELe63rn+Nt9g43qJOLih6VCMP4gPb";
hensoko-2 = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAqkqMYgncrnczcW/0PY+Z+FmNXXpgw6D9JWTTwiainy";
teutat3s-1 = "ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBFro/k4Mgqyh8yV/7Zwjc0dv60ZM7bROBU9JNd99P/4co6fxPt1pJiU/pEz2Dax/HODxgcO+jFZfvPEuLMCeAl0= YubiKey #10593996 PIV Slot 9a";
}

8
public-keys/default.nix Normal file
View file

@ -0,0 +1,8 @@
{lib, ...}:
{
flake = {
publicKeys = {
allAdmins = lib.attrsets.attrValues (import ./admins.nix);
};
};
}