Compare commits
10 commits
bfbba966c6
...
44fa924c02
Author | SHA1 | Date | |
---|---|---|---|
chaos | 44fa924c02 | ||
chaos | d480efd55c | ||
chaos | 20f1ca70fa | ||
chaos | 78a5e913cf | ||
0e9e741ae3 | |||
dd3790c14d | |||
90f450d7d9 | |||
4206a3f07e | |||
b82f229a6b | |||
73cd331583 |
|
@ -1,37 +0,0 @@
|
||||||
let
|
|
||||||
internalWireGuard = import ../wireguard/chaosInternalWireGuard.nix;
|
|
||||||
ports = import ./pipedClusterPorts.nix;
|
|
||||||
in rec {
|
|
||||||
inherit ports;
|
|
||||||
|
|
||||||
hosts = {
|
|
||||||
# map of hostname to config for cluster node
|
|
||||||
"piped-fi" = rec {
|
|
||||||
ip = "${internalWireGuard.hosts.hetzner-vm.ip}";
|
|
||||||
|
|
||||||
# ssh -L 3014:127.0.0.1:3014 -L 26257:127.0.0.1:26257 hetzner-vm
|
|
||||||
joinString = "${ip}:${toString ports.cockroachDB}";
|
|
||||||
advertiseAddr = joinString;
|
|
||||||
|
|
||||||
resticBucket = "Piped-Finland";
|
|
||||||
|
|
||||||
vaultUserName = "hetzner-vm-container-piped-fi";
|
|
||||||
|
|
||||||
baseDomain = "piped-fi.owo.monster";
|
|
||||||
};
|
|
||||||
|
|
||||||
"piped-uk" = rec {
|
|
||||||
ip = "${internalWireGuard.hosts.raspberry.ip}";
|
|
||||||
|
|
||||||
# ssh -L 3014:127.0.0.1:3014 -L 26257:127.0.0.1:26257 raspberry
|
|
||||||
joinString = "${ip}:${toString ports.cockroachDB}";
|
|
||||||
advertiseAddr = joinString;
|
|
||||||
|
|
||||||
resticBucket = "Piped-UK";
|
|
||||||
|
|
||||||
vaultUserName = "rapsberry-container-piped-uk";
|
|
||||||
|
|
||||||
baseDomain = "piped-uk.owo.monster";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -1,8 +0,0 @@
|
||||||
{
|
|
||||||
internalPipedBackend = 3012;
|
|
||||||
internalPipedProxy = 3013;
|
|
||||||
|
|
||||||
cockroachDB = 26257;
|
|
||||||
cockroachDB_HTTP = 3014;
|
|
||||||
cockroachDB_HAProxy = 26258;
|
|
||||||
}
|
|
|
@ -1,8 +1,4 @@
|
||||||
rec {
|
rec {
|
||||||
"hetzner-vm" = {
|
|
||||||
ipv4 = "65.21.182.73";
|
|
||||||
ipv6 = "2a01:4f9:c010:8beb::1";
|
|
||||||
};
|
|
||||||
"hetzner-arm" = {
|
"hetzner-arm" = {
|
||||||
ipv4 = "65.21.145.62";
|
ipv4 = "65.21.145.62";
|
||||||
ipv6 = "2a01:4f9:c012:9dbf::1";
|
ipv6 = "2a01:4f9:c012:9dbf::1";
|
||||||
|
|
|
@ -2,10 +2,10 @@ let
|
||||||
pubkeys = builtins.fromJSON (builtins.readFile ./chaosInternalWireGuardPubKeys.json);
|
pubkeys = builtins.fromJSON (builtins.readFile ./chaosInternalWireGuardPubKeys.json);
|
||||||
in rec {
|
in rec {
|
||||||
hosts = {
|
hosts = {
|
||||||
"hetzner-vm" = {
|
"hetzner-arm" = {
|
||||||
ip = "10.69.42.1";
|
ip = "10.69.42.1";
|
||||||
public = pubkeys."hetzner-vm";
|
public = pubkeys."hetzner-arm";
|
||||||
endpoint = "hetzner-vm.servers.genderfucked.monster:51820";
|
endpoint = "hetzner-arm.servers.genderfucked.monster:51820";
|
||||||
};
|
};
|
||||||
"vault" = {
|
"vault" = {
|
||||||
ip = "10.69.42.2";
|
ip = "10.69.42.2";
|
||||||
|
@ -25,11 +25,5 @@ in rec {
|
||||||
public = pubkeys."raspberry";
|
public = pubkeys."raspberry";
|
||||||
endpoint = "raspberry.servers.genderfucked.monster:51820";
|
endpoint = "raspberry.servers.genderfucked.monster:51820";
|
||||||
};
|
};
|
||||||
# TODO: make this .1 again after migration like hetzner-vm
|
|
||||||
"hetzner-arm" = {
|
|
||||||
ip = "10.69.42.6";
|
|
||||||
public = pubkeys."hetzner-arm";
|
|
||||||
endpoint = "hetzner-arm.servers.genderfucked.monster:51820";
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
{
|
{
|
||||||
"hetzner-vm": "xgOQQcZQXftPC25+A7Iyf/XK6/iSo3Osyx6kTrZKdzw=",
|
"vault": "0jGdR0yBnjY5CUCQpqWIaWAfgT36QdGdhZXtaAV+MkE=",
|
||||||
"vault": "u8hSeht8xR48O9AN+0cSsXPK0ZZFNcnPhOxdc+rsrlI=",
|
"raspberry": "DXXUfkR4qlytdsf37NGzgzVhDxPuhz8oxRcSxOX2fQk=",
|
||||||
"raspberry": "Ghrs0ps2RCsg0My9seLq+8ZFZCM4NLZWE8RiY3g9/RU=",
|
"lappy-t495": "kyykcuDMWy1WRxX97PImEYgwWw8HUbhM53kW6bEyryA=",
|
||||||
"lappy-t495": "8aZBM3f8/qThiHvGlGP1IHLoe61m/3VTwNzCi7CrhF8=",
|
"iphone8": "1u/G60EWg2bo1iyViWAGXs8HXES2zenZCVdD5X+yJi4=",
|
||||||
"iphone8": "jHPQuWXO5TTBACr4o/tk4bpb+N/x/AjCPGbmqkopOko=",
|
"hetzner-arm": "rCkptlaz5IFSZ+4OPaylbyKVoUwYNWBNkaT63QApymA="
|
||||||
"hetzner-arm": "2SS9jT6Sba61lB2ayhp+2fz+GN706Jr1Ydr6/RveqUQ="
|
|
||||||
}
|
}
|
||||||
|
|
48
flake.lock
48
flake.lock
|
@ -47,11 +47,11 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1694166985,
|
"lastModified": 1695831427,
|
||||||
"narHash": "sha256-8tVqDfKfZ4vbOV5i+E2xWhiNAQVJhaI6shx3e0925S8=",
|
"narHash": "sha256-wyWgooFXg8SLF1DYMLU4JP6aB/zkwRCLBajO8sIeHQM=",
|
||||||
"owner": "ChaotiCryptidz",
|
"owner": "ChaotiCryptidz",
|
||||||
"repo": "gitlab_archiver",
|
"repo": "gitlab_archiver",
|
||||||
"rev": "4aac975a7cc375084c7f9eb4bc60a1c0948c1c28",
|
"rev": "090ace071629556b50087a2e80f9255340b286df",
|
||||||
"type": "gitlab"
|
"type": "gitlab"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
@ -73,11 +73,11 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1694166776,
|
"lastModified": 1695831616,
|
||||||
"narHash": "sha256-wMTnkW98Fx/BpRpSABf9b0PlruVnzd4m3zEQaopE2+o=",
|
"narHash": "sha256-86pme6c8WtplRoZVcZp/zjsq9XnGuBjPrO6V/pAmW94=",
|
||||||
"owner": "ChaotiCryptidz",
|
"owner": "ChaotiCryptidz",
|
||||||
"repo": "gitlab_artifacts_sync",
|
"repo": "gitlab_artifacts_sync",
|
||||||
"rev": "09a5988927a3493585357f5d61abdce3a9e4da17",
|
"rev": "5099274ccff8fae50979ce94eb5287c3dcf5b914",
|
||||||
"type": "gitlab"
|
"type": "gitlab"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
@ -93,11 +93,11 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1694643239,
|
"lastModified": 1695738267,
|
||||||
"narHash": "sha256-pv2k/5FvyirDE8g4TNehzwZ0T4UOMMmqWSQnM/luRtE=",
|
"narHash": "sha256-LTNAbTQ96xSj17xBfsFrFS9i56U2BMLpD0BduhrsVkU=",
|
||||||
"owner": "nix-community",
|
"owner": "nix-community",
|
||||||
"repo": "home-manager",
|
"repo": "home-manager",
|
||||||
"rev": "d9b88b43524db1591fb3d9410a21428198d75d49",
|
"rev": "0f4e5b4999fd6a42ece5da8a3a2439a50e48e486",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
@ -119,11 +119,11 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1694166910,
|
"lastModified": 1695831628,
|
||||||
"narHash": "sha256-6Vxz6H4H3bfl1PUCeHTmIKg96PHwJEzkE7XRN09y5nM=",
|
"narHash": "sha256-UyVJXVWjbZ4TLgCeOVYUE44ekfD5duUfA2akoc1VGj0=",
|
||||||
"owner": "ChaotiCryptidz",
|
"owner": "ChaotiCryptidz",
|
||||||
"repo": "musicutil",
|
"repo": "musicutil",
|
||||||
"rev": "7580e1fd0164e414a11e03c1037b37722160df25",
|
"rev": "0e9aceb2b9b418f876a5fcd549420edbf8e8fdcb",
|
||||||
"type": "gitlab"
|
"type": "gitlab"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
@ -134,11 +134,11 @@
|
||||||
},
|
},
|
||||||
"nixpkgs-unstable": {
|
"nixpkgs-unstable": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1694669921,
|
"lastModified": 1695644571,
|
||||||
"narHash": "sha256-6ESpJ6FsftHV96JO/zn6je07tyV2dlLR7SdLsmkegTY=",
|
"narHash": "sha256-asS9dCCdlt1lPq0DLwkVBbVoEKuEuz+Zi3DG7pR/RxA=",
|
||||||
"owner": "nixos",
|
"owner": "nixos",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "f2ea252d23ebc9a5336bf6a61e0644921f64e67c",
|
"rev": "6500b4580c2a1f3d0f980d32d285739d8e156d92",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
@ -150,11 +150,11 @@
|
||||||
},
|
},
|
||||||
"nur": {
|
"nur": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1694778311,
|
"lastModified": 1695844033,
|
||||||
"narHash": "sha256-Hu5U9pXwMqUjWF7uh4SKqdKy1QMy9RVGxmst11srSgA=",
|
"narHash": "sha256-UX5sbK9dc/bOupgDGWer75zBjoh7eWIheyGGCjD7FIg=",
|
||||||
"owner": "nix-community",
|
"owner": "nix-community",
|
||||||
"repo": "NUR",
|
"repo": "NUR",
|
||||||
"rev": "7a673ac1f35648a908730206a2793b0e3818bc25",
|
"rev": "f08568d903901b7ac1017572b9af9855e935155a",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
@ -176,11 +176,11 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1695142252,
|
"lastModified": 1695847501,
|
||||||
"narHash": "sha256-rcYxKVb6Mpna3xNSwRHMw/Yzw3tky0+JuMLM5qoBiUw=",
|
"narHash": "sha256-UxYiNfUApZ6IYJ0U83CzRBSRvmApDHMWa5o9WT99ukM=",
|
||||||
"owner": "ChaotiCryptidz",
|
"owner": "ChaotiCryptidz",
|
||||||
"repo": "piped-flake",
|
"repo": "piped-flake",
|
||||||
"rev": "994a8e983eef9071d73c9b2daad9bd42aac0b1aa",
|
"rev": "2a03d86df5075f5060704bb68742af2ace8973e3",
|
||||||
"type": "gitlab"
|
"type": "gitlab"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
@ -268,11 +268,11 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1694618271,
|
"lastModified": 1695831820,
|
||||||
"narHash": "sha256-8y2/x27QkhRtTZ/3A0HOmfNJT0hDSk+2ZSGyKB46Q40=",
|
"narHash": "sha256-ZhSQqGg32WA/WYsjPMuYU96GgyljszPcjvc+GBLZVpY=",
|
||||||
"owner": "ChaotiCryptidz",
|
"owner": "ChaotiCryptidz",
|
||||||
"repo": "VaultUI",
|
"repo": "VaultUI",
|
||||||
"rev": "6365eb49cec7eb8a76a24160b25363cf4a8bfa40",
|
"rev": "d5fc05612e44cc2c8307186b0d36f7022d7a2f91",
|
||||||
"type": "gitlab"
|
"type": "gitlab"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|
|
@ -106,10 +106,7 @@ in {
|
||||||
# browser toolbar and UI
|
# browser toolbar and UI
|
||||||
# may need updating when extensions change
|
# may need updating when extensions change
|
||||||
"browser.toolbars.bookmarks.visibility" = "always";
|
"browser.toolbars.bookmarks.visibility" = "always";
|
||||||
"layout.css.devPixelsPerPx" =
|
"layout.css.devPixelsPerPx" = "1.4";
|
||||||
if nixosConfig.networking.hostName == "lappy-t495"
|
|
||||||
then "1.4"
|
|
||||||
else "1.8";
|
|
||||||
"browser.uiCustomization.state" = builtins.toJSON {
|
"browser.uiCustomization.state" = builtins.toJSON {
|
||||||
currentVersion = 18;
|
currentVersion = 18;
|
||||||
dirtyAreaCache = [
|
dirtyAreaCache = [
|
||||||
|
|
|
@ -7,22 +7,22 @@
|
||||||
inherit (lib.lists) forEach;
|
inherit (lib.lists) forEach;
|
||||||
inherit (builtins) attrNames;
|
inherit (builtins) attrNames;
|
||||||
|
|
||||||
containerAddresses = import "${self}/hosts/hetzner-vm/data/containerAddresses.nix";
|
containerAddresses = import "${self}/hosts/hetzner-arm/data/containerAddresses.nix";
|
||||||
in {
|
in {
|
||||||
programs.ssh.enable = true;
|
programs.ssh.enable = true;
|
||||||
programs.ssh.matchBlocks =
|
programs.ssh.matchBlocks =
|
||||||
mkMerge
|
mkMerge
|
||||||
((forEach ["hetzner-vm" "vault" "raspberry" "vault-decrypt"] (hostname: {
|
((forEach ["hetzner-arm" "hetzner-arm-decrypt" "vault" "vault-decrypt" "raspberry"] (hostname: {
|
||||||
"${hostname}" = {
|
"${hostname}" = {
|
||||||
user = "root";
|
user = "root";
|
||||||
hostname = "${hostname}.servers.genderfucked.monster";
|
hostname = "${hostname}.servers.genderfucked.monster";
|
||||||
};
|
};
|
||||||
}))
|
}))
|
||||||
++ (forEach (attrNames containerAddresses.containers) (name: {
|
++ (forEach (attrNames containerAddresses.containers) (name: {
|
||||||
"hetzner-vm-container-${name}" = {
|
"hetzner-arm-container-${name}" = {
|
||||||
user = "root";
|
user = "root";
|
||||||
hostname = "${containerAddresses.containers.${name}}";
|
hostname = "${containerAddresses.containers.${name}}";
|
||||||
proxyJump = "hetzner-vm";
|
proxyJump = "hetzner-arm";
|
||||||
};
|
};
|
||||||
}))
|
}))
|
||||||
++ [
|
++ [
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
tmux
|
tmux
|
||||||
socat
|
socat
|
||||||
file
|
file
|
||||||
|
python3
|
||||||
binutils # for strings
|
binutils # for strings
|
||||||
|
|
||||||
# (pkgs.busybox.override {enableAppletSymlinks = false;})
|
# (pkgs.busybox.override {enableAppletSymlinks = false;})
|
||||||
|
|
|
@ -1,10 +1,21 @@
|
||||||
{pkgs, ...}: {
|
{pkgs, ...}: let
|
||||||
|
gitPackage = pkgs.gitAndTools.gitFull;
|
||||||
|
in {
|
||||||
programs.git = {
|
programs.git = {
|
||||||
enable = true;
|
enable = true;
|
||||||
lfs.enable = true;
|
lfs.enable = true;
|
||||||
package = pkgs.gitAndTools.gitFull;
|
package = gitPackage;
|
||||||
userName = "chaos";
|
userName = "chaos";
|
||||||
userEmail = "chaoticryptidz@owo.monster";
|
userEmail = "chaos@owo.monster";
|
||||||
extraConfig = {credential = {helper = "store";};};
|
extraConfig = {credential.helper = "store";};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
home.packages = [
|
||||||
|
(pkgs.runCommand "git-extras" {} (let
|
||||||
|
gitLibExec = "${gitPackage}/libexec/git-core";
|
||||||
|
in ''
|
||||||
|
mkdir -p $out/bin
|
||||||
|
ln -s ${gitLibExec}/git-diff $out/bin/git-diff
|
||||||
|
''))
|
||||||
|
];
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
{pkgs, ...}: {
|
{pkgs, ...}: {
|
||||||
home.packages = with pkgs; [neofetch inxi htop pciutils usbutils iotop iptraf-ng];
|
home.packages = with pkgs; [neofetch inxi btop htop pciutils usbutils iotop iptraf-ng];
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,5 +9,7 @@
|
||||||
openssh
|
openssh
|
||||||
nmap
|
nmap
|
||||||
tcpdump
|
tcpdump
|
||||||
|
iftop
|
||||||
|
speedtest-cli
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,8 +3,12 @@
|
||||||
nixosConfig,
|
nixosConfig,
|
||||||
pkgs,
|
pkgs,
|
||||||
inputs,
|
inputs,
|
||||||
|
lib,
|
||||||
...
|
...
|
||||||
}: let
|
}: let
|
||||||
|
inherit (lib.lists) optional;
|
||||||
|
inherit (lib.modules) mkIf;
|
||||||
|
|
||||||
homeManagerLib = inputs.home-manager.lib.hm;
|
homeManagerLib = inputs.home-manager.lib.hm;
|
||||||
|
|
||||||
fontSizesAll = {
|
fontSizesAll = {
|
||||||
|
@ -18,10 +22,16 @@
|
||||||
if fontSizesAll ? nixosConfig.networking.hostName
|
if fontSizesAll ? nixosConfig.networking.hostName
|
||||||
then fontSizesAll.${nixosConfig.networking.hostName}
|
then fontSizesAll.${nixosConfig.networking.hostName}
|
||||||
else fontSizesAll.default;
|
else fontSizesAll.default;
|
||||||
in {
|
|
||||||
imports = with tree; [home.gui.base home.apps.kitty];
|
|
||||||
|
|
||||||
home.packages = with pkgs; [dconf2nix gnome.dconf-editor xclip];
|
isWayland = nixosConfig.services.xserver.displayManager.gdm.wayland;
|
||||||
|
in {
|
||||||
|
imports = with tree; [home.gui.base home.apps.kitty] ++ (optional isWayland home.apps.rofi);
|
||||||
|
|
||||||
|
home.packages = with pkgs; [
|
||||||
|
dconf2nix
|
||||||
|
gnome.dconf-editor
|
||||||
|
xclip
|
||||||
|
];
|
||||||
|
|
||||||
home.sessionVariables = {
|
home.sessionVariables = {
|
||||||
SAL_USE_VCLPLUGIN = "gtk3"; # GTK3 on LibreOffice
|
SAL_USE_VCLPLUGIN = "gtk3"; # GTK3 on LibreOffice
|
||||||
|
@ -126,17 +136,18 @@ in {
|
||||||
area-screenshot-clip = ["<Shift>Print"];
|
area-screenshot-clip = ["<Shift>Print"];
|
||||||
screenshot = [];
|
screenshot = [];
|
||||||
screenshot-clip = ["Print"];
|
screenshot-clip = ["Print"];
|
||||||
|
search = mkIf isWayland ["<Alt>d"];
|
||||||
custom-keybindings = [
|
custom-keybindings = [
|
||||||
# Rofi & Kitty
|
# Rofi & Kitty
|
||||||
#"/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/rofi/"
|
"/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/rofi/"
|
||||||
"/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/kitty/"
|
"/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/kitty/"
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
#"org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/rofi" = {
|
"org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/rofi" = mkIf (!isWayland) {
|
||||||
# binding = "<Alt>d";
|
binding = "<Alt>d";
|
||||||
# command = "rofi -show run";
|
command = "rofi -show run";
|
||||||
# name = "rofi";
|
name = "rofi";
|
||||||
#};
|
};
|
||||||
"org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/kitty" = {
|
"org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/kitty" = {
|
||||||
binding = "<Alt>Return";
|
binding = "<Alt>Return";
|
||||||
command = "kitty";
|
command = "kitty";
|
||||||
|
|
|
@ -8,8 +8,7 @@
|
||||||
hostPath,
|
hostPath,
|
||||||
...
|
...
|
||||||
}: let
|
}: let
|
||||||
inherit (lib.modules) mkMerge;
|
inherit (lib.modules) mkMerge mkForce;
|
||||||
inherit (lib.lists) forEach;
|
|
||||||
|
|
||||||
ports = [
|
ports = [
|
||||||
# SMTP
|
# SMTP
|
||||||
|
@ -26,20 +25,6 @@
|
||||||
4190
|
4190
|
||||||
];
|
];
|
||||||
|
|
||||||
containerLib = import "${self}/lib/containerLib.nix" {
|
|
||||||
inherit lib;
|
|
||||||
};
|
|
||||||
|
|
||||||
# Using secrets from Host
|
|
||||||
secrets = config.services.secrets.secrets;
|
|
||||||
secretsList = [
|
|
||||||
"mail_restic_password"
|
|
||||||
"mail_restic_env"
|
|
||||||
"private_mail_aliases"
|
|
||||||
"chaos_mail_passwd"
|
|
||||||
"system_mail_passwd"
|
|
||||||
"gotosocial_mail_passwd"
|
|
||||||
];
|
|
||||||
sharedFiles = [
|
sharedFiles = [
|
||||||
"/var/lib/acme/mail.owo.monster/fullchain.pem"
|
"/var/lib/acme/mail.owo.monster/fullchain.pem"
|
||||||
"/var/lib/acme/mail.owo.monster/key.pem"
|
"/var/lib/acme/mail.owo.monster/key.pem"
|
||||||
|
@ -48,74 +33,51 @@ in {
|
||||||
containers.mail = {
|
containers.mail = {
|
||||||
autoStart = true;
|
autoStart = true;
|
||||||
|
|
||||||
bindMounts = mkMerge [
|
bindMounts = mkMerge (map (file: {
|
||||||
(containerLib.genBindHostsForSecrets secrets secretsList)
|
|
||||||
|
|
||||||
(mkMerge (forEach sharedFiles (file: {
|
|
||||||
"${file}" = {
|
"${file}" = {
|
||||||
hostPath = "${file}";
|
hostPath = "${file}";
|
||||||
};
|
};
|
||||||
})))
|
})
|
||||||
];
|
sharedFiles);
|
||||||
|
|
||||||
specialArgs = {
|
specialArgs = {
|
||||||
inherit inputs;
|
inherit inputs;
|
||||||
inherit tree;
|
inherit tree;
|
||||||
inherit self;
|
inherit self;
|
||||||
inherit hostPath;
|
inherit hostPath;
|
||||||
hostSecrets = secrets;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
config = {config, ...}: {
|
config = {...}: {
|
||||||
nixpkgs.pkgs = pkgs;
|
nixpkgs.pkgs = pkgs;
|
||||||
|
|
||||||
imports = with tree;
|
imports = with tree;
|
||||||
[
|
[
|
||||||
profiles.base
|
presets.nixos.containerBase
|
||||||
inputs.home-manager-unstable.nixosModules.home-manager
|
|
||||||
|
|
||||||
profiles.nginx
|
profiles.nginx
|
||||||
modules.nixos.secrets
|
|
||||||
|
|
||||||
users.root
|
./secrets.nix
|
||||||
]
|
]
|
||||||
++ (with hosts.hetzner-vm.containers.mail; [
|
++ (with hosts.hetzner-arm.containers.mail; [
|
||||||
modules.mailserver
|
modules.mailserver
|
||||||
profiles.mailserver
|
profiles.mailserver
|
||||||
profiles.restic
|
profiles.restic
|
||||||
]);
|
]);
|
||||||
|
|
||||||
# For Shared Secrets
|
|
||||||
systemd.tmpfiles.rules = [
|
systemd.tmpfiles.rules = [
|
||||||
"d ${config.services.secrets.secretsDir} - root root"
|
|
||||||
"d /var/lib/acme - root root"
|
"d /var/lib/acme - root root"
|
||||||
"d /var/lib/acme/mail.owo.monster - root root"
|
"d /var/lib/acme/mail.owo.monster - root root"
|
||||||
];
|
];
|
||||||
|
|
||||||
networking.firewall = {
|
networking.firewall = {
|
||||||
enable = false;
|
enable = mkForce false;
|
||||||
};
|
};
|
||||||
|
|
||||||
home-manager.users.root = {
|
home-manager.users.root.home.stateVersion = "23.05";
|
||||||
imports = with tree; [home.base home.dev.small];
|
|
||||||
|
|
||||||
home.stateVersion = "23.05";
|
|
||||||
};
|
|
||||||
|
|
||||||
# Manually configure nameserver. Using resolved inside the container seems to fail
|
|
||||||
# currently
|
|
||||||
environment.etc."resolv.conf".text = "nameserver 8.8.8.8";
|
|
||||||
system.stateVersion = "23.05";
|
system.stateVersion = "23.05";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
# users for secrets
|
|
||||||
users.users."dovecot2" = {
|
|
||||||
uid = config.ids.uids.dovecot2;
|
|
||||||
group = "dovecot2";
|
|
||||||
};
|
|
||||||
users.groups."dovecot2".gid = config.ids.gids.dovecot2;
|
|
||||||
|
|
||||||
# ssl for mail
|
# ssl for mail
|
||||||
services.nginx = {
|
services.nginx = {
|
||||||
enable = true;
|
enable = true;
|
|
@ -1,9 +1,9 @@
|
||||||
{
|
{
|
||||||
pkgs,
|
pkgs,
|
||||||
hostSecrets,
|
config,
|
||||||
...
|
...
|
||||||
}: let
|
}: let
|
||||||
secrets = hostSecrets;
|
secrets = config.services.secrets.secrets;
|
||||||
in {
|
in {
|
||||||
services.mailserver = {
|
services.mailserver = {
|
||||||
enable = true;
|
enable = true;
|
|
@ -1,11 +1,12 @@
|
||||||
{
|
{
|
||||||
pkgs,
|
pkgs,
|
||||||
config,
|
config,
|
||||||
hostSecrets,
|
|
||||||
...
|
...
|
||||||
}: let
|
}: let
|
||||||
secrets = hostSecrets;
|
secrets = config.services.secrets.secrets;
|
||||||
|
|
||||||
mailConfig = config.services.mailserver;
|
mailConfig = config.services.mailserver;
|
||||||
|
|
||||||
backupPrepareCommand = "${
|
backupPrepareCommand = "${
|
||||||
(pkgs.writeShellScriptBin "backupPrepareCommand" ''
|
(pkgs.writeShellScriptBin "backupPrepareCommand" ''
|
||||||
systemctl start postgresqlBackup-roundcube --wait
|
systemctl start postgresqlBackup-roundcube --wait
|
||||||
|
@ -16,8 +17,8 @@ in {
|
||||||
restic
|
restic
|
||||||
(pkgs.writeShellScriptBin "restic-mail" ''
|
(pkgs.writeShellScriptBin "restic-mail" ''
|
||||||
env \
|
env \
|
||||||
RESTIC_PASSWORD_FILE=${secrets.mail_restic_password.path} \
|
RESTIC_PASSWORD_FILE=${secrets.restic_password.path} \
|
||||||
$(cat ${secrets.mail_restic_env.path}) \
|
$(cat ${secrets.restic_env.path}) \
|
||||||
${pkgs.restic}/bin/restic $@
|
${pkgs.restic}/bin/restic $@
|
||||||
'')
|
'')
|
||||||
];
|
];
|
||||||
|
@ -36,8 +37,8 @@ in {
|
||||||
# repository is overrided in environmentFile to contain auth
|
# repository is overrided in environmentFile to contain auth
|
||||||
# make sure to keep up to date when changing repository
|
# make sure to keep up to date when changing repository
|
||||||
repository = "rest:https://storage-restic.owo.monster/Mail";
|
repository = "rest:https://storage-restic.owo.monster/Mail";
|
||||||
passwordFile = "${secrets.mail_restic_password.path}";
|
passwordFile = "${secrets.restic_password.path}";
|
||||||
environmentFile = "${secrets.mail_restic_env.path}";
|
environmentFile = "${secrets.restic_env.path}";
|
||||||
|
|
||||||
pruneOpts = [
|
pruneOpts = [
|
||||||
"--keep-last 5"
|
"--keep-last 5"
|
75
hosts/hetzner-arm/containers/mail/secrets.nix
Normal file
75
hosts/hetzner-arm/containers/mail/secrets.nix
Normal file
|
@ -0,0 +1,75 @@
|
||||||
|
{pkgs, ...}: {
|
||||||
|
services.secrets = {
|
||||||
|
enable = true;
|
||||||
|
|
||||||
|
vaultLogin = {
|
||||||
|
enable = true;
|
||||||
|
loginUsername = "hetzner-arm-container-mail";
|
||||||
|
};
|
||||||
|
|
||||||
|
autoSecrets = {
|
||||||
|
enable = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
requiredVaultPaths = [
|
||||||
|
"api-keys/data/storage/restic/Mail"
|
||||||
|
"api-keys/data/chaos_mail/system"
|
||||||
|
"api-keys/data/chaos_mail/gotosocial"
|
||||||
|
"passwords/data/mail"
|
||||||
|
"private-public-keys/data/restic/Mail"
|
||||||
|
"infra/data/private-mail-aliases"
|
||||||
|
];
|
||||||
|
|
||||||
|
packages = with pkgs; [
|
||||||
|
apacheHttpd
|
||||||
|
];
|
||||||
|
|
||||||
|
secrets = {
|
||||||
|
vault_password = {
|
||||||
|
manual = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
restic_password = {
|
||||||
|
fetchScript = ''
|
||||||
|
simple_get "/private-public-keys/restic/Mail" .password > "$secretFile"
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
restic_env = {
|
||||||
|
fetchScript = ''
|
||||||
|
RESTIC_USERNAME=$(simple_get "/api-keys/storage/restic/Mail" .username)
|
||||||
|
RESTIC_PASSWORD=$(simple_get "/api-keys/storage/restic/Mail" .password)
|
||||||
|
echo "RESTIC_REPOSITORY=rest:https://$RESTIC_USERNAME:$RESTIC_PASSWORD@storage-restic.owo.monster/Mail" > "$secretFile"
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
private_mail_aliases = {
|
||||||
|
fetchScript = ''
|
||||||
|
kv_get "/infra/private-mail-aliases" | jq .data.data | jq -r 'to_entries|map("\(.key) \(.value.to)")[]' > "$secretFile"
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
chaos_mail_passwd = {
|
||||||
|
user = "dovecot2";
|
||||||
|
group = "dovecot2";
|
||||||
|
fetchScript = ''
|
||||||
|
password=$(simple_get "/passwords/mail" .password)
|
||||||
|
htpasswd -nbB "" "$password" 2>/dev/null | cut -d: -f2 > "$secretFile"
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
system_mail_passwd = {
|
||||||
|
user = "dovecot2";
|
||||||
|
group = "dovecot2";
|
||||||
|
fetchScript = ''
|
||||||
|
password=$(simple_get "/api-keys/chaos_mail/system" .password)
|
||||||
|
htpasswd -nbB "" "$password" 2>/dev/null | cut -d: -f2 > "$secretFile"
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
gotosocial_mail_passwd = {
|
||||||
|
user = "dovecot2";
|
||||||
|
group = "dovecot2";
|
||||||
|
fetchScript = ''
|
||||||
|
password=$(simple_get "/api-keys/chaos_mail/gotosocial" .password)
|
||||||
|
htpasswd -nbB "" "$password" 2>/dev/null | cut -d: -f2 > "$secretFile"
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
|
@ -4,50 +4,40 @@
|
||||||
tree,
|
tree,
|
||||||
lib,
|
lib,
|
||||||
inputs,
|
inputs,
|
||||||
config,
|
|
||||||
pkgs,
|
pkgs,
|
||||||
|
config,
|
||||||
...
|
...
|
||||||
}: let
|
}: let
|
||||||
inherit (lib.modules) mkMerge;
|
inherit (lib.modules) mkMerge;
|
||||||
inherit (lib.lists) forEach;
|
inherit (lib.lists) forEach;
|
||||||
|
|
||||||
|
containerName = "music";
|
||||||
|
|
||||||
containerAddresses = import "${hostPath}/data/containerAddresses.nix";
|
containerAddresses = import "${hostPath}/data/containerAddresses.nix";
|
||||||
|
|
||||||
hostIP = containerAddresses.host;
|
hostIP = containerAddresses.host;
|
||||||
containerIP = containerAddresses.containers.${containerName};
|
containerIP = containerAddresses.containers.${containerName};
|
||||||
|
|
||||||
containerName = "music";
|
|
||||||
containerConfig = config.containers.${containerName}.config;
|
|
||||||
|
|
||||||
containerLib = import "${self}/lib/containerLib.nix" {
|
|
||||||
inherit lib;
|
|
||||||
};
|
|
||||||
|
|
||||||
# Using secrets from Host
|
|
||||||
secrets = config.services.secrets.secrets;
|
|
||||||
secretsList = [
|
|
||||||
"mpd_control_password"
|
|
||||||
"slskd_env"
|
|
||||||
];
|
|
||||||
|
|
||||||
ports = import ./data/ports.nix;
|
ports = import ./data/ports.nix;
|
||||||
|
|
||||||
|
# these secrets should probs be in host but im lazy
|
||||||
|
containerSecrets = config.containers.${containerName}.config.services.secrets.secrets;
|
||||||
|
pathInContainer = path: "/var/lib/nixos-containers/${containerName}" + path;
|
||||||
in {
|
in {
|
||||||
containers.music = {
|
containers.music = {
|
||||||
autoStart = true;
|
autoStart = true;
|
||||||
privateNetwork = true;
|
privateNetwork = true;
|
||||||
hostAddress = hostIP;
|
hostAddress = hostIP;
|
||||||
localAddress = containerIP;
|
localAddress = containerIP;
|
||||||
bindMounts = containerLib.genBindHostsForSecrets secrets secretsList;
|
|
||||||
|
|
||||||
specialArgs = {
|
specialArgs = {
|
||||||
inherit inputs;
|
inherit inputs;
|
||||||
inherit tree;
|
inherit tree;
|
||||||
inherit self;
|
inherit self;
|
||||||
inherit hostPath;
|
inherit hostPath;
|
||||||
hostSecrets = secrets;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
config = {config, ...}: {
|
config = {...}: {
|
||||||
nixpkgs.pkgs = pkgs;
|
nixpkgs.pkgs = pkgs;
|
||||||
|
|
||||||
imports = with tree;
|
imports = with tree;
|
||||||
|
@ -58,8 +48,10 @@ in {
|
||||||
|
|
||||||
profiles.nginx
|
profiles.nginx
|
||||||
profiles.firewallAllow.httpCommon
|
profiles.firewallAllow.httpCommon
|
||||||
|
|
||||||
|
./secrets.nix
|
||||||
]
|
]
|
||||||
++ (with hosts.hetzner-vm.containers.music; [
|
++ (with hosts.hetzner-arm.containers.music; [
|
||||||
profiles.mpd
|
profiles.mpd
|
||||||
profiles.musicSync
|
profiles.musicSync
|
||||||
profiles.soulseek
|
profiles.soulseek
|
||||||
|
@ -75,11 +67,6 @@ in {
|
||||||
slskd-web
|
slskd-web
|
||||||
];
|
];
|
||||||
|
|
||||||
# For Shared Secrets
|
|
||||||
systemd.tmpfiles.rules = [
|
|
||||||
"d ${config.services.secrets.secretsDir} - root root"
|
|
||||||
];
|
|
||||||
|
|
||||||
home-manager.users.root.home.stateVersion = "23.05";
|
home-manager.users.root.home.stateVersion = "23.05";
|
||||||
system.stateVersion = "23.05";
|
system.stateVersion = "23.05";
|
||||||
};
|
};
|
||||||
|
@ -97,7 +84,7 @@ in {
|
||||||
services.nginx.virtualHosts."stream.owo.monster" = let
|
services.nginx.virtualHosts."stream.owo.monster" = let
|
||||||
extraConfig = ''
|
extraConfig = ''
|
||||||
auth_basic "Music Password";
|
auth_basic "Music Password";
|
||||||
auth_basic_user_file ${secrets.music_stream_passwd.path};
|
auth_basic_user_file ${pathInContainer containerSecrets.music_stream_passwd.path};
|
||||||
'';
|
'';
|
||||||
in {
|
in {
|
||||||
forceSSL = true;
|
forceSSL = true;
|
||||||
|
@ -118,15 +105,6 @@ in {
|
||||||
})));
|
})));
|
||||||
};
|
};
|
||||||
|
|
||||||
# For permissions of secrets
|
|
||||||
users.users."mpd" = {
|
|
||||||
uid = containerConfig.ids.uids.mpd;
|
|
||||||
group = "mpd";
|
|
||||||
};
|
|
||||||
users.groups."mpd" = {
|
|
||||||
gid = containerConfig.ids.gids.mpd;
|
|
||||||
};
|
|
||||||
|
|
||||||
networking = {
|
networking = {
|
||||||
nat.forwardPorts = [
|
nat.forwardPorts = [
|
||||||
{
|
{
|
|
@ -1,14 +1,14 @@
|
||||||
{
|
{
|
||||||
lib,
|
lib,
|
||||||
pkgs,
|
pkgs,
|
||||||
hostSecrets,
|
config,
|
||||||
...
|
...
|
||||||
}: let
|
}: let
|
||||||
inherit (lib.strings) concatStringsSep;
|
inherit (lib.strings) concatStringsSep;
|
||||||
inherit (lib.lists) forEach;
|
inherit (lib.lists) forEach;
|
||||||
|
|
||||||
ports = import ../data/ports.nix;
|
ports = import ../data/ports.nix;
|
||||||
secrets = hostSecrets;
|
secrets = config.services.secrets.secrets;
|
||||||
in {
|
in {
|
||||||
environment.systemPackages = with pkgs; [
|
environment.systemPackages = with pkgs; [
|
||||||
mpc_cli
|
mpc_cli
|
|
@ -1,10 +1,10 @@
|
||||||
{
|
{
|
||||||
lib,
|
lib,
|
||||||
hostSecrets,
|
config,
|
||||||
...
|
...
|
||||||
}: let
|
}: let
|
||||||
ports = import ../data/ports.nix;
|
ports = import ../data/ports.nix;
|
||||||
secrets = hostSecrets;
|
secrets = config.services.secrets.secrets;
|
||||||
|
|
||||||
inherit (lib.modules) mkForce;
|
inherit (lib.modules) mkForce;
|
||||||
in {
|
in {
|
57
hosts/hetzner-arm/containers/music/secrets.nix
Normal file
57
hosts/hetzner-arm/containers/music/secrets.nix
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
{pkgs, ...}: {
|
||||||
|
services.secrets = {
|
||||||
|
enable = true;
|
||||||
|
|
||||||
|
vaultLogin = {
|
||||||
|
enable = true;
|
||||||
|
loginUsername = "hetzner-arm-container-music";
|
||||||
|
};
|
||||||
|
|
||||||
|
autoSecrets = {
|
||||||
|
enable = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
requiredVaultPaths = [
|
||||||
|
"api-keys/data/mpd"
|
||||||
|
"api-keys/data/music-stream"
|
||||||
|
"passwords/data/soulseek"
|
||||||
|
"passwords/data/slskd"
|
||||||
|
];
|
||||||
|
|
||||||
|
packages = with pkgs; [
|
||||||
|
apacheHttpd
|
||||||
|
];
|
||||||
|
|
||||||
|
secrets = {
|
||||||
|
vault_password = {
|
||||||
|
manual = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
mpd_control_password = {
|
||||||
|
user = "mpd";
|
||||||
|
group = "mpd";
|
||||||
|
fetchScript = ''
|
||||||
|
simple_get "/api-keys/mpd" .password > "$secretFile"
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
music_stream_passwd = {
|
||||||
|
user = "nginx";
|
||||||
|
group = "nginx";
|
||||||
|
fetchScript = ''
|
||||||
|
username=$(simple_get "/api-keys/music-stream" .username)
|
||||||
|
password=$(simple_get "/api-keys/music-stream" .password)
|
||||||
|
htpasswd -bc "$secretFile" "$username" "$password" 2>/dev/null
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
slskd_env = {
|
||||||
|
fetchScript = ''
|
||||||
|
soulseek_password=$(simple_get "/passwords/soulseek" .password)
|
||||||
|
slskd_password=$(simple_get "/passwords/slskd" .password)
|
||||||
|
echo > "$secretFile"
|
||||||
|
echo "SLSKD_SLSK_PASSWORD=$soulseek_password" >> "$secretFile"
|
||||||
|
echo "SLSKD_PASSWORD=$slskd_password" >> "$secretFile"
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
41
hosts/hetzner-arm/containers/piped-db/default.nix
Normal file
41
hosts/hetzner-arm/containers/piped-db/default.nix
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
{
|
||||||
|
self,
|
||||||
|
hostPath,
|
||||||
|
tree,
|
||||||
|
inputs,
|
||||||
|
config,
|
||||||
|
pkgs,
|
||||||
|
lib,
|
||||||
|
...
|
||||||
|
}: let
|
||||||
|
inherit (lib.modules) mkForce;
|
||||||
|
in {
|
||||||
|
containers.piped-db = {
|
||||||
|
autoStart = true;
|
||||||
|
privateNetwork = false;
|
||||||
|
|
||||||
|
specialArgs = {
|
||||||
|
inherit inputs;
|
||||||
|
inherit tree;
|
||||||
|
inherit self;
|
||||||
|
inherit hostPath;
|
||||||
|
};
|
||||||
|
|
||||||
|
config = {...}: {
|
||||||
|
nixpkgs.pkgs = pkgs;
|
||||||
|
|
||||||
|
imports = with tree; [
|
||||||
|
presets.nixos.containerBase
|
||||||
|
./secrets.nix
|
||||||
|
|
||||||
|
./profiles/postgres.nix
|
||||||
|
./profiles/restic.nix
|
||||||
|
];
|
||||||
|
|
||||||
|
networking.firewall.enable = mkForce false;
|
||||||
|
|
||||||
|
home-manager.users.root.home.stateVersion = "23.05";
|
||||||
|
system.stateVersion = "23.05";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
21
hosts/hetzner-arm/containers/piped-db/profiles/postgres.nix
Normal file
21
hosts/hetzner-arm/containers/piped-db/profiles/postgres.nix
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
{self, ...}: let
|
||||||
|
wireguardData = import "${self}/data/wireguard/chaosInternalWireGuard.nix";
|
||||||
|
wireguardHosts = wireguardData.hosts;
|
||||||
|
in {
|
||||||
|
services.postgresql = {
|
||||||
|
enable = true;
|
||||||
|
port = 5434;
|
||||||
|
enableTCPIP = true;
|
||||||
|
ensureUsers = [
|
||||||
|
{
|
||||||
|
name = "piped";
|
||||||
|
ensurePermissions."DATABASE piped" = "ALL PRIVILEGES";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
ensureDatabases = ["piped"];
|
||||||
|
authentication = ''
|
||||||
|
host piped piped ${wireguardHosts."raspberry".ip}/32 trust
|
||||||
|
host piped piped ${wireguardHosts."hetzner-arm".ip}/32 trust
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
}
|
55
hosts/hetzner-arm/containers/piped-db/profiles/restic.nix
Normal file
55
hosts/hetzner-arm/containers/piped-db/profiles/restic.nix
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
{
|
||||||
|
pkgs,
|
||||||
|
config,
|
||||||
|
...
|
||||||
|
}: let
|
||||||
|
secrets = config.services.secrets.secrets;
|
||||||
|
|
||||||
|
backupPrepareCommand = "${
|
||||||
|
(pkgs.writeShellScriptBin "backupPrepareCommand" ''
|
||||||
|
systemctl start postgresqlBackup-piped --wait
|
||||||
|
'')
|
||||||
|
}/bin/backupPrepareCommand";
|
||||||
|
in {
|
||||||
|
environment.systemPackages = with pkgs; [
|
||||||
|
restic
|
||||||
|
(pkgs.writeShellScriptBin "restic-piped" ''
|
||||||
|
env \
|
||||||
|
RESTIC_PASSWORD_FILE=${secrets.restic_password.path} \
|
||||||
|
$(cat ${secrets.restic_env.path}) \
|
||||||
|
${pkgs.restic}/bin/restic $@
|
||||||
|
'')
|
||||||
|
];
|
||||||
|
|
||||||
|
services.restic.backups.piped = {
|
||||||
|
user = "root";
|
||||||
|
paths = [
|
||||||
|
"/var/backup/postgresql"
|
||||||
|
];
|
||||||
|
|
||||||
|
# repository is overrided in environmentFile to contain auth
|
||||||
|
# make sure to keep up to date when changing repository
|
||||||
|
repository = "rest:https://storage-restic.owo.monster/Piped";
|
||||||
|
passwordFile = "${secrets.restic_password.path}";
|
||||||
|
environmentFile = "${secrets.restic_env.path}";
|
||||||
|
|
||||||
|
pruneOpts = [
|
||||||
|
"--keep-last 5"
|
||||||
|
];
|
||||||
|
|
||||||
|
timerConfig = {
|
||||||
|
OnBootSec = "1m";
|
||||||
|
OnCalendar = "daily";
|
||||||
|
};
|
||||||
|
|
||||||
|
inherit backupPrepareCommand;
|
||||||
|
};
|
||||||
|
|
||||||
|
services.postgresqlBackup = {
|
||||||
|
enable = true;
|
||||||
|
backupAll = false;
|
||||||
|
pgdumpOptions = "-p ${toString config.services.postgresql.port}";
|
||||||
|
databases = ["piped"];
|
||||||
|
compression = "zstd";
|
||||||
|
};
|
||||||
|
}
|
38
hosts/hetzner-arm/containers/piped-db/secrets.nix
Normal file
38
hosts/hetzner-arm/containers/piped-db/secrets.nix
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
{...}: {
|
||||||
|
services.secrets = {
|
||||||
|
enable = true;
|
||||||
|
|
||||||
|
vaultLogin = {
|
||||||
|
enable = true;
|
||||||
|
loginUsername = "hetzner-arm-container-piped-db";
|
||||||
|
};
|
||||||
|
|
||||||
|
autoSecrets = {
|
||||||
|
enable = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
requiredVaultPaths = [
|
||||||
|
"api-keys/data/storage/restic/Piped"
|
||||||
|
"private-public-keys/data/restic/Piped"
|
||||||
|
];
|
||||||
|
|
||||||
|
secrets = {
|
||||||
|
vault_password = {
|
||||||
|
manual = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
restic_password = {
|
||||||
|
fetchScript = ''
|
||||||
|
simple_get "/private-public-keys/restic/Piped" .password > "$secretFile"
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
restic_env = {
|
||||||
|
fetchScript = ''
|
||||||
|
RESTIC_USERNAME=$(simple_get "/api-keys/storage/restic/Piped" .username)
|
||||||
|
RESTIC_PASSWORD=$(simple_get "/api-keys/storage/restic/Piped" .password)
|
||||||
|
echo "RESTIC_REPOSITORY=rest:https://$RESTIC_USERNAME:$RESTIC_PASSWORD@storage-restic.owo.monster/Piped" > "$secretFile"
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
|
@ -5,16 +5,19 @@
|
||||||
inputs,
|
inputs,
|
||||||
config,
|
config,
|
||||||
pkgs,
|
pkgs,
|
||||||
|
lib,
|
||||||
...
|
...
|
||||||
}: let
|
}: let
|
||||||
containerName = "piped-fi";
|
inherit (lib.modules) mkForce;
|
||||||
containerConfig = config.containers.${containerName}.config;
|
|
||||||
|
pipedName = "piped-fi";
|
||||||
|
containerName = pipedName;
|
||||||
|
|
||||||
pipedSocketForComponent = (
|
pipedSocketForComponent = (
|
||||||
component: "/var/lib/nixos-containers/${containerName}/var/sockets/piped-${component}.sock"
|
component: "/var/lib/nixos-containers/${containerName}/var/sockets/piped-${component}.sock"
|
||||||
);
|
);
|
||||||
in {
|
in {
|
||||||
containers.piped-fi = {
|
containers.${containerName} = {
|
||||||
autoStart = true;
|
autoStart = true;
|
||||||
privateNetwork = false;
|
privateNetwork = false;
|
||||||
|
|
||||||
|
@ -28,32 +31,19 @@ in {
|
||||||
config = {...}: {
|
config = {...}: {
|
||||||
nixpkgs.pkgs = pkgs;
|
nixpkgs.pkgs = pkgs;
|
||||||
|
|
||||||
imports = with tree;
|
imports = with tree; [
|
||||||
[
|
presets.nixos.containerBase
|
||||||
presets.nixos.containerBase
|
presets.nixos.pipedNode
|
||||||
|
|
||||||
profiles.nginx
|
|
||||||
profiles.firewallAllow.httpCommon
|
|
||||||
|
|
||||||
profiles.pipedCluster
|
|
||||||
|
|
||||||
./secrets.nix
|
|
||||||
]
|
|
||||||
++ (with hosts.hetzner-vm.containers.piped-fi.profiles; [
|
|
||||||
restic
|
|
||||||
]);
|
|
||||||
|
|
||||||
# For Shared Secrets
|
|
||||||
systemd.tmpfiles.rules = [
|
|
||||||
"d /var/lib/cockroachdb-certs - root root"
|
|
||||||
];
|
];
|
||||||
|
|
||||||
|
networking.firewall.enable = mkForce false;
|
||||||
|
|
||||||
home-manager.users.root.home.stateVersion = "23.05";
|
home-manager.users.root.home.stateVersion = "23.05";
|
||||||
system.stateVersion = "23.05";
|
system.stateVersion = "23.05";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
services.nginx.virtualHosts."piped-fi.owo.monster" = {
|
services.nginx.virtualHosts."${pipedName}.owo.monster" = {
|
||||||
forceSSL = true;
|
forceSSL = true;
|
||||||
enableACME = true;
|
enableACME = true;
|
||||||
locations."/" = {
|
locations."/" = {
|
||||||
|
@ -61,7 +51,7 @@ in {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
services.nginx.virtualHosts."backend.piped-fi.owo.monster" = {
|
services.nginx.virtualHosts."backend.${pipedName}.owo.monster" = {
|
||||||
forceSSL = true;
|
forceSSL = true;
|
||||||
enableACME = true;
|
enableACME = true;
|
||||||
locations."/" = {
|
locations."/" = {
|
||||||
|
@ -69,7 +59,7 @@ in {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
services.nginx.virtualHosts."proxy.piped-fi.owo.monster" = {
|
services.nginx.virtualHosts."proxy.${pipedName}.owo.monster" = {
|
||||||
forceSSL = true;
|
forceSSL = true;
|
||||||
enableACME = true;
|
enableACME = true;
|
||||||
locations."/" = {
|
locations."/" = {
|
|
@ -2,7 +2,6 @@
|
||||||
self,
|
self,
|
||||||
hostPath,
|
hostPath,
|
||||||
tree,
|
tree,
|
||||||
lib,
|
|
||||||
inputs,
|
inputs,
|
||||||
config,
|
config,
|
||||||
pkgs,
|
pkgs,
|
||||||
|
@ -11,34 +10,21 @@
|
||||||
containerAddresses = import "${hostPath}/data/containerAddresses.nix";
|
containerAddresses = import "${hostPath}/data/containerAddresses.nix";
|
||||||
hostIP = containerAddresses.host;
|
hostIP = containerAddresses.host;
|
||||||
containerIP = containerAddresses.containers.quassel;
|
containerIP = containerAddresses.containers.quassel;
|
||||||
|
|
||||||
containerLib = import "${self}/lib/containerLib.nix" {
|
|
||||||
inherit lib;
|
|
||||||
};
|
|
||||||
|
|
||||||
# Using secrets from Host
|
|
||||||
secrets = config.services.secrets.secrets;
|
|
||||||
secretsList = [
|
|
||||||
"quassel_restic_env"
|
|
||||||
"quassel_restic_password"
|
|
||||||
];
|
|
||||||
in {
|
in {
|
||||||
containers.quassel = {
|
containers.quassel = {
|
||||||
autoStart = true;
|
autoStart = true;
|
||||||
privateNetwork = true;
|
privateNetwork = true;
|
||||||
hostAddress = hostIP;
|
hostAddress = hostIP;
|
||||||
localAddress = containerIP;
|
localAddress = containerIP;
|
||||||
bindMounts = containerLib.genBindHostsForSecrets secrets secretsList;
|
|
||||||
|
|
||||||
specialArgs = {
|
specialArgs = {
|
||||||
inherit inputs;
|
inherit inputs;
|
||||||
inherit tree;
|
inherit tree;
|
||||||
inherit self;
|
inherit self;
|
||||||
inherit hostPath;
|
inherit hostPath;
|
||||||
hostSecrets = secrets;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
config = {config, ...}: {
|
config = {...}: {
|
||||||
nixpkgs.pkgs = pkgs;
|
nixpkgs.pkgs = pkgs;
|
||||||
|
|
||||||
imports = with tree;
|
imports = with tree;
|
||||||
|
@ -46,17 +32,14 @@ in {
|
||||||
presets.nixos.containerBase
|
presets.nixos.containerBase
|
||||||
profiles.sshd
|
profiles.sshd
|
||||||
profiles.firewallAllow.ssh
|
profiles.firewallAllow.ssh
|
||||||
|
|
||||||
|
./secrets.nix
|
||||||
]
|
]
|
||||||
++ (with hosts.hetzner-vm.containers.quassel.profiles; [
|
++ (with hosts.hetzner-arm.containers.quassel.profiles; [
|
||||||
quassel
|
quassel
|
||||||
restic
|
restic
|
||||||
]);
|
]);
|
||||||
|
|
||||||
# For Shared Secrets
|
|
||||||
systemd.tmpfiles.rules = [
|
|
||||||
"d ${config.services.secrets.secretsDir} - root root"
|
|
||||||
];
|
|
||||||
|
|
||||||
networking.firewall.allowedTCPPorts = [4242];
|
networking.firewall.allowedTCPPorts = [4242];
|
||||||
|
|
||||||
home-manager.users.root.home.stateVersion = "23.05";
|
home-manager.users.root.home.stateVersion = "23.05";
|
|
@ -1,9 +1,9 @@
|
||||||
{
|
{
|
||||||
pkgs,
|
pkgs,
|
||||||
hostSecrets,
|
config,
|
||||||
...
|
...
|
||||||
}: let
|
}: let
|
||||||
secrets = hostSecrets;
|
secrets = config.services.secrets.secrets;
|
||||||
|
|
||||||
backupPrepareCommand = "${
|
backupPrepareCommand = "${
|
||||||
(pkgs.writeShellScriptBin "backupPrepareCommand" ''
|
(pkgs.writeShellScriptBin "backupPrepareCommand" ''
|
||||||
|
@ -15,8 +15,8 @@ in {
|
||||||
restic
|
restic
|
||||||
(pkgs.writeShellScriptBin "restic-quassel" ''
|
(pkgs.writeShellScriptBin "restic-quassel" ''
|
||||||
env \
|
env \
|
||||||
RESTIC_PASSWORD_FILE=${secrets.quassel_restic_password.path} \
|
RESTIC_PASSWORD_FILE=${secrets.restic_password.path} \
|
||||||
$(cat ${secrets.quassel_restic_env.path}) \
|
$(cat ${secrets.restic_env.path}) \
|
||||||
${pkgs.restic}/bin/restic $@
|
${pkgs.restic}/bin/restic $@
|
||||||
'')
|
'')
|
||||||
];
|
];
|
||||||
|
@ -31,8 +31,8 @@ in {
|
||||||
# repository is overrided in environmentFile to contain auth
|
# repository is overrided in environmentFile to contain auth
|
||||||
# make sure to keep up to date when changing repository
|
# make sure to keep up to date when changing repository
|
||||||
repository = "rest:https://storage-restic.owo.monster/Quassel";
|
repository = "rest:https://storage-restic.owo.monster/Quassel";
|
||||||
passwordFile = "${secrets.quassel_restic_password.path}";
|
passwordFile = "${secrets.restic_password.path}";
|
||||||
environmentFile = "${secrets.quassel_restic_env.path}";
|
environmentFile = "${secrets.restic_env.path}";
|
||||||
|
|
||||||
pruneOpts = [
|
pruneOpts = [
|
||||||
"--keep-last 5"
|
"--keep-last 5"
|
38
hosts/hetzner-arm/containers/quassel/secrets.nix
Normal file
38
hosts/hetzner-arm/containers/quassel/secrets.nix
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
{...}: {
|
||||||
|
services.secrets = {
|
||||||
|
enable = true;
|
||||||
|
|
||||||
|
vaultLogin = {
|
||||||
|
enable = true;
|
||||||
|
loginUsername = "hetzner-arm-container-quassel";
|
||||||
|
};
|
||||||
|
|
||||||
|
autoSecrets = {
|
||||||
|
enable = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
requiredVaultPaths = [
|
||||||
|
"api-keys/data/storage/restic/Quassel"
|
||||||
|
"private-public-keys/data/restic/Quassel"
|
||||||
|
];
|
||||||
|
|
||||||
|
secrets = {
|
||||||
|
vault_password = {
|
||||||
|
manual = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
restic_password = {
|
||||||
|
fetchScript = ''
|
||||||
|
simple_get "/private-public-keys/restic/Quassel" .password > "$secretFile"
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
restic_env = {
|
||||||
|
fetchScript = ''
|
||||||
|
RESTIC_USERNAME=$(simple_get "/api-keys/storage/restic/Quassel" .username)
|
||||||
|
RESTIC_PASSWORD=$(simple_get "/api-keys/storage/restic/Quassel" .password)
|
||||||
|
echo "RESTIC_REPOSITORY=rest:https://$RESTIC_USERNAME:$RESTIC_PASSWORD@storage-restic.owo.monster/Quassel" > "$secretFile"
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
70
hosts/hetzner-arm/containers/social/default.nix
Normal file
70
hosts/hetzner-arm/containers/social/default.nix
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
{
|
||||||
|
self,
|
||||||
|
hostPath,
|
||||||
|
tree,
|
||||||
|
inputs,
|
||||||
|
config,
|
||||||
|
pkgs,
|
||||||
|
...
|
||||||
|
}: let
|
||||||
|
containerAddresses = import "${hostPath}/data/containerAddresses.nix";
|
||||||
|
hostIP = containerAddresses.host;
|
||||||
|
containerIP = containerAddresses.containers.social;
|
||||||
|
in {
|
||||||
|
containers.social = {
|
||||||
|
autoStart = true;
|
||||||
|
privateNetwork = true;
|
||||||
|
hostAddress = hostIP;
|
||||||
|
localAddress = containerIP;
|
||||||
|
|
||||||
|
specialArgs = {
|
||||||
|
inherit inputs;
|
||||||
|
inherit tree;
|
||||||
|
inherit self;
|
||||||
|
inherit hostPath;
|
||||||
|
};
|
||||||
|
|
||||||
|
config = {...}: {
|
||||||
|
nixpkgs.pkgs = pkgs;
|
||||||
|
|
||||||
|
imports = with tree;
|
||||||
|
[
|
||||||
|
presets.nixos.containerBase
|
||||||
|
profiles.sshd
|
||||||
|
profiles.firewallAllow.ssh
|
||||||
|
|
||||||
|
./secrets.nix
|
||||||
|
]
|
||||||
|
++ (with hosts.hetzner-arm.containers.social.profiles; [
|
||||||
|
gotosocial
|
||||||
|
restic
|
||||||
|
]);
|
||||||
|
|
||||||
|
networking.firewall = {
|
||||||
|
enable = true;
|
||||||
|
allowedTCPPorts = [8080];
|
||||||
|
};
|
||||||
|
|
||||||
|
home-manager.users.root.home.stateVersion = "23.05";
|
||||||
|
system.stateVersion = "23.05";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
services.nginx.virtualHosts."gts-01.owo.monster" = {
|
||||||
|
forceSSL = true;
|
||||||
|
enableACME = true;
|
||||||
|
locations."/" = {
|
||||||
|
proxyPass = "http://${containerIP}:8080";
|
||||||
|
proxyWebsockets = true;
|
||||||
|
extraConfig = ''
|
||||||
|
# uncomment if running nginx without recommendedProxySettings
|
||||||
|
# proxy_set_header Host $host;
|
||||||
|
# proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
# proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
extraConfig = ''
|
||||||
|
client_max_body_size 128M;
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
}
|
|
@ -1,18 +1,18 @@
|
||||||
{
|
{
|
||||||
hostPath,
|
hostPath,
|
||||||
hostSecrets,
|
config,
|
||||||
...
|
...
|
||||||
}: let
|
}: let
|
||||||
containerAddresses = import "${hostPath}/data/containerAddresses.nix";
|
containerAddresses = import "${hostPath}/data/containerAddresses.nix";
|
||||||
hostIP = containerAddresses.host;
|
hostIP = containerAddresses.host;
|
||||||
containerIP = containerAddresses.containers.social;
|
containerIP = containerAddresses.containers.social;
|
||||||
|
|
||||||
secrets = hostSecrets;
|
secrets = config.services.secrets.secrets;
|
||||||
in {
|
in {
|
||||||
services.gotosocial = {
|
services.gotosocial = {
|
||||||
enable = true;
|
enable = true;
|
||||||
setupPostgresqlDB = true;
|
setupPostgresqlDB = true;
|
||||||
environmentFile = secrets.social_env_secrets.path;
|
environmentFile = secrets.env_secrets.path;
|
||||||
|
|
||||||
settings = {
|
settings = {
|
||||||
application-name = "chaos-gts";
|
application-name = "chaos-gts";
|
|
@ -2,13 +2,12 @@
|
||||||
pkgs,
|
pkgs,
|
||||||
config,
|
config,
|
||||||
lib,
|
lib,
|
||||||
hostSecrets,
|
|
||||||
...
|
...
|
||||||
}: let
|
}: let
|
||||||
inherit (lib.strings) concatStringsSep;
|
inherit (lib.strings) concatStringsSep;
|
||||||
inherit (lib.lists) forEach;
|
inherit (lib.lists) forEach;
|
||||||
|
|
||||||
secrets = hostSecrets;
|
secrets = config.services.secrets.secrets;
|
||||||
|
|
||||||
# Because gotosocial-admin isn't a seporate package we need to generate a seperate config
|
# Because gotosocial-admin isn't a seporate package we need to generate a seperate config
|
||||||
# and duplicate the wrapper for use in a systemd unit
|
# and duplicate the wrapper for use in a systemd unit
|
||||||
|
@ -48,8 +47,8 @@ in {
|
||||||
restic
|
restic
|
||||||
(pkgs.writeShellScriptBin "restic-social" ''
|
(pkgs.writeShellScriptBin "restic-social" ''
|
||||||
env \
|
env \
|
||||||
RESTIC_PASSWORD_FILE=${secrets.social_restic_password.path} \
|
RESTIC_PASSWORD_FILE=${secrets.restic_password.path} \
|
||||||
$(cat ${secrets.social_restic_env.path}) \
|
$(cat ${secrets.restic_env.path}) \
|
||||||
${pkgs.restic}/bin/restic $@
|
${pkgs.restic}/bin/restic $@
|
||||||
'')
|
'')
|
||||||
];
|
];
|
||||||
|
@ -64,8 +63,8 @@ in {
|
||||||
# repository is overrided in environmentFile to contain auth
|
# repository is overrided in environmentFile to contain auth
|
||||||
# make sure to keep up to date when changing repository
|
# make sure to keep up to date when changing repository
|
||||||
repository = "rest:https://storage-restic.owo.monster/Social";
|
repository = "rest:https://storage-restic.owo.monster/Social";
|
||||||
passwordFile = "${secrets.social_restic_password.path}";
|
passwordFile = "${secrets.restic_password.path}";
|
||||||
environmentFile = "${secrets.social_restic_env.path}";
|
environmentFile = "${secrets.restic_env.path}";
|
||||||
|
|
||||||
pruneOpts = [
|
pruneOpts = [
|
||||||
"--keep-last 10"
|
"--keep-last 10"
|
47
hosts/hetzner-arm/containers/social/secrets.nix
Normal file
47
hosts/hetzner-arm/containers/social/secrets.nix
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
{...}: {
|
||||||
|
services.secrets = {
|
||||||
|
enable = true;
|
||||||
|
|
||||||
|
vaultLogin = {
|
||||||
|
enable = true;
|
||||||
|
loginUsername = "hetzner-arm-container-social";
|
||||||
|
};
|
||||||
|
|
||||||
|
autoSecrets = {
|
||||||
|
enable = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
requiredVaultPaths = [
|
||||||
|
"private-public-keys/data/restic/Social"
|
||||||
|
|
||||||
|
"api-keys/data/storage/restic/Social"
|
||||||
|
|
||||||
|
"api-keys/data/chaos_mail/gotosocial"
|
||||||
|
];
|
||||||
|
|
||||||
|
secrets = {
|
||||||
|
vault_password = {
|
||||||
|
manual = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
restic_password = {
|
||||||
|
fetchScript = ''
|
||||||
|
simple_get "/private-public-keys/restic/Social" .password > "$secretFile"
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
restic_env = {
|
||||||
|
fetchScript = ''
|
||||||
|
RESTIC_USERNAME=$(simple_get "/api-keys/storage/restic/Social" .username)
|
||||||
|
RESTIC_PASSWORD=$(simple_get "/api-keys/storage/restic/Social" .password)
|
||||||
|
echo "RESTIC_REPOSITORY=rest:https://$RESTIC_USERNAME:$RESTIC_PASSWORD@storage-restic.owo.monster/Social" > "$secretFile"
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
env_secrets = {
|
||||||
|
fetchScript = ''
|
||||||
|
smtp_password=$(simple_get "/api-keys/chaos_mail/gotosocial" .password)
|
||||||
|
echo "GTS_SMTP_PASSWORD=$smtp_password" > "$secretFile"
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
|
@ -7,7 +7,7 @@
|
||||||
rclone_serve_restic_vault = 4211;
|
rclone_serve_restic_vault = 4211;
|
||||||
rclone_serve_restic_social = 4212;
|
rclone_serve_restic_social = 4212;
|
||||||
rclone_serve_restic_quassel = 4213;
|
rclone_serve_restic_quassel = 4213;
|
||||||
rclone_serve_restic_piped_finland = 4214;
|
rclone_serve_restic_piped = 4214;
|
||||||
rclone_serve_restic_mail = 4215;
|
rclone_serve_restic_mail = 4215;
|
||||||
|
|
||||||
rclone_serve_http_music = 4220;
|
rclone_serve_http_music = 4220;
|
|
@ -36,20 +36,14 @@ in {
|
||||||
|
|
||||||
imports = with tree;
|
imports = with tree;
|
||||||
[
|
[
|
||||||
profiles.base
|
presets.nixos.containerBase
|
||||||
inputs.home-manager-unstable.nixosModules.home-manager
|
|
||||||
|
|
||||||
profiles.sshd
|
profiles.sshd
|
||||||
|
profiles.firewallAllow.ssh
|
||||||
modules.nixos.rclone-serve
|
|
||||||
modules.nixos.rclone-sync
|
|
||||||
modules.nixos.secrets
|
|
||||||
|
|
||||||
./secrets.nix
|
./secrets.nix
|
||||||
|
|
||||||
users.root
|
|
||||||
]
|
]
|
||||||
++ (with hosts.hetzner-vm.containers.storage.profiles; [
|
++ (with hosts.hetzner-arm.containers.storage.profiles; [
|
||||||
rcloneConfigs
|
rcloneConfigs
|
||||||
rcloneServe
|
rcloneServe
|
||||||
rcloneSync
|
rcloneSync
|
||||||
|
@ -58,20 +52,12 @@ in {
|
||||||
|
|
||||||
environment.systemPackages = with pkgs; [rclone];
|
environment.systemPackages = with pkgs; [rclone];
|
||||||
|
|
||||||
home-manager.users.root = {
|
|
||||||
imports = with tree; [home.base home.dev.small];
|
|
||||||
home.packages = with pkgs; [vault-bin];
|
|
||||||
home.stateVersion = "23.05";
|
|
||||||
};
|
|
||||||
|
|
||||||
networking.firewall = {
|
networking.firewall = {
|
||||||
enable = true;
|
enable = true;
|
||||||
allowedTCPPorts = attrValues ports;
|
allowedTCPPorts = attrValues ports;
|
||||||
};
|
};
|
||||||
|
|
||||||
# Manually configure nameserver. Using resolved inside the container seems to fail
|
home-manager.users.root.home.stateVersion = "23.05";
|
||||||
# currently
|
|
||||||
environment.etc."resolv.conf".text = "nameserver 8.8.8.8";
|
|
||||||
system.stateVersion = "23.05";
|
system.stateVersion = "23.05";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -109,7 +95,7 @@ in {
|
||||||
"/Vault/".proxyPass = "http://${containerIP}:${toString ports.rclone_serve_restic_vault}";
|
"/Vault/".proxyPass = "http://${containerIP}:${toString ports.rclone_serve_restic_vault}";
|
||||||
"/Social/".proxyPass = "http://${containerIP}:${toString ports.rclone_serve_restic_social}";
|
"/Social/".proxyPass = "http://${containerIP}:${toString ports.rclone_serve_restic_social}";
|
||||||
"/Quassel/".proxyPass = "http://${containerIP}:${toString ports.rclone_serve_restic_quassel}";
|
"/Quassel/".proxyPass = "http://${containerIP}:${toString ports.rclone_serve_restic_quassel}";
|
||||||
"/Piped-Finland/".proxyPass = "http://${containerIP}:${toString ports.rclone_serve_restic_piped_finland}";
|
"/Piped/".proxyPass = "http://${containerIP}:${toString ports.rclone_serve_restic_piped}";
|
||||||
"/Mail/".proxyPass = "http://${containerIP}:${toString ports.rclone_serve_restic_mail}";
|
"/Mail/".proxyPass = "http://${containerIP}:${toString ports.rclone_serve_restic_mail}";
|
||||||
};
|
};
|
||||||
extraConfig = ''
|
extraConfig = ''
|
|
@ -117,13 +117,13 @@ in {
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
id = "restic-piped-finland";
|
id = "restic-piped";
|
||||||
remote = "StorageBox:Backups/Restic/Piped-Finland";
|
remote = "StorageBox:Backups/Restic/Piped";
|
||||||
type = "restic";
|
type = "restic";
|
||||||
extraArgs = [
|
extraArgs = [
|
||||||
"--addr=0.0.0.0:${toString ports.rclone_serve_restic_piped_finland}"
|
"--addr=0.0.0.0:${toString ports.rclone_serve_restic_piped}"
|
||||||
"--htpasswd=${secrets.restic_piped_finland_htpasswd.path}"
|
"--htpasswd=${secrets.restic_piped_htpasswd.path}"
|
||||||
"--baseurl=/Piped-Finland/"
|
"--baseurl=/Piped/"
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
{
|
{
|
|
@ -10,11 +10,16 @@
|
||||||
wants = ["auto-secrets.service"];
|
wants = ["auto-secrets.service"];
|
||||||
};
|
};
|
||||||
timerConfig = {
|
timerConfig = {
|
||||||
OnStartupSec = "60";
|
OnStartupSec = "120";
|
||||||
OnCalendar = "4h";
|
OnCalendar = "4h";
|
||||||
};
|
};
|
||||||
extraArgs = [
|
extraArgs = [
|
||||||
"--fast-list"
|
"--fast-list"
|
||||||
|
"--check-first"
|
||||||
|
"--delete-before"
|
||||||
|
"--b2-upload-concurrency=4"
|
||||||
|
"--transfers=4"
|
||||||
|
"--bwlimit 80M"
|
||||||
];
|
];
|
||||||
}) [
|
}) [
|
||||||
# My B2
|
# My B2
|
|
@ -1,4 +1,4 @@
|
||||||
[StorageBox-Remote]
|
[StorageBox-Remote-WebDAV]
|
||||||
type = webdav
|
type = webdav
|
||||||
vendor = other
|
vendor = other
|
||||||
host = u323231.your-storagebox.de
|
host = u323231.your-storagebox.de
|
||||||
|
@ -6,6 +6,22 @@ url = https://u323231.your-storagebox.de
|
||||||
user = u323231
|
user = u323231
|
||||||
pass = STORAGEBOX_PASSWORD
|
pass = STORAGEBOX_PASSWORD
|
||||||
|
|
||||||
|
[StorageBox-Remote-SFTP]
|
||||||
|
type = sftp
|
||||||
|
host = u323231.your-storagebox.de
|
||||||
|
user = u323231
|
||||||
|
port = 23
|
||||||
|
pass = STORAGEBOX_PASSWORD
|
||||||
|
shell_type = unix
|
||||||
|
md5sum_command = md5 -r
|
||||||
|
sha1sum_command = sha1 -r
|
||||||
|
|
||||||
|
# Can change which protocol to use at runtime by editing config
|
||||||
|
# after deploy or redeploying with different alias if storagebox breaks
|
||||||
|
[StorageBox-Remote]
|
||||||
|
type = alias
|
||||||
|
remote = StorageBox-Remote-SFTP:
|
||||||
|
|
||||||
[StorageBox-Hasher]
|
[StorageBox-Hasher]
|
||||||
type = hasher
|
type = hasher
|
||||||
remote = StorageBox-Remote:
|
remote = StorageBox-Remote:
|
||||||
|
@ -101,4 +117,4 @@ password2 = STORAGE_MEDIA_CRYPT_SALT
|
||||||
|
|
||||||
[Media-Combine-Serve]
|
[Media-Combine-Serve]
|
||||||
type = combine
|
type = combine
|
||||||
upstreams = "Media=Storage-Media-Crypt:" "PutIO=PutIO-WebDAV:"
|
upstreams = "Media=Storage-Media-Crypt:" "PutIO=PutIO-WebDAV:"
|
|
@ -1,17 +1,10 @@
|
||||||
{
|
{pkgs, ...}: {
|
||||||
config,
|
|
||||||
pkgs,
|
|
||||||
...
|
|
||||||
}: let
|
|
||||||
cfg = config.services.secrets;
|
|
||||||
in {
|
|
||||||
services.secrets = {
|
services.secrets = {
|
||||||
enable = true;
|
enable = true;
|
||||||
|
|
||||||
vaultLogin = {
|
vaultLogin = {
|
||||||
enable = true;
|
enable = true;
|
||||||
loginUsername = "hetzner-vm-container-storage";
|
loginUsername = "hetzner-arm-container-storage";
|
||||||
loginPasswordFile = cfg.secrets.vault_password.path;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
autoSecrets = {
|
autoSecrets = {
|
||||||
|
@ -35,7 +28,7 @@ in {
|
||||||
"api-keys/data/storage/restic/Vault"
|
"api-keys/data/storage/restic/Vault"
|
||||||
"api-keys/data/storage/restic/Social"
|
"api-keys/data/storage/restic/Social"
|
||||||
"api-keys/data/storage/restic/Quassel"
|
"api-keys/data/storage/restic/Quassel"
|
||||||
"api-keys/data/storage/restic/Piped-Finland"
|
"api-keys/data/storage/restic/Piped"
|
||||||
"api-keys/data/storage/restic/Mail"
|
"api-keys/data/storage/restic/Mail"
|
||||||
|
|
||||||
"api-keys/data/storage/webdav/main"
|
"api-keys/data/storage/webdav/main"
|
||||||
|
@ -51,14 +44,6 @@ in {
|
||||||
rclone
|
rclone
|
||||||
];
|
];
|
||||||
|
|
||||||
uidMap = {
|
|
||||||
"storage" = config.users.users."storage".uid;
|
|
||||||
};
|
|
||||||
|
|
||||||
gidMap = {
|
|
||||||
"storage" = config.users.groups."storage".gid;
|
|
||||||
};
|
|
||||||
|
|
||||||
extraFunctions = ''
|
extraFunctions = ''
|
||||||
replace_slash_for_sed() {
|
replace_slash_for_sed() {
|
||||||
sed "s#/#\\\/#"
|
sed "s#/#\\\/#"
|
||||||
|
@ -80,11 +65,11 @@ in {
|
||||||
}
|
}
|
||||||
|
|
||||||
simple_get_replace_crypt() {
|
simple_get_replace_crypt() {
|
||||||
password=$(simple_get "$1" .password | replace_slash_for_sed)
|
password=$(simple_get_obscure "$1" .password)
|
||||||
salt=$(simple_get "$1" .salt | replace_slash_for_sed)
|
salt=$(simple_get_obscure "$1" .salt)
|
||||||
|
|
||||||
replace_password=''${2}_ACCOUNT
|
replace_password=''${2}_PASSWORD
|
||||||
replace_salt=''${2}_KEY
|
replace_salt=''${2}_SALT
|
||||||
|
|
||||||
sed -i "s/$replace_password/$password/" "$3"
|
sed -i "s/$replace_password/$password/" "$3"
|
||||||
sed -i "s/$replace_salt/$salt/" "$3"
|
sed -i "s/$replace_salt/$salt/" "$3"
|
||||||
|
@ -132,12 +117,12 @@ in {
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
restic_piped_finland_htpasswd = {
|
restic_piped_htpasswd = {
|
||||||
user = "storage";
|
user = "storage";
|
||||||
group = "storage";
|
group = "storage";
|
||||||
fetchScript = ''
|
fetchScript = ''
|
||||||
username=$(simple_get "/api-keys/storage/restic/Piped-Finland" .username)
|
username=$(simple_get "/api-keys/storage/restic/Piped" .username)
|
||||||
password=$(simple_get "/api-keys/storage/restic/Piped-Finland" .password)
|
password=$(simple_get "/api-keys/storage/restic/Piped" .password)
|
||||||
htpasswd -bc "$secretFile" "$username" "$password" 2>/dev/null
|
htpasswd -bc "$secretFile" "$username" "$password" 2>/dev/null
|
||||||
'';
|
'';
|
||||||
};
|
};
|
|
@ -5,6 +5,5 @@
|
||||||
social = "192.168.100.12";
|
social = "192.168.100.12";
|
||||||
music = "192.168.100.13";
|
music = "192.168.100.13";
|
||||||
quassel = "192.168.100.14";
|
quassel = "192.168.100.14";
|
||||||
piped = "192.168.100.15";
|
|
||||||
};
|
};
|
||||||
}
|
}
|
|
@ -3,4 +3,4 @@
|
||||||
systemd-boot.enable = true;
|
systemd-boot.enable = true;
|
||||||
efi.canTouchEfiVariables = true;
|
efi.canTouchEfiVariables = true;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,25 +11,25 @@ in {
|
||||||
presets.nixos.serverHetzner
|
presets.nixos.serverHetzner
|
||||||
presets.nixos.serverEncryptedDrive
|
presets.nixos.serverEncryptedDrive
|
||||||
|
|
||||||
#profiles.nginx
|
profiles.nginx
|
||||||
#profiles.firewallAllow.httpCommon
|
profiles.firewallAllow.httpCommon
|
||||||
|
|
||||||
#profiles.chaosInternalWireGuard
|
profiles.chaosInternalWireGuard
|
||||||
|
|
||||||
./hardware.nix
|
./hardware.nix
|
||||||
./secrets.nix
|
./secrets.nix
|
||||||
]
|
]
|
||||||
++ (forEach [
|
++ (forEach [
|
||||||
#"social"
|
"social"
|
||||||
#"storage"
|
"storage"
|
||||||
#"music"
|
"music"
|
||||||
#"quassel"
|
"quassel"
|
||||||
#"piped-fi"
|
"piped-db"
|
||||||
#"mail"
|
"piped-fi"
|
||||||
|
"mail"
|
||||||
] (name: ./containers + "/${name}"))
|
] (name: ./containers + "/${name}"))
|
||||||
++ (with hosts.hetzner-vm.profiles; [
|
++ (with hosts.hetzner-arm.profiles; [
|
||||||
#vaultUI
|
gitlabStaticSites
|
||||||
#gitlabStaticSites
|
|
||||||
]);
|
]);
|
||||||
|
|
||||||
# For Containers
|
# For Containers
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
{pkgs, ...}: {
|
{...}: {
|
||||||
services.secrets = {
|
services.secrets = {
|
||||||
enable = true;
|
enable = true;
|
||||||
|
|
||||||
|
@ -9,12 +9,15 @@
|
||||||
|
|
||||||
autoSecrets = {
|
autoSecrets = {
|
||||||
enable = true;
|
enable = true;
|
||||||
#affectedSystemdServices = [
|
affectedSystemdServices = [
|
||||||
# "wg-quick-wg0"
|
"wg-quick-wg0"
|
||||||
#];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
requiredVaultPaths = [
|
requiredVaultPaths = [
|
||||||
|
"private-public-keys/data/ssh/root@hetzner-arm"
|
||||||
|
"private-public-keys/data/ssh/root@hetzner-arm-decrypt"
|
||||||
|
|
||||||
"api-keys/data/gitlab/gitlab_pages_serve"
|
"api-keys/data/gitlab/gitlab_pages_serve"
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@ -23,6 +26,34 @@
|
||||||
manual = true;
|
manual = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
ssh_host_ed25519_key = {
|
||||||
|
path = "/etc/ssh/ssh_host_ed25519_key";
|
||||||
|
permissions = "600";
|
||||||
|
fetchScript = ''
|
||||||
|
[ ! -d "$SYSROOT/etc/ssh" ] && mkdir -p "$SYSROOT/etc/ssh/"
|
||||||
|
simple_get "/private-public-keys/ssh/root@hetzner-arm" .private | base64 -d > "$secretFile"
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
ssh_host_ed25519_key_pub = {
|
||||||
|
path = "/etc/ssh/ssh_host_ed25519_key.pub";
|
||||||
|
permissions = "600";
|
||||||
|
fetchScript = ''
|
||||||
|
[ ! -d "$SYSROOT/etc/ssh" ] && mkdir -p "$SYSROOT/etc/ssh/"
|
||||||
|
simple_get "/private-public-keys/ssh/root@hetzner-arm" .private | base64 -d > "$secretFile"
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
# this doesn't need to be a secret and can be generated at install time
|
||||||
|
# but it makes it easier to install.
|
||||||
|
# it's stored in /nix store anyway
|
||||||
|
initrd_ssh_host_ed25519_key = {
|
||||||
|
path = "/initrd_ssh_host_ed25519_key";
|
||||||
|
permissions = "600";
|
||||||
|
fetchScript = ''
|
||||||
|
simple_get "/private-public-keys/ssh/root@hetzner-arm-decrypt" .private | base64 -d > "$secretFile"
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
# Used directly by server
|
# Used directly by server
|
||||||
# for fetching gitlab static sites
|
# for fetching gitlab static sites
|
||||||
gitlab_env = {
|
gitlab_env = {
|
||||||
|
|
|
@ -1,38 +0,0 @@
|
||||||
{
|
|
||||||
pkgs,
|
|
||||||
config,
|
|
||||||
...
|
|
||||||
}: let
|
|
||||||
secrets = config.services.secrets.secrets;
|
|
||||||
in {
|
|
||||||
environment.systemPackages = with pkgs; [
|
|
||||||
restic
|
|
||||||
(pkgs.writeShellScriptBin "restic-piped-finland" ''
|
|
||||||
env \
|
|
||||||
RESTIC_PASSWORD_FILE=${secrets.restic_password.path} \
|
|
||||||
$(cat ${secrets.restic_env.path}) \
|
|
||||||
${pkgs.restic}/bin/restic $@
|
|
||||||
'')
|
|
||||||
];
|
|
||||||
|
|
||||||
services.restic.backups.piped-finland = {
|
|
||||||
user = "root";
|
|
||||||
paths = [
|
|
||||||
"/var/lib/cockroachdb"
|
|
||||||
"/var/lib/cockroachdb-certs"
|
|
||||||
];
|
|
||||||
|
|
||||||
repository = "rest:https://storage-restic.owo.monster/Piped-Finland";
|
|
||||||
passwordFile = "${secrets.restic_password.path}";
|
|
||||||
environmentFile = "${secrets.restic_env.path}";
|
|
||||||
|
|
||||||
pruneOpts = [
|
|
||||||
"--keep-last 5"
|
|
||||||
];
|
|
||||||
|
|
||||||
timerConfig = {
|
|
||||||
OnBootSec = "1m";
|
|
||||||
OnCalendar = "daily";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -1,75 +0,0 @@
|
||||||
{...}: {
|
|
||||||
services.secrets = {
|
|
||||||
enable = true;
|
|
||||||
|
|
||||||
vaultLogin = {
|
|
||||||
enable = true;
|
|
||||||
loginUsername = "hetzner-vm-container-piped-fi";
|
|
||||||
};
|
|
||||||
|
|
||||||
autoSecrets = {
|
|
||||||
enable = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
requiredVaultPaths = [
|
|
||||||
"api-keys/data/storage/restic/Piped-Finland"
|
|
||||||
|
|
||||||
"private-public-keys/data/piped-cockroachdb-ca/nodes/piped-fi"
|
|
||||||
|
|
||||||
"private-public-keys/data/restic/Piped-Finland"
|
|
||||||
];
|
|
||||||
|
|
||||||
secrets = {
|
|
||||||
vault_password = {
|
|
||||||
manual = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
restic_password = {
|
|
||||||
fetchScript = ''
|
|
||||||
simple_get "/private-public-keys/restic/Piped-Finland" .password > "$secretFile"
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
restic_env = {
|
|
||||||
fetchScript = ''
|
|
||||||
RESTIC_USERNAME=$(simple_get "/api-keys/storage/restic/Piped-Finland" .username)
|
|
||||||
RESTIC_PASSWORD=$(simple_get "/api-keys/storage/restic/Piped-Finland" .password)
|
|
||||||
echo "RESTIC_REPOSITORY=rest:https://$RESTIC_USERNAME:$RESTIC_PASSWORD@storage-restic.owo.monster/Piped-Finland" > "$secretFile"
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
cockroachdb_ca_certificate = {
|
|
||||||
user = "cockroachdb";
|
|
||||||
group = "cockroachdb";
|
|
||||||
permissions = "600";
|
|
||||||
path = "/var/lib/cockroachdb-certs/ca.crt";
|
|
||||||
fetchScript = ''
|
|
||||||
simple_get "/private-public-keys/piped-cockroachdb-ca/nodes/piped-fi" .ca_certificate \
|
|
||||||
| base64 -d > "$secretFile"
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
cockroachdb_node_certificate = {
|
|
||||||
user = "cockroachdb";
|
|
||||||
group = "cockroachdb";
|
|
||||||
permissions = "600";
|
|
||||||
path = "/var/lib/cockroachdb-certs/node.crt";
|
|
||||||
fetchScript = ''
|
|
||||||
simple_get "/private-public-keys/piped-cockroachdb-ca/nodes/piped-fi" .node_certificate \
|
|
||||||
| base64 -d > "$secretFile"
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
cockroachdb_node_key = {
|
|
||||||
user = "cockroachdb";
|
|
||||||
group = "cockroachdb";
|
|
||||||
permissions = "600";
|
|
||||||
path = "/var/lib/cockroachdb-certs/node.key";
|
|
||||||
fetchScript = ''
|
|
||||||
simple_get "/private-public-keys/piped-cockroachdb-ca/nodes/piped-fi" .node_key \
|
|
||||||
| base64 -d > "$secretFile"
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -1,105 +0,0 @@
|
||||||
{
|
|
||||||
self,
|
|
||||||
hostPath,
|
|
||||||
tree,
|
|
||||||
inputs,
|
|
||||||
config,
|
|
||||||
pkgs,
|
|
||||||
...
|
|
||||||
}: let
|
|
||||||
containerAddresses = import "${hostPath}/data/containerAddresses.nix";
|
|
||||||
hostIP = containerAddresses.host;
|
|
||||||
containerIP = containerAddresses.containers.social;
|
|
||||||
|
|
||||||
# Using secrets from Host
|
|
||||||
secrets = config.services.secrets.secrets;
|
|
||||||
in {
|
|
||||||
containers.social = {
|
|
||||||
autoStart = true;
|
|
||||||
privateNetwork = true;
|
|
||||||
hostAddress = hostIP;
|
|
||||||
localAddress = containerIP;
|
|
||||||
bindMounts = {
|
|
||||||
"${secrets.social_restic_password.path}" = {
|
|
||||||
hostPath = "${secrets.social_restic_password.path}";
|
|
||||||
};
|
|
||||||
"${secrets.social_restic_env.path}" = {
|
|
||||||
hostPath = "${secrets.social_restic_env.path}";
|
|
||||||
};
|
|
||||||
"${secrets.social_env_secrets.path}" = {
|
|
||||||
hostPath = "${secrets.social_env_secrets.path}";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
specialArgs = {
|
|
||||||
inherit inputs;
|
|
||||||
inherit tree;
|
|
||||||
inherit self;
|
|
||||||
inherit hostPath;
|
|
||||||
hostSecrets = secrets;
|
|
||||||
};
|
|
||||||
|
|
||||||
config = {config, ...}: {
|
|
||||||
nixpkgs.pkgs = pkgs;
|
|
||||||
|
|
||||||
imports = with tree;
|
|
||||||
[
|
|
||||||
profiles.base
|
|
||||||
inputs.home-manager-unstable.nixosModules.home-manager
|
|
||||||
|
|
||||||
profiles.sshd
|
|
||||||
|
|
||||||
modules.nixos.secrets
|
|
||||||
|
|
||||||
users.root
|
|
||||||
]
|
|
||||||
++ (with hosts.hetzner-vm.containers.social; [
|
|
||||||
profiles.gotosocial
|
|
||||||
profiles.restic
|
|
||||||
]);
|
|
||||||
|
|
||||||
environment.systemPackages = with pkgs; [
|
|
||||||
rclone
|
|
||||||
restic
|
|
||||||
];
|
|
||||||
|
|
||||||
# For Shared Secrets
|
|
||||||
systemd.tmpfiles.rules = [
|
|
||||||
"d ${config.services.secrets.secretsDir} - root root"
|
|
||||||
];
|
|
||||||
|
|
||||||
networking.firewall = {
|
|
||||||
enable = true;
|
|
||||||
allowedTCPPorts = [22 8080];
|
|
||||||
};
|
|
||||||
|
|
||||||
home-manager.users.root = {
|
|
||||||
imports = with tree; [home.base home.dev.small];
|
|
||||||
home.stateVersion = "23.05";
|
|
||||||
};
|
|
||||||
|
|
||||||
# Manually configure nameserver. Using resolved inside the container seems to fail
|
|
||||||
# currently
|
|
||||||
environment.etc."resolv.conf".text = "nameserver 8.8.8.8";
|
|
||||||
system.stateVersion = "23.05";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
services.nginx.virtualHosts."gts-01.owo.monster" = {
|
|
||||||
forceSSL = true;
|
|
||||||
enableACME = true;
|
|
||||||
locations."/" = {
|
|
||||||
proxyPass = "http://${containerIP}:8080";
|
|
||||||
proxyWebsockets = true;
|
|
||||||
extraConfig = ''
|
|
||||||
# uncomment if running nginx without recommendedProxySettings
|
|
||||||
# proxy_set_header Host $host;
|
|
||||||
# proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
||||||
# proxy_set_header X-Forwarded-Proto $scheme;
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
extraConfig = ''
|
|
||||||
client_max_body_size 128M;
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -1,15 +0,0 @@
|
||||||
{...}: {
|
|
||||||
boot.loader = {
|
|
||||||
grub = {
|
|
||||||
enable = true;
|
|
||||||
device = "/dev/sda";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
boot.initrd.kernelModules = ["nvme"];
|
|
||||||
|
|
||||||
fileSystems."/" = {
|
|
||||||
device = "/dev/sda1";
|
|
||||||
fsType = "ext4";
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -1,46 +0,0 @@
|
||||||
{
|
|
||||||
tree,
|
|
||||||
lib,
|
|
||||||
...
|
|
||||||
}: let
|
|
||||||
inherit (lib.lists) forEach;
|
|
||||||
in {
|
|
||||||
imports = with tree;
|
|
||||||
[
|
|
||||||
presets.nixos.serverBase
|
|
||||||
presets.nixos.serverHetzner
|
|
||||||
|
|
||||||
profiles.nginx
|
|
||||||
profiles.firewallAllow.httpCommon
|
|
||||||
|
|
||||||
profiles.cross.arm64
|
|
||||||
profiles.chaosInternalWireGuard
|
|
||||||
|
|
||||||
./hardware.nix
|
|
||||||
./secrets.nix
|
|
||||||
]
|
|
||||||
++ (forEach [
|
|
||||||
"social"
|
|
||||||
"storage"
|
|
||||||
"music"
|
|
||||||
"quassel"
|
|
||||||
"piped-fi"
|
|
||||||
"mail"
|
|
||||||
] (name: ./containers + "/${name}"))
|
|
||||||
++ (with hosts.hetzner-vm.profiles; [
|
|
||||||
vaultUI
|
|
||||||
gitlabStaticSites
|
|
||||||
]);
|
|
||||||
|
|
||||||
# For Containers
|
|
||||||
networking.nat = {
|
|
||||||
enable = true;
|
|
||||||
internalInterfaces = ["ve-+"];
|
|
||||||
externalInterface = "enp1s0";
|
|
||||||
};
|
|
||||||
|
|
||||||
networking.hostName = "hetzner-vm";
|
|
||||||
|
|
||||||
home-manager.users.root.home.stateVersion = "23.05";
|
|
||||||
system.stateVersion = "23.05";
|
|
||||||
}
|
|
|
@ -1,171 +0,0 @@
|
||||||
{pkgs, ...}: {
|
|
||||||
services.secrets = {
|
|
||||||
enable = true;
|
|
||||||
|
|
||||||
vaultLogin = {
|
|
||||||
enable = true;
|
|
||||||
loginUsername = "hetzner-vm";
|
|
||||||
};
|
|
||||||
|
|
||||||
autoSecrets = {
|
|
||||||
enable = true;
|
|
||||||
affectedSystemdServices = [
|
|
||||||
"wg-quick-wg0"
|
|
||||||
"container@music"
|
|
||||||
"container@social"
|
|
||||||
"container@quassel"
|
|
||||||
"container@piped-fi"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
packages = with pkgs; [
|
|
||||||
# for music & mail passwd files
|
|
||||||
apacheHttpd
|
|
||||||
];
|
|
||||||
|
|
||||||
requiredVaultPaths = [
|
|
||||||
"api-keys/data/mpd"
|
|
||||||
"api-keys/data/music-stream"
|
|
||||||
|
|
||||||
"api-keys/data/gitlab/gitlab_pages_serve"
|
|
||||||
|
|
||||||
"api-keys/data/storage/restic/Mail"
|
|
||||||
"api-keys/data/storage/restic/Social"
|
|
||||||
"api-keys/data/storage/restic/Quassel"
|
|
||||||
|
|
||||||
"api-keys/data/chaos_mail/system"
|
|
||||||
"api-keys/data/chaos_mail/gotosocial"
|
|
||||||
|
|
||||||
"passwords/data/soulseek"
|
|
||||||
"passwords/data/slskd"
|
|
||||||
"passwords/data/mail"
|
|
||||||
|
|
||||||
"private-public-keys/data/restic/Mail"
|
|
||||||
"private-public-keys/data/restic/Social"
|
|
||||||
"private-public-keys/data/restic/Quassel"
|
|
||||||
|
|
||||||
"infra/data/private-mail-aliases"
|
|
||||||
];
|
|
||||||
|
|
||||||
secrets = {
|
|
||||||
vault_password = {
|
|
||||||
manual = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
# Used directly by server
|
|
||||||
# for fetching gitlab static sites
|
|
||||||
gitlab_env = {
|
|
||||||
user = "gitlab_artifacts_sync";
|
|
||||||
group = "gitlab_artifacts_sync";
|
|
||||||
fetchScript = ''
|
|
||||||
token=$(simple_get "/api-keys/gitlab/gitlab_pages_serve" .token)
|
|
||||||
echo "GITLAB_TOKEN=$token" > "$secretFile"
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
# Container: music
|
|
||||||
mpd_control_password = {
|
|
||||||
user = "mpd";
|
|
||||||
group = "mpd";
|
|
||||||
fetchScript = ''
|
|
||||||
simple_get "/api-keys/mpd" .password > "$secretFile"
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
music_stream_passwd = {
|
|
||||||
user = "nginx";
|
|
||||||
group = "nginx";
|
|
||||||
fetchScript = ''
|
|
||||||
username=$(simple_get "/api-keys/music-stream" .username)
|
|
||||||
password=$(simple_get "/api-keys/music-stream" .password)
|
|
||||||
htpasswd -bc "$secretFile" "$username" "$password" 2>/dev/null
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
slskd_env = {
|
|
||||||
fetchScript = ''
|
|
||||||
soulseek_password=$(simple_get "/passwords/soulseek" .password)
|
|
||||||
slskd_password=$(simple_get "/passwords/slskd" .password)
|
|
||||||
echo > "$secretFile"
|
|
||||||
echo "SLSKD_SLSK_PASSWORD=$soulseek_password" >> "$secretFile"
|
|
||||||
echo "SLSKD_PASSWORD=$slskd_password" >> "$secretFile"
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
# Container: mail
|
|
||||||
mail_restic_password = {
|
|
||||||
fetchScript = ''
|
|
||||||
simple_get "/private-public-keys/restic/Mail" .password > "$secretFile"
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
mail_restic_env = {
|
|
||||||
fetchScript = ''
|
|
||||||
RESTIC_USERNAME=$(simple_get "/api-keys/storage/restic/Mail" .username)
|
|
||||||
RESTIC_PASSWORD=$(simple_get "/api-keys/storage/restic/Mail" .password)
|
|
||||||
echo "RESTIC_REPOSITORY=rest:https://$RESTIC_USERNAME:$RESTIC_PASSWORD@storage-restic.owo.monster/Mail" > "$secretFile"
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
private_mail_aliases = {
|
|
||||||
fetchScript = ''
|
|
||||||
kv_get "/infra/private-mail-aliases" | jq .data.data | jq -r 'to_entries|map("\(.key) \(.value.to)")[]' > "$secretFile"
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
chaos_mail_passwd = {
|
|
||||||
user = "dovecot2";
|
|
||||||
group = "dovecot2";
|
|
||||||
fetchScript = ''
|
|
||||||
password=$(simple_get "/passwords/mail" .password)
|
|
||||||
htpasswd -nbB "" "$password" 2>/dev/null | cut -d: -f2 > "$secretFile"
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
system_mail_passwd = {
|
|
||||||
user = "dovecot2";
|
|
||||||
group = "dovecot2";
|
|
||||||
fetchScript = ''
|
|
||||||
password=$(simple_get "/api-keys/chaos_mail/system" .password)
|
|
||||||
htpasswd -nbB "" "$password" 2>/dev/null | cut -d: -f2 > "$secretFile"
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
gotosocial_mail_passwd = {
|
|
||||||
user = "dovecot2";
|
|
||||||
group = "dovecot2";
|
|
||||||
fetchScript = ''
|
|
||||||
password=$(simple_get "/api-keys/chaos_mail/gotosocial" .password)
|
|
||||||
htpasswd -nbB "" "$password" 2>/dev/null | cut -d: -f2 > "$secretFile"
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
# Container: social
|
|
||||||
social_restic_password = {
|
|
||||||
fetchScript = ''
|
|
||||||
simple_get "/private-public-keys/restic/Social" .password > "$secretFile"
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
social_restic_env = {
|
|
||||||
fetchScript = ''
|
|
||||||
RESTIC_USERNAME=$(simple_get "/api-keys/storage/restic/Social" .username)
|
|
||||||
RESTIC_PASSWORD=$(simple_get "/api-keys/storage/restic/Social" .password)
|
|
||||||
echo "RESTIC_REPOSITORY=rest:https://$RESTIC_USERNAME:$RESTIC_PASSWORD@storage-restic.owo.monster/Social" > "$secretFile"
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
social_env_secrets = {
|
|
||||||
fetchScript = ''
|
|
||||||
smtp_password=$(simple_get "/api-keys/chaos_mail/gotosocial" .password)
|
|
||||||
echo "GTS_SMTP_PASSWORD=$smtp_password" > "$secretFile"
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
# Container: quassel
|
|
||||||
quassel_restic_password = {
|
|
||||||
fetchScript = ''
|
|
||||||
simple_get "/private-public-keys/restic/Quassel" .password > "$secretFile"
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
quassel_restic_env = {
|
|
||||||
fetchScript = ''
|
|
||||||
RESTIC_USERNAME=$(simple_get "/api-keys/storage/restic/Quassel" .username)
|
|
||||||
RESTIC_PASSWORD=$(simple_get "/api-keys/storage/restic/Quassel" .password)
|
|
||||||
echo "RESTIC_REPOSITORY=rest:https://$RESTIC_USERNAME:$RESTIC_PASSWORD@storage-restic.owo.monster/Quassel" > "$secretFile"
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -9,8 +9,9 @@
|
||||||
presets.nixos.encryptedUSB
|
presets.nixos.encryptedUSB
|
||||||
|
|
||||||
profiles.cross.arm64
|
profiles.cross.arm64
|
||||||
#profiles.remote-builders
|
profiles.remoteBuilders
|
||||||
profiles.chaosInternalWireGuard
|
profiles.chaosInternalWireGuard
|
||||||
|
profiles.fingerprint
|
||||||
|
|
||||||
./secrets.nix
|
./secrets.nix
|
||||||
];
|
];
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
music_stream_password = {
|
music_stream_password = {
|
||||||
user = 1000;
|
user = "chaos";
|
||||||
group = "users";
|
group = "users";
|
||||||
fetchScript = ''
|
fetchScript = ''
|
||||||
simple_get "/api-keys/music-stream" .password > "$secretFile"
|
simple_get "/api-keys/music-stream" .password > "$secretFile"
|
||||||
|
@ -17,8 +17,6 @@
|
||||||
# Required for home.apps.manualBackupApps
|
# Required for home.apps.manualBackupApps
|
||||||
gitlab_archiver_token = {
|
gitlab_archiver_token = {
|
||||||
user = "chaos";
|
user = "chaos";
|
||||||
group = "users";
|
|
||||||
|
|
||||||
fetchScript = ''
|
fetchScript = ''
|
||||||
simple_get "/api-keys/gitlab/gitlab_archiver" .token > "$secretFile"
|
simple_get "/api-keys/gitlab/gitlab_archiver" .token > "$secretFile"
|
||||||
'';
|
'';
|
||||||
|
@ -27,8 +25,6 @@
|
||||||
# Required for home.apps.manualBackupApps
|
# Required for home.apps.manualBackupApps
|
||||||
restic_music_env = {
|
restic_music_env = {
|
||||||
user = "chaos";
|
user = "chaos";
|
||||||
group = "users";
|
|
||||||
|
|
||||||
fetchScript = ''
|
fetchScript = ''
|
||||||
api_username=$(simple_get "/api-keys/storage/restic/Music" .username)
|
api_username=$(simple_get "/api-keys/storage/restic/Music" .username)
|
||||||
api_password=$(simple_get "/api-keys/storage/restic/Music" .password)
|
api_password=$(simple_get "/api-keys/storage/restic/Music" .password)
|
||||||
|
|
|
@ -33,10 +33,9 @@
|
||||||
inputs.gitlab_artifacts_sync.nixosModules.default
|
inputs.gitlab_artifacts_sync.nixosModules.default
|
||||||
inputs.piped-flake.nixosModules.default
|
inputs.piped-flake.nixosModules.default
|
||||||
|
|
||||||
tree.modules.nixos.rclone-serve
|
tree.modules.nixos.rcloneServe
|
||||||
tree.modules.nixos.rclone-sync
|
tree.modules.nixos.rcloneSync
|
||||||
tree.modules.nixos.secrets
|
tree.modules.nixos.secrets
|
||||||
tree.modules.nixos.cockroachdb-bin
|
|
||||||
];
|
];
|
||||||
|
|
||||||
nixosUnstableSystem = nixpkgs-unstable.lib.nixosSystem;
|
nixosUnstableSystem = nixpkgs-unstable.lib.nixosSystem;
|
||||||
|
@ -81,16 +80,6 @@ in {
|
||||||
modules = defaultModules ++ [./hetzner-arm/hetzner-arm.nix];
|
modules = defaultModules ++ [./hetzner-arm/hetzner-arm.nix];
|
||||||
};
|
};
|
||||||
|
|
||||||
hetzner-vm = nixosUnstableSystem {
|
|
||||||
specialArgs =
|
|
||||||
defaultSpecialArgs
|
|
||||||
// {
|
|
||||||
hostPath = ./hetzner-vm;
|
|
||||||
};
|
|
||||||
system = "x86_64-linux";
|
|
||||||
modules = defaultModules ++ [./hetzner-vm/hetzner-vm.nix];
|
|
||||||
};
|
|
||||||
|
|
||||||
vault = nixosUnstableSystem {
|
vault = nixosUnstableSystem {
|
||||||
specialArgs =
|
specialArgs =
|
||||||
defaultSpecialArgs
|
defaultSpecialArgs
|
||||||
|
|
|
@ -5,16 +5,19 @@
|
||||||
inputs,
|
inputs,
|
||||||
config,
|
config,
|
||||||
pkgs,
|
pkgs,
|
||||||
|
lib,
|
||||||
...
|
...
|
||||||
}: let
|
}: let
|
||||||
containerName = "piped-uk";
|
inherit (lib.modules) mkForce;
|
||||||
containerConfig = config.containers.${containerName}.config;
|
|
||||||
|
pipedName = "piped-uk";
|
||||||
|
containerName = pipedName;
|
||||||
|
|
||||||
pipedSocketForComponent = (
|
pipedSocketForComponent = (
|
||||||
component: "/var/lib/nixos-containers/${containerName}/var/sockets/piped-${component}.sock"
|
component: "/var/lib/nixos-containers/${containerName}/var/sockets/piped-${component}.sock"
|
||||||
);
|
);
|
||||||
in {
|
in {
|
||||||
containers.piped-uk = {
|
containers.${containerName} = {
|
||||||
autoStart = true;
|
autoStart = true;
|
||||||
privateNetwork = false;
|
privateNetwork = false;
|
||||||
|
|
||||||
|
@ -30,26 +33,17 @@ in {
|
||||||
|
|
||||||
imports = with tree; [
|
imports = with tree; [
|
||||||
presets.nixos.containerBase
|
presets.nixos.containerBase
|
||||||
|
presets.nixos.pipedNode
|
||||||
profiles.nginx
|
|
||||||
profiles.firewallAllow.httpCommon
|
|
||||||
|
|
||||||
profiles.pipedCluster
|
|
||||||
|
|
||||||
./secrets.nix
|
|
||||||
];
|
];
|
||||||
|
|
||||||
# For Shared Secrets
|
networking.firewall.enable = mkForce false;
|
||||||
systemd.tmpfiles.rules = [
|
|
||||||
"d /var/lib/cockroachdb-certs - root root"
|
|
||||||
];
|
|
||||||
|
|
||||||
home-manager.users.root.home.stateVersion = "23.05";
|
home-manager.users.root.home.stateVersion = "23.05";
|
||||||
system.stateVersion = "23.05";
|
system.stateVersion = "23.05";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
services.nginx.virtualHosts."piped-uk.owo.monster" = {
|
services.nginx.virtualHosts."${pipedName}.owo.monster" = {
|
||||||
forceSSL = true;
|
forceSSL = true;
|
||||||
enableACME = true;
|
enableACME = true;
|
||||||
locations."/" = {
|
locations."/" = {
|
||||||
|
@ -57,7 +51,7 @@ in {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
services.nginx.virtualHosts."backend.piped-uk.owo.monster" = {
|
services.nginx.virtualHosts."backend.${pipedName}.owo.monster" = {
|
||||||
forceSSL = true;
|
forceSSL = true;
|
||||||
enableACME = true;
|
enableACME = true;
|
||||||
locations."/" = {
|
locations."/" = {
|
||||||
|
@ -65,7 +59,7 @@ in {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
services.nginx.virtualHosts."proxy.piped-uk.owo.monster" = {
|
services.nginx.virtualHosts."proxy.${pipedName}.owo.monster" = {
|
||||||
forceSSL = true;
|
forceSSL = true;
|
||||||
enableACME = true;
|
enableACME = true;
|
||||||
locations."/" = {
|
locations."/" = {
|
||||||
|
|
|
@ -1,73 +0,0 @@
|
||||||
{pkgs, ...}: {
|
|
||||||
services.secrets = {
|
|
||||||
enable = true;
|
|
||||||
|
|
||||||
packages = with pkgs; [rclone];
|
|
||||||
|
|
||||||
vaultLogin = {
|
|
||||||
enable = true;
|
|
||||||
loginUsername = "raspberry";
|
|
||||||
};
|
|
||||||
|
|
||||||
autoSecrets = {
|
|
||||||
enable = true;
|
|
||||||
affectedSystemdServices = ["wg-quick-wg0" "cockroachdb"];
|
|
||||||
};
|
|
||||||
|
|
||||||
extraFunctions = ''
|
|
||||||
simple_get_obscure() {
|
|
||||||
rclone obscure "$(simple_get "$@")"
|
|
||||||
}
|
|
||||||
'';
|
|
||||||
|
|
||||||
requiredVaultPaths = [
|
|
||||||
"private-public-keys/data/piped-cockroachdb-ca/nodes/raspberry"
|
|
||||||
];
|
|
||||||
|
|
||||||
secrets = {
|
|
||||||
vault_password = {
|
|
||||||
manual = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
piped_cockroachdb_ca_certificate = {
|
|
||||||
user = "cockroachdb";
|
|
||||||
group = "cockroachdb";
|
|
||||||
permissions = "600";
|
|
||||||
path = "/var/lib/cockroachdb-certs/ca.crt";
|
|
||||||
fetchScript = ''
|
|
||||||
if [ ! -d "$SYSROOT/var/lib/cockroachdb-certs" ]; then
|
|
||||||
mkdir -p "$SYSROOT/var/lib/cockroachdb-certs"
|
|
||||||
fi
|
|
||||||
simple_get "/private-public-keys/piped-cockroachdb-ca/nodes/raspberry" .ca_certificate \
|
|
||||||
| base64 -d > "$secretFile"
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
piped_cockroachdb_node_certificate = {
|
|
||||||
user = "cockroachdb";
|
|
||||||
group = "cockroachdb";
|
|
||||||
permissions = "600";
|
|
||||||
path = "/var/lib/cockroachdb-certs/node.crt";
|
|
||||||
fetchScript = ''
|
|
||||||
if [ ! -d "$SYSROOT/var/lib/cockroachdb-certs" ]; then
|
|
||||||
mkdir -p "$SYSROOT/var/lib/cockroachdb-certs"
|
|
||||||
fi
|
|
||||||
simple_get "/private-public-keys/piped-cockroachdb-ca/nodes/raspberry" .node_certificate \
|
|
||||||
| base64 -d > "$secretFile"
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
piped_cockroachdb_node_key = {
|
|
||||||
user = "cockroachdb";
|
|
||||||
group = "cockroachdb";
|
|
||||||
permissions = "600";
|
|
||||||
path = "/var/lib/cockroachdb-certs/node.key";
|
|
||||||
fetchScript = ''
|
|
||||||
if [ ! -d "$SYSROOT/var/lib/cockroachdb-certs" ]; then
|
|
||||||
mkdir -p "$SYSROOT/var/lib/cockroachdb-certs"
|
|
||||||
fi
|
|
||||||
simple_get "/private-public-keys/piped-cockroachdb-ca/nodes/raspberry" .node_key \
|
|
||||||
| base64 -d > "$secretFile"
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -15,7 +15,8 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
requiredVaultPaths = [
|
requiredVaultPaths = [
|
||||||
"/private-public-keys/data/ssh/root@vault-decrypt"
|
"private-public-keys/data/ssh/root@vault"
|
||||||
|
"private-public-keys/data/ssh/root@vault-decrypt"
|
||||||
|
|
||||||
"private-public-keys/data/restic/Vault"
|
"private-public-keys/data/restic/Vault"
|
||||||
|
|
||||||
|
@ -27,11 +28,28 @@
|
||||||
manual = true;
|
manual = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
ssh_host_ed25519_key = {
|
||||||
|
path = "/etc/ssh/ssh_host_ed25519_key";
|
||||||
|
permissions = "600";
|
||||||
|
fetchScript = ''
|
||||||
|
[ ! -d "$SYSROOT/etc/ssh" ] && mkdir -p "$SYSROOT/etc/ssh/"
|
||||||
|
simple_get "/private-public-keys/ssh/root@vault" .private | base64 -d > "$secretFile"
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
ssh_host_ed25519_key_pub = {
|
||||||
|
path = "/etc/ssh/ssh_host_ed25519_key.pub";
|
||||||
|
permissions = "600";
|
||||||
|
fetchScript = ''
|
||||||
|
[ ! -d "$SYSROOT/etc/ssh" ] && mkdir -p "$SYSROOT/etc/ssh/"
|
||||||
|
simple_get "/private-public-keys/ssh/root@vault" .private | base64 -d > "$secretFile"
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
# this doesn't need to be a secret and can be generated at install time
|
# this doesn't need to be a secret and can be generated at install time
|
||||||
# but it makes it easier to install.
|
# but it makes it easier to install.
|
||||||
# it's stored in /nix store anyway
|
# it's stored in /nix store anyway
|
||||||
ssh_host_ed25519_key = {
|
initrd_ssh_host_ed25519_key = {
|
||||||
path = "/ssh_host_ed25519_key";
|
path = "/initrd_ssh_host_ed25519_key";
|
||||||
permissions = "600";
|
permissions = "600";
|
||||||
fetchScript = ''
|
fetchScript = ''
|
||||||
simple_get "/private-public-keys/ssh/root@vault-decrypt" .private | base64 -d > "$secretFile"
|
simple_get "/private-public-keys/ssh/root@vault-decrypt" .private | base64 -d > "$secretFile"
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
]
|
]
|
||||||
++ (with hosts.vault.profiles; [
|
++ (with hosts.vault.profiles; [
|
||||||
vault
|
vault
|
||||||
|
vaultUI
|
||||||
restic
|
restic
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
|
|
@ -1,248 +0,0 @@
|
||||||
{
|
|
||||||
config,
|
|
||||||
lib,
|
|
||||||
pkgs,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
with lib; let
|
|
||||||
cfg = config.services.cockroachdb-bin;
|
|
||||||
crdb = cfg.package;
|
|
||||||
|
|
||||||
escapeSystemdExecArg = arg: let
|
|
||||||
s =
|
|
||||||
if builtins.isPath arg
|
|
||||||
then "${arg}"
|
|
||||||
else if builtins.isString arg
|
|
||||||
then arg
|
|
||||||
else if builtins.isInt arg || builtins.isFloat arg
|
|
||||||
then toString arg
|
|
||||||
else throw "escapeSystemdExecArg only allows strings, paths and numbers";
|
|
||||||
in
|
|
||||||
lib.replaceStrings ["%" "$"] ["%%" "$$"] (builtins.toJSON s);
|
|
||||||
|
|
||||||
# Quotes a list of arguments into a single string for use in a Exec*
|
|
||||||
# line.
|
|
||||||
escapeSystemdExecArgs = lib.concatMapStringsSep " " escapeSystemdExecArg;
|
|
||||||
|
|
||||||
startupCommand =
|
|
||||||
escapeSystemdExecArgs
|
|
||||||
([
|
|
||||||
# Basic startup
|
|
||||||
"${crdb}/bin/cockroach"
|
|
||||||
(
|
|
||||||
if (cfg.join != null)
|
|
||||||
then "start"
|
|
||||||
else "start-single-node"
|
|
||||||
)
|
|
||||||
"--logtostderr"
|
|
||||||
"--store=/var/lib/cockroachdb"
|
|
||||||
|
|
||||||
# WebUI settings
|
|
||||||
"--http-addr=${cfg.http.address}:${toString cfg.http.port}"
|
|
||||||
|
|
||||||
# Cluster listen address
|
|
||||||
"--listen-addr=${cfg.listen.address}:${toString cfg.listen.port}"
|
|
||||||
|
|
||||||
# Cache and memory settings.
|
|
||||||
"--cache=${cfg.cache}"
|
|
||||||
"--max-sql-memory=${cfg.maxSqlMemory}"
|
|
||||||
|
|
||||||
# Certificate/security settings.
|
|
||||||
(
|
|
||||||
if cfg.insecure
|
|
||||||
then "--insecure"
|
|
||||||
else "--certs-dir=${cfg.certsDir}"
|
|
||||||
)
|
|
||||||
]
|
|
||||||
++ lib.optional (cfg.join != null) "--join=${cfg.join}"
|
|
||||||
++ lib.optional (cfg.locality != null) "--locality=${cfg.locality}"
|
|
||||||
++ cfg.extraArgs);
|
|
||||||
|
|
||||||
addressOption = descr: defaultPort: {
|
|
||||||
address = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
default = "localhost";
|
|
||||||
description = lib.mdDoc "Address to bind to for ${descr}";
|
|
||||||
};
|
|
||||||
|
|
||||||
port = mkOption {
|
|
||||||
type = types.port;
|
|
||||||
default = defaultPort;
|
|
||||||
description = lib.mdDoc "Port to bind to for ${descr}";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
in {
|
|
||||||
options = {
|
|
||||||
services.cockroachdb-bin = {
|
|
||||||
enable = mkEnableOption (lib.mdDoc "CockroachDB Server");
|
|
||||||
|
|
||||||
listen = addressOption "intra-cluster communication" 26257;
|
|
||||||
|
|
||||||
http = addressOption "http-based Admin UI" 8080;
|
|
||||||
|
|
||||||
locality = mkOption {
|
|
||||||
type = types.nullOr types.str;
|
|
||||||
default = null;
|
|
||||||
description = lib.mdDoc ''
|
|
||||||
An ordered, comma-separated list of key-value pairs that describe the
|
|
||||||
topography of the machine. Topography might include country,
|
|
||||||
datacenter or rack designations. Data is automatically replicated to
|
|
||||||
maximize diversities of each tier. The order of tiers is used to
|
|
||||||
determine the priority of the diversity, so the more inclusive
|
|
||||||
localities like country should come before less inclusive localities
|
|
||||||
like datacenter. The tiers and order must be the same on all nodes.
|
|
||||||
Including more tiers is better than including fewer. For example:
|
|
||||||
|
|
||||||
```
|
|
||||||
country=us,region=us-west,datacenter=us-west-1b,rack=12
|
|
||||||
country=ca,region=ca-east,datacenter=ca-east-2,rack=4
|
|
||||||
|
|
||||||
planet=earth,province=manitoba,colo=secondary,power=3
|
|
||||||
```
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
join = mkOption {
|
|
||||||
type = types.nullOr types.str;
|
|
||||||
default = null;
|
|
||||||
description = lib.mdDoc "The addresses for connecting the node to a cluster.";
|
|
||||||
};
|
|
||||||
|
|
||||||
insecure = mkOption {
|
|
||||||
type = types.bool;
|
|
||||||
default = false;
|
|
||||||
description = lib.mdDoc "Run in insecure mode.";
|
|
||||||
};
|
|
||||||
|
|
||||||
certsDir = mkOption {
|
|
||||||
type = types.nullOr types.path;
|
|
||||||
default = null;
|
|
||||||
description = lib.mdDoc "The path to the certificate directory.";
|
|
||||||
};
|
|
||||||
|
|
||||||
user = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
default = "cockroachdb";
|
|
||||||
description = lib.mdDoc "User account under which CockroachDB runs";
|
|
||||||
};
|
|
||||||
|
|
||||||
group = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
default = "cockroachdb";
|
|
||||||
description = lib.mdDoc "User account under which CockroachDB runs";
|
|
||||||
};
|
|
||||||
|
|
||||||
openPorts = mkOption {
|
|
||||||
type = types.bool;
|
|
||||||
default = false;
|
|
||||||
description = lib.mdDoc "Open firewall ports for cluster communication by default";
|
|
||||||
};
|
|
||||||
|
|
||||||
cache = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
default = "25%";
|
|
||||||
description = lib.mdDoc ''
|
|
||||||
The total size for caches.
|
|
||||||
|
|
||||||
This can be a percentage, expressed with a fraction sign or as a
|
|
||||||
decimal-point number, or any bytes-based unit. For example,
|
|
||||||
`"25%"`, `"0.25"` both represent
|
|
||||||
25% of the available system memory. The values
|
|
||||||
`"1000000000"` and `"1GB"` both
|
|
||||||
represent 1 gigabyte of memory.
|
|
||||||
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
maxSqlMemory = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
default = "25%";
|
|
||||||
description = lib.mdDoc ''
|
|
||||||
The maximum in-memory storage capacity available to store temporary
|
|
||||||
data for SQL queries.
|
|
||||||
|
|
||||||
This can be a percentage, expressed with a fraction sign or as a
|
|
||||||
decimal-point number, or any bytes-based unit. For example,
|
|
||||||
`"25%"`, `"0.25"` both represent
|
|
||||||
25% of the available system memory. The values
|
|
||||||
`"1000000000"` and `"1GB"` both
|
|
||||||
represent 1 gigabyte of memory.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
package = mkOption {
|
|
||||||
type = types.package;
|
|
||||||
default = pkgs.cockroachdb-bin;
|
|
||||||
defaultText = literalExpression "pkgs.cockroachdb-bin";
|
|
||||||
description = lib.mdDoc ''
|
|
||||||
The CockroachDB derivation to use for running the service.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
extraArgs = mkOption {
|
|
||||||
type = types.listOf types.str;
|
|
||||||
default = [];
|
|
||||||
example = ["--advertise-addr" "[fe80::f6f2:::]"];
|
|
||||||
description = lib.mdDoc ''
|
|
||||||
Extra CLI arguments passed to {command}`cockroach start`.
|
|
||||||
For the full list of supported arguments, check <https://www.cockroachlabs.com/docs/stable/cockroach-start.html#flags>
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
config = mkIf config.services.cockroachdb-bin.enable {
|
|
||||||
assertions = [
|
|
||||||
{
|
|
||||||
assertion = !cfg.insecure -> cfg.certsDir != null;
|
|
||||||
message = "CockroachDB must have a set of SSL certificates (.certsDir), or run in Insecure Mode (.insecure = true)";
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
environment.systemPackages = [crdb];
|
|
||||||
|
|
||||||
users.users = optionalAttrs (cfg.user == "cockroachdb") {
|
|
||||||
cockroachdb = {
|
|
||||||
description = "CockroachDB Server User";
|
|
||||||
uid = config.ids.uids.cockroachdb;
|
|
||||||
group = cfg.group;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
users.groups = optionalAttrs (cfg.group == "cockroachdb") {
|
|
||||||
cockroachdb.gid = config.ids.gids.cockroachdb;
|
|
||||||
};
|
|
||||||
|
|
||||||
networking.firewall.allowedTCPPorts =
|
|
||||||
lib.optionals cfg.openPorts
|
|
||||||
[cfg.http.port cfg.listen.port];
|
|
||||||
|
|
||||||
systemd.services.cockroachdb = {
|
|
||||||
description = "CockroachDB Server";
|
|
||||||
documentation = ["man:cockroach(1)" "https://www.cockroachlabs.com"];
|
|
||||||
|
|
||||||
after = ["network.target" "time-sync.target"];
|
|
||||||
requires = ["time-sync.target"];
|
|
||||||
wantedBy = ["multi-user.target"];
|
|
||||||
|
|
||||||
unitConfig.RequiresMountsFor = "/var/lib/cockroachdb";
|
|
||||||
|
|
||||||
serviceConfig = {
|
|
||||||
ExecStart = startupCommand;
|
|
||||||
Type = "notify";
|
|
||||||
User = cfg.user;
|
|
||||||
StateDirectory = "cockroachdb";
|
|
||||||
StateDirectoryMode = "0700";
|
|
||||||
|
|
||||||
Restart = "always";
|
|
||||||
|
|
||||||
# A conservative-ish timeout is alright here, because for Type=notify
|
|
||||||
# cockroach will send systemd pings during startup to keep it alive
|
|
||||||
TimeoutStopSec = 60;
|
|
||||||
RestartSec = 10;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
meta.maintainers = with lib.maintainers; [thoughtpolice];
|
|
||||||
}
|
|
|
@ -84,6 +84,12 @@ in {
|
||||||
(mkIf (cfg.enable && cfg.syncJobs != []) {
|
(mkIf (cfg.enable && cfg.syncJobs != []) {
|
||||||
environment.systemPackages =
|
environment.systemPackages =
|
||||||
[
|
[
|
||||||
|
(pkgs.writeShellScriptBin "rclone-sync-stop-all" (concatStringsSep "\n" (map (
|
||||||
|
job: ''
|
||||||
|
systemctl stop rclone-sync-${job.id}.service
|
||||||
|
''
|
||||||
|
)
|
||||||
|
cfg.syncJobs)))
|
||||||
(pkgs.writeShellScriptBin "rclone-sync-all" (concatStringsSep "\n" (map (
|
(pkgs.writeShellScriptBin "rclone-sync-all" (concatStringsSep "\n" (map (
|
||||||
job: ''
|
job: ''
|
||||||
${pkgs.rclone}/bin/rclone sync ${job.source} ${job.dest} ${concatStringsSep " " job.extraArgs} -P $@
|
${pkgs.rclone}/bin/rclone sync ${job.source} ${job.dest} ${concatStringsSep " " job.extraArgs} -P $@
|
|
@ -8,7 +8,7 @@
|
||||||
inherit (lib.options) mkOption mkEnableOption;
|
inherit (lib.options) mkOption mkEnableOption;
|
||||||
inherit (lib.lists) filter;
|
inherit (lib.lists) filter;
|
||||||
inherit (lib) types;
|
inherit (lib) types;
|
||||||
inherit (builtins) isString listToAttrs;
|
inherit (builtins) isString listToAttrs attrNames;
|
||||||
|
|
||||||
cfg = config.services.secrets;
|
cfg = config.services.secrets;
|
||||||
|
|
||||||
|
@ -115,25 +115,79 @@ in {
|
||||||
extraFunctions = mkOption {
|
extraFunctions = mkOption {
|
||||||
type = types.lines;
|
type = types.lines;
|
||||||
default = "";
|
default = "";
|
||||||
description = "extra bash functions to add to top of script";
|
description = "extra bash functions to add to top of script for init";
|
||||||
|
};
|
||||||
|
|
||||||
|
extraCheckFunctions = mkOption {
|
||||||
|
type = types.lines;
|
||||||
|
default = "";
|
||||||
|
description = "extra bash functions to add to top of script for check";
|
||||||
};
|
};
|
||||||
|
|
||||||
uidMap = mkOption {
|
uidMap = mkOption {
|
||||||
type = types.attrsOf types.int;
|
type = types.attrsOf types.int;
|
||||||
default = {};
|
default = listToAttrs (map (
|
||||||
description = "optional mapping of users to user IDs; required for SYSROOT when user isn't available on host";
|
secretName: let
|
||||||
|
secretUserName = cfg.secrets.${secretName}.user;
|
||||||
|
in {
|
||||||
|
name = "${secretUserName}";
|
||||||
|
value = config.users.users.${secretUserName}.uid;
|
||||||
|
}
|
||||||
|
) (filter
|
||||||
|
(secretName: let
|
||||||
|
secret = cfg.secrets.${secretName};
|
||||||
|
in
|
||||||
|
isString secret.user
|
||||||
|
&& (
|
||||||
|
if config.users.users ? "${secret.user}"
|
||||||
|
then true
|
||||||
|
else builtins.trace "warning: secrets module could not find a uid mapping for user ${secret.user}" false
|
||||||
|
))
|
||||||
|
(attrNames cfg.secrets)));
|
||||||
|
description = ''
|
||||||
|
optional mapping of users to user IDs
|
||||||
|
required for SYSROOT when user isn't available on host
|
||||||
|
defaults to getting values from users.users.<name>.uid for all secrets with user set as string
|
||||||
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
gidMap = mkOption {
|
gidMap = mkOption {
|
||||||
type = types.attrsOf types.int;
|
type = types.attrsOf types.int;
|
||||||
default = {};
|
default = listToAttrs (map (
|
||||||
description = "optional mapping of groups to group IDs; required for SYSROOT when group isn't available on host";
|
secretName: let
|
||||||
|
secretGroupName = cfg.secrets.${secretName}.group;
|
||||||
|
in {
|
||||||
|
name = "${secretGroupName}";
|
||||||
|
value = config.users.groups.${secretGroupName}.gid;
|
||||||
|
}
|
||||||
|
) (filter
|
||||||
|
(secretName: let
|
||||||
|
secret = cfg.secrets.${secretName};
|
||||||
|
in
|
||||||
|
isString secret.group
|
||||||
|
&& (
|
||||||
|
if config.users.groups ? "${secret.group}"
|
||||||
|
then true
|
||||||
|
else builtins.trace "warning: secrets module could not find a gid mapping for group ${secret.group}" false
|
||||||
|
))
|
||||||
|
(attrNames cfg.secrets)));
|
||||||
|
description = ''
|
||||||
|
optional mapping of groups to group IDs
|
||||||
|
required for SYSROOT when group isn't available on host
|
||||||
|
defaults to getting values from users.groups.<group>.gid for all secrets with group set as string
|
||||||
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
packages = mkOption {
|
packages = mkOption {
|
||||||
type = types.listOf types.package;
|
type = types.listOf types.package;
|
||||||
default = [];
|
default = [];
|
||||||
description = "packages for script";
|
description = "packages for init script";
|
||||||
|
};
|
||||||
|
|
||||||
|
checkPackages = mkOption {
|
||||||
|
type = types.listOf types.package;
|
||||||
|
default = [];
|
||||||
|
description = "packages for checkscript";
|
||||||
};
|
};
|
||||||
|
|
||||||
secrets = mkOption {
|
secrets = mkOption {
|
||||||
|
@ -241,7 +295,7 @@ in {
|
||||||
// {
|
// {
|
||||||
auto-secrets.partOf =
|
auto-secrets.partOf =
|
||||||
map (unitConfig: unitConfig.name + ".service")
|
map (unitConfig: unitConfig.name + ".service")
|
||||||
(lib.filter
|
(filter
|
||||||
(unitConfig: unitConfig.withPartOf)
|
(unitConfig: unitConfig.withPartOf)
|
||||||
affectedSystemdServices);
|
affectedSystemdServices);
|
||||||
};
|
};
|
||||||
|
|
|
@ -195,6 +195,11 @@
|
||||||
stat --format "%a" "$1" 2>/dev/null
|
stat --format "%a" "$1" 2>/dev/null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
emojiTick="✅"
|
||||||
|
emojiCross="❌"
|
||||||
|
|
||||||
|
${cfg.extraCheckFunctions}
|
||||||
|
|
||||||
GLOBAL_FAIL=false
|
GLOBAL_FAIL=false
|
||||||
''
|
''
|
||||||
+ (concatStringsSep "\n" (mapAttrsToList (_name: secret: let
|
+ (concatStringsSep "\n" (mapAttrsToList (_name: secret: let
|
||||||
|
@ -226,40 +231,40 @@
|
||||||
secretFile="$SYSROOT${secretPath}"
|
secretFile="$SYSROOT${secretPath}"
|
||||||
|
|
||||||
if [[ -f "$SYSROOT${secretPath}" ]]; then
|
if [[ -f "$SYSROOT${secretPath}" ]]; then
|
||||||
echo "✅ File Exists"
|
echo "$emojiTick File Exists"
|
||||||
else
|
else
|
||||||
echo "❌ File Does Not Exist"
|
echo "$emojiCross File Does Not Exist"
|
||||||
LOCAL_FAIL=true
|
LOCAL_FAIL=true
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if getUserID "$SYSROOT${secretPath}" >/dev/null && ${userCheck}; then
|
if getUserID "$SYSROOT${secretPath}" >/dev/null && ${userCheck}; then
|
||||||
echo "✅ File Is Owned By Correct User"
|
echo "$emojiTick File Is Owned By Correct User"
|
||||||
else
|
else
|
||||||
echo "❌ File Is Not Owned By Correct User (${toString secretUser})"
|
echo "$emojiCross File Is Not Owned By Correct User (${toString secretUser})"
|
||||||
LOCAL_FAIL=true
|
LOCAL_FAIL=true
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if getGroupID "$SYSROOT${secretPath}" >/dev/null && ${groupCheck}; then
|
if getGroupID "$SYSROOT${secretPath}" >/dev/null && ${groupCheck}; then
|
||||||
echo "✅ File Is Owned By Correct Group"
|
echo "$emojiTick File Is Owned By Correct Group"
|
||||||
else
|
else
|
||||||
echo "❌ File Is Not Owned By Correct Group (${toString secretGroup})"
|
echo "$emojiCross File Is Not Owned By Correct Group (${toString secretGroup})"
|
||||||
LOCAL_FAIL=true
|
LOCAL_FAIL=true
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if getPermissions "$SYSROOT${secretPath}" >/dev/null && [[ "$(getPermissions "$SYSROOT${secretPath}")" -eq "${secretPermissions}" ]]; then
|
if getPermissions "$SYSROOT${secretPath}" >/dev/null && [[ "$(getPermissions "$SYSROOT${secretPath}")" -eq "${secretPermissions}" ]]; then
|
||||||
echo "✅ File Has Correct Permissions"
|
echo "$emojiTick File Has Correct Permissions"
|
||||||
else
|
else
|
||||||
echo "❌ File Does Not Have Correct Permissions (${secretPermissions})"
|
echo "$emojiCross File Does Not Have Correct Permissions (${secretPermissions})"
|
||||||
LOCAL_FAIL=true
|
LOCAL_FAIL=true
|
||||||
fi
|
fi
|
||||||
|
|
||||||
${optionalString (secret.checkScript != null) secret.checkScript}
|
${optionalString (secret.checkScript != null) secret.checkScript}
|
||||||
|
|
||||||
if [[ "$LOCAL_FAIL" == "true" ]]; then
|
if [[ "$LOCAL_FAIL" == "true" ]]; then
|
||||||
echo "❌ File Did Not Pass The Vibe Check"
|
echo "$emojiCross File Did Not Pass The Vibe Check"
|
||||||
GLOBAL_FAIL=true
|
GLOBAL_FAIL=true
|
||||||
else
|
else
|
||||||
echo "✅ File Passed The Vibe Check"
|
echo "$emojiTick File Passed The Vibe Check"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo
|
echo
|
||||||
|
@ -267,10 +272,10 @@
|
||||||
cfg.secrets))
|
cfg.secrets))
|
||||||
+ ''
|
+ ''
|
||||||
if [[ "$GLOBAL_FAIL" == "true" ]]; then
|
if [[ "$GLOBAL_FAIL" == "true" ]]; then
|
||||||
echo "❌ One Or More Secrets Did Not Pass The Vibe Check"
|
echo "$emojiCross One Or More Secrets Did Not Pass The Vibe Check"
|
||||||
exit 1
|
exit 1
|
||||||
else
|
else
|
||||||
echo "✅ All Secrets Passed The Vibe Check"
|
echo "$emojiTick All Secrets Passed The Vibe Check"
|
||||||
fi
|
fi
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
@ -319,7 +324,7 @@ in rec {
|
||||||
scripts = genScripts cfg;
|
scripts = genScripts cfg;
|
||||||
in (writeShellApplication {
|
in (writeShellApplication {
|
||||||
name = scriptName;
|
name = scriptName;
|
||||||
runtimeInputs = defaultPackages ++ cfg.packages;
|
runtimeInputs = defaultPackages ++ cfg.checkPackages;
|
||||||
text = scripts.checkScript;
|
text = scripts.checkScript;
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
26
outputs.nix
26
outputs.nix
|
@ -18,6 +18,22 @@ in
|
||||||
overlays = [
|
overlays = [
|
||||||
(import ./overlay)
|
(import ./overlay)
|
||||||
inputs.piped-flake.overlays.default
|
inputs.piped-flake.overlays.default
|
||||||
|
(_prev: final: {
|
||||||
|
piped-backend-deps =
|
||||||
|
final.piped-backend-deps.overrideAttrs
|
||||||
|
{
|
||||||
|
# Won't build due to this; added a native-arm64 to all builders on arm64
|
||||||
|
# https://github.com/NixOS/nixpkgs/issues/255780
|
||||||
|
requiredSystemFeatures = ["native-arm64"];
|
||||||
|
};
|
||||||
|
piped-backend =
|
||||||
|
final.piped-backend.overrideAttrs
|
||||||
|
{
|
||||||
|
# Won't build due to this; added a native-arm64 to all builders on arm64
|
||||||
|
# https://github.com/NixOS/nixpkgs/issues/255780
|
||||||
|
requiredSystemFeatures = ["native-arm64"];
|
||||||
|
};
|
||||||
|
})
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
in
|
in
|
||||||
|
@ -50,7 +66,6 @@ in
|
||||||
inherit (pkgs) comic-code comic-sans;
|
inherit (pkgs) comic-code comic-sans;
|
||||||
inherit (pkgs) mk-enc-usb mk-encrypted-drive mk-raspberry-ext-drive;
|
inherit (pkgs) mk-enc-usb mk-encrypted-drive mk-raspberry-ext-drive;
|
||||||
inherit (pkgs) gotosocial;
|
inherit (pkgs) gotosocial;
|
||||||
inherit (pkgs) cockroachdb;
|
|
||||||
inherit (pkgs) piped-backend piped-frontend piped-proxy;
|
inherit (pkgs) piped-backend piped-frontend piped-proxy;
|
||||||
inherit (pkgs) kitty-terminfo;
|
inherit (pkgs) kitty-terminfo;
|
||||||
};
|
};
|
||||||
|
@ -124,18 +139,15 @@ in
|
||||||
|
|
||||||
# All machines/containers with secrets.nix
|
# All machines/containers with secrets.nix
|
||||||
machines = rec {
|
machines = rec {
|
||||||
"hetzner-vm" = {
|
|
||||||
containers = ["storage" "piped-fi"];
|
|
||||||
sshAddress = "hetzner-vm.servers.genderfucked.monster";
|
|
||||||
};
|
|
||||||
"hetzner-arm" = {
|
"hetzner-arm" = {
|
||||||
containers = ["storage" "piped-fi"];
|
containers = ["storage" "music" "quassel" "social" "mail" "piped-db" "piped-fi"];
|
||||||
sshAddress = "hetzner-vm.servers.genderfucked.monster";
|
sshAddress = "hetzner-arm.servers.genderfucked.monster";
|
||||||
};
|
};
|
||||||
"vault" = {
|
"vault" = {
|
||||||
sshAddress = "vault.servers.genderfucked.monster";
|
sshAddress = "vault.servers.genderfucked.monster";
|
||||||
};
|
};
|
||||||
"raspberry" = {
|
"raspberry" = {
|
||||||
|
containers = ["piped-uk"];
|
||||||
sshAddress = "raspberry.servers.genderfucked.monster";
|
sshAddress = "raspberry.servers.genderfucked.monster";
|
||||||
};
|
};
|
||||||
"lappy-t495" = {};
|
"lappy-t495" = {};
|
||||||
|
|
|
@ -1,48 +0,0 @@
|
||||||
{
|
|
||||||
lib,
|
|
||||||
stdenv,
|
|
||||||
autoPatchelfHook,
|
|
||||||
fetchzip,
|
|
||||||
}:
|
|
||||||
stdenv.mkDerivation rec {
|
|
||||||
pname = "cockroachdb-bin";
|
|
||||||
version = "23.1.9";
|
|
||||||
|
|
||||||
src = let
|
|
||||||
inherit (stdenv.hostPlatform) system;
|
|
||||||
selectSystem = attrs: attrs.${system} or (throw "Unsupported system: ${system}");
|
|
||||||
suffix = selectSystem {
|
|
||||||
x86_64-linux = "linux-amd64";
|
|
||||||
aarch64-linux = "linux-arm64";
|
|
||||||
};
|
|
||||||
sha256 = selectSystem {
|
|
||||||
x86_64-linux = "sha256-TopDCszdU73WiD/fsa/lq4h7jPUk0u50v3ELiuakzTU=";
|
|
||||||
aarch64-linux = "sha256-uRW1g2IFAfQ6a1w7pz5GKklHmfaNgk70qj3hhm6KV6s=";
|
|
||||||
};
|
|
||||||
in
|
|
||||||
fetchzip {
|
|
||||||
url = "https://binaries.cockroachdb.com/cockroach-v${version}.${suffix}.tgz";
|
|
||||||
inherit sha256;
|
|
||||||
};
|
|
||||||
|
|
||||||
dontConfigure = true;
|
|
||||||
dontBuild = true;
|
|
||||||
dontStrip = stdenv.isDarwin;
|
|
||||||
|
|
||||||
nativeBuildInputs = [autoPatchelfHook];
|
|
||||||
|
|
||||||
installPhase = ''
|
|
||||||
runHook preInstall
|
|
||||||
install -D cockroach $out/bin/cockroach
|
|
||||||
runHook postInstall
|
|
||||||
'';
|
|
||||||
|
|
||||||
meta = with lib; {
|
|
||||||
homepage = "https://www.cockroachlabs.com";
|
|
||||||
description = "A scalable, survivable, strongly-consistent SQL database";
|
|
||||||
license = licenses.bsl11;
|
|
||||||
mainProgram = "cockroach";
|
|
||||||
sourceProvenance = with sourceTypes; [binaryNativeCode];
|
|
||||||
platforms = ["x86_64-linux" "aarch64-linux"];
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -13,9 +13,6 @@ final: prev: rec {
|
||||||
cp -r ${./kitty-terminfo}/* $out/share
|
cp -r ${./kitty-terminfo}/* $out/share
|
||||||
'';
|
'';
|
||||||
|
|
||||||
cockroachdb-bin = final.callPackage ./cockroachdb-bin {};
|
|
||||||
cockroachdb = cockroachdb-bin;
|
|
||||||
|
|
||||||
gotosocial = prev.gotosocial.overrideAttrs (_old: let
|
gotosocial = prev.gotosocial.overrideAttrs (_old: let
|
||||||
owner = "superseriousbusiness";
|
owner = "superseriousbusiness";
|
||||||
repo = "gotosocial";
|
repo = "gotosocial";
|
||||||
|
|
|
@ -8,10 +8,9 @@
|
||||||
profiles.base
|
profiles.base
|
||||||
users.root
|
users.root
|
||||||
|
|
||||||
modules.nixos.rclone-serve
|
modules.nixos.rcloneServe
|
||||||
modules.nixos.rclone-sync
|
modules.nixos.rcloneSync
|
||||||
modules.nixos.secrets
|
modules.nixos.secrets
|
||||||
modules.nixos.cockroachdb-bin
|
|
||||||
])
|
])
|
||||||
++ [
|
++ [
|
||||||
# Default modules which are usually included in nixos.nix
|
# Default modules which are usually included in nixos.nix
|
||||||
|
|
|
@ -8,6 +8,8 @@
|
||||||
profiles.tor
|
profiles.tor
|
||||||
];
|
];
|
||||||
|
|
||||||
|
services.fwupd.enable = true;
|
||||||
|
|
||||||
# TODO: Better DNS setup
|
# TODO: Better DNS setup
|
||||||
services.resolved.enable = false;
|
services.resolved.enable = false;
|
||||||
environment.etc."resolv.conf".text = ''
|
environment.etc."resolv.conf".text = ''
|
||||||
|
|
|
@ -1,17 +1,44 @@
|
||||||
{
|
{
|
||||||
self,
|
self,
|
||||||
config,
|
config,
|
||||||
|
tree,
|
||||||
...
|
...
|
||||||
}: let
|
}: let
|
||||||
clusterConfig = import "${self}/data/piped/pipedClusterConfig.nix";
|
inherit (builtins) attrNames elem;
|
||||||
inherit (clusterConfig) hosts ports;
|
|
||||||
|
|
||||||
currentHostName = config.networking.hostName;
|
wireguardData = import "${self}/data/wireguard/chaosInternalWireGuard.nix";
|
||||||
currentHostConfig = hosts.${currentHostName};
|
wireguardHosts = wireguardData.hosts;
|
||||||
|
|
||||||
baseDomain = currentHostConfig.baseDomain;
|
hostName = config.networking.hostName;
|
||||||
|
|
||||||
|
defaultPorts = {
|
||||||
|
internalPipedBackend = 3012;
|
||||||
|
internalPipedProxy = 3013;
|
||||||
|
|
||||||
|
internalNginxPort = 8199;
|
||||||
|
};
|
||||||
|
|
||||||
|
hostConfigs = {
|
||||||
|
"piped-fi" = {
|
||||||
|
baseDomain = "piped-fi.owo.monster";
|
||||||
|
ports = defaultPorts;
|
||||||
|
};
|
||||||
|
"piped-uk" = {
|
||||||
|
baseDomain = "piped-uk.owo.monster";
|
||||||
|
ports = defaultPorts;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
hostConfig =
|
||||||
|
if elem hostName (attrNames hostConfigs)
|
||||||
|
then hostConfigs.${hostName}
|
||||||
|
else throw "host isn't configured for piped node";
|
||||||
|
|
||||||
|
inherit (hostConfig) baseDomain ports;
|
||||||
in {
|
in {
|
||||||
systemd.coredump.enable = true;
|
imports = with tree; [
|
||||||
|
profiles.nginx
|
||||||
|
];
|
||||||
|
|
||||||
services.piped = {
|
services.piped = {
|
||||||
enable = true;
|
enable = true;
|
||||||
|
@ -42,10 +69,9 @@ in {
|
||||||
disablePostgresDB = true;
|
disablePostgresDB = true;
|
||||||
name = "piped";
|
name = "piped";
|
||||||
username = "piped";
|
username = "piped";
|
||||||
passwordFile = builtins.toFile "password-file" "piped";
|
usePassword = false;
|
||||||
host = "127.0.0.1";
|
host = "${wireguardHosts."hetzner-arm".ip}";
|
||||||
port = ports.cockroachDB;
|
port = 5434;
|
||||||
dialect = "org.hibernate.dialect.CockroachDialect";
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -70,42 +96,28 @@ in {
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
systemd.services.piped-backend = {
|
|
||||||
after = ["network.target" "cockroachdb.service" "haproxy.service"];
|
|
||||||
wants = ["network.target" "cockroachdb.service" "haproxy.service"];
|
|
||||||
};
|
|
||||||
|
|
||||||
services.nginx.virtualHosts = let
|
services.nginx.virtualHosts = let
|
||||||
componentPath = component: "/var/sockets/piped-${component}.sock";
|
componentPath = component: "/var/sockets/piped-${component}.sock";
|
||||||
|
listen = [
|
||||||
|
{
|
||||||
|
addr = "127.0.0.1";
|
||||||
|
port = ports.internalNginxPort;
|
||||||
|
}
|
||||||
|
];
|
||||||
in {
|
in {
|
||||||
"${baseDomain}" = {
|
"${baseDomain}" = {
|
||||||
listen = [
|
inherit listen;
|
||||||
{
|
|
||||||
addr = "127.0.0.1";
|
|
||||||
port = 8091;
|
|
||||||
}
|
|
||||||
];
|
|
||||||
extraConfig = "listen unix:${componentPath "frontend"};";
|
extraConfig = "listen unix:${componentPath "frontend"};";
|
||||||
};
|
};
|
||||||
|
|
||||||
"backend.${baseDomain}" = {
|
"backend.${baseDomain}" = {
|
||||||
|
inherit listen;
|
||||||
extraConfig = "listen unix:${componentPath "backend"};";
|
extraConfig = "listen unix:${componentPath "backend"};";
|
||||||
listen = [
|
|
||||||
{
|
|
||||||
addr = "127.0.0.1";
|
|
||||||
port = 8092;
|
|
||||||
}
|
|
||||||
];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
"proxy.${baseDomain}" = {
|
"proxy.${baseDomain}" = {
|
||||||
|
inherit listen;
|
||||||
extraConfig = "listen unix:${componentPath "proxy"};";
|
extraConfig = "listen unix:${componentPath "proxy"};";
|
||||||
listen = [
|
|
||||||
{
|
|
||||||
addr = "127.0.0.1";
|
|
||||||
port = 8093;
|
|
||||||
}
|
|
||||||
];
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
|
@ -27,6 +27,8 @@
|
||||||
'';
|
'';
|
||||||
|
|
||||||
boot.kernel.sysctl = {
|
boot.kernel.sysctl = {
|
||||||
|
"net.core.default_qdisc" = "fq";
|
||||||
|
"net.ipv4.tcp_congestion_control" = "bbr";
|
||||||
"fs.inotify.max_user_watches" = 1024 * 64 * 16;
|
"fs.inotify.max_user_watches" = 1024 * 64 * 16;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
...
|
...
|
||||||
}: let
|
}: let
|
||||||
inherit (lib.modules) mkForce;
|
inherit (lib.modules) mkForce;
|
||||||
inherit (lib.lists) optional;
|
inherit (lib.lists) optionals;
|
||||||
|
|
||||||
system = pkgs.system;
|
system = pkgs.system;
|
||||||
|
|
||||||
|
@ -33,10 +33,10 @@ in {
|
||||||
"dm_mod"
|
"dm_mod"
|
||||||
"cryptd"
|
"cryptd"
|
||||||
]
|
]
|
||||||
++ (lib.optionals (system == "x86_64_linux") ["aesni_intel"]);
|
++ (optionals (system == "x86_64_linux") ["aesni_intel"]);
|
||||||
|
|
||||||
secrets = {
|
secrets = {
|
||||||
"/ssh_host_ed25519_key" = "/ssh_host_ed25519_key";
|
"/ssh_host_ed25519_key" = mkForce "/initrd_ssh_host_ed25519_key";
|
||||||
};
|
};
|
||||||
|
|
||||||
luks = {
|
luks = {
|
||||||
|
|
|
@ -42,13 +42,12 @@ in {
|
||||||
|
|
||||||
boot.kernelParams =
|
boot.kernelParams =
|
||||||
[
|
[
|
||||||
"console=tty0"
|
|
||||||
"ip=${hostServerIPs.ipv4}::${gateway}:${netmask}:${hostName}:enp1s0:any"
|
"ip=${hostServerIPs.ipv4}::${gateway}:${netmask}:${hostName}:enp1s0:any"
|
||||||
"boot.shell_on_fail"
|
"boot.shell_on_fail"
|
||||||
"nohibernate"
|
"nohibernate"
|
||||||
"loglevel=4"
|
"loglevel=4"
|
||||||
]
|
]
|
||||||
++ (lib.optionals (system == "aarch64-linux") ["console=tty" "console=ttyAMA0,115200" "console=ttyS0,115200"]);
|
++ (lib.optionals (system == "aarch64-linux") ["console=tty"]);
|
||||||
|
|
||||||
systemd.network = {
|
systemd.network = {
|
||||||
enable = true;
|
enable = true;
|
||||||
|
|
|
@ -1,5 +0,0 @@
|
||||||
{lib, ...}: let
|
|
||||||
inherit (lib.modules) mkForce;
|
|
||||||
in {
|
|
||||||
security.sudo.wheelNeedsPassword = mkForce false;
|
|
||||||
}
|
|
|
@ -1,10 +1,12 @@
|
||||||
{
|
{
|
||||||
inputs,
|
inputs,
|
||||||
config,
|
config,
|
||||||
|
pkgs,
|
||||||
lib,
|
lib,
|
||||||
...
|
...
|
||||||
}: let
|
}: let
|
||||||
inherit (lib.strings) optionalString versionAtLeast;
|
inherit (lib.strings) optionalString versionAtLeast;
|
||||||
|
inherit (lib.optional);
|
||||||
in {
|
in {
|
||||||
nix = {
|
nix = {
|
||||||
nixPath = ["nixpkgs=${inputs.nixpkgs}"];
|
nixPath = ["nixpkgs=${inputs.nixpkgs}"];
|
||||||
|
@ -13,6 +15,7 @@ in {
|
||||||
(versionAtLeast config.nix.package.version "2.4") ''
|
(versionAtLeast config.nix.package.version "2.4") ''
|
||||||
experimental-features = nix-command flakes
|
experimental-features = nix-command flakes
|
||||||
'';
|
'';
|
||||||
|
settings.system-features = lib.optional (pkgs.system == "aarch64-linux") "native-arm64";
|
||||||
settings.trusted-users = ["root" "@wheel"];
|
settings.trusted-users = ["root" "@wheel"];
|
||||||
};
|
};
|
||||||
nixpkgs = {
|
nixpkgs = {
|
||||||
|
@ -30,6 +33,23 @@ in {
|
||||||
inputs.gitlab_artifacts_sync.overlays.default
|
inputs.gitlab_artifacts_sync.overlays.default
|
||||||
inputs.gitlab_archiver.overlays.default
|
inputs.gitlab_archiver.overlays.default
|
||||||
inputs.piped-flake.overlays.default
|
inputs.piped-flake.overlays.default
|
||||||
|
|
||||||
|
(_prev: final: {
|
||||||
|
piped-backend-deps =
|
||||||
|
final.piped-backend-deps.overrideAttrs
|
||||||
|
{
|
||||||
|
# Won't build due to this; added a native-arm64 to all builders on arm64
|
||||||
|
# https://github.com/NixOS/nixpkgs/issues/255780
|
||||||
|
requiredSystemFeatures = ["native-arm64"];
|
||||||
|
};
|
||||||
|
piped-backend =
|
||||||
|
final.piped-backend.overrideAttrs
|
||||||
|
{
|
||||||
|
# Won't build due to this; added a native-arm64 to all builders on arm64
|
||||||
|
# https://github.com/NixOS/nixpkgs/issues/255780
|
||||||
|
requiredSystemFeatures = ["native-arm64"];
|
||||||
|
};
|
||||||
|
})
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
environment.etc."nixpkgs-commit".text = inputs.nixpkgs-unstable.rev;
|
environment.etc."nixpkgs-commit".text = inputs.nixpkgs-unstable.rev;
|
||||||
|
|
5
profiles/base/sudo.nix
Normal file
5
profiles/base/sudo.nix
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
{lib, ...}: let
|
||||||
|
inherit (lib.modules) mkDefault;
|
||||||
|
in {
|
||||||
|
security.sudo.wheelNeedsPassword = mkDefault false;
|
||||||
|
}
|
37
profiles/fingerprint.nix
Normal file
37
profiles/fingerprint.nix
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
{
|
||||||
|
lib,
|
||||||
|
pkgs,
|
||||||
|
config,
|
||||||
|
...
|
||||||
|
}: let
|
||||||
|
inherit (lib.modules) mkIf mkForce;
|
||||||
|
in {
|
||||||
|
services.fprintd.enable = true;
|
||||||
|
|
||||||
|
security.sudo.wheelNeedsPassword = mkForce true;
|
||||||
|
|
||||||
|
security.pam.services = {
|
||||||
|
sudo.fprintAuth = true;
|
||||||
|
login.fprintAuth = true;
|
||||||
|
|
||||||
|
gdm-fingerprint = mkIf (config.services.xserver.displayManager.gdm.enable) {
|
||||||
|
text = ''
|
||||||
|
auth required pam_shells.so
|
||||||
|
auth requisite pam_nologin.so
|
||||||
|
auth requisite pam_faillock.so preauth
|
||||||
|
auth required ${pkgs.fprintd}/lib/security/pam_fprintd.so
|
||||||
|
auth optional pam_permit.so
|
||||||
|
auth required pam_env.so
|
||||||
|
auth [success=ok default=1] ${pkgs.gnome.gdm}/lib/security/pam_gdm.so
|
||||||
|
auth optional ${pkgs.gnome.gnome-keyring}/lib/security/pam_gnome_keyring.so
|
||||||
|
|
||||||
|
account include login
|
||||||
|
|
||||||
|
password required pam_deny.so
|
||||||
|
|
||||||
|
session include login
|
||||||
|
session optional ${pkgs.gnome.gnome-keyring}/lib/security/pam_gnome_keyring.so auto_start
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
|
@ -72,5 +72,7 @@ in {
|
||||||
|
|
||||||
programs.dconf.enable = true;
|
programs.dconf.enable = true;
|
||||||
|
|
||||||
|
services.gnome.gnome-keyring.enable = mkForce false;
|
||||||
|
|
||||||
services.xserver = {layout = "gb";};
|
services.xserver = {layout = "gb";};
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,40 +0,0 @@
|
||||||
{
|
|
||||||
self,
|
|
||||||
config,
|
|
||||||
lib,
|
|
||||||
...
|
|
||||||
}: let
|
|
||||||
inherit (lib.lists) filter;
|
|
||||||
inherit (builtins) attrNames;
|
|
||||||
|
|
||||||
clusterConfig = import "${self}/data/piped/pipedClusterConfig.nix";
|
|
||||||
inherit (clusterConfig) hosts ports;
|
|
||||||
|
|
||||||
currentHostName = config.networking.hostName;
|
|
||||||
|
|
||||||
joinString = lib.concatStringsSep "," ([
|
|
||||||
"localhost:${toString ports.cockroachDB}"
|
|
||||||
]
|
|
||||||
++ (
|
|
||||||
map
|
|
||||||
(hostName: hosts.${hostName}.joinString)
|
|
||||||
(filter (hostName: hostName != currentHostName) (attrNames hosts))
|
|
||||||
));
|
|
||||||
in {
|
|
||||||
systemd.services.haproxy.wantedBy = ["piped-backend.service"];
|
|
||||||
|
|
||||||
services.cockroachdb-bin = {
|
|
||||||
enable = true;
|
|
||||||
certsDir = "/var/lib/cockroachdb-certs";
|
|
||||||
join = joinString;
|
|
||||||
extraArgs = ["--advertise-addr=${hosts.${currentHostName}.advertiseAddr}"];
|
|
||||||
listen = {
|
|
||||||
port = ports.cockroachDB;
|
|
||||||
address = "0.0.0.0";
|
|
||||||
};
|
|
||||||
http = {
|
|
||||||
address = "0.0.0.0";
|
|
||||||
port = ports.cockroachDB_HTTP;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -1,36 +0,0 @@
|
||||||
{self, ...}: let
|
|
||||||
inherit (builtins) concatStringsSep attrNames;
|
|
||||||
|
|
||||||
clusterConfig = import "${self}/data/piped/pipedClusterConfig.nix";
|
|
||||||
inherit (clusterConfig) hosts ports;
|
|
||||||
in {
|
|
||||||
systemd.services.haproxy.wantedBy = ["piped-backend.service"];
|
|
||||||
|
|
||||||
services.haproxy = {
|
|
||||||
enable = true;
|
|
||||||
config = ''
|
|
||||||
global
|
|
||||||
maxconn 4096
|
|
||||||
|
|
||||||
defaults
|
|
||||||
mode tcp
|
|
||||||
retries 5
|
|
||||||
timeout connect 5s
|
|
||||||
timeout client 10m
|
|
||||||
timeout server 10m
|
|
||||||
option clitcpka
|
|
||||||
|
|
||||||
listen psql
|
|
||||||
bind :${toString ports.cockroachDB_HAProxy}
|
|
||||||
mode tcp
|
|
||||||
balance roundrobin
|
|
||||||
option httpchk GET /health?ready=1
|
|
||||||
${concatStringsSep "\n" (
|
|
||||||
map (serverConfig: " " + serverConfig)
|
|
||||||
(map (
|
|
||||||
hostName: "server ${hostName} ${hosts.${hostName}.advertiseAddr} check port ${toString ports.cockroachDB_HTTP}"
|
|
||||||
) (attrNames hosts))
|
|
||||||
)}
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -3,7 +3,7 @@
|
||||||
config,
|
config,
|
||||||
...
|
...
|
||||||
}: let
|
}: let
|
||||||
inherit (lib.modules) mkIf;
|
inherit (lib.modules) mkIf mkMerge;
|
||||||
|
|
||||||
currentHostname = config.networking.hostName;
|
currentHostname = config.networking.hostName;
|
||||||
|
|
||||||
|
@ -26,22 +26,28 @@
|
||||||
};
|
};
|
||||||
in {
|
in {
|
||||||
nix.buildMachines = [
|
nix.buildMachines = [
|
||||||
(mkIf (currentHostname != "hetzner-vm") (builderDefaults
|
(mkIf (currentHostname != "hetzner-arm") (mkMerge [
|
||||||
// {
|
builderDefaults
|
||||||
hostName = "hetzner-vm.servers.genderfucked.monster";
|
{
|
||||||
systems = ["x86_64-linux" "aarch64-linux"];
|
hostName = "hetzner-arm.servers.genderfucked.monster";
|
||||||
publicHostKey = "c3NoLWVkMjU1MTkgQUFBQUMzTnphQzFsWkRJMU5URTVBQUFBSU1JdDJBQnF3SGhNano5cjZhdHY0WHVYNTh4RVdlU3RrbVhVd3ZNVkd2NHcgcm9vdEBuaXhvcwo=";
|
systems = ["aarch64-linux"];
|
||||||
maxJobs = 3;
|
supportedFeatures = ["native-arm64"];
|
||||||
speedFactor = 2;
|
publicHostKey = "c3NoLWVkMjU1MTkgQUFBQUMzTnphQzFsWkRJMU5URTVBQUFBSUk5cGM0REU1UlV4UUp2T1pwenFOQWVac0JlRW1kcmp4OFlnV3orVXBMckcgcm9vdEBoZXR6bmVyLWFybQo=";
|
||||||
}))
|
maxJobs = 4;
|
||||||
(mkIf (currentHostname != "vault") (builderDefaults
|
speedFactor = 3;
|
||||||
// {
|
}
|
||||||
|
]))
|
||||||
|
(mkIf (currentHostname != "vault") (mkMerge [
|
||||||
|
builderDefaults
|
||||||
|
{
|
||||||
hostName = "vault.servers.genderfucked.monster";
|
hostName = "vault.servers.genderfucked.monster";
|
||||||
systems = ["x86_64-linux"];
|
systems = ["aarch64-linux"];
|
||||||
publicHostKey = "c3NoLWVkMjU1MTkgQUFBQUMzTnphQzFsWkRJMU5URTVBQUFBSU16L1dyaG81MTFGdzhXN3FsU0NUY1V4cWh4TGlBQkJXbFNNNFRNNzJ5RWQgcm9vdEBuaXhvcwo=";
|
supportedFeatures = ["native-arm64"];
|
||||||
maxJobs = 2;
|
publicHostKey = "c3NoLWVkMjU1MTkgQUFBQUMzTnphQzFsWkRJMU5URTVBQUFBSURGTlFjUTdkbUlRS1lqMUVVTFBlcTI4d2hzMTg2YVZ0WitWU05rd3I2aEkgcm9vdEB2YXVsdAo=";
|
||||||
|
maxJobs = 1;
|
||||||
speedFactor = 1;
|
speedFactor = 1;
|
||||||
}))
|
}
|
||||||
|
]))
|
||||||
];
|
];
|
||||||
nix.distributedBuilds = true;
|
nix.distributedBuilds = true;
|
||||||
nix.extraOptions = "builders-use-substitutes = true";
|
nix.extraOptions = "builders-use-substitutes = true";
|
||||||
|
|
9
scripts/deploy/hetzner-arm.sh
Executable file
9
scripts/deploy/hetzner-arm.sh
Executable file
|
@ -0,0 +1,9 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
|
||||||
|
cd $SCRIPT_DIR
|
||||||
|
cd $(git rev-parse --show-toplevel)
|
||||||
|
|
||||||
|
DEFAULT_HOST="root@hetzner-arm.servers.genderfucked.monster"
|
||||||
|
TARGET_HOST=${HOST:-${DEFAULT_HOST}}
|
||||||
|
nixos-rebuild switch --flake .#hetzner-arm --target-host "$TARGET_HOST" --use-substitutes -s "$@"
|
|
@ -1,7 +0,0 @@
|
||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
|
|
||||||
cd $SCRIPT_DIR
|
|
||||||
cd $(git rev-parse --show-toplevel)
|
|
||||||
|
|
||||||
nixos-rebuild switch --flake .#hetzner-vm --target-host hetzner-vm -s "$@"
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue