1
1
Fork 1
mirror of https://github.com/oddlama/nix-config.git synced 2025-10-10 23:00:39 +02:00

refactor: add lib extensions to nixpkgs.lib as overlays

This commit is contained in:
oddlama 2023-07-02 00:08:17 +02:00
parent 385d8178a2
commit e1e7516e1a
No known key found for this signature in database
GPG key ID: 14EFE510775FE39A
19 changed files with 743 additions and 813 deletions

View file

@ -2,12 +2,12 @@
This is my personal nix config. It's still in the making, but this is what I got so far:
- Full disk encryption using [disko](https://github.com/nix-community/disko), remotely unlockable via ssh
- Zoned nftables firewall
- Service isolation using [microvms](https://github.com/astro/microvm.nix) instead of containers
- Log and system monitoring via loki, telegraf, influxdb, promtail and grafana
- Single-Sign-On for all services using oauth2 via kanidm
- Automatic wireguard mesh generation
- Full disk encryption using [disko](https://github.com/nix-community/disko), remotely unlockable via ssh
- Zoned nftables firewall via [nixos-nftables-firewall](https://github.com/thelegy/nixos-nftables-firewall)
- Service isolation using [microvms](https://github.com/astro/microvm.nix) instead of containers
- Secret rekeying, generation and bootstrapping using [agenix-rekey](https://github.com/oddlama/agenix-rekey)
- Support for repository-wide secrets at evaluation time (hides PII like MACs)

View file

@ -131,7 +131,10 @@
pkgs = import nixpkgs {
localSystem = system;
config.allowUnfree = true;
overlays = [microvm.overlay] ++ import ./pkgs/default.nix;
overlays =
import ./lib inputs
++ import ./pkgs/default.nix
++ [microvm.overlay];
};
apps =

View file

@ -1,16 +1,14 @@
{
inputs,
config,
lib,
...
}: let
disko = import ../../lib/disko.nix inputs;
in {
}: {
disko.devices = {
disk = {
m2-ssd = {
type = "disk";
device = "/dev/disk/by-id/${config.repo.secrets.local.disk.m2-ssd}";
content = with disko.gpt; {
content = with lib.disko.gpt; {
type = "table";
format = "gpt";
partitions = [
@ -21,7 +19,7 @@ in {
boot-ssd = {
type = "disk";
device = "/dev/disk/by-id/${config.repo.secrets.local.disk.boot-ssd}";
content = with disko.gpt; {
content = with lib.disko.gpt; {
type = "table";
format = "gpt";
partitions = [
@ -31,7 +29,7 @@ in {
};
};
};
zpool = with disko.zfs; {
zpool = with lib.disko.zfs; {
rpool = defaultZpoolOptions // {datasets = defaultZfsDatasets;};
};
};

View file

@ -1,16 +1,14 @@
{
config,
inputs,
lib,
...
}: let
disko = import ../../lib/disko.nix inputs;
in {
}: {
disko.devices = {
disk = {
main = {
type = "disk";
device = "/dev/disk/by-id/${config.repo.secrets.local.disk.main}";
content = with disko.gpt; {
content = with lib.disko.gpt; {
type = "table";
format = "gpt";
partitions = [
@ -21,7 +19,7 @@ in {
};
};
};
zpool = with disko.zfs; {
zpool = with lib.disko.zfs; {
rpool = defaultZpoolOptions // {datasets = defaultZfsDatasets;};
};
};

View file

@ -1,18 +1,15 @@
{
config,
inputs,
lib,
pkgs,
...
}: let
disko = import ../../lib/disko.nix inputs;
in {
}: {
disko.devices = {
disk = {
m2-ssd = {
type = "disk";
device = "/dev/disk/by-id/${config.repo.secrets.local.disk.m2-ssd}";
content = with disko.gpt; {
content = with lib.disko.gpt; {
type = "table";
format = "gpt";
partitions = [
@ -23,7 +20,7 @@ in {
};
};
};
zpool = with disko.zfs; {
zpool = with lib.disko.zfs; {
rpool =
defaultZpoolOptions
// {

View file

@ -1,15 +1,9 @@
{
config,
inputs,
lib,
utils,
...
}: let
inherit
(import ../../lib/net.nix inputs)
cidr
;
lanCidrv4 = "192.168.100.0/24";
lanCidrv6 = "fd10::/64";
in {
@ -60,8 +54,8 @@ in {
};
"20-lan-self" = {
address = [
(cidr.hostCidr 1 lanCidrv4)
(cidr.hostCidr 1 lanCidrv6)
(lib.net.cidr.hostCidr 1 lanCidrv4)
(lib.net.cidr.hostCidr 1 lanCidrv6)
];
matchConfig.Name = "lan-self";
networkConfig = {
@ -84,7 +78,7 @@ in {
ipv6SendRAConfig = {
EmitDNS = true;
# TODO change to self later
#DNS = cidr.host 1 net.lan.ipv6cidr;
#DNS = lib.net.cidr.host 1 net.lan.ipv6cidr;
DNS = ["2606:4700:4700::1111" "2001:4860:4860::8888"];
};
linkConfig.RequiredForOnline = "routable";
@ -160,12 +154,12 @@ in {
interface = "lan-self";
subnet = lanCidrv4;
pools = [
{pool = "${cidr.host 20 lanCidrv4} - ${cidr.host (-6) lanCidrv4}";}
{pool = "${lib.net.cidr.host 20 lanCidrv4} - ${lib.net.cidr.host (-6) lanCidrv4}";}
];
option-data = [
{
name = "routers";
data = cidr.host 1 lanCidrv4;
data = lib.net.cidr.host 1 lanCidrv4;
}
];
}

View file

@ -1,14 +1,8 @@
{
config,
inputs,
lib,
...
}: let
inherit
(import ../../lib/net.nix inputs)
cidr
;
iotCidrv4 = "10.90.0.0/24";
iotCidrv6 = "fd00:90::/64";
in {
@ -31,8 +25,8 @@ in {
};
"10-wlan1" = {
address = [
(cidr.hostCidr 1 iotCidrv4)
(cidr.hostCidr 1 iotCidrv6)
(lib.net.cidr.hostCidr 1 iotCidrv4)
(lib.net.cidr.hostCidr 1 iotCidrv6)
];
matchConfig.MACAddress = config.repo.secrets.local.networking.interfaces.wlan1.mac;
linkConfig.RequiredForOnline = "no";

7
lib/default.nix Normal file
View file

@ -0,0 +1,7 @@
inputs: [
(import ./disko.nix inputs)
(import ./misc.nix inputs)
(import ./net.nix inputs)
(import ./types.nix inputs)
(import ./wireguard.nix inputs)
]

View file

@ -1,4 +1,8 @@
inputs: {
inputs: self: super: {
lib =
super.lib
// {
disko = {
gpt = {
partGrub = name: start: end: {
inherit name start end;
@ -78,4 +82,6 @@ inputs: {
inherit mountpoint;
};
};
};
};
}

View file

@ -1,54 +1,25 @@
inputs: let
inputs: self: super: let
inherit
(inputs.nixpkgs.lib)
all
any
assertMsg
attrNames
attrValues
concatLists
concatMap
(super.lib)
concatMapStrings
concatStringsSep
elem
escapeShellArg
filter
flatten
flip
foldAttrs
foldl'
genAttrs
genList
hasInfix
head
isAttrs
mapAttrs'
mergeAttrs
min
mkMerge
mkOptionType
nameValuePair
optionalAttrs
partition
range
recursiveUpdate
removeSuffix
reverseList
showOption
splitString
stringToCharacters
substring
types
unique
warnIf
;
in rec {
# Counts how often each element occurrs in xs
countOccurrences = let
addOrUpdate = acc: x:
acc // {${x} = (acc.${x} or 0) + 1;};
in
foldl' addOrUpdate {};
# Counts how often each element occurrs in xs.
# Elements must be strings.
countOccurrences =
foldl'
(acc: x: acc // {${x} = (acc.${x} or 0) + 1;})
{};
# Returns all elements in xs that occur at least twice
duplicates = xs: let
@ -70,10 +41,7 @@ in rec {
# Calculates base^exp, but careful, this overflows for results > 2^62
pow = base: exp: foldl' (a: x: x * a) 1 (genList (_: base) exp);
# Converts the given hex string to an integer. Only reliable for inputs in [0, 2^63),
# after that the sign bit will overflow.
hexToDec = v: let
literalValues = {
hexLiteralValues = {
"0" = 0;
"1" = 1;
"2" = 2;
@ -97,9 +65,28 @@ in rec {
"E" = 14;
"F" = 15;
};
in
foldl' (acc: x: acc * 16 + literalValues.${x}) 0 (stringToCharacters v);
# Converts the given hex string to an integer. Only reliable for inputs in [0, 2^63),
# after that the sign bit will overflow.
hexToDec = v: foldl' (acc: x: acc * 16 + hexLiteralValues.${x}) 0 (stringToCharacters v);
in {
lib =
super.lib
// {
inherit
concatAttrs
countOccurrences
duplicates
hexToDec
isAbsolutePath
mergeToplevelConfigs
pow
;
# TODO separate this or get rid of it
# TODO separate this or get rid of it
# TODO separate this or get rid of it
# TODO separate this or get rid of it
secrets = let
rageMasterIdentityArgs = concatMapStrings (x: "-i ${escapeShellArg x} ") inputs.self.secretsConfig.masterIdentities;
rageExtraEncryptionPubkeys =
@ -116,4 +103,5 @@ in rec {
rageDecryptArgs = "${rageMasterIdentityArgs}";
rageEncryptArgs = "${rageMasterIdentityArgs} ${rageExtraEncryptionPubkeys}";
};
};
}

View file

@ -1,50 +1,28 @@
inputs: let
inputs: self: super: let
inherit
(inputs.nixpkgs.lib)
all
any
assertMsg
attrNames
attrValues
concatLists
concatMap
concatMapStrings
concatStringsSep
elem
escapeShellArg
filter
flatten
flip
foldAttrs
foldl'
genAttrs
genList
hasInfix
head
isAttrs
mapAttrs'
mergeAttrs
min
mkMerge
mkOptionType
nameValuePair
optionalAttrs
partition
range
recursiveUpdate
removeSuffix
reverseList
showOption
splitString
stringToCharacters
substring
types
unique
warnIf
;
inherit
(import ./misc.nix inputs)
(self.lib)
hexToDec
pow
;
@ -58,8 +36,9 @@ inputs: let
})
.lib
.net;
in
recursiveUpdate libNet {
in {
lib = recursiveUpdate super.lib {
net = recursiveUpdate (removeAttrs libNet ["types"]) {
cidr = rec {
# host :: (ip | mac | integer) -> cidr -> ip
#
@ -337,7 +316,7 @@ in
# Generates a hash (i.e. offset value) for a given hostname
hashElem = x:
builtins.bitAnd (capacity - 1)
(hexToDec (builtins.substring 0 16 (builtins.hashString "sha256" x)));
(hexToDec (substring 0 16 (builtins.hashString "sha256" x)));
# Do linear probing. Returns the first unused value at or after the given value.
probe = avoid: value:
if elem value avoid
@ -375,4 +354,7 @@ in
sortedHosts)
.assigned;
};
}
};
types.net = libNet.types;
};
}

View file

@ -1,48 +1,15 @@
inputs: let
inputs: self: super: let
inherit
(inputs.nixpkgs.lib)
all
any
assertMsg
attrNames
attrValues
concatLists
concatMap
concatMapStrings
concatStringsSep
elem
escapeShellArg
filter
flatten
flip
foldAttrs
foldl'
genAttrs
genList
hasInfix
head
isAttrs
mapAttrs'
mergeAttrs
min
mkMerge
mkOptionType
nameValuePair
optionalAttrs
partition
range
recursiveUpdate
removeSuffix
reverseList
showOption
splitString
stringToCharacters
substring
types
unique
warnIf
;
in rec {
# Checks whether the value is a lazy value without causing
# it's value to be evaluated
isLazyValue = x: isAttrs x && x ? _lazyValue;
@ -71,4 +38,15 @@ in rec {
# Represents a value or lazy value of the given type that will
# automatically be coerced to the given type when merged.
lazyOf = type: types.coercedTo (lazyValueOf type) (x: x._lazyValue) type;
in {
lib = recursiveUpdate super.lib {
types = {
inherit
isLazyValue
lazyValue
lazyValueOf
lazyOf
;
};
};
}

View file

@ -1,67 +1,41 @@
inputs: wgName: let
inputs: self: super: let
inherit
(inputs.nixpkgs.lib)
all
any
assertMsg
attrNames
attrValues
concatLists
concatMap
concatMapStrings
concatStringsSep
elem
escapeShellArg
filter
flatten
flip
foldAttrs
foldl'
genAttrs
genList
hasInfix
head
isAttrs
mapAttrs'
mergeAttrs
min
mkMerge
mkOptionType
nameValuePair
optionalAttrs
partition
range
recursiveUpdate
removeSuffix
reverseList
showOption
splitString
stringToCharacters
substring
types
unique
warnIf
;
net = import ./net.nix inputs;
misc = import ./misc.nix inputs;
inherit
(import ./types.nix inputs)
isLazyValue
;
inherit
(misc)
(self.lib)
net
concatAttrs
types
;
inherit
(misc.secrets)
(self.lib.secrets)
rageDecryptArgs
;
inherit (inputs.self) nodes;
in rec {
in {
lib =
super.lib
// {
wireguard = wgName: let
# Returns the given node's wireguard configuration of this network
wgCfgOf = node: nodes.${node}.config.meta.wireguard.${wgName};
@ -136,7 +110,7 @@ in rec {
explicitlyUsedAddresses =
flip concatMap participatingNodes
(n:
filter (x: !isLazyValue x)
filter (x: !types.isLazyValue x)
(concatLists
(nodes.${n}.options.meta.wireguard.type.functor.wrapped.getSubOptions (wgCfgOf n)).addresses.definitions))
++ flatten (concatMap (n: attrValues (wgCfgOf n).server.externalPeers) participatingNodes);
@ -215,4 +189,37 @@ in rec {
PersistentKeepalive = 25
EOF
'';
in {
inherit
allExternalPeers
allPeers
assignedIpv4Addresses
assignedIpv6Addresses
explicitlyUsedAddresses
externalPeerName
externalPeerNamesRaw
externalPeersForNode
networkAddresses
networkCidrs
nodePeers
participatingClientNodes
participatingNodes
participatingServerNodes
peerPresharedKeyFile
peerPresharedKeyPath
peerPresharedKeySecret
peerPrivateKeyFile
peerPrivateKeyPath
peerPrivateKeySecret
peerPublicKeyFile
peerPublicKeyPath
sortedPeers
spannedReservedNetwork
toNetworkAddr
usedAddresses
wgCfgOf
wgQuickConfigScript
;
};
};
}

View file

@ -12,32 +12,27 @@
attrNames
attrValues
concatStringsSep
disko
escapeShellArg
filterAttrs
foldl'
makeBinPath
mapAttrsToList
mdDoc
mergeToplevelConfigs
mkDefault
mkEnableOption
mkForce
mkIf
mkMerge
mkOption
net
optional
optionalAttrs
recursiveUpdate
types
;
inherit
(import ../../lib/misc.nix inputs)
mergeToplevelConfigs
;
net = import ../../lib/net.nix inputs;
disko = import ../../lib/disko.nix inputs;
parentConfig = config;
cfg = config.meta.microvms;
nodeName = config.node.name;
@ -236,7 +231,7 @@ in {
networking = {
baseMac = mkOption {
type = net.types.mac;
type = types.net.mac;
description = mdDoc ''
This MAC address will be used as a base address to derive all MicroVM MAC addresses from.
A good practise is to use the physical address of the macvtap interface.
@ -250,13 +245,13 @@ in {
wireguard = {
cidrv4 = mkOption {
type = net.types.cidrv4;
type = types.net.cidrv4;
description = mdDoc "The ipv4 network address range to use for internal vm traffic.";
default = "172.31.0.0/24";
};
cidrv6 = mkOption {
type = net.types.cidrv6;
type = types.net.cidrv6;
description = mdDoc "The ipv6 network address range to use for internal vm traffic.";
default = "fd00:172:31::/120";
};

View file

@ -1,6 +1,5 @@
{
config,
inputs,
lib,
nodes,
pkgs,
@ -12,10 +11,12 @@
assertMsg
attrNames
attrValues
concatAttrs
concatLists
concatMap
concatMapStrings
concatStringsSep
duplicates
escapeShellArg
filter
filterAttrs
@ -27,41 +28,28 @@
mapAttrsToList
mdDoc
mergeAttrs
mergeToplevelConfigs
mkForce
mkIf
mkMerge
mkOption
nameValuePair
net
optionalAttrs
optionals
partition
removeSuffix
stringLength
types
wireguard
;
inherit
(import ../../lib/misc.nix inputs)
concatAttrs
duplicates
mergeToplevelConfigs
;
inherit
(import ../../lib/types.nix inputs)
lazyOf
lazyValue
;
net = import ../../lib/net.nix inputs;
wgLibFor = import ../../lib/wireguard.nix inputs;
cfg = config.meta.wireguard;
nodeName = config.node.name;
configForNetwork = wgName: wgCfg: let
inherit
(wgLibFor wgName)
(wireguard wgName)
externalPeerName
externalPeerNamesRaw
networkCidrs
@ -307,7 +295,7 @@ in {
};
externalPeers = mkOption {
type = types.attrsOf (types.listOf (net.types.ip-in config.addresses));
type = types.attrsOf (types.listOf (types.net.ip-in config.addresses));
default = {};
example = {my-android-phone = ["10.0.0.97"];};
description = mdDoc ''
@ -321,7 +309,7 @@ in {
};
reservedAddresses = mkOption {
type = types.listOf net.types.cidr;
type = types.listOf types.net.cidr;
default = [];
example = ["10.0.0.1/24" "fd00:cafe::/64"];
description = mdDoc ''
@ -377,8 +365,8 @@ in {
};
ipv4 = mkOption {
type = lazyOf net.types.ipv4;
default = lazyValue (wgLibFor name).assignedIpv4Addresses.${nodeName};
type = types.lazyOf types.net.ipv4;
default = types.lazyValue (wireguard name).assignedIpv4Addresses.${nodeName};
description = mdDoc ''
The ipv4 address for this machine. If you do not set this explicitly,
a semi-stable ipv4 address will be derived automatically based on the
@ -389,8 +377,8 @@ in {
};
ipv6 = mkOption {
type = lazyOf net.types.ipv6;
default = lazyValue (wgLibFor name).assignedIpv6Addresses.${nodeName};
type = types.lazyOf types.net.ipv6;
default = types.lazyValue (wireguard name).assignedIpv6Addresses.${nodeName};
description = mdDoc ''
The ipv6 address for this machine. If you do not set this explicitly,
a semi-stable ipv6 address will be derived automatically based on the
@ -401,7 +389,7 @@ in {
};
addresses = mkOption {
type = types.listOf (lazyOf net.types.ip);
type = types.listOf (types.lazyOf types.net.ip);
default = [
(head options.ipv4.definitions)
(head options.ipv6.definitions)
@ -420,7 +408,7 @@ in {
# to use the network without routing additional stuff.
# - allow specifying the route metric.
routedAddresses = mkOption {
type = types.listOf net.types.cidr;
type = types.listOf types.net.cidr;
default = [];
example = ["0.0.0.0/0"];
description = mdDoc ''

View file

@ -1,7 +1,6 @@
# Provides an option to easily rename interfaces by their mac addresses.
{
config,
inputs,
lib,
pkgs,
...
@ -10,17 +9,13 @@
(lib)
attrValues
concatStringsSep
duplicates
mapAttrsToList
mkIf
mkOption
types
;
inherit
(import ../../lib/misc.nix inputs)
duplicates
;
cfg = config.networking.renameInterfacesByMac;
interfaceNamesUdevRules = pkgs.writeTextFile {

View file

@ -22,7 +22,7 @@
inherit system;
pkgs = self.pkgs.${system};
specialArgs = {
inherit (nixpkgs) lib;
inherit (self.pkgs.${system}) lib;
inherit (self) nodes;
inherit inputs;
};

View file

@ -1,6 +1,6 @@
final: prev: let
self: super: let
inherit
(final.lib)
(self.lib)
escapeShellArg
concatMapStrings
flatten
@ -21,9 +21,9 @@ final: prev: let
version,
}: "go get ${escapeShellArg name}@${escapeShellArg version}\n");
in
prev.caddy.override {
super.caddy.override {
buildGoModule = args:
prev.buildGoModule (args
super.buildGoModule (args
// {
inherit vendorHash;
passthru.plugins = plugins;
@ -45,5 +45,5 @@ in {
# ];
# vendorHash = "sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=";
# }
caddy = prev.caddy.overrideAttrs (_: {passthru.withPackages = make-custom-caddy;});
caddy = super.caddy.overrideAttrs (_: {passthru.withPackages = make-custom-caddy;});
}

View file

@ -1,5 +1,5 @@
final: prev: {
oauth2-proxy = prev.oauth2-proxy.overrideAttrs (_: {
self: super: {
oauth2-proxy = super.oauth2-proxy.overrideAttrs (_: {
patches = [./0001-scopes-as-groups.patch];
});
}