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 {
|
||||
"hetzner-vm" = {
|
||||
ipv4 = "65.21.182.73";
|
||||
ipv6 = "2a01:4f9:c010:8beb::1";
|
||||
};
|
||||
"hetzner-arm" = {
|
||||
ipv4 = "65.21.145.62";
|
||||
ipv6 = "2a01:4f9:c012:9dbf::1";
|
||||
|
|
|
@ -2,10 +2,10 @@ let
|
|||
pubkeys = builtins.fromJSON (builtins.readFile ./chaosInternalWireGuardPubKeys.json);
|
||||
in rec {
|
||||
hosts = {
|
||||
"hetzner-vm" = {
|
||||
"hetzner-arm" = {
|
||||
ip = "10.69.42.1";
|
||||
public = pubkeys."hetzner-vm";
|
||||
endpoint = "hetzner-vm.servers.genderfucked.monster:51820";
|
||||
public = pubkeys."hetzner-arm";
|
||||
endpoint = "hetzner-arm.servers.genderfucked.monster:51820";
|
||||
};
|
||||
"vault" = {
|
||||
ip = "10.69.42.2";
|
||||
|
@ -25,11 +25,5 @@ in rec {
|
|||
public = pubkeys."raspberry";
|
||||
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": "u8hSeht8xR48O9AN+0cSsXPK0ZZFNcnPhOxdc+rsrlI=",
|
||||
"raspberry": "Ghrs0ps2RCsg0My9seLq+8ZFZCM4NLZWE8RiY3g9/RU=",
|
||||
"lappy-t495": "8aZBM3f8/qThiHvGlGP1IHLoe61m/3VTwNzCi7CrhF8=",
|
||||
"iphone8": "jHPQuWXO5TTBACr4o/tk4bpb+N/x/AjCPGbmqkopOko=",
|
||||
"hetzner-arm": "2SS9jT6Sba61lB2ayhp+2fz+GN706Jr1Ydr6/RveqUQ="
|
||||
"vault": "0jGdR0yBnjY5CUCQpqWIaWAfgT36QdGdhZXtaAV+MkE=",
|
||||
"raspberry": "DXXUfkR4qlytdsf37NGzgzVhDxPuhz8oxRcSxOX2fQk=",
|
||||
"lappy-t495": "kyykcuDMWy1WRxX97PImEYgwWw8HUbhM53kW6bEyryA=",
|
||||
"iphone8": "1u/G60EWg2bo1iyViWAGXs8HXES2zenZCVdD5X+yJi4=",
|
||||
"hetzner-arm": "rCkptlaz5IFSZ+4OPaylbyKVoUwYNWBNkaT63QApymA="
|
||||
}
|
||||
|
|
48
flake.lock
48
flake.lock
|
@ -47,11 +47,11 @@
|
|||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1694166985,
|
||||
"narHash": "sha256-8tVqDfKfZ4vbOV5i+E2xWhiNAQVJhaI6shx3e0925S8=",
|
||||
"lastModified": 1695831427,
|
||||
"narHash": "sha256-wyWgooFXg8SLF1DYMLU4JP6aB/zkwRCLBajO8sIeHQM=",
|
||||
"owner": "ChaotiCryptidz",
|
||||
"repo": "gitlab_archiver",
|
||||
"rev": "4aac975a7cc375084c7f9eb4bc60a1c0948c1c28",
|
||||
"rev": "090ace071629556b50087a2e80f9255340b286df",
|
||||
"type": "gitlab"
|
||||
},
|
||||
"original": {
|
||||
|
@ -73,11 +73,11 @@
|
|||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1694166776,
|
||||
"narHash": "sha256-wMTnkW98Fx/BpRpSABf9b0PlruVnzd4m3zEQaopE2+o=",
|
||||
"lastModified": 1695831616,
|
||||
"narHash": "sha256-86pme6c8WtplRoZVcZp/zjsq9XnGuBjPrO6V/pAmW94=",
|
||||
"owner": "ChaotiCryptidz",
|
||||
"repo": "gitlab_artifacts_sync",
|
||||
"rev": "09a5988927a3493585357f5d61abdce3a9e4da17",
|
||||
"rev": "5099274ccff8fae50979ce94eb5287c3dcf5b914",
|
||||
"type": "gitlab"
|
||||
},
|
||||
"original": {
|
||||
|
@ -93,11 +93,11 @@
|
|||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1694643239,
|
||||
"narHash": "sha256-pv2k/5FvyirDE8g4TNehzwZ0T4UOMMmqWSQnM/luRtE=",
|
||||
"lastModified": 1695738267,
|
||||
"narHash": "sha256-LTNAbTQ96xSj17xBfsFrFS9i56U2BMLpD0BduhrsVkU=",
|
||||
"owner": "nix-community",
|
||||
"repo": "home-manager",
|
||||
"rev": "d9b88b43524db1591fb3d9410a21428198d75d49",
|
||||
"rev": "0f4e5b4999fd6a42ece5da8a3a2439a50e48e486",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
@ -119,11 +119,11 @@
|
|||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1694166910,
|
||||
"narHash": "sha256-6Vxz6H4H3bfl1PUCeHTmIKg96PHwJEzkE7XRN09y5nM=",
|
||||
"lastModified": 1695831628,
|
||||
"narHash": "sha256-UyVJXVWjbZ4TLgCeOVYUE44ekfD5duUfA2akoc1VGj0=",
|
||||
"owner": "ChaotiCryptidz",
|
||||
"repo": "musicutil",
|
||||
"rev": "7580e1fd0164e414a11e03c1037b37722160df25",
|
||||
"rev": "0e9aceb2b9b418f876a5fcd549420edbf8e8fdcb",
|
||||
"type": "gitlab"
|
||||
},
|
||||
"original": {
|
||||
|
@ -134,11 +134,11 @@
|
|||
},
|
||||
"nixpkgs-unstable": {
|
||||
"locked": {
|
||||
"lastModified": 1694669921,
|
||||
"narHash": "sha256-6ESpJ6FsftHV96JO/zn6je07tyV2dlLR7SdLsmkegTY=",
|
||||
"lastModified": 1695644571,
|
||||
"narHash": "sha256-asS9dCCdlt1lPq0DLwkVBbVoEKuEuz+Zi3DG7pR/RxA=",
|
||||
"owner": "nixos",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "f2ea252d23ebc9a5336bf6a61e0644921f64e67c",
|
||||
"rev": "6500b4580c2a1f3d0f980d32d285739d8e156d92",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
@ -150,11 +150,11 @@
|
|||
},
|
||||
"nur": {
|
||||
"locked": {
|
||||
"lastModified": 1694778311,
|
||||
"narHash": "sha256-Hu5U9pXwMqUjWF7uh4SKqdKy1QMy9RVGxmst11srSgA=",
|
||||
"lastModified": 1695844033,
|
||||
"narHash": "sha256-UX5sbK9dc/bOupgDGWer75zBjoh7eWIheyGGCjD7FIg=",
|
||||
"owner": "nix-community",
|
||||
"repo": "NUR",
|
||||
"rev": "7a673ac1f35648a908730206a2793b0e3818bc25",
|
||||
"rev": "f08568d903901b7ac1017572b9af9855e935155a",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
@ -176,11 +176,11 @@
|
|||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1695142252,
|
||||
"narHash": "sha256-rcYxKVb6Mpna3xNSwRHMw/Yzw3tky0+JuMLM5qoBiUw=",
|
||||
"lastModified": 1695847501,
|
||||
"narHash": "sha256-UxYiNfUApZ6IYJ0U83CzRBSRvmApDHMWa5o9WT99ukM=",
|
||||
"owner": "ChaotiCryptidz",
|
||||
"repo": "piped-flake",
|
||||
"rev": "994a8e983eef9071d73c9b2daad9bd42aac0b1aa",
|
||||
"rev": "2a03d86df5075f5060704bb68742af2ace8973e3",
|
||||
"type": "gitlab"
|
||||
},
|
||||
"original": {
|
||||
|
@ -268,11 +268,11 @@
|
|||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1694618271,
|
||||
"narHash": "sha256-8y2/x27QkhRtTZ/3A0HOmfNJT0hDSk+2ZSGyKB46Q40=",
|
||||
"lastModified": 1695831820,
|
||||
"narHash": "sha256-ZhSQqGg32WA/WYsjPMuYU96GgyljszPcjvc+GBLZVpY=",
|
||||
"owner": "ChaotiCryptidz",
|
||||
"repo": "VaultUI",
|
||||
"rev": "6365eb49cec7eb8a76a24160b25363cf4a8bfa40",
|
||||
"rev": "d5fc05612e44cc2c8307186b0d36f7022d7a2f91",
|
||||
"type": "gitlab"
|
||||
},
|
||||
"original": {
|
||||
|
|
|
@ -106,10 +106,7 @@ in {
|
|||
# browser toolbar and UI
|
||||
# may need updating when extensions change
|
||||
"browser.toolbars.bookmarks.visibility" = "always";
|
||||
"layout.css.devPixelsPerPx" =
|
||||
if nixosConfig.networking.hostName == "lappy-t495"
|
||||
then "1.4"
|
||||
else "1.8";
|
||||
"layout.css.devPixelsPerPx" = "1.4";
|
||||
"browser.uiCustomization.state" = builtins.toJSON {
|
||||
currentVersion = 18;
|
||||
dirtyAreaCache = [
|
||||
|
|
|
@ -7,22 +7,22 @@
|
|||
inherit (lib.lists) forEach;
|
||||
inherit (builtins) attrNames;
|
||||
|
||||
containerAddresses = import "${self}/hosts/hetzner-vm/data/containerAddresses.nix";
|
||||
containerAddresses = import "${self}/hosts/hetzner-arm/data/containerAddresses.nix";
|
||||
in {
|
||||
programs.ssh.enable = true;
|
||||
programs.ssh.matchBlocks =
|
||||
mkMerge
|
||||
((forEach ["hetzner-vm" "vault" "raspberry" "vault-decrypt"] (hostname: {
|
||||
((forEach ["hetzner-arm" "hetzner-arm-decrypt" "vault" "vault-decrypt" "raspberry"] (hostname: {
|
||||
"${hostname}" = {
|
||||
user = "root";
|
||||
hostname = "${hostname}.servers.genderfucked.monster";
|
||||
};
|
||||
}))
|
||||
++ (forEach (attrNames containerAddresses.containers) (name: {
|
||||
"hetzner-vm-container-${name}" = {
|
||||
"hetzner-arm-container-${name}" = {
|
||||
user = "root";
|
||||
hostname = "${containerAddresses.containers.${name}}";
|
||||
proxyJump = "hetzner-vm";
|
||||
proxyJump = "hetzner-arm";
|
||||
};
|
||||
}))
|
||||
++ [
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
tmux
|
||||
socat
|
||||
file
|
||||
python3
|
||||
binutils # for strings
|
||||
|
||||
# (pkgs.busybox.override {enableAppletSymlinks = false;})
|
||||
|
|
|
@ -1,10 +1,21 @@
|
|||
{pkgs, ...}: {
|
||||
{pkgs, ...}: let
|
||||
gitPackage = pkgs.gitAndTools.gitFull;
|
||||
in {
|
||||
programs.git = {
|
||||
enable = true;
|
||||
lfs.enable = true;
|
||||
package = pkgs.gitAndTools.gitFull;
|
||||
package = gitPackage;
|
||||
userName = "chaos";
|
||||
userEmail = "chaoticryptidz@owo.monster";
|
||||
extraConfig = {credential = {helper = "store";};};
|
||||
userEmail = "chaos@owo.monster";
|
||||
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, ...}: {
|
||||
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
|
||||
nmap
|
||||
tcpdump
|
||||
iftop
|
||||
speedtest-cli
|
||||
];
|
||||
}
|
||||
|
|
|
@ -3,8 +3,12 @@
|
|||
nixosConfig,
|
||||
pkgs,
|
||||
inputs,
|
||||
lib,
|
||||
...
|
||||
}: let
|
||||
inherit (lib.lists) optional;
|
||||
inherit (lib.modules) mkIf;
|
||||
|
||||
homeManagerLib = inputs.home-manager.lib.hm;
|
||||
|
||||
fontSizesAll = {
|
||||
|
@ -18,10 +22,16 @@
|
|||
if fontSizesAll ? nixosConfig.networking.hostName
|
||||
then fontSizesAll.${nixosConfig.networking.hostName}
|
||||
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 = {
|
||||
SAL_USE_VCLPLUGIN = "gtk3"; # GTK3 on LibreOffice
|
||||
|
@ -126,17 +136,18 @@ in {
|
|||
area-screenshot-clip = ["<Shift>Print"];
|
||||
screenshot = [];
|
||||
screenshot-clip = ["Print"];
|
||||
search = mkIf isWayland ["<Alt>d"];
|
||||
custom-keybindings = [
|
||||
# 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/rofi" = {
|
||||
# binding = "<Alt>d";
|
||||
# command = "rofi -show run";
|
||||
# name = "rofi";
|
||||
#};
|
||||
"org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/rofi" = mkIf (!isWayland) {
|
||||
binding = "<Alt>d";
|
||||
command = "rofi -show run";
|
||||
name = "rofi";
|
||||
};
|
||||
"org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/kitty" = {
|
||||
binding = "<Alt>Return";
|
||||
command = "kitty";
|
||||
|
|
|
@ -8,8 +8,7 @@
|
|||
hostPath,
|
||||
...
|
||||
}: let
|
||||
inherit (lib.modules) mkMerge;
|
||||
inherit (lib.lists) forEach;
|
||||
inherit (lib.modules) mkMerge mkForce;
|
||||
|
||||
ports = [
|
||||
# SMTP
|
||||
|
@ -26,20 +25,6 @@
|
|||
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 = [
|
||||
"/var/lib/acme/mail.owo.monster/fullchain.pem"
|
||||
"/var/lib/acme/mail.owo.monster/key.pem"
|
||||
|
@ -48,74 +33,51 @@ in {
|
|||
containers.mail = {
|
||||
autoStart = true;
|
||||
|
||||
bindMounts = mkMerge [
|
||||
(containerLib.genBindHostsForSecrets secrets secretsList)
|
||||
|
||||
(mkMerge (forEach sharedFiles (file: {
|
||||
bindMounts = mkMerge (map (file: {
|
||||
"${file}" = {
|
||||
hostPath = "${file}";
|
||||
};
|
||||
})))
|
||||
];
|
||||
})
|
||||
sharedFiles);
|
||||
|
||||
specialArgs = {
|
||||
inherit inputs;
|
||||
inherit tree;
|
||||
inherit self;
|
||||
inherit hostPath;
|
||||
hostSecrets = secrets;
|
||||
};
|
||||
|
||||
config = {config, ...}: {
|
||||
config = {...}: {
|
||||
nixpkgs.pkgs = pkgs;
|
||||
|
||||
imports = with tree;
|
||||
[
|
||||
profiles.base
|
||||
inputs.home-manager-unstable.nixosModules.home-manager
|
||||
presets.nixos.containerBase
|
||||
|
||||
profiles.nginx
|
||||
modules.nixos.secrets
|
||||
|
||||
users.root
|
||||
./secrets.nix
|
||||
]
|
||||
++ (with hosts.hetzner-vm.containers.mail; [
|
||||
++ (with hosts.hetzner-arm.containers.mail; [
|
||||
modules.mailserver
|
||||
profiles.mailserver
|
||||
profiles.restic
|
||||
]);
|
||||
|
||||
# For Shared Secrets
|
||||
systemd.tmpfiles.rules = [
|
||||
"d ${config.services.secrets.secretsDir} - root root"
|
||||
"d /var/lib/acme - root root"
|
||||
"d /var/lib/acme/mail.owo.monster - root root"
|
||||
];
|
||||
|
||||
networking.firewall = {
|
||||
enable = false;
|
||||
enable = mkForce false;
|
||||
};
|
||||
|
||||
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";
|
||||
home-manager.users.root.home.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
|
||||
services.nginx = {
|
||||
enable = true;
|
|
@ -1,9 +1,9 @@
|
|||
{
|
||||
pkgs,
|
||||
hostSecrets,
|
||||
config,
|
||||
...
|
||||
}: let
|
||||
secrets = hostSecrets;
|
||||
secrets = config.services.secrets.secrets;
|
||||
in {
|
||||
services.mailserver = {
|
||||
enable = true;
|
|
@ -1,11 +1,12 @@
|
|||
{
|
||||
pkgs,
|
||||
config,
|
||||
hostSecrets,
|
||||
...
|
||||
}: let
|
||||
secrets = hostSecrets;
|
||||
secrets = config.services.secrets.secrets;
|
||||
|
||||
mailConfig = config.services.mailserver;
|
||||
|
||||
backupPrepareCommand = "${
|
||||
(pkgs.writeShellScriptBin "backupPrepareCommand" ''
|
||||
systemctl start postgresqlBackup-roundcube --wait
|
||||
|
@ -16,8 +17,8 @@ in {
|
|||
restic
|
||||
(pkgs.writeShellScriptBin "restic-mail" ''
|
||||
env \
|
||||
RESTIC_PASSWORD_FILE=${secrets.mail_restic_password.path} \
|
||||
$(cat ${secrets.mail_restic_env.path}) \
|
||||
RESTIC_PASSWORD_FILE=${secrets.restic_password.path} \
|
||||
$(cat ${secrets.restic_env.path}) \
|
||||
${pkgs.restic}/bin/restic $@
|
||||
'')
|
||||
];
|
||||
|
@ -36,8 +37,8 @@ in {
|
|||
# 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/Mail";
|
||||
passwordFile = "${secrets.mail_restic_password.path}";
|
||||
environmentFile = "${secrets.mail_restic_env.path}";
|
||||
passwordFile = "${secrets.restic_password.path}";
|
||||
environmentFile = "${secrets.restic_env.path}";
|
||||
|
||||
pruneOpts = [
|
||||
"--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,
|
||||
lib,
|
||||
inputs,
|
||||
config,
|
||||
pkgs,
|
||||
config,
|
||||
...
|
||||
}: let
|
||||
inherit (lib.modules) mkMerge;
|
||||
inherit (lib.lists) forEach;
|
||||
|
||||
containerName = "music";
|
||||
|
||||
containerAddresses = import "${hostPath}/data/containerAddresses.nix";
|
||||
|
||||
hostIP = containerAddresses.host;
|
||||
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;
|
||||
|
||||
# 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 {
|
||||
containers.music = {
|
||||
autoStart = true;
|
||||
privateNetwork = true;
|
||||
hostAddress = hostIP;
|
||||
localAddress = containerIP;
|
||||
bindMounts = containerLib.genBindHostsForSecrets secrets secretsList;
|
||||
|
||||
specialArgs = {
|
||||
inherit inputs;
|
||||
inherit tree;
|
||||
inherit self;
|
||||
inherit hostPath;
|
||||
hostSecrets = secrets;
|
||||
};
|
||||
|
||||
config = {config, ...}: {
|
||||
config = {...}: {
|
||||
nixpkgs.pkgs = pkgs;
|
||||
|
||||
imports = with tree;
|
||||
|
@ -58,8 +48,10 @@ in {
|
|||
|
||||
profiles.nginx
|
||||
profiles.firewallAllow.httpCommon
|
||||
|
||||
./secrets.nix
|
||||
]
|
||||
++ (with hosts.hetzner-vm.containers.music; [
|
||||
++ (with hosts.hetzner-arm.containers.music; [
|
||||
profiles.mpd
|
||||
profiles.musicSync
|
||||
profiles.soulseek
|
||||
|
@ -75,11 +67,6 @@ in {
|
|||
slskd-web
|
||||
];
|
||||
|
||||
# For Shared Secrets
|
||||
systemd.tmpfiles.rules = [
|
||||
"d ${config.services.secrets.secretsDir} - root root"
|
||||
];
|
||||
|
||||
home-manager.users.root.home.stateVersion = "23.05";
|
||||
system.stateVersion = "23.05";
|
||||
};
|
||||
|
@ -97,7 +84,7 @@ in {
|
|||
services.nginx.virtualHosts."stream.owo.monster" = let
|
||||
extraConfig = ''
|
||||
auth_basic "Music Password";
|
||||
auth_basic_user_file ${secrets.music_stream_passwd.path};
|
||||
auth_basic_user_file ${pathInContainer containerSecrets.music_stream_passwd.path};
|
||||
'';
|
||||
in {
|
||||
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 = {
|
||||
nat.forwardPorts = [
|
||||
{
|
|
@ -1,14 +1,14 @@
|
|||
{
|
||||
lib,
|
||||
pkgs,
|
||||
hostSecrets,
|
||||
config,
|
||||
...
|
||||
}: let
|
||||
inherit (lib.strings) concatStringsSep;
|
||||
inherit (lib.lists) forEach;
|
||||
|
||||
ports = import ../data/ports.nix;
|
||||
secrets = hostSecrets;
|
||||
secrets = config.services.secrets.secrets;
|
||||
in {
|
||||
environment.systemPackages = with pkgs; [
|
||||
mpc_cli
|
|
@ -1,10 +1,10 @@
|
|||
{
|
||||
lib,
|
||||
hostSecrets,
|
||||
config,
|
||||
...
|
||||
}: let
|
||||
ports = import ../data/ports.nix;
|
||||
secrets = hostSecrets;
|
||||
secrets = config.services.secrets.secrets;
|
||||
|
||||
inherit (lib.modules) mkForce;
|
||||
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,
|
||||
config,
|
||||
pkgs,
|
||||
lib,
|
||||
...
|
||||
}: let
|
||||
containerName = "piped-fi";
|
||||
containerConfig = config.containers.${containerName}.config;
|
||||
inherit (lib.modules) mkForce;
|
||||
|
||||
pipedName = "piped-fi";
|
||||
containerName = pipedName;
|
||||
|
||||
pipedSocketForComponent = (
|
||||
component: "/var/lib/nixos-containers/${containerName}/var/sockets/piped-${component}.sock"
|
||||
);
|
||||
in {
|
||||
containers.piped-fi = {
|
||||
containers.${containerName} = {
|
||||
autoStart = true;
|
||||
privateNetwork = false;
|
||||
|
||||
|
@ -28,32 +31,19 @@ in {
|
|||
config = {...}: {
|
||||
nixpkgs.pkgs = pkgs;
|
||||
|
||||
imports = with tree;
|
||||
[
|
||||
presets.nixos.containerBase
|
||||
|
||||
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"
|
||||
imports = with tree; [
|
||||
presets.nixos.containerBase
|
||||
presets.nixos.pipedNode
|
||||
];
|
||||
|
||||
networking.firewall.enable = mkForce false;
|
||||
|
||||
home-manager.users.root.home.stateVersion = "23.05";
|
||||
system.stateVersion = "23.05";
|
||||
};
|
||||
};
|
||||
|
||||
services.nginx.virtualHosts."piped-fi.owo.monster" = {
|
||||
services.nginx.virtualHosts."${pipedName}.owo.monster" = {
|
||||
forceSSL = true;
|
||||
enableACME = true;
|
||||
locations."/" = {
|
||||
|
@ -61,7 +51,7 @@ in {
|
|||
};
|
||||
};
|
||||
|
||||
services.nginx.virtualHosts."backend.piped-fi.owo.monster" = {
|
||||
services.nginx.virtualHosts."backend.${pipedName}.owo.monster" = {
|
||||
forceSSL = true;
|
||||
enableACME = true;
|
||||
locations."/" = {
|
||||
|
@ -69,7 +59,7 @@ in {
|
|||
};
|
||||
};
|
||||
|
||||
services.nginx.virtualHosts."proxy.piped-fi.owo.monster" = {
|
||||
services.nginx.virtualHosts."proxy.${pipedName}.owo.monster" = {
|
||||
forceSSL = true;
|
||||
enableACME = true;
|
||||
locations."/" = {
|
|
@ -2,7 +2,6 @@
|
|||
self,
|
||||
hostPath,
|
||||
tree,
|
||||
lib,
|
||||
inputs,
|
||||
config,
|
||||
pkgs,
|
||||
|
@ -11,34 +10,21 @@
|
|||
containerAddresses = import "${hostPath}/data/containerAddresses.nix";
|
||||
hostIP = containerAddresses.host;
|
||||
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 {
|
||||
containers.quassel = {
|
||||
autoStart = true;
|
||||
privateNetwork = true;
|
||||
hostAddress = hostIP;
|
||||
localAddress = containerIP;
|
||||
bindMounts = containerLib.genBindHostsForSecrets secrets secretsList;
|
||||
|
||||
specialArgs = {
|
||||
inherit inputs;
|
||||
inherit tree;
|
||||
inherit self;
|
||||
inherit hostPath;
|
||||
hostSecrets = secrets;
|
||||
};
|
||||
|
||||
config = {config, ...}: {
|
||||
config = {...}: {
|
||||
nixpkgs.pkgs = pkgs;
|
||||
|
||||
imports = with tree;
|
||||
|
@ -46,17 +32,14 @@ in {
|
|||
presets.nixos.containerBase
|
||||
profiles.sshd
|
||||
profiles.firewallAllow.ssh
|
||||
|
||||
./secrets.nix
|
||||
]
|
||||
++ (with hosts.hetzner-vm.containers.quassel.profiles; [
|
||||
++ (with hosts.hetzner-arm.containers.quassel.profiles; [
|
||||
quassel
|
||||
restic
|
||||
]);
|
||||
|
||||
# For Shared Secrets
|
||||
systemd.tmpfiles.rules = [
|
||||
"d ${config.services.secrets.secretsDir} - root root"
|
||||
];
|
||||
|
||||
networking.firewall.allowedTCPPorts = [4242];
|
||||
|
||||
home-manager.users.root.home.stateVersion = "23.05";
|
|
@ -1,9 +1,9 @@
|
|||
{
|
||||
pkgs,
|
||||
hostSecrets,
|
||||
config,
|
||||
...
|
||||
}: let
|
||||
secrets = hostSecrets;
|
||||
secrets = config.services.secrets.secrets;
|
||||
|
||||
backupPrepareCommand = "${
|
||||
(pkgs.writeShellScriptBin "backupPrepareCommand" ''
|
||||
|
@ -15,8 +15,8 @@ in {
|
|||
restic
|
||||
(pkgs.writeShellScriptBin "restic-quassel" ''
|
||||
env \
|
||||
RESTIC_PASSWORD_FILE=${secrets.quassel_restic_password.path} \
|
||||
$(cat ${secrets.quassel_restic_env.path}) \
|
||||
RESTIC_PASSWORD_FILE=${secrets.restic_password.path} \
|
||||
$(cat ${secrets.restic_env.path}) \
|
||||
${pkgs.restic}/bin/restic $@
|
||||
'')
|
||||
];
|
||||
|
@ -31,8 +31,8 @@ in {
|
|||
# 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/Quassel";
|
||||
passwordFile = "${secrets.quassel_restic_password.path}";
|
||||
environmentFile = "${secrets.quassel_restic_env.path}";
|
||||
passwordFile = "${secrets.restic_password.path}";
|
||||
environmentFile = "${secrets.restic_env.path}";
|
||||
|
||||
pruneOpts = [
|
||||
"--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,
|
||||
hostSecrets,
|
||||
config,
|
||||
...
|
||||
}: let
|
||||
containerAddresses = import "${hostPath}/data/containerAddresses.nix";
|
||||
hostIP = containerAddresses.host;
|
||||
containerIP = containerAddresses.containers.social;
|
||||
|
||||
secrets = hostSecrets;
|
||||
secrets = config.services.secrets.secrets;
|
||||
in {
|
||||
services.gotosocial = {
|
||||
enable = true;
|
||||
setupPostgresqlDB = true;
|
||||
environmentFile = secrets.social_env_secrets.path;
|
||||
environmentFile = secrets.env_secrets.path;
|
||||
|
||||
settings = {
|
||||
application-name = "chaos-gts";
|
|
@ -2,13 +2,12 @@
|
|||
pkgs,
|
||||
config,
|
||||
lib,
|
||||
hostSecrets,
|
||||
...
|
||||
}: let
|
||||
inherit (lib.strings) concatStringsSep;
|
||||
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
|
||||
# and duplicate the wrapper for use in a systemd unit
|
||||
|
@ -48,8 +47,8 @@ in {
|
|||
restic
|
||||
(pkgs.writeShellScriptBin "restic-social" ''
|
||||
env \
|
||||
RESTIC_PASSWORD_FILE=${secrets.social_restic_password.path} \
|
||||
$(cat ${secrets.social_restic_env.path}) \
|
||||
RESTIC_PASSWORD_FILE=${secrets.restic_password.path} \
|
||||
$(cat ${secrets.restic_env.path}) \
|
||||
${pkgs.restic}/bin/restic $@
|
||||
'')
|
||||
];
|
||||
|
@ -64,8 +63,8 @@ in {
|
|||
# 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/Social";
|
||||
passwordFile = "${secrets.social_restic_password.path}";
|
||||
environmentFile = "${secrets.social_restic_env.path}";
|
||||
passwordFile = "${secrets.restic_password.path}";
|
||||
environmentFile = "${secrets.restic_env.path}";
|
||||
|
||||
pruneOpts = [
|
||||
"--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_social = 4212;
|
||||
rclone_serve_restic_quassel = 4213;
|
||||
rclone_serve_restic_piped_finland = 4214;
|
||||
rclone_serve_restic_piped = 4214;
|
||||
rclone_serve_restic_mail = 4215;
|
||||
|
||||
rclone_serve_http_music = 4220;
|
|
@ -36,20 +36,14 @@ in {
|
|||
|
||||
imports = with tree;
|
||||
[
|
||||
profiles.base
|
||||
inputs.home-manager-unstable.nixosModules.home-manager
|
||||
presets.nixos.containerBase
|
||||
|
||||
profiles.sshd
|
||||
|
||||
modules.nixos.rclone-serve
|
||||
modules.nixos.rclone-sync
|
||||
modules.nixos.secrets
|
||||
profiles.firewallAllow.ssh
|
||||
|
||||
./secrets.nix
|
||||
|
||||
users.root
|
||||
]
|
||||
++ (with hosts.hetzner-vm.containers.storage.profiles; [
|
||||
++ (with hosts.hetzner-arm.containers.storage.profiles; [
|
||||
rcloneConfigs
|
||||
rcloneServe
|
||||
rcloneSync
|
||||
|
@ -58,20 +52,12 @@ in {
|
|||
|
||||
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 = {
|
||||
enable = true;
|
||||
allowedTCPPorts = attrValues ports;
|
||||
};
|
||||
|
||||
# Manually configure nameserver. Using resolved inside the container seems to fail
|
||||
# currently
|
||||
environment.etc."resolv.conf".text = "nameserver 8.8.8.8";
|
||||
home-manager.users.root.home.stateVersion = "23.05";
|
||||
system.stateVersion = "23.05";
|
||||
};
|
||||
};
|
||||
|
@ -109,7 +95,7 @@ in {
|
|||
"/Vault/".proxyPass = "http://${containerIP}:${toString ports.rclone_serve_restic_vault}";
|
||||
"/Social/".proxyPass = "http://${containerIP}:${toString ports.rclone_serve_restic_social}";
|
||||
"/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}";
|
||||
};
|
||||
extraConfig = ''
|
|
@ -117,13 +117,13 @@ in {
|
|||
];
|
||||
}
|
||||
{
|
||||
id = "restic-piped-finland";
|
||||
remote = "StorageBox:Backups/Restic/Piped-Finland";
|
||||
id = "restic-piped";
|
||||
remote = "StorageBox:Backups/Restic/Piped";
|
||||
type = "restic";
|
||||
extraArgs = [
|
||||
"--addr=0.0.0.0:${toString ports.rclone_serve_restic_piped_finland}"
|
||||
"--htpasswd=${secrets.restic_piped_finland_htpasswd.path}"
|
||||
"--baseurl=/Piped-Finland/"
|
||||
"--addr=0.0.0.0:${toString ports.rclone_serve_restic_piped}"
|
||||
"--htpasswd=${secrets.restic_piped_htpasswd.path}"
|
||||
"--baseurl=/Piped/"
|
||||
];
|
||||
}
|
||||
{
|
|
@ -10,11 +10,16 @@
|
|||
wants = ["auto-secrets.service"];
|
||||
};
|
||||
timerConfig = {
|
||||
OnStartupSec = "60";
|
||||
OnStartupSec = "120";
|
||||
OnCalendar = "4h";
|
||||
};
|
||||
extraArgs = [
|
||||
"--fast-list"
|
||||
"--check-first"
|
||||
"--delete-before"
|
||||
"--b2-upload-concurrency=4"
|
||||
"--transfers=4"
|
||||
"--bwlimit 80M"
|
||||
];
|
||||
}) [
|
||||
# My B2
|
|
@ -1,4 +1,4 @@
|
|||
[StorageBox-Remote]
|
||||
[StorageBox-Remote-WebDAV]
|
||||
type = webdav
|
||||
vendor = other
|
||||
host = u323231.your-storagebox.de
|
||||
|
@ -6,6 +6,22 @@ url = https://u323231.your-storagebox.de
|
|||
user = u323231
|
||||
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]
|
||||
type = hasher
|
||||
remote = StorageBox-Remote:
|
|
@ -1,17 +1,10 @@
|
|||
{
|
||||
config,
|
||||
pkgs,
|
||||
...
|
||||
}: let
|
||||
cfg = config.services.secrets;
|
||||
in {
|
||||
{pkgs, ...}: {
|
||||
services.secrets = {
|
||||
enable = true;
|
||||
|
||||
vaultLogin = {
|
||||
enable = true;
|
||||
loginUsername = "hetzner-vm-container-storage";
|
||||
loginPasswordFile = cfg.secrets.vault_password.path;
|
||||
loginUsername = "hetzner-arm-container-storage";
|
||||
};
|
||||
|
||||
autoSecrets = {
|
||||
|
@ -35,7 +28,7 @@ in {
|
|||
"api-keys/data/storage/restic/Vault"
|
||||
"api-keys/data/storage/restic/Social"
|
||||
"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/webdav/main"
|
||||
|
@ -51,14 +44,6 @@ in {
|
|||
rclone
|
||||
];
|
||||
|
||||
uidMap = {
|
||||
"storage" = config.users.users."storage".uid;
|
||||
};
|
||||
|
||||
gidMap = {
|
||||
"storage" = config.users.groups."storage".gid;
|
||||
};
|
||||
|
||||
extraFunctions = ''
|
||||
replace_slash_for_sed() {
|
||||
sed "s#/#\\\/#"
|
||||
|
@ -80,11 +65,11 @@ in {
|
|||
}
|
||||
|
||||
simple_get_replace_crypt() {
|
||||
password=$(simple_get "$1" .password | replace_slash_for_sed)
|
||||
salt=$(simple_get "$1" .salt | replace_slash_for_sed)
|
||||
password=$(simple_get_obscure "$1" .password)
|
||||
salt=$(simple_get_obscure "$1" .salt)
|
||||
|
||||
replace_password=''${2}_ACCOUNT
|
||||
replace_salt=''${2}_KEY
|
||||
replace_password=''${2}_PASSWORD
|
||||
replace_salt=''${2}_SALT
|
||||
|
||||
sed -i "s/$replace_password/$password/" "$3"
|
||||
sed -i "s/$replace_salt/$salt/" "$3"
|
||||
|
@ -132,12 +117,12 @@ in {
|
|||
'';
|
||||
};
|
||||
|
||||
restic_piped_finland_htpasswd = {
|
||||
restic_piped_htpasswd = {
|
||||
user = "storage";
|
||||
group = "storage";
|
||||
fetchScript = ''
|
||||
username=$(simple_get "/api-keys/storage/restic/Piped-Finland" .username)
|
||||
password=$(simple_get "/api-keys/storage/restic/Piped-Finland" .password)
|
||||
username=$(simple_get "/api-keys/storage/restic/Piped" .username)
|
||||
password=$(simple_get "/api-keys/storage/restic/Piped" .password)
|
||||
htpasswd -bc "$secretFile" "$username" "$password" 2>/dev/null
|
||||
'';
|
||||
};
|
|
@ -5,6 +5,5 @@
|
|||
social = "192.168.100.12";
|
||||
music = "192.168.100.13";
|
||||
quassel = "192.168.100.14";
|
||||
piped = "192.168.100.15";
|
||||
};
|
||||
}
|
|
@ -11,25 +11,25 @@ in {
|
|||
presets.nixos.serverHetzner
|
||||
presets.nixos.serverEncryptedDrive
|
||||
|
||||
#profiles.nginx
|
||||
#profiles.firewallAllow.httpCommon
|
||||
profiles.nginx
|
||||
profiles.firewallAllow.httpCommon
|
||||
|
||||
#profiles.chaosInternalWireGuard
|
||||
profiles.chaosInternalWireGuard
|
||||
|
||||
./hardware.nix
|
||||
./secrets.nix
|
||||
]
|
||||
++ (forEach [
|
||||
#"social"
|
||||
#"storage"
|
||||
#"music"
|
||||
#"quassel"
|
||||
#"piped-fi"
|
||||
#"mail"
|
||||
"social"
|
||||
"storage"
|
||||
"music"
|
||||
"quassel"
|
||||
"piped-db"
|
||||
"piped-fi"
|
||||
"mail"
|
||||
] (name: ./containers + "/${name}"))
|
||||
++ (with hosts.hetzner-vm.profiles; [
|
||||
#vaultUI
|
||||
#gitlabStaticSites
|
||||
++ (with hosts.hetzner-arm.profiles; [
|
||||
gitlabStaticSites
|
||||
]);
|
||||
|
||||
# For Containers
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
{pkgs, ...}: {
|
||||
{...}: {
|
||||
services.secrets = {
|
||||
enable = true;
|
||||
|
||||
|
@ -9,12 +9,15 @@
|
|||
|
||||
autoSecrets = {
|
||||
enable = true;
|
||||
#affectedSystemdServices = [
|
||||
# "wg-quick-wg0"
|
||||
#];
|
||||
affectedSystemdServices = [
|
||||
"wg-quick-wg0"
|
||||
];
|
||||
};
|
||||
|
||||
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"
|
||||
];
|
||||
|
||||
|
@ -23,6 +26,34 @@
|
|||
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
|
||||
# for fetching gitlab static sites
|
||||
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
|
||||
|
||||
profiles.cross.arm64
|
||||
#profiles.remote-builders
|
||||
profiles.remoteBuilders
|
||||
profiles.chaosInternalWireGuard
|
||||
profiles.fingerprint
|
||||
|
||||
./secrets.nix
|
||||
];
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
};
|
||||
|
||||
music_stream_password = {
|
||||
user = 1000;
|
||||
user = "chaos";
|
||||
group = "users";
|
||||
fetchScript = ''
|
||||
simple_get "/api-keys/music-stream" .password > "$secretFile"
|
||||
|
@ -17,8 +17,6 @@
|
|||
# Required for home.apps.manualBackupApps
|
||||
gitlab_archiver_token = {
|
||||
user = "chaos";
|
||||
group = "users";
|
||||
|
||||
fetchScript = ''
|
||||
simple_get "/api-keys/gitlab/gitlab_archiver" .token > "$secretFile"
|
||||
'';
|
||||
|
@ -27,8 +25,6 @@
|
|||
# Required for home.apps.manualBackupApps
|
||||
restic_music_env = {
|
||||
user = "chaos";
|
||||
group = "users";
|
||||
|
||||
fetchScript = ''
|
||||
api_username=$(simple_get "/api-keys/storage/restic/Music" .username)
|
||||
api_password=$(simple_get "/api-keys/storage/restic/Music" .password)
|
||||
|
|
|
@ -33,10 +33,9 @@
|
|||
inputs.gitlab_artifacts_sync.nixosModules.default
|
||||
inputs.piped-flake.nixosModules.default
|
||||
|
||||
tree.modules.nixos.rclone-serve
|
||||
tree.modules.nixos.rclone-sync
|
||||
tree.modules.nixos.rcloneServe
|
||||
tree.modules.nixos.rcloneSync
|
||||
tree.modules.nixos.secrets
|
||||
tree.modules.nixos.cockroachdb-bin
|
||||
];
|
||||
|
||||
nixosUnstableSystem = nixpkgs-unstable.lib.nixosSystem;
|
||||
|
@ -81,16 +80,6 @@ in {
|
|||
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 {
|
||||
specialArgs =
|
||||
defaultSpecialArgs
|
||||
|
|
|
@ -5,16 +5,19 @@
|
|||
inputs,
|
||||
config,
|
||||
pkgs,
|
||||
lib,
|
||||
...
|
||||
}: let
|
||||
containerName = "piped-uk";
|
||||
containerConfig = config.containers.${containerName}.config;
|
||||
inherit (lib.modules) mkForce;
|
||||
|
||||
pipedName = "piped-uk";
|
||||
containerName = pipedName;
|
||||
|
||||
pipedSocketForComponent = (
|
||||
component: "/var/lib/nixos-containers/${containerName}/var/sockets/piped-${component}.sock"
|
||||
);
|
||||
in {
|
||||
containers.piped-uk = {
|
||||
containers.${containerName} = {
|
||||
autoStart = true;
|
||||
privateNetwork = false;
|
||||
|
||||
|
@ -30,26 +33,17 @@ in {
|
|||
|
||||
imports = with tree; [
|
||||
presets.nixos.containerBase
|
||||
|
||||
profiles.nginx
|
||||
profiles.firewallAllow.httpCommon
|
||||
|
||||
profiles.pipedCluster
|
||||
|
||||
./secrets.nix
|
||||
presets.nixos.pipedNode
|
||||
];
|
||||
|
||||
# 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";
|
||||
system.stateVersion = "23.05";
|
||||
};
|
||||
};
|
||||
|
||||
services.nginx.virtualHosts."piped-uk.owo.monster" = {
|
||||
services.nginx.virtualHosts."${pipedName}.owo.monster" = {
|
||||
forceSSL = true;
|
||||
enableACME = true;
|
||||
locations."/" = {
|
||||
|
@ -57,7 +51,7 @@ in {
|
|||
};
|
||||
};
|
||||
|
||||
services.nginx.virtualHosts."backend.piped-uk.owo.monster" = {
|
||||
services.nginx.virtualHosts."backend.${pipedName}.owo.monster" = {
|
||||
forceSSL = true;
|
||||
enableACME = true;
|
||||
locations."/" = {
|
||||
|
@ -65,7 +59,7 @@ in {
|
|||
};
|
||||
};
|
||||
|
||||
services.nginx.virtualHosts."proxy.piped-uk.owo.monster" = {
|
||||
services.nginx.virtualHosts."proxy.${pipedName}.owo.monster" = {
|
||||
forceSSL = true;
|
||||
enableACME = true;
|
||||
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 = [
|
||||
"/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"
|
||||
|
||||
|
@ -27,11 +28,28 @@
|
|||
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
|
||||
# but it makes it easier to install.
|
||||
# it's stored in /nix store anyway
|
||||
ssh_host_ed25519_key = {
|
||||
path = "/ssh_host_ed25519_key";
|
||||
initrd_ssh_host_ed25519_key = {
|
||||
path = "/initrd_ssh_host_ed25519_key";
|
||||
permissions = "600";
|
||||
fetchScript = ''
|
||||
simple_get "/private-public-keys/ssh/root@vault-decrypt" .private | base64 -d > "$secretFile"
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
]
|
||||
++ (with hosts.vault.profiles; [
|
||||
vault
|
||||
vaultUI
|
||||
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 != []) {
|
||||
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 (
|
||||
job: ''
|
||||
${pkgs.rclone}/bin/rclone sync ${job.source} ${job.dest} ${concatStringsSep " " job.extraArgs} -P $@
|
|
@ -8,7 +8,7 @@
|
|||
inherit (lib.options) mkOption mkEnableOption;
|
||||
inherit (lib.lists) filter;
|
||||
inherit (lib) types;
|
||||
inherit (builtins) isString listToAttrs;
|
||||
inherit (builtins) isString listToAttrs attrNames;
|
||||
|
||||
cfg = config.services.secrets;
|
||||
|
||||
|
@ -115,25 +115,79 @@ in {
|
|||
extraFunctions = mkOption {
|
||||
type = types.lines;
|
||||
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 {
|
||||
type = types.attrsOf types.int;
|
||||
default = {};
|
||||
description = "optional mapping of users to user IDs; required for SYSROOT when user isn't available on host";
|
||||
default = listToAttrs (map (
|
||||
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 {
|
||||
type = types.attrsOf types.int;
|
||||
default = {};
|
||||
description = "optional mapping of groups to group IDs; required for SYSROOT when group isn't available on host";
|
||||
default = listToAttrs (map (
|
||||
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 {
|
||||
type = types.listOf types.package;
|
||||
default = [];
|
||||
description = "packages for script";
|
||||
description = "packages for init script";
|
||||
};
|
||||
|
||||
checkPackages = mkOption {
|
||||
type = types.listOf types.package;
|
||||
default = [];
|
||||
description = "packages for checkscript";
|
||||
};
|
||||
|
||||
secrets = mkOption {
|
||||
|
@ -241,7 +295,7 @@ in {
|
|||
// {
|
||||
auto-secrets.partOf =
|
||||
map (unitConfig: unitConfig.name + ".service")
|
||||
(lib.filter
|
||||
(filter
|
||||
(unitConfig: unitConfig.withPartOf)
|
||||
affectedSystemdServices);
|
||||
};
|
||||
|
|
|
@ -195,6 +195,11 @@
|
|||
stat --format "%a" "$1" 2>/dev/null
|
||||
}
|
||||
|
||||
emojiTick="✅"
|
||||
emojiCross="❌"
|
||||
|
||||
${cfg.extraCheckFunctions}
|
||||
|
||||
GLOBAL_FAIL=false
|
||||
''
|
||||
+ (concatStringsSep "\n" (mapAttrsToList (_name: secret: let
|
||||
|
@ -226,40 +231,40 @@
|
|||
secretFile="$SYSROOT${secretPath}"
|
||||
|
||||
if [[ -f "$SYSROOT${secretPath}" ]]; then
|
||||
echo "✅ File Exists"
|
||||
echo "$emojiTick File Exists"
|
||||
else
|
||||
echo "❌ File Does Not Exist"
|
||||
echo "$emojiCross File Does Not Exist"
|
||||
LOCAL_FAIL=true
|
||||
fi
|
||||
|
||||
if getUserID "$SYSROOT${secretPath}" >/dev/null && ${userCheck}; then
|
||||
echo "✅ File Is Owned By Correct User"
|
||||
echo "$emojiTick File Is Owned By Correct User"
|
||||
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
|
||||
fi
|
||||
|
||||
if getGroupID "$SYSROOT${secretPath}" >/dev/null && ${groupCheck}; then
|
||||
echo "✅ File Is Owned By Correct Group"
|
||||
echo "$emojiTick File Is Owned By Correct Group"
|
||||
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
|
||||
fi
|
||||
|
||||
if getPermissions "$SYSROOT${secretPath}" >/dev/null && [[ "$(getPermissions "$SYSROOT${secretPath}")" -eq "${secretPermissions}" ]]; then
|
||||
echo "✅ File Has Correct Permissions"
|
||||
echo "$emojiTick File Has Correct Permissions"
|
||||
else
|
||||
echo "❌ File Does Not Have Correct Permissions (${secretPermissions})"
|
||||
echo "$emojiCross File Does Not Have Correct Permissions (${secretPermissions})"
|
||||
LOCAL_FAIL=true
|
||||
fi
|
||||
|
||||
${optionalString (secret.checkScript != null) secret.checkScript}
|
||||
|
||||
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
|
||||
else
|
||||
echo "✅ File Passed The Vibe Check"
|
||||
echo "$emojiTick File Passed The Vibe Check"
|
||||
fi
|
||||
|
||||
echo
|
||||
|
@ -267,10 +272,10 @@
|
|||
cfg.secrets))
|
||||
+ ''
|
||||
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
|
||||
else
|
||||
echo "✅ All Secrets Passed The Vibe Check"
|
||||
echo "$emojiTick All Secrets Passed The Vibe Check"
|
||||
fi
|
||||
'';
|
||||
};
|
||||
|
@ -319,7 +324,7 @@ in rec {
|
|||
scripts = genScripts cfg;
|
||||
in (writeShellApplication {
|
||||
name = scriptName;
|
||||
runtimeInputs = defaultPackages ++ cfg.packages;
|
||||
runtimeInputs = defaultPackages ++ cfg.checkPackages;
|
||||
text = scripts.checkScript;
|
||||
})
|
||||
);
|
||||
|
|
26
outputs.nix
26
outputs.nix
|
@ -18,6 +18,22 @@ in
|
|||
overlays = [
|
||||
(import ./overlay)
|
||||
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
|
||||
|
@ -50,7 +66,6 @@ in
|
|||
inherit (pkgs) comic-code comic-sans;
|
||||
inherit (pkgs) mk-enc-usb mk-encrypted-drive mk-raspberry-ext-drive;
|
||||
inherit (pkgs) gotosocial;
|
||||
inherit (pkgs) cockroachdb;
|
||||
inherit (pkgs) piped-backend piped-frontend piped-proxy;
|
||||
inherit (pkgs) kitty-terminfo;
|
||||
};
|
||||
|
@ -124,18 +139,15 @@ in
|
|||
|
||||
# All machines/containers with secrets.nix
|
||||
machines = rec {
|
||||
"hetzner-vm" = {
|
||||
containers = ["storage" "piped-fi"];
|
||||
sshAddress = "hetzner-vm.servers.genderfucked.monster";
|
||||
};
|
||||
"hetzner-arm" = {
|
||||
containers = ["storage" "piped-fi"];
|
||||
sshAddress = "hetzner-vm.servers.genderfucked.monster";
|
||||
containers = ["storage" "music" "quassel" "social" "mail" "piped-db" "piped-fi"];
|
||||
sshAddress = "hetzner-arm.servers.genderfucked.monster";
|
||||
};
|
||||
"vault" = {
|
||||
sshAddress = "vault.servers.genderfucked.monster";
|
||||
};
|
||||
"raspberry" = {
|
||||
containers = ["piped-uk"];
|
||||
sshAddress = "raspberry.servers.genderfucked.monster";
|
||||
};
|
||||
"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
|
||||
'';
|
||||
|
||||
cockroachdb-bin = final.callPackage ./cockroachdb-bin {};
|
||||
cockroachdb = cockroachdb-bin;
|
||||
|
||||
gotosocial = prev.gotosocial.overrideAttrs (_old: let
|
||||
owner = "superseriousbusiness";
|
||||
repo = "gotosocial";
|
||||
|
|
|
@ -8,10 +8,9 @@
|
|||
profiles.base
|
||||
users.root
|
||||
|
||||
modules.nixos.rclone-serve
|
||||
modules.nixos.rclone-sync
|
||||
modules.nixos.rcloneServe
|
||||
modules.nixos.rcloneSync
|
||||
modules.nixos.secrets
|
||||
modules.nixos.cockroachdb-bin
|
||||
])
|
||||
++ [
|
||||
# Default modules which are usually included in nixos.nix
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
profiles.tor
|
||||
];
|
||||
|
||||
services.fwupd.enable = true;
|
||||
|
||||
# TODO: Better DNS setup
|
||||
services.resolved.enable = false;
|
||||
environment.etc."resolv.conf".text = ''
|
||||
|
|
|
@ -1,17 +1,44 @@
|
|||
{
|
||||
self,
|
||||
config,
|
||||
tree,
|
||||
...
|
||||
}: let
|
||||
clusterConfig = import "${self}/data/piped/pipedClusterConfig.nix";
|
||||
inherit (clusterConfig) hosts ports;
|
||||
inherit (builtins) attrNames elem;
|
||||
|
||||
currentHostName = config.networking.hostName;
|
||||
currentHostConfig = hosts.${currentHostName};
|
||||
wireguardData = import "${self}/data/wireguard/chaosInternalWireGuard.nix";
|
||||
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 {
|
||||
systemd.coredump.enable = true;
|
||||
imports = with tree; [
|
||||
profiles.nginx
|
||||
];
|
||||
|
||||
services.piped = {
|
||||
enable = true;
|
||||
|
@ -42,10 +69,9 @@ in {
|
|||
disablePostgresDB = true;
|
||||
name = "piped";
|
||||
username = "piped";
|
||||
passwordFile = builtins.toFile "password-file" "piped";
|
||||
host = "127.0.0.1";
|
||||
port = ports.cockroachDB;
|
||||
dialect = "org.hibernate.dialect.CockroachDialect";
|
||||
usePassword = false;
|
||||
host = "${wireguardHosts."hetzner-arm".ip}";
|
||||
port = 5434;
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -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
|
||||
componentPath = component: "/var/sockets/piped-${component}.sock";
|
||||
listen = [
|
||||
{
|
||||
addr = "127.0.0.1";
|
||||
port = ports.internalNginxPort;
|
||||
}
|
||||
];
|
||||
in {
|
||||
"${baseDomain}" = {
|
||||
listen = [
|
||||
{
|
||||
addr = "127.0.0.1";
|
||||
port = 8091;
|
||||
}
|
||||
];
|
||||
inherit listen;
|
||||
extraConfig = "listen unix:${componentPath "frontend"};";
|
||||
};
|
||||
|
||||
"backend.${baseDomain}" = {
|
||||
inherit listen;
|
||||
extraConfig = "listen unix:${componentPath "backend"};";
|
||||
listen = [
|
||||
{
|
||||
addr = "127.0.0.1";
|
||||
port = 8092;
|
||||
}
|
||||
];
|
||||
};
|
||||
|
||||
"proxy.${baseDomain}" = {
|
||||
inherit listen;
|
||||
extraConfig = "listen unix:${componentPath "proxy"};";
|
||||
listen = [
|
||||
{
|
||||
addr = "127.0.0.1";
|
||||
port = 8093;
|
||||
}
|
||||
];
|
||||
};
|
||||
};
|
||||
}
|
|
@ -27,6 +27,8 @@
|
|||
'';
|
||||
|
||||
boot.kernel.sysctl = {
|
||||
"net.core.default_qdisc" = "fq";
|
||||
"net.ipv4.tcp_congestion_control" = "bbr";
|
||||
"fs.inotify.max_user_watches" = 1024 * 64 * 16;
|
||||
};
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
...
|
||||
}: let
|
||||
inherit (lib.modules) mkForce;
|
||||
inherit (lib.lists) optional;
|
||||
inherit (lib.lists) optionals;
|
||||
|
||||
system = pkgs.system;
|
||||
|
||||
|
@ -33,10 +33,10 @@ in {
|
|||
"dm_mod"
|
||||
"cryptd"
|
||||
]
|
||||
++ (lib.optionals (system == "x86_64_linux") ["aesni_intel"]);
|
||||
++ (optionals (system == "x86_64_linux") ["aesni_intel"]);
|
||||
|
||||
secrets = {
|
||||
"/ssh_host_ed25519_key" = "/ssh_host_ed25519_key";
|
||||
"/ssh_host_ed25519_key" = mkForce "/initrd_ssh_host_ed25519_key";
|
||||
};
|
||||
|
||||
luks = {
|
||||
|
|
|
@ -42,13 +42,12 @@ in {
|
|||
|
||||
boot.kernelParams =
|
||||
[
|
||||
"console=tty0"
|
||||
"ip=${hostServerIPs.ipv4}::${gateway}:${netmask}:${hostName}:enp1s0:any"
|
||||
"boot.shell_on_fail"
|
||||
"nohibernate"
|
||||
"loglevel=4"
|
||||
]
|
||||
++ (lib.optionals (system == "aarch64-linux") ["console=tty" "console=ttyAMA0,115200" "console=ttyS0,115200"]);
|
||||
++ (lib.optionals (system == "aarch64-linux") ["console=tty"]);
|
||||
|
||||
systemd.network = {
|
||||
enable = true;
|
||||
|
|
|
@ -1,5 +0,0 @@
|
|||
{lib, ...}: let
|
||||
inherit (lib.modules) mkForce;
|
||||
in {
|
||||
security.sudo.wheelNeedsPassword = mkForce false;
|
||||
}
|
|
@ -1,10 +1,12 @@
|
|||
{
|
||||
inputs,
|
||||
config,
|
||||
pkgs,
|
||||
lib,
|
||||
...
|
||||
}: let
|
||||
inherit (lib.strings) optionalString versionAtLeast;
|
||||
inherit (lib.optional);
|
||||
in {
|
||||
nix = {
|
||||
nixPath = ["nixpkgs=${inputs.nixpkgs}"];
|
||||
|
@ -13,6 +15,7 @@ in {
|
|||
(versionAtLeast config.nix.package.version "2.4") ''
|
||||
experimental-features = nix-command flakes
|
||||
'';
|
||||
settings.system-features = lib.optional (pkgs.system == "aarch64-linux") "native-arm64";
|
||||
settings.trusted-users = ["root" "@wheel"];
|
||||
};
|
||||
nixpkgs = {
|
||||
|
@ -30,6 +33,23 @@ in {
|
|||
inputs.gitlab_artifacts_sync.overlays.default
|
||||
inputs.gitlab_archiver.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;
|
||||
|
|
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;
|
||||
|
||||
services.gnome.gnome-keyring.enable = mkForce false;
|
||||
|
||||
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,
|
||||
...
|
||||
}: let
|
||||
inherit (lib.modules) mkIf;
|
||||
inherit (lib.modules) mkIf mkMerge;
|
||||
|
||||
currentHostname = config.networking.hostName;
|
||||
|
||||
|
@ -26,22 +26,28 @@
|
|||
};
|
||||
in {
|
||||
nix.buildMachines = [
|
||||
(mkIf (currentHostname != "hetzner-vm") (builderDefaults
|
||||
// {
|
||||
hostName = "hetzner-vm.servers.genderfucked.monster";
|
||||
systems = ["x86_64-linux" "aarch64-linux"];
|
||||
publicHostKey = "c3NoLWVkMjU1MTkgQUFBQUMzTnphQzFsWkRJMU5URTVBQUFBSU1JdDJBQnF3SGhNano5cjZhdHY0WHVYNTh4RVdlU3RrbVhVd3ZNVkd2NHcgcm9vdEBuaXhvcwo=";
|
||||
maxJobs = 3;
|
||||
speedFactor = 2;
|
||||
}))
|
||||
(mkIf (currentHostname != "vault") (builderDefaults
|
||||
// {
|
||||
(mkIf (currentHostname != "hetzner-arm") (mkMerge [
|
||||
builderDefaults
|
||||
{
|
||||
hostName = "hetzner-arm.servers.genderfucked.monster";
|
||||
systems = ["aarch64-linux"];
|
||||
supportedFeatures = ["native-arm64"];
|
||||
publicHostKey = "c3NoLWVkMjU1MTkgQUFBQUMzTnphQzFsWkRJMU5URTVBQUFBSUk5cGM0REU1UlV4UUp2T1pwenFOQWVac0JlRW1kcmp4OFlnV3orVXBMckcgcm9vdEBoZXR6bmVyLWFybQo=";
|
||||
maxJobs = 4;
|
||||
speedFactor = 3;
|
||||
}
|
||||
]))
|
||||
(mkIf (currentHostname != "vault") (mkMerge [
|
||||
builderDefaults
|
||||
{
|
||||
hostName = "vault.servers.genderfucked.monster";
|
||||
systems = ["x86_64-linux"];
|
||||
publicHostKey = "c3NoLWVkMjU1MTkgQUFBQUMzTnphQzFsWkRJMU5URTVBQUFBSU16L1dyaG81MTFGdzhXN3FsU0NUY1V4cWh4TGlBQkJXbFNNNFRNNzJ5RWQgcm9vdEBuaXhvcwo=";
|
||||
maxJobs = 2;
|
||||
systems = ["aarch64-linux"];
|
||||
supportedFeatures = ["native-arm64"];
|
||||
publicHostKey = "c3NoLWVkMjU1MTkgQUFBQUMzTnphQzFsWkRJMU5URTVBQUFBSURGTlFjUTdkbUlRS1lqMUVVTFBlcTI4d2hzMTg2YVZ0WitWU05rd3I2aEkgcm9vdEB2YXVsdAo=";
|
||||
maxJobs = 1;
|
||||
speedFactor = 1;
|
||||
}))
|
||||
}
|
||||
]))
|
||||
];
|
||||
nix.distributedBuilds = 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 "$@"
|
|
@ -4,5 +4,6 @@ SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
|
|||
cd $SCRIPT_DIR
|
||||
cd $(git rev-parse --show-toplevel)
|
||||
|
||||
[ -n "$NO_BUILD_PIPED_BACKEND" ] && ./scripts/buildPipedBackendAArch64.nix
|
||||
nixos-rebuild switch --flake .#raspberry --target-host raspberry -s "$@"
|
||||
DEFAULT_HOST="root@raspberry.servers.genderfucked.monster"
|
||||
TARGET_HOST=${HOST:-${DEFAULT_HOST}}
|
||||
nixos-rebuild switch --flake .#raspberry --target-host "$TARGET_HOST" --use-substitutes -s "$@"
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue