added stuff
This commit is contained in:
parent
6d31f5b5a1
commit
7d4f626b7d
907 changed files with 70990 additions and 0 deletions
36
nyx/lib/aliases.nix
Normal file
36
nyx/lib/aliases.nix
Normal file
|
@ -0,0 +1,36 @@
|
|||
_: let
|
||||
# this is a forced SSL template for Nginx
|
||||
# returns the attribute set with our desired settings
|
||||
sslTemplate = {
|
||||
forceSSL = true;
|
||||
enableACME = true;
|
||||
};
|
||||
|
||||
common = {
|
||||
shellColors = ''
|
||||
# Reset colors
|
||||
CO='\033[0m'
|
||||
|
||||
# Colors
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[0;33m'
|
||||
BLUE='\033[0;34m'
|
||||
PURPLE='\033[0;35m'
|
||||
CYAN='\033[0;36m'
|
||||
WHITE='\033[0;37m'
|
||||
|
||||
# Bold colors
|
||||
BBLACK='\033[1;30m'
|
||||
BRED='\033[1;31m'
|
||||
BGREEN='\033[1;32m'
|
||||
BYELLOW='\033[1;33m'
|
||||
BBLUE='\033[1;34m'
|
||||
BPURPLE='\033[1;35m'
|
||||
BCYAN='\033[1;36m'
|
||||
BWHITE='\033[1;37m'
|
||||
'';
|
||||
};
|
||||
in {
|
||||
inherit sslTemplate common;
|
||||
}
|
85
nyx/lib/builders.nix
Normal file
85
nyx/lib/builders.nix
Normal file
|
@ -0,0 +1,85 @@
|
|||
{
|
||||
lib,
|
||||
inputs,
|
||||
...
|
||||
}: let
|
||||
# inherit self from inputs
|
||||
inherit (inputs) self;
|
||||
|
||||
# just an alias to nixpkgs.lib.nixosSystem, lets me avoid adding
|
||||
# nixpkgs to the scope in the file it is used in
|
||||
mkSystem = lib.nixosSystem;
|
||||
|
||||
# mkNixoSystem is a convenient wrapper that wraps lib.nixosSystem (aliased to mkSystem here) to
|
||||
# provide us a convenient boostrapper for new systems with inputs' and self' (alongside other specialArgs)
|
||||
# already passed to the nixosSystem attribute set without us having to re-define them everytime, instead
|
||||
# defining specialArgs by default and lazily merging any additional arguments defined by the host in the builder
|
||||
mkNixosSystem = {
|
||||
modules,
|
||||
system,
|
||||
hostname,
|
||||
withSystem,
|
||||
...
|
||||
} @ args:
|
||||
withSystem system ({
|
||||
inputs',
|
||||
self',
|
||||
...
|
||||
}:
|
||||
mkSystem {
|
||||
inherit system;
|
||||
specialArgs = {inherit lib inputs self inputs' self';} // args.specialArgs or {};
|
||||
modules =
|
||||
[
|
||||
{
|
||||
config = {
|
||||
networking.hostName = args.hostname;
|
||||
nixpkgs.hostPlatform = lib.mkDefault args.system;
|
||||
};
|
||||
}
|
||||
]
|
||||
++ args.modules or [];
|
||||
});
|
||||
|
||||
# mkIso is should be a set that extends mkSystem with necessary modules
|
||||
# to create an Iso image
|
||||
# we do not use mkNixosSystem because it overcomplicates things, an ISO does not require what we get in return for those complications
|
||||
mkNixosIso = {
|
||||
modules,
|
||||
system,
|
||||
hostname,
|
||||
...
|
||||
} @ args:
|
||||
mkSystem {
|
||||
inherit system;
|
||||
specialArgs = {inherit inputs lib self;} // args.specialArgs or {};
|
||||
modules =
|
||||
[
|
||||
# get an installer profile from nixpkgs to base the Isos off of
|
||||
"${inputs.nixpkgs}/nixos/modules/installer/cd-dvd/installation-cd-minimal.nix"
|
||||
"${inputs.nixpkgs}/nixos/modules/installer/cd-dvd/channel.nix"
|
||||
|
||||
{config.networking.hostName = args.hostname;}
|
||||
]
|
||||
++ args.modules or [];
|
||||
};
|
||||
|
||||
mkSdImage = {
|
||||
modules,
|
||||
system,
|
||||
...
|
||||
} @ args:
|
||||
mkSystem {
|
||||
inherit system;
|
||||
specialArgs = {inherit inputs lib self;} // args.specialArgs or {};
|
||||
modules =
|
||||
[
|
||||
# get an installer profile from nixpkgs to base the Isos off of
|
||||
"${inputs.nixpkgs}/nixos/modules/installer/sd-card/sd-image-raspberrypi.nix"
|
||||
inputs.nixos-hardware.nixosModules.raspberry-pi-4
|
||||
]
|
||||
++ args.modules or [];
|
||||
};
|
||||
in {
|
||||
inherit mkSystem mkNixosSystem mkNixosIso mkSdImage;
|
||||
}
|
23
nyx/lib/core.nix
Normal file
23
nyx/lib/core.nix
Normal file
|
@ -0,0 +1,23 @@
|
|||
{lib}: let
|
||||
inherit (lib) recursiveUpdate;
|
||||
|
||||
# the below function is by far the most cursed I've put in my configuration
|
||||
# if you are, for whatever reason, copying my configuration - PLEASE omit this
|
||||
# and do your imports manually
|
||||
# credits go to @nrabulinski
|
||||
import' = path: let
|
||||
func = import path;
|
||||
args = lib.functionArgs func;
|
||||
requiredArgs = lib.filterAttrs (_: val: !val) args;
|
||||
defaultArgs = (lib.mapAttrs (_: _: null) requiredArgs) // {inherit lib;};
|
||||
functor = {__functor = _: attrs: func (defaultArgs // attrs);};
|
||||
in
|
||||
(func defaultArgs) // functor;
|
||||
|
||||
# recursively merges two attribute sets
|
||||
# it is used to convert the importedLibs list into an attrset
|
||||
# there is probably a better way to do it, more cleanly - but I wouldn't know
|
||||
mergeRecursively = lhs: rhs: recursiveUpdate lhs rhs;
|
||||
in {
|
||||
inherit import' mergeRecursively;
|
||||
}
|
27
nyx/lib/default.nix
Normal file
27
nyx/lib/default.nix
Normal file
|
@ -0,0 +1,27 @@
|
|||
{inputs}: let
|
||||
inherit (inputs.nixpkgs) lib;
|
||||
inherit (lib) foldl;
|
||||
inherit (import ./core.nix {inherit lib;}) import' mergeRecursively;
|
||||
|
||||
# helpful utility functions used around the system
|
||||
builders = import' ./builders.nix {inherit inputs;}; # system builders
|
||||
services = import' ./services.nix; # systemd-service generators
|
||||
validators = import' ./validators.nix; # validate system conditions
|
||||
helpers = import' ./helpers; # helper functions
|
||||
hardware = import' ./hardware.nix; # hardware capability checks
|
||||
xdg = import' ./xdg; # xdg user directories & templates
|
||||
|
||||
# abstractions over networking functions
|
||||
# dag library is a modified version of the one found in
|
||||
# rycee's NUR repository
|
||||
dag = import' ./network/dag.nix; # dag is in network because it's designed for network only use
|
||||
firewall = import' ./network/firewall.nix {inherit dag;}; # build nftables tables and chains
|
||||
namespacing = import' ./network/namespacing.nix; # TODO
|
||||
|
||||
# aliases for commonly used strings or functions
|
||||
aliases = import' ./aliases.nix;
|
||||
|
||||
importedLibs = [builders services validators helpers hardware aliases firewall namespacing dag xdg];
|
||||
in
|
||||
# extend nixpkgs lib
|
||||
lib.extend (_: _: foldl mergeRecursively {} importedLibs)
|
12
nyx/lib/hardware.nix
Normal file
12
nyx/lib/hardware.nix
Normal file
|
@ -0,0 +1,12 @@
|
|||
_: let
|
||||
# check if the host platform is linux and x86
|
||||
# (isx86Linux pkgs) -> true
|
||||
isx86Linux = pkgs: with pkgs.stdenv; hostPlatform.isLinux && hostPlatform.isx86;
|
||||
|
||||
# assume the first monitor in the list of monitors is primary
|
||||
# get its name from the list of monitors
|
||||
# `primaryMonitor osConfig` -> "DP-1"
|
||||
primaryMonitor = config: builtins.elemAt config.modules.device.monitors 0;
|
||||
in {
|
||||
inherit isx86Linux primaryMonitor;
|
||||
}
|
15
nyx/lib/helpers/default.nix
Normal file
15
nyx/lib/helpers/default.nix
Normal file
|
@ -0,0 +1,15 @@
|
|||
{lib}: let
|
||||
inherit (import ../core.nix {inherit lib;}) import';
|
||||
|
||||
systemd = import' ./systemd.nix;
|
||||
fs = import' ./fs.nix;
|
||||
types = import' ./types.nix;
|
||||
themes = import' ./themes.nix;
|
||||
modules = import' ./modules.nix;
|
||||
in {
|
||||
inherit (systemd) hardenService;
|
||||
inherit (fs) mkBtrfs;
|
||||
inherit (types) filterNixFiles importNixFiles boolToNum fetchKeys containsStrings indexOf intListToStringList;
|
||||
inherit (themes) serializeTheme compileSCSS;
|
||||
inherit (modules) mkModule;
|
||||
}
|
5
nyx/lib/helpers/fs.nix
Normal file
5
nyx/lib/helpers/fs.nix
Normal file
|
@ -0,0 +1,5 @@
|
|||
_: let
|
||||
mkBtrfs = list: list + ["compress=zstd" "noatime"];
|
||||
in {
|
||||
inherit mkBtrfs;
|
||||
}
|
34
nyx/lib/helpers/modules.nix
Normal file
34
nyx/lib/helpers/modules.nix
Normal file
|
@ -0,0 +1,34 @@
|
|||
{lib}: let
|
||||
inherit (lib) mkEnableOption mkOption;
|
||||
inherit (lib.types) str int;
|
||||
|
||||
# mkModule takes a few arguments to generate a module for a service without
|
||||
# repeating the same options over and over
|
||||
# this is actually a horrendous abstractation
|
||||
mkModule = {
|
||||
name,
|
||||
type ? "", # type being an empty string means it can be skipped, ommitted
|
||||
host ? "127.0.0.1", # default to listening only on localhost
|
||||
port ? 0, # don't set a port by default
|
||||
extraOptions ? {}, # used to define additional modules
|
||||
}: {
|
||||
enable = mkEnableOption "${name} ${type} service";
|
||||
settings =
|
||||
{
|
||||
host = mkOption {
|
||||
type = str;
|
||||
default = host;
|
||||
description = "The host ${name} will listen on";
|
||||
};
|
||||
|
||||
port = mkOption {
|
||||
type = int;
|
||||
default = port;
|
||||
description = "The port ${name} will listen on";
|
||||
};
|
||||
}
|
||||
// extraOptions;
|
||||
};
|
||||
in {
|
||||
inherit mkModule;
|
||||
}
|
40
nyx/lib/helpers/systemd.nix
Normal file
40
nyx/lib/helpers/systemd.nix
Normal file
|
@ -0,0 +1,40 @@
|
|||
{lib, ...}: let
|
||||
inherit (lib) mkOptionDefault mapAttrs;
|
||||
|
||||
hardenService = attrs:
|
||||
attrs
|
||||
// (mapAttrs (_: mkOptionDefault) {
|
||||
AmbientCapabilities = "";
|
||||
CapabilityBoundingSet = "";
|
||||
LockPersonality = true;
|
||||
MemoryDenyWriteExecute = true;
|
||||
NoNewPrivileges = true;
|
||||
PrivateDevices = true;
|
||||
PrivateMounts = true;
|
||||
PrivateTmp = true;
|
||||
ProcSubset = "pid";
|
||||
ProtectClock = true;
|
||||
ProtectControlGroups = true;
|
||||
ProtectHome = true;
|
||||
ProtectHostname = true;
|
||||
ProtectKernelLogs = true;
|
||||
ProtectKernelModules = true;
|
||||
ProtectKernelTunables = true;
|
||||
ProtectProc = "invisible";
|
||||
ProtectSystem = "strict";
|
||||
RemoveIPC = true;
|
||||
RestrictAddressFamilies = ["AF_UNIX" "AF_INET" "AF_INET6"];
|
||||
RestrictNamespaces = true;
|
||||
RestrictRealtime = true;
|
||||
RestrictSUIDSGID = true;
|
||||
SystemCallArchitectures = "native";
|
||||
SystemCallErrorNumber = "EPERM";
|
||||
SystemCallFilter = [
|
||||
"@system-service"
|
||||
# Route-chain and OpenJ9 requires @resources calls
|
||||
"~@clock @cpu-emulation @debug @module @mount @obsolete @privileged @raw-io @reboot @swap"
|
||||
];
|
||||
});
|
||||
in {
|
||||
inherit hardenService;
|
||||
}
|
21
nyx/lib/helpers/themes.nix
Normal file
21
nyx/lib/helpers/themes.nix
Normal file
|
@ -0,0 +1,21 @@
|
|||
{lib}: let
|
||||
# function to generate theme slugs from theme names
|
||||
# "A String With Whitespaces" -> "a-string-with-whitespaces"
|
||||
serializeTheme = inputString: lib.strings.toLower (builtins.replaceStrings [" "] ["-"] inputString);
|
||||
|
||||
# a function that takes a theme name and a source file and compiles it to CSS
|
||||
# compileSCSS "theme-name" "path/to/theme.scss" -> "$out/theme-name.css"
|
||||
# adapted from <https://github.com/spikespaz/dotfiles>
|
||||
compileSCSS = pkgs: {
|
||||
name,
|
||||
source,
|
||||
args ? "-t expanded",
|
||||
}: "${
|
||||
pkgs.runCommandLocal name {} ''
|
||||
mkdir -p $out
|
||||
${lib.getExe pkgs.sassc} ${args} '${source}' > $out/${name}.css
|
||||
''
|
||||
}/${name}.css";
|
||||
in {
|
||||
inherit serializeTheme compileSCSS;
|
||||
}
|
49
nyx/lib/helpers/types.nix
Normal file
49
nyx/lib/helpers/types.nix
Normal file
|
@ -0,0 +1,49 @@
|
|||
{lib, ...}: let
|
||||
inherit (lib) lists mapAttrsToList filterAttrs hasSuffix;
|
||||
|
||||
# filter files that have the .nix suffix
|
||||
filterNixFiles = k: v: v == "regular" && hasSuffix ".nix" k;
|
||||
|
||||
# import files that are selected by filterNixFiles
|
||||
importNixFiles = path:
|
||||
(lists.forEach (mapAttrsToList (name: _: path + ("/" + name))
|
||||
(filterAttrs filterNixFiles (builtins.readDir path))))
|
||||
import;
|
||||
|
||||
# return an int (1/0) based on boolean value
|
||||
# `boolToNum true` -> 1
|
||||
boolToNum = bool:
|
||||
if bool
|
||||
then 1
|
||||
else 0;
|
||||
|
||||
# convert a list of integers to a list of string
|
||||
# `intListToStringList [1 2 3]` -> ["1" "2" "3"]
|
||||
intListToStringList = list: map (toString list);
|
||||
|
||||
# a basic function to fetch a specified user's public keys from github .keys url
|
||||
# `fetchKeys "username` -> "ssh-rsa AAAA...== username@hostname"
|
||||
fetchKeys = username: (builtins.fetchurl "https://github.com/${username}.keys");
|
||||
|
||||
# a helper function that checks if a list contains a list of given strings
|
||||
# `containsStrings { targetStrings = ["foo" "bar"]; list = ["foo" "bar" "baz"]; }` -> true
|
||||
containsStrings = {
|
||||
list,
|
||||
targetStrings,
|
||||
}:
|
||||
builtins.all (s: builtins.any (x: x == s) list) targetStrings;
|
||||
|
||||
# indexOf is a function that returns the index of an element in a list
|
||||
# `indexOf ["foo" "bar" "baz"] "bar"` -> 1
|
||||
indexOf = list: elem: let
|
||||
f = f: i:
|
||||
if i == (builtins.length list)
|
||||
then null
|
||||
else if (builtins.elemAt list i) == elem
|
||||
then i
|
||||
else f f (i + 1);
|
||||
in
|
||||
f f 0;
|
||||
in {
|
||||
inherit filterNixFiles importNixFiles boolToNum fetchKeys containsStrings indexOf intListToStringList;
|
||||
}
|
140
nyx/lib/network/dag.nix
Normal file
140
nyx/lib/network/dag.nix
Normal file
|
@ -0,0 +1,140 @@
|
|||
# Adjusted from https://gitlab.com/rycee/nur-expressions/blob/b34e2e548da574c7bd4da14d1779c95b62349a3a/lib/dag.nix (MIT)
|
||||
# A generalization of Nixpkgs's `strings-with-deps.nix`.
|
||||
#
|
||||
# The main differences from the Nixpkgs version are
|
||||
#
|
||||
# - not specific to strings, i.e., any payload is OK,
|
||||
#
|
||||
# - the addition of the function `entryBefore` indicating a
|
||||
# "wanted by" relationship.
|
||||
{lib, ...}: let
|
||||
inherit (lib) mkOption filterAttrs mapAttrsToList toposort mapAttrs any types;
|
||||
|
||||
types' =
|
||||
types
|
||||
// {
|
||||
dagOf = subType:
|
||||
types.attrsOf (types.submodule {
|
||||
options = {
|
||||
data = mkOption {
|
||||
type = subType;
|
||||
description = "Entry value.";
|
||||
};
|
||||
|
||||
before = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [];
|
||||
description = "Entries to guarantee before.";
|
||||
};
|
||||
|
||||
after = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [];
|
||||
description = "Entries to guarantee after.";
|
||||
};
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
dag = {
|
||||
# Takes an attribute set containing entries built by
|
||||
# entryAnywhere, entryAfter, and entryBefore to a
|
||||
# topologically sorted list of entries.
|
||||
#
|
||||
# Internally this function uses the `toposort` function in
|
||||
# `<nixpkgs/lib/lists.nix>` and its value is accordingly.
|
||||
#
|
||||
# Specifically, the result on success is
|
||||
#
|
||||
# { result = [{name = ?; data = ?;} …] }
|
||||
#
|
||||
# For example
|
||||
#
|
||||
# nix-repl> topoSort {
|
||||
# a = entryAnywhere "1";
|
||||
# b = entryAfter ["a" "c"] "2";
|
||||
# c = entryBefore ["d"] "3";
|
||||
# d = entryBefore ["e"] "4";
|
||||
# e = entryAnywhere "5";
|
||||
# } == {
|
||||
# result = [
|
||||
# { data = "1"; name = "a"; }
|
||||
# { data = "3"; name = "c"; }
|
||||
# { data = "2"; name = "b"; }
|
||||
# { data = "4"; name = "d"; }
|
||||
# { data = "5"; name = "e"; }
|
||||
# ];
|
||||
# }
|
||||
# true
|
||||
#
|
||||
# And the result on error is
|
||||
#
|
||||
# {
|
||||
# cycle = [ {after = ?; name = ?; data = ?} … ];
|
||||
# loops = [ {after = ?; name = ?; data = ?} … ];
|
||||
# }
|
||||
#
|
||||
# For example
|
||||
#
|
||||
# nix-repl> topoSort {
|
||||
# a = entryAnywhere "1";
|
||||
# b = entryAfter ["a" "c"] "2";
|
||||
# c = entryAfter ["d"] "3";
|
||||
# d = entryAfter ["b"] "4";
|
||||
# e = entryAnywhere "5";
|
||||
# } == {
|
||||
# cycle = [
|
||||
# { after = ["a" "c"]; data = "2"; name = "b"; }
|
||||
# { after = ["d"]; data = "3"; name = "c"; }
|
||||
# { after = ["b"]; data = "4"; name = "d"; }
|
||||
# ];
|
||||
# loops = [
|
||||
# { after = ["a" "c"]; data = "2"; name = "b"; }
|
||||
# ];
|
||||
# } == {}
|
||||
# true
|
||||
topoSort = dag: let
|
||||
dagBefore = dag: name:
|
||||
mapAttrsToList (n: v: n) (
|
||||
filterAttrs (n: v: any (a: a == name) v.before) dag
|
||||
);
|
||||
normalizedDag =
|
||||
mapAttrs (n: v: {
|
||||
name = n;
|
||||
data = v.data;
|
||||
after = v.after ++ dagBefore dag n;
|
||||
})
|
||||
dag;
|
||||
before = a: b: any (c: a.name == c) b.after;
|
||||
sorted = toposort before (mapAttrsToList (n: v: v) normalizedDag);
|
||||
in
|
||||
if sorted ? result
|
||||
then {result = map (v: {inherit (v) name data;}) sorted.result;}
|
||||
else sorted;
|
||||
|
||||
# Create a DAG entry with no particular dependency information.
|
||||
entryAnywhere = data: {
|
||||
inherit data;
|
||||
before = [];
|
||||
after = [];
|
||||
};
|
||||
|
||||
# Ordering of after and before flipped from the original
|
||||
entryBetween = after: before: data: {
|
||||
inherit data before after;
|
||||
};
|
||||
|
||||
entryAfter = after: data: {
|
||||
inherit data after;
|
||||
before = [];
|
||||
};
|
||||
|
||||
entryBefore = before: data: {
|
||||
inherit data before;
|
||||
after = [];
|
||||
};
|
||||
};
|
||||
in {
|
||||
inherit (dag) entryBefore entryBetween entryAfter entryAnywhere topoSort;
|
||||
inherit (types') dagOf;
|
||||
}
|
177
nyx/lib/network/firewall.nix
Normal file
177
nyx/lib/network/firewall.nix
Normal file
|
@ -0,0 +1,177 @@
|
|||
{
|
||||
dag,
|
||||
lib,
|
||||
...
|
||||
}: let
|
||||
inherit (lib.options) mkOption mkEnableOption;
|
||||
inherit (lib.strings) optionalString concatMapStringsSep concatStringsSep;
|
||||
inherit (lib.attrsets) filterAttrs mapAttrsToList;
|
||||
inherit (lib.lists) concatLists;
|
||||
inherit (lib) types;
|
||||
inherit (dag) dagOf topoSort;
|
||||
|
||||
mkTable = desc: body:
|
||||
mkOption {
|
||||
default = {};
|
||||
description = "Containers for chains, sets, and other stateful objects.";
|
||||
type = types.submodule ({config, ...}: {
|
||||
options =
|
||||
{
|
||||
enable = mkEnableOption desc;
|
||||
objects = mkOption {
|
||||
type = with types; listOf str;
|
||||
description = "Objects associated with this table.";
|
||||
default = [];
|
||||
};
|
||||
}
|
||||
// body;
|
||||
|
||||
config = let
|
||||
buildChainDag = chain:
|
||||
concatMapStringsSep "\n" ({
|
||||
name,
|
||||
data,
|
||||
}: let
|
||||
protocol =
|
||||
if builtins.isNull data.protocol
|
||||
then ""
|
||||
else data.protocol;
|
||||
field =
|
||||
if builtins.isNull data.field
|
||||
then ""
|
||||
else data.field;
|
||||
inherit (data) policy;
|
||||
values = map toString data.value;
|
||||
value =
|
||||
if builtins.isNull data.value
|
||||
then ""
|
||||
else
|
||||
(
|
||||
if builtins.length data.value == 1
|
||||
then builtins.head values
|
||||
else "{ ${concatStringsSep ", " values} }"
|
||||
);
|
||||
in ''
|
||||
${protocol} ${field} ${value} ${policy} comment ${name}
|
||||
'') ((topoSort chain).result or (throw "Cycle in DAG"));
|
||||
|
||||
buildChain = chainType: chain:
|
||||
mapAttrsToList (chainName: chainDag: ''
|
||||
chain ${chainName} {
|
||||
type ${chainType} hook ${chainName} priority 0;
|
||||
|
||||
${buildChainDag chainDag}
|
||||
}
|
||||
'') (filterAttrs (_: g: builtins.length (builtins.attrNames g) > 0) chain);
|
||||
in {
|
||||
objects = let
|
||||
chains = concatLists [
|
||||
(
|
||||
if config ? filter
|
||||
then buildChain "filter" config.filter
|
||||
else []
|
||||
)
|
||||
(
|
||||
if config ? nat
|
||||
then buildChain "nat" config.nat
|
||||
else []
|
||||
)
|
||||
(
|
||||
if config ? route
|
||||
then buildChain "route" config.route
|
||||
else []
|
||||
)
|
||||
];
|
||||
in
|
||||
chains;
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
mkChain = _: description:
|
||||
mkOption {
|
||||
inherit description;
|
||||
default = {};
|
||||
type = dagOf (types.submodule {
|
||||
options = {
|
||||
protocol = mkOption {
|
||||
default = null;
|
||||
description = "Protocol to match.";
|
||||
type = with types;
|
||||
nullOr (either (enum [
|
||||
"ether"
|
||||
"vlan"
|
||||
"arp"
|
||||
"ip"
|
||||
"icmp"
|
||||
"igmp"
|
||||
"ip6"
|
||||
"icmpv6"
|
||||
"tcp"
|
||||
"udp"
|
||||
"udplite"
|
||||
"sctp"
|
||||
"dccp"
|
||||
"ah"
|
||||
"esp"
|
||||
"comp"
|
||||
])
|
||||
str);
|
||||
};
|
||||
|
||||
field = mkOption {
|
||||
default = null;
|
||||
description = "Field value to match.";
|
||||
type = with types;
|
||||
nullOr (enum [
|
||||
"dport"
|
||||
"sport"
|
||||
"daddr"
|
||||
"saddr"
|
||||
"type"
|
||||
"state"
|
||||
"iifname"
|
||||
"pkttype"
|
||||
]);
|
||||
};
|
||||
|
||||
value = mkOption {
|
||||
default = null;
|
||||
description = "Associated value.";
|
||||
type = with types; let
|
||||
valueType = oneOf [port str];
|
||||
in
|
||||
nullOr (coercedTo valueType (value: [value]) (listOf valueType));
|
||||
};
|
||||
|
||||
policy = mkOption {
|
||||
description = "What to do with matching packets.";
|
||||
type = types.enum [
|
||||
"accept"
|
||||
"reject"
|
||||
"drop"
|
||||
"log"
|
||||
];
|
||||
};
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
mkRuleset = ruleset:
|
||||
concatStringsSep "\n" (mapAttrsToList (name: table:
|
||||
optionalString (builtins.length table.objects > 0) ''
|
||||
table ${name} nixos {
|
||||
${concatStringsSep "\n" table.objects}
|
||||
}
|
||||
'')
|
||||
ruleset);
|
||||
|
||||
mkIngressChain = mkChain "Process all packets before they enter the system";
|
||||
mkPrerouteChain = mkChain "Process all packets entering the system";
|
||||
mkInputChain = mkChain "Process packets delivered to the local system";
|
||||
mkForwardChain = mkChain "Process packets forwarded to a different host";
|
||||
mkOutputChain = mkChain "Process packets sent by local processes";
|
||||
mkPostrouteChain = mkChain "Process all packets leaving the system";
|
||||
in {
|
||||
inherit mkTable mkRuleset mkIngressChain mkPrerouteChain mkInputChain mkForwardChain mkOutputChain mkPostrouteChain;
|
||||
}
|
13
nyx/lib/network/namespacing.nix
Normal file
13
nyx/lib/network/namespacing.nix
Normal file
|
@ -0,0 +1,13 @@
|
|||
_: let
|
||||
makeServiceNsPhysical = name: {
|
||||
systemd.services."${name}".serviceConfig.NetworkNamespacePath = "/var/run/netns/physical";
|
||||
};
|
||||
makeSocketNsPhysical = name: {
|
||||
systemd.sockets."${name}".socketConfig.NetworkNamespacePath = "/var/run/netns/physical";
|
||||
};
|
||||
unRestrictNamespaces = name: {
|
||||
systemd.sockets."${name}".socketConfig.RestrictNamespaces = "~net";
|
||||
};
|
||||
in {
|
||||
inherit makeSocketNsPhysical makeServiceNsPhysical unRestrictNamespaces;
|
||||
}
|
17
nyx/lib/services.nix
Normal file
17
nyx/lib/services.nix
Normal file
|
@ -0,0 +1,17 @@
|
|||
{lib, ...}: let
|
||||
# make a service that is a part of the graphical session target
|
||||
mkGraphicalService = lib.recursiveUpdate {
|
||||
Unit.PartOf = ["graphical-session.target"];
|
||||
Unit.After = ["graphical-session.target"];
|
||||
Install.WantedBy = ["graphical-session.target"];
|
||||
};
|
||||
|
||||
# make a service that is a part of the hyprland session target
|
||||
mkHyprlandService = lib.recursiveUpdate {
|
||||
Unit.PartOf = ["graphical-session.target"];
|
||||
Unit.After = ["graphical-session.target"];
|
||||
Install.WantedBy = ["hyprland-session.target"];
|
||||
};
|
||||
in {
|
||||
inherit mkGraphicalService mkHyprlandService;
|
||||
}
|
23
nyx/lib/validators.nix
Normal file
23
nyx/lib/validators.nix
Normal file
|
@ -0,0 +1,23 @@
|
|||
{lib, ...}: let
|
||||
# a function that will append a list of groups if they exist in config.users.groups
|
||||
ifTheyExist = config: groups: builtins.filter (group: builtins.hasAttr group config.users.groups) groups;
|
||||
|
||||
# a function that returns a boolean based on whether or not the groups exist
|
||||
ifGroupsExist = config: groups: lib.any (group: builtins.hasAttr group config.users.groups) groups;
|
||||
|
||||
# convenience function check if the declared device type is of an accepted type
|
||||
# takes config and a list of accepted device types
|
||||
# `isAcceptedDevice osConfig ["foo" "bar"];`
|
||||
isAcceptedDevice = conf: list: builtins.elem conf.modules.device.type list;
|
||||
|
||||
# assert if the device is wayland-ready by checking sys.video and env.isWayland options
|
||||
# `(lib.isWayland config)` where config is in scope
|
||||
# `isWayland osConfig` -> true
|
||||
isWayland = conf: conf.modules.system.video.enable && conf.modules.usrEnv.isWayland;
|
||||
|
||||
# ifOneEnabled takes a parent option and 3 child options and checks if at least one of them is enabled
|
||||
# `ifOneEnabled config.modules.services "service1" "service2" "service3"`
|
||||
ifOneEnabled = cfg: a: b: c: (cfg.a || cfg.b || cfg.c);
|
||||
in {
|
||||
inherit ifTheyExist ifGroupsExist isAcceptedDevice isWayland ifOneEnabled;
|
||||
}
|
5
nyx/lib/xdg/default.nix
Normal file
5
nyx/lib/xdg/default.nix
Normal file
|
@ -0,0 +1,5 @@
|
|||
_: let
|
||||
xdgTemplate = ./. + /template.nix;
|
||||
in {
|
||||
inherit xdgTemplate;
|
||||
}
|
98
nyx/lib/xdg/template.nix
Normal file
98
nyx/lib/xdg/template.nix
Normal file
|
@ -0,0 +1,98 @@
|
|||
system: let
|
||||
# copy paste done right
|
||||
XDG_CONFIG_HOME = "$HOME/.config";
|
||||
XDG_CACHE_HOME = "$HOME/.cache";
|
||||
XDG_DATA_HOME = "$HOME/.local/share";
|
||||
XDG_STATE_HOME = "$HOME/.local/state";
|
||||
XDG_BIN_HOME = "$HOME}/.local/bin";
|
||||
XDG_RUNTIME_DIR = "/run/user/$UID";
|
||||
in {
|
||||
# global env
|
||||
glEnv = {
|
||||
inherit XDG_DATA_HOME XDG_CONFIG_HOME XDG_CACHE_HOME XDG_STATE_HOME XDG_RUNTIME_DIR XDG_BIN_HOME;
|
||||
PATH = ["$XDG_BIN_HOME"];
|
||||
};
|
||||
|
||||
sysEnv = {
|
||||
# general programs
|
||||
CUDA_CACHE_PATH = "${XDG_CACHE_HOME}/nv";
|
||||
ERRFILE = "${XDG_CACHE_HOME}/X11/xsession-errors";
|
||||
GNUPGHOME = "${XDG_DATA_HOME}/gnupg";
|
||||
KDEHOME = "${XDG_CONFIG_HOME}/kde";
|
||||
LESSHISTFILE = "${XDG_DATA_HOME}/less/history";
|
||||
STEPPATH = "${XDG_DATA_HOME}/step";
|
||||
WAKATIME_HOME = "${XDG_DATA_HOME}/wakatime";
|
||||
XCOMPOSECACHE = "${XDG_CACHE_HOME}/X11/xcompose";
|
||||
INPUTRC = "${XDG_CONFIG_HOME}/readline/inputrc";
|
||||
PLATFORMIO_CORE_DIR = "${XDG_DATA_HOME}/platformio";
|
||||
WINEPREFIX = "${XDG_DATA_HOME}/wine";
|
||||
DOTNET_CLI_HOME = "${XDG_DATA_HOME}/dotnet";
|
||||
MPLAYER_HOME = "${XDG_CONFIG_HOME}/mplayer";
|
||||
SQLITE_HISTORY = "${XDG_CACHE_HOME}/sqlite_history";
|
||||
NBRC_PATH = "${XDG_CONFIG_HOME}/nbrc";
|
||||
NB_DIR = "${XDG_DATA_HOME}/nb";
|
||||
|
||||
# programming languages/package managers/tools
|
||||
ANDROID_HOME = "${XDG_DATA_HOME}/android";
|
||||
DOCKER_CONFIG = "${XDG_CONFIG_HOME}/docker";
|
||||
GRADLE_USER_HOME = "${XDG_DATA_HOME}/gradle";
|
||||
IPYTHONDIR = "${XDG_CONFIG_HOME}/ipython";
|
||||
JUPYTER_CONFIG_DIR = "${XDG_CONFIG_HOME}/jupyter";
|
||||
GOPATH = "${XDG_DATA_HOME}/go";
|
||||
M2_HOME = "${XDG_DATA_HOME}/m2";
|
||||
_JAVA_OPTIONS = "-Djava.util.prefs.userRoot=${XDG_CONFIG_HOME}/java";
|
||||
CARGO_HOME = "${XDG_DATA_HOME}/cargo";
|
||||
NODE_REPL_HISTORY = "${XDG_DATA_HOME}/node_repl_history";
|
||||
NPM_CONFIG_CACE = "${XDG_CACHE_HOME}/npm";
|
||||
NPM_CONFIG_TMP = "${XDG_RUNTIME_DIR}/npm";
|
||||
NPM_CONFIG_USERCONFIG = "${XDG_CONFIG_HOME}/npm/config";
|
||||
PYTHONSTARTUP =
|
||||
if system == "nixos"
|
||||
then "/etc/pythonrc"
|
||||
else "${XDG_CONFIG_HOME}/python/pythonrc";
|
||||
};
|
||||
|
||||
npmrc.text = ''
|
||||
prefix=''${XDG_DATA_HOME}/npm
|
||||
cache=''${XDG_CACHE_HOME}/npm
|
||||
init-module=''${XDG_CONFIG_HOME}/npm/config/npm-init.js
|
||||
'';
|
||||
|
||||
pythonrc.text =
|
||||
/*
|
||||
python
|
||||
*/
|
||||
''
|
||||
import os
|
||||
import atexit
|
||||
import readline
|
||||
from pathlib import Path
|
||||
|
||||
if readline.get_current_history_length() == 0:
|
||||
|
||||
state_home = os.environ.get("XDG_STATE_HOME")
|
||||
if state_home is None:
|
||||
state_home = Path.home() / ".local" / "state"
|
||||
else:
|
||||
state_home = Path(state_home)
|
||||
|
||||
history_path = state_home / "python_history"
|
||||
if history_path.is_dir():
|
||||
raise OSError(f"'{history_path}' cannot be a directory")
|
||||
|
||||
history = str(history_path)
|
||||
|
||||
try:
|
||||
readline.read_history_file(history)
|
||||
except OSError: # Non existent
|
||||
pass
|
||||
|
||||
def write_history():
|
||||
try:
|
||||
readline.write_history_file(history)
|
||||
except OSError:
|
||||
pass
|
||||
|
||||
atexit.register(write_history)
|
||||
'';
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue