Compare commits

..

10 Commits

Author SHA1 Message Date
8f4c7fe4cc
feat: add modules to bicboye
* change interface name from `enp6s0` to `enp2s0`
* add arr suite + ntfy deployment, monitoring
* add keys for ssh access
* add default_server configuration to nginx for security

Signed-off-by: Chinmay D. Pai <chinmaydpai@gmail.com>
2024-09-02 19:19:09 +05:30
7520c9a86d
fix: use correct ssh domain and port for gitea
Signed-off-by: Chinmay D. Pai <chinmaydpai@gmail.com>
2024-09-02 19:18:38 +05:30
e6b20e5def
feat: refactor unifi-controller, add unifi-unpoller for monitoring
Signed-off-by: Chinmay D. Pai <chinmaydpai@gmail.com>
2024-09-02 19:17:56 +05:30
f433953ebd
feat: add monitoring module for infrastructure
* VictoriaMetrics for polling/collecting metrics
* Grafana for UI
* Multiple prometheus-exporter modules for gathering data

Signed-off-by: Chinmay D. Pai <chinmaydpai@gmail.com>
2024-09-02 19:16:01 +05:30
3408ceb62c
feat: add nix module for arr suite
Can finally deploy:
* Jellyfin
* Jellyseerr
* Radarr, Prowlarr, Sonarr, Bazarr
* QBitTorrent + VueTorrent

Signed-off-by: Chinmay D. Pai <chinmaydpai@gmail.com>
2024-09-02 19:14:35 +05:30
73cd391baf
chore: rekey agenix secrets, add grafana and unifi-unpoller
Signed-off-by: Chinmay D. Pai <chinmaydpai@gmail.com>
2024-09-02 19:13:18 +05:30
711c1f9821
chore: use terminus for console font and remove kernel param
* Lat2-Terminus16 looks nice, not sure why I replaced it.
* Remove `udev.log_level=3` from the kernel param cmdline. This option
was added to test out plymouth on boot, which surprisingly seems to not
be working right now. Will revisit this later.

Signed-off-by: Chinmay D. Pai <chinmaydpai@gmail.com>
2024-09-02 19:09:28 +05:30
ef02b8168d
feat: setup bicboye server on new hardware
Signed-off-by: Chinmay D. Pai <chinmaydpai@gmail.com>
2024-09-02 19:08:33 +05:30
796368d3df
fix: remove autodefrag from btrfs subvolumes
BTRFS subvolumes do not require autodefrag, and it's not recommended for
the filesystem.

Signed-off-by: Chinmay D. Pai <chinmaydpai@gmail.com>
2024-09-02 19:07:11 +05:30
3ee3a05d61
chore: allow docker to use iptables
Had been removed to debug issues with netbird connectivity after suspend.
Can be added back since the issue is unrelated.

Signed-off-by: Chinmay D. Pai <chinmaydpai@gmail.com>
2024-09-02 19:05:15 +05:30
36 changed files with 750 additions and 128 deletions

View File

@ -10,6 +10,11 @@
root-password.file = ./secrets/machines/bicboye/root-password.age;
};
};
monitoring = {
grafana = {
password.file = ./secrets/monitoring/grafana/password.age;
};
};
services = {
gitea = {
password.file = ./secrets/services/gitea/password.age;
@ -20,6 +25,9 @@
paperless = {
password.file = ./secrets/services/paperless/password.age;
};
unifi-unpoller = {
password.file = ./secrets/services/unifi-unpoller/password.age;
};
vaultwarden = {
password.file = ./secrets/services/vaultwarden/password.age;
};

View File

@ -24,9 +24,9 @@
config = {
console = {
font = "Lat2-Terminus16";
keyMap = lib.mkDefault "us";
useXkbConfig = true;
font = lib.mkDefault "${pkgs.terminus_font}/share/consolefonts/ter-u28n.psf.gz";
};
# Enable all snowflake core modules.
@ -46,7 +46,6 @@
kernelParams = [
"pcie_aspm.policy=performance"
"nmi_watchdog=0"
"udev.log_level=3"
];
loader = {

View File

@ -20,7 +20,6 @@
autoPrune = {
enable = true;
};
extraOptions = "--iptables=False";
inherit (config.snowflake.core.docker) storageDriver;
};

View File

@ -0,0 +1,23 @@
{
config,
lib,
...
}: {
options.snowflake.monitoring.enable = lib.mkEnableOption "Enable the base monitoring stack configuration";
config = lib.mkIf config.snowflake.monitoring.enable {
# Enable base snowflake monitoring modules.
snowflake.monitoring = {
victoriametrics.enable = lib.mkDefault true;
grafana.enable = lib.mkDefault true;
exporter.collectd.enable = lib.mkDefault true;
exporter.node.enable = lib.mkDefault true;
exporter.systemd.enable = lib.mkDefault true;
# NOTE: Extra modules such as unifi-unpoller can be
# enabled in the system configuration manually.
# For example:
# exporter.unifi = true;
# Check exporter/default.nix for more details.
};
};
}

View File

@ -0,0 +1,33 @@
{
config,
lib,
...
}: {
options.snowflake.monitoring.exporter = {
collectd.enable = lib.mkEnableOption "Enable collectd exporter service";
node.enable = lib.mkEnableOption "Enable node-exporter service";
systemd.enable = lib.mkEnableOption "Enable systemd exporter service";
};
config = let
cfg = config.snowflake.monitoring.exporter;
in {
services.prometheus.exporters = {
collectd.enable = cfg.collectd.enable;
node.enable = cfg.node.enable;
systemd.enable = cfg.systemd.enable;
# NOTE: These are the base monitoring modules meant to
# be enabled by default as sane defaults.
# Extra options for the defined exporters or custom exporters
# can be added to machine configuration manually.
# For example:
# services.prometheus.exporters.unifi = {
# enable = true;
# unifiUsername = "username";
# unifiPassword = "password";
# unifiInsecure = true;
# };
# This can then be added to the vmagent configuration as extraConfig.
};
};
}

View File

@ -0,0 +1,90 @@
{
config,
lib,
pkgs,
...
}: {
options.snowflake.monitoring.grafana = let
settingsFormat = pkgs.formats.yaml {};
in {
enable = lib.mkEnableOption "Enable grafana for monitoring stack";
domain = lib.mkOption {
type = lib.types.str;
default = "";
description = "Configuration domain to use for the grafana service";
};
adminPasswordFile = lib.mkOption {
description = "Age module containing the administrator password to use for grafana";
};
port = lib.mkOption {
type = lib.types.port;
default = 3010;
description = "Configuration port to use for the grafana service";
};
extraDatasourceConfig = lib.mkOption {
description = "Extra datasource configuration for grafana";
type = lib.types.listOf (lib.types.submodule {freeformType = settingsFormat.type;});
default = [];
};
};
config = let
cfg = config.snowflake.monitoring.grafana;
in
lib.mkIf cfg.enable {
age.secrets.grafana = {
inherit (cfg.adminPasswordFile) file;
owner = "grafana";
group = "grafana";
};
services.grafana = {
enable = true;
settings = {
server = {
http_addr = "127.0.0.1";
http_port = cfg.port;
};
analytics = {
reporting_enabled = false;
feedback_links_enabled = false;
};
security.admin_password = "$__file{${config.age.secrets.grafana.path}}";
};
provision = {
enable = true;
datasources.settings.datasources =
[]
++ lib.optional config.services.victoriametrics.enable {
name = "Victoriametrics";
type = "prometheus";
access = "proxy";
url = "http://127.0.0.1:${toString config.snowflake.monitoring.victoriametrics.port}";
}
++ cfg.extraDatasourceConfig;
};
};
# Requires services.nginx.enable.
services.nginx = {
virtualHosts = {
"${cfg.domain}" = {
serverName = "${cfg.domain}";
enableACME = true;
forceSSL = true;
locations."/" = {
proxyPass = "http://${config.services.grafana.settings.server.http_addr}:${toString config.services.grafana.settings.server.http_port}/";
};
};
};
};
};
}

View File

@ -0,0 +1,81 @@
{
config,
lib,
pkgs,
...
}: {
options.snowflake.monitoring.victoriametrics = let
settingsFormat = pkgs.formats.json {};
in {
enable = lib.mkEnableOption "Enable victoriametrics and vmagent stack";
port = lib.mkOption {
type = lib.types.port;
default = 8428;
description = "Port to listen on for victoriametrics";
};
extraPrometheusConfig = lib.mkOption {
description = "Extra prometheus scrape config for vmagent";
type = lib.types.listOf (lib.types.submodule {freeformType = settingsFormat.type;});
default = [];
};
};
config = let
cfg = config.snowflake.monitoring.victoriametrics;
exporterCfg = config.services.prometheus.exporters;
in
lib.mkIf cfg.enable {
services.victoriametrics = {
enable = cfg.enable;
listenAddress = "127.0.0.1:${toString cfg.port}";
retentionPeriod = 3;
};
services.vmagent = {
enable = cfg.enable;
remoteWrite.url = "http://${config.services.victoriametrics.listenAddress}/api/v1/write";
prometheusConfig = {
global = {
scrape_interval = "1m";
scrape_timeout = "30s";
};
scrape_configs =
[]
++ lib.optional exporterCfg.node.enable {
job_name = "node";
static_configs = [
{
targets = ["127.0.0.1:${toString exporterCfg.node.port}"];
}
];
relabel_configs = [
{
source_labels = ["__address__"];
target_label = "instance";
regex = "([^:]+)(:[0-9]+)?";
replacement = config.networking.hostName;
}
];
}
++ lib.optional exporterCfg.collectd.enable {
job_name = "collectd";
static_configs = [
{
targets = ["127.0.0.1:${toString exporterCfg.collectd.port}"];
}
];
}
++ lib.optional exporterCfg.systemd.enable {
job_name = "systemd";
static_configs = [
{
targets = ["127.0.0.1:${toString exporterCfg.systemd.port}"];
}
];
}
++ cfg.extraPrometheusConfig;
};
};
};
}

View File

@ -0,0 +1,18 @@
{
config,
lib,
...
}: {
options.snowflake.services.bazarr = {
enable = lib.mkEnableOption "Enable bazarr deployment configuration";
};
# NOTE: No good subtitle providers are available right now.
# There's no need to enable bazarr, private trackers have decent
# subtitles for releases.
config = lib.mkIf config.snowflake.services.bazarr.enable {
services.bazarr.enable = true;
services.bazarr.group = "media";
services.bazarr.openFirewall = true;
};
}

View File

@ -1,51 +1,32 @@
{
config,
lib,
pkgs,
...
}: {
options.snowflake.services.arr = {
enable = lib.mkEnableOption "Enable arr suite configuration";
jellyfin.enable = lib.mkEnableOption "Enable jellyfin configuration for NixOS";
# mediaDir = lib.mkOption {
# type = lib.types.path;
# description = "Path to media storage directory, accessible by all *arr suite applications";
# };
monitoring = {
enable = lib.mkEnableOption "Enable monitoring for arr suite";
sonarrApiKeyFile = lib.mkOption {
description = "Age module containing the sonarr API Key to use for monitoring";
};
radarrApiKeyFile = lib.mkOption {
description = "Age module containing the radarr API Key to use for monitoring";
};
};
};
config = let
cfg = config.snowflake.services.arr;
in
lib.mkIf cfg.enable {
services.jellyfin = {
enable = cfg.jellyfin.enable;
config = lib.mkIf config.snowflake.services.arr.enable {
snowflake.services = {
jellyfin.enable = true;
jellyseerr.enable = true;
radarr.enable = true;
sonarr.enable = true;
prowlarr.enable = true;
qbittorrent-nox = {
enable = true;
openFirewall = true;
};
users.groups.media = {
members = ["@wheel" "jellyfin"];
};
nixpkgs.config.packageOverrides = pkgs: {
jellyfin-ffmpeg = pkgs.jellyfin-ffmpeg.override {
ffmpeg_6-full = pkgs.ffmpeg_6-full.override {
withMfx = false;
withVpl = true;
};
};
};
hardware.graphics = {
enable = true;
extraPackages = with pkgs; [
intel-media-driver
intel-compute-runtime
onevpl-intel-gpu
libvdpau-va-gl
];
};
services.jellyseerr.enable = true;
services.jellyseerr.openFirewall = true;
};
};
}

View File

@ -0,0 +1,66 @@
{
config,
lib,
pkgs,
...
}: {
options.snowflake.services.jellyfin = {
enable = lib.mkEnableOption "Enable jellyfin deployment configuration";
};
config = let
cfg = config.snowflake.services.jellyfin;
in
lib.mkIf cfg.enable {
services.jellyfin = {
enable = true;
openFirewall = true;
};
users.groups.media = {
members = ["@wheel" "jellyfin"];
};
nixpkgs.config.packageOverrides = pkgs: {
jellyfin-ffmpeg = pkgs.jellyfin-ffmpeg.override {
ffmpeg_6-full = pkgs.ffmpeg_6-full.override {
withMfx = false;
withVpl = true;
};
};
vaapiIntel = pkgs.vaapiIntel.override {enableHybridCodec = true;};
};
environment.systemPackages = with pkgs; [
jellyfin-ffmpeg
];
hardware.graphics = {
enable = true;
extraPackages = with pkgs; [
intel-media-driver
intel-compute-runtime
vpl-gpu-rt
vaapiIntel
vaapiVdpau
libvdpau-va-gl
];
};
services.jellyseerr.enable = true;
services.jellyseerr.openFirewall = true;
services.nginx = {
virtualHosts = {
"jelly.deku.moe" = {
serverName = "jelly.deku.moe";
enableACME = true;
forceSSL = true;
locations."/" = {
proxyPass = "http://localhost:8096/";
};
};
};
};
};
}

View File

@ -0,0 +1,26 @@
{
config,
lib,
...
}: {
options.snowflake.services.jellyseerr = {
enable = lib.mkEnableOption "Enable jellyseerr deployment configuration";
};
config = lib.mkIf config.snowflake.services.jellyseerr.enable {
services.jellyseerr.enable = true;
services.jellyseerr.openFirewall = true;
services.nginx = {
virtualHosts = {
"seerr.deku.moe" = {
serverName = "seerr.deku.moe";
enableACME = true;
forceSSL = true;
locations."/" = {
proxyPass = "http://localhost:5055/";
};
};
};
};
};
}

View File

@ -0,0 +1,14 @@
{
config,
lib,
...
}: {
options.snowflake.services.prowlarr = {
enable = lib.mkEnableOption "Enable prowlarr deployment configuration";
};
config = lib.mkIf config.snowflake.services.prowlarr.enable {
services.prowlarr.enable = true;
services.prowlarr.openFirewall = true;
};
}

View File

@ -0,0 +1,76 @@
{
config,
lib,
pkgs,
namespace,
...
}: {
options.snowflake.services.qbittorrent-nox = {
enable = lib.mkEnableOption "Enable qbittorrent-nox service configuration";
package = lib.mkPackageOption pkgs "qbittorrent-nox" {};
openFirewall = lib.mkOption {
description = "Allow firewall access for qbittorrent-nox";
type = lib.types.bool;
default = false;
};
uiPort = lib.mkOption {
description = "Web UI Port for qbittorrent-nox";
type = lib.types.port;
default = 8069;
};
torrentPort = lib.mkOption {
description = "Torrenting port";
type = with lib.types; nullOr port;
default = 64211;
};
};
config = let
cfg = config.snowflake.services.qbittorrent-nox;
in
lib.mkIf cfg.enable {
networking.firewall.allowedTCPPorts =
lib.optional (cfg.openFirewall && cfg.torrentPort != null) cfg.torrentPort
++ lib.optional cfg.openFirewall cfg.uiPort;
networking.firewall.allowedUDPPorts =
lib.optional (cfg.openFirewall && cfg.torrentPort != null) cfg.torrentPort;
users.users.qbittorrent-nox = {
isSystemUser = true;
group = "media";
home = "/var/lib/qbittorrent-nox";
};
systemd.services.qbittorrent-nox = {
description = "qBittorrent-nox service";
wants = ["network-online.target"];
after = ["local-fs.target" "network-online.target" "nss-lookup.target"];
wantedBy = ["multi-user.target"];
unitConfig.Documentation = "man:qbittorrent-nox(1)";
# required for reverse proxying
preStart = ''
rm -rf /var/lib/qbittorrent-nox/qBittorrent/config/vuetorrent
ln -sf ${pkgs.${namespace}.vuetorrent} /var/lib/qbittorrent-nox/qBittorrent/config/vuetorrent
if [[ ! -f /var/lib/qbittorrent-nox/qBittorrent/config/qBittorrent.conf ]]; then
mkdir -p /var/lib/qbittorrent-nox/qBittorrent/config
echo "Preferences\WebUI\HostHeaderValidation=false" >> /var/lib/qbittorrent-nox/qBittorrent/config/qBittorrent.conf
fi
'';
serviceConfig = {
User = "qbittorrent-nox";
Group = "media";
StateDirectory = "qbittorrent-nox";
WorkingDirectory = "/var/lib/qbittorrent-nox";
ExecStart = ''
${cfg.package}/bin/qbittorrent-nox ${lib.optionalString (cfg.torrentPort != null) "--torrenting-port=${toString cfg.torrentPort}"} \
--webui-port=${toString cfg.uiPort} --profile=/var/lib/qbittorrent-nox
'';
};
};
};
}

View File

@ -0,0 +1,15 @@
{
config,
lib,
...
}: {
options.snowflake.services.radarr = {
enable = lib.mkEnableOption "Enable radarr deployment configuration";
};
config = lib.mkIf config.snowflake.services.radarr.enable {
services.radarr.enable = true;
services.radarr.group = "media";
services.radarr.openFirewall = true;
};
}

View File

@ -0,0 +1,15 @@
{
config,
lib,
...
}: {
options.snowflake.services.sonarr = {
enable = lib.mkEnableOption "Enable sonarr deployment configuration";
};
config = lib.mkIf config.snowflake.services.sonarr.enable {
services.sonarr.enable = true;
services.sonarr.group = "media";
services.sonarr.openFirewall = true;
};
}

View File

@ -1,5 +1,8 @@
{ config, lib, ... }:
{
config,
lib,
...
}: {
options.snowflake.services.gitea = {
enable = lib.mkEnableOption "Enable gitea service";
@ -60,7 +63,7 @@
HTTP_ADDR = "127.0.0.1";
HTTP_PORT = config.snowflake.services.gitea.httpPort;
ROOT_URL = "https://${config.snowflake.services.gitea.domain}";
SSH_DOMAIN = "https://${config.snowflake.services.gitea.sshDomain}";
SSH_DOMAIN = config.snowflake.services.gitea.sshDomain;
SSH_PORT = config.snowflake.services.gitea.sshPort;
};
service = {
@ -81,7 +84,7 @@
};
networking.firewall = lib.mkIf config.networking.firewall.enable {
allowedTCPPorts = [ config.snowflake.services.gitea.sshPort ];
allowedTCPPorts = [config.snowflake.services.gitea.sshPort];
};
users.users.git = {
@ -91,7 +94,7 @@
group = "git";
isSystemUser = true;
};
users.groups.git = { };
users.groups.git = {};
services.nginx = {
virtualHosts = {

View File

@ -3,19 +3,71 @@
lib,
pkgs,
...
}:
{
options.snowflake.services.unifi-controller.enable = lib.mkEnableOption "Enable Unifi controller service for Unifi devices";
}: {
options.snowflake.services.unifi-controller = {
enable = lib.mkEnableOption "Enable Unifi controller service for Unifi devices";
unpoller = {
enable = lib.mkEnableOption "Enable unpoller metrics for Unifi controller";
config = lib.mkIf config.snowflake.services.unifi-controller.enable {
networking.firewall.allowedTCPPorts = [ 8443 ];
services.unifi = {
enable = true;
unifiPackage = pkgs.unifi8;
# Limit memory to 256MB. Works well enough
# for small, home-based controller deployments.
maximumJavaHeapSize = 256;
openFirewall = true;
user = lib.mkOption {
type = lib.types.str;
default = "unifi-unpoller";
description = "Username for unpoller access to Unifi controller";
};
passwordFile = lib.mkOption {
description = "Age module containing the password to use for unpoller user";
};
url = lib.mkOption {
type = lib.types.str;
default = "https://127.0.0.1:8443";
description = "URL for the unifi controller service";
};
};
};
config = let
cfg = config.snowflake.services.unifi-controller;
in
lib.mkMerge [
(lib.mkIf cfg.enable
{
networking.firewall.allowedTCPPorts = [8443];
services.unifi = {
enable = true;
unifiPackage = pkgs.unifi8;
# mongodbPackage = pkgs.mongodb-6_0;
# Limit memory to 256MB. Works well enough
# for small, home-based controller deployments.
maximumJavaHeapSize = 256;
openFirewall = true;
};
})
(lib.mkIf cfg.unpoller.enable
{
age.secrets.unpoller-password = {
inherit (cfg.unpoller.passwordFile) file;
owner = config.services.prometheus.exporters.unpoller.user;
group = config.services.prometheus.exporters.unpoller.user;
};
services.prometheus.exporters.unpoller = {
enable = cfg.unpoller.enable;
controllers = [
{
url = cfg.unpoller.url;
user = cfg.unpoller.user;
pass = config.age.secrets.unpoller-password.path;
save_ids = true;
save_events = true;
save_alarms = true;
save_anomalies = true;
verify_ssl = false;
}
];
};
})
];
}

View File

@ -0,0 +1,35 @@
{
pkgs,
lib,
stdenv,
...
}:
stdenv.mkDerivation rec {
pname = "vuetorrent";
version = "2.10.2";
src = pkgs.fetchurl {
url = "https://github.com/WDaan/VueTorrent/releases/download/v${version}/vuetorrent.zip";
sha256 = "sha256-pJzj3jHXmpKca1zyOTlzUQvp7/LtjjMGNt9SMDo89yo=";
};
buildInputs = with pkgs; [unzip];
unpackPhase = ''
unzip $src
'';
dontStrip = true;
installPhase = ''
mkdir -p $out/
cp -r vuetorrent/public/ $out/
'';
meta = with lib; {
description = "The sleekest looking WEBUI for qBittorrent made with Vuejs! ";
homepage = "https://github.com/WDaan/VueTorrent";
license = [licenses.gpl3Only];
platforms = ["x86_64-darwin" "aarch64-darwin" "aarch64-linux" "x86_64-linux"];
};
}

View File

@ -1,7 +1,10 @@
age-encryption.org/v1
-> ssh-ed25519 XInHQA KqFc6Ej8L8yNVX3EoEqlJZlpdmsBTAn3GDPlH0CsmWc
6cEtER5dcQNzWfPUGeN0tMyPEwOUMkSTiqnCQrsNhp8
-> ssh-ed25519 9JjquQ sFTTVGk5VDcfw/K4yKbwGX73O2LFXp5eHWkzHhAeDVY
usZ/giJLoWxXJ0pA8HZZSHMybxuxf8HxjDkeD5Kpuz4
--- CjABvoWY5QYTJ2OmUnqxOxyehm3r/YQmYyx00auShxY
t0æ<EFBFBD>Ç]—iéû<C3A9>fEÇ!ö¿‹úi µ—+­ÕÔ¬íA(¥Ò£TÚ”R ë,ªM9׺¤Ã?‰¼såÎ~ù=ÓÀ¦ýžOô“Ôõ¢þx<C3BE>}¼7!õã<12>{£"'FÎC¥ $Æ@Æžoæø‘ïç%§íJÝ®bxE·W:³x­<ò3(U±
-> ssh-ed25519 XInHQA /NRM0XjHa8w8lmRHi+aTpCuViwJGcUxAVAez0PSGdwQ
UiW+Vnk2Z1/8apx8JTTXNw0+Mw+txBvwzh3xgQyslig
-> ssh-ed25519 9JjquQ Cd54qelvmj8O4x4eIi0UtWxGhqvlfCIHBqBxtd99h2E
IdYDmPrOPzAimL/M2foYOFsEMcLXTMUolPOy+0gZxNg
-> ssh-ed25519 8S096g x1o/dQKQIywGlX/vJ2eQqCuWPb2BQNZsEIO4RkkNRxA
oijplPOdsYYreti3I7bX1KwdHQrWft63bAJBlUGcSzg
--- H78isjmjr1DgBAaq0cuzpxQHEwrdVf7rgbgGSX/K/pQ
Ȯ8²D>X€<å X€9 ?Ǥ{>ìüšLÌ«ž°üãk·††Œ}݉_ß%×Sµ÷<C2B5>ïÈ\—|-žÊø"Ã䩘#;ÃJŽÁ»£ãÕäÉ2iÚ(ƒ¹ùR3°ÜØÔ(Ð=F.^¦<E280B9>»<C2BB>
Iž£MLuäãΠì©ÙïÜ 'ÕúÚ

View File

@ -0,0 +1,7 @@
age-encryption.org/v1
-> ssh-ed25519 XInHQA k39Tpe44MbIY/fa8Sf3f9JXjTlQN849nKWI3G+c4plA
Y05ZLbNPJePRU1mLV87KuhQceWZC3LcpM/qX5mOMHg8
-> ssh-ed25519 9JjquQ Si+4zoaU6TMP0cymWGQdc54fDhLisYGIi1EXZ9+vbmY
cMRoa1Owu1zwhnT6HPwGKk6y3vtHBi8rCnyJfbrAPZY
--- Y27ZK2+ekW1WKGZqTV6Q3mrNNzVWXA7v8JPOylZWYdE
> âQà0l­Zy±¼jÈI|TVÖ KPæ[ìþ˜ªFàI*~LŒÅܯK|b ™!|ÏÅ,é¯ûö­´e™G

View File

@ -13,7 +13,9 @@ let
];
smolboye = ["ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICQFm91hLes24sYbq96zD52mDrrr1l2F2xstcfAEg+qI"];
bicboye = ["ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBsciEMPwLAYtbHNkdedjhSrb66fFQ46lgnVGssCuiLH"];
bicboye = [
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBsciEMPwLAYtbHNkdedjhSrb66fFQ46lgnVGssCuiLH"
];
servers = bicboye ++ smolboye;
users = thunderbottom ++ codingcoffee;
@ -22,6 +24,7 @@ in {
"machines/thonkpad/root-password.age".publicKeys = thunderbottom ++ thonkpad;
"machines/bicboye/password.age".publicKeys = thunderbottom ++ bicboye;
"machines/bicboye/root-password.age".publicKeys = thunderbottom ++ bicboye;
"monitoring/grafana/password.age".publicKeys = thunderbottom ++ bicboye;
"services/backup/environment.age".publicKeys = thunderbottom ++ bicboye;
"services/backup/password.age".publicKeys = thunderbottom ++ bicboye;
"services/gitea/password.age".publicKeys = thunderbottom ++ bicboye;
@ -29,5 +32,6 @@ in {
"services/maddy/user-watashi.age".publicKeys = thunderbottom ++ servers;
"services/miniflux/password.age".publicKeys = thunderbottom ++ bicboye;
"services/paperless/password.age".publicKeys = users ++ bicboye;
"services/unifi-unpoller/password.age".publicKeys = users ++ bicboye;
"services/vaultwarden/password.age".publicKeys = users ++ bicboye;
}

View File

@ -1,7 +1,9 @@
age-encryption.org/v1
-> ssh-ed25519 XInHQA cu04OlowGfn91ape/TGXYToi4kFU9JIS4iY09qlMPmo
Yv2vSFELyNl93DaNQc+E3b9MuwGr0k79TISXF2fUxTY
-> ssh-ed25519 9JjquQ FJ0QtlUi+VKZ7S6BtqCj21x5Q2QG/8s2bay4j+JFFlQ
K1ijqw6pz7F0CZedLxNdXWuPrKMm/y4cnVaVlMuQ4CM
--- WJz/j8eixXYAzN4VxyHrdMaXCSFsVzlVAhXU8cgq6cU
â[Ŕ ˙UuŕÜ ßfL—8ľĚ¶śÇ­QÂRrV4Łň'_&Ĺ»zĎ<7A>ţ,<2C>ĆîQ•š6gä<>ˇNŮq
-> ssh-ed25519 XInHQA aJsT3kOeJa2ZPVkY8qcu74Ch+KHOxdN/8FLRu5hcrw0
PehT0Fp2CVTIO77v8jhGcIcUYS33d5NvmVQeNt3TtjY
-> ssh-ed25519 9JjquQ Kuvah0sJwGwGGDFAUTjqmkapUGUW9QPCvZ206cFgukU
yan/IUu6MrhctKCgrAtbMwdsp+hX9FjHIAeG/gkokHw
-> ssh-ed25519 8S096g CLror+G56H5TOuOqjBOLL1GvOyPU8jzYXTlXEjoM6xY
LmqGHmsW5M2TTa4+BuWJk7qNP4YtT6/bHZBXwKKx6VU
--- q3W/w3KhMsEENOa+L0F7Do3H1gQtrlD8F53RrAYtsWQ
Žm`—îê%¨Ë¼ìezéñžW÷` ÐZA.ÓüÔ„Êʴ·|¨ÊM'ë%3á´Ëî&Ö»lÇV

View File

@ -1,7 +1,9 @@
age-encryption.org/v1
-> ssh-ed25519 XInHQA PIaYFOuYTsAufLY3jySjdLfKzfcQ6hAetR8sG9k4KTM
Wg1kb+WgD8MW81bJfwejeTiiEVJCH9WWQ7O7J5zeYj8
-> ssh-ed25519 9JjquQ nN0gqdhhk+tcsXgb2YdlNr9TCM8ZzJ8jgwFQK+o3Cw0
uklN8haFY8XCUMIlAPqIheganGtCyLSg2w/4LM9dcdM
--- uNsDhT+Z43s4wRMaKiuVS0CIib7Geh+zBtSHIPLdHmY
7Vÿ<EFBFBD>ÌäŒ%Ð)¶},1¾Ã½r㊔_× Ù;œçÝ·ï°õÿÍ­Nbîl
-> ssh-ed25519 XInHQA CHnxIyP3ch6zmozgHHGKyrNwCukFOzpQqzqmhBBK3HU
cShHERfT2fay87wUcFMzLo2CqQjo2GlPckbN9ajIzoE
-> ssh-ed25519 9JjquQ JUjEXgduMtZG7k3p8vs4kAp7npo5yenMlaqYeRDvs3I
FTzPyilqsUhBE1tVzePrWEG9AMaBTvYfJpPp9dMahfs
-> ssh-ed25519 8S096g +kQ00HeKJSTEZhH+kDYVAS8JmphGAIX3O4gAcg+uATs
Lswx4AtFXJBrJThwIzeKeUFdOYkNXmAEEuJ8OuNmCVo
--- LmvUVzAHHAEgun76eCLHe+nxgv2Xj5qhPbUgVWirjxU
Ÿi—Ø¡v(•<-‰d'ЫGñ£ÔEzV¾š;ߺåµKc3ŸÈè I¹ÁX´

Binary file not shown.

View File

@ -1,9 +1,11 @@
age-encryption.org/v1
-> ssh-ed25519 XInHQA OsckddKmgFuwo64IFPysoEWhUWdaNz0fQOpgup0dKQY
o1/BcRP/NND8YHZYuQnclfa1GxlczSdc57nOw9Zm2io
-> ssh-ed25519 9JjquQ pLjLs2p363cKXPmz8iYAOJUYSlmK4N9GCXlizaE5fj4
kIdPVG/i3WdRGYxLefEnCA8cTytHCZEcpqbp5Y8aG2o
-> ssh-ed25519 H9OGOA BowCiYKCWxWbiapKpdshcRzdZR1UEscscAAOe/kEig8
Lexjp0LuPZs5bV8CQ63Scb+xh8lPDM7x17KD9r0/1qU
--- e+NBlts82HBx3gbjznmUKufAYF1w2fzEO+LNx9yvq18
<EFBFBD>#<ÐUŲݲ?Ã{çþC¹ÝÈäÓ_ÞoyXüZBEʶ£%é§Ä,m<>#÷fSõkÀ§à­~z
-> ssh-ed25519 XInHQA RfnooKxGudC9db3TeLiHCeBAQmoBMKQYwne1kPwBB3Y
Cy7nE5t4HksIkTGiE5A5eWugtPpLLgKg675a9QAJ1OQ
-> ssh-ed25519 9JjquQ IXrC89snSDyCk0/cHfZxK3I7VBDOkMB7RqLikSzFfhc
gJUgWJT00puABYjKgSlQIScxwIzLzw9G04MeYq5skMw
-> ssh-ed25519 8S096g euxCvoiDEsR3+X5YsbTeDluRA8f5iLFV7KOC1aLwH3U
TDIIZoqkh2DPUVno76U16Y/9HaU5dCL/AqgbqBNF/BU
-> ssh-ed25519 H9OGOA VmODcaMxRDUeD0sbrtFNTAiuI/gI7+zVEQwfhC7gT1s
p95/aXRwH3PdgsiMMxR/pEFlithxc68STelHRxAZoKM
--- WVxsIeOZysNFXyQiihNL527CpfNy6WuSVw7UnrMEmAU
Ì ¦=K+t¹zf8 coœÈÅQZ÷<5A>ÀŸ.ý²/xðSç«Yª?ÜÊÂ<=^Ny€¿`'ŠÜù¯Z¸¾ŠÚà7

View File

@ -1,12 +1,13 @@
age-encryption.org/v1
-> ssh-ed25519 XInHQA uCUIywKJrUQhqYI8uhhxNIsXoTcRBbZSRVfUJPCp2wM
2p1OvwRBUMJTXvhp2PdGBCwxKU/rFPBHKZaKJ38HvAo
-> ssh-ed25519 K8TEKA d4DDO/774I+lhafaKbrERWsl6NqeqpdkbmZy0FA6Dws
ObQGhn0BmzqE5pSg+vPSVdx3rLng9h3wPfoFx2umVAI
-> ssh-ed25519 7+Zv5Q M1P+teBvn1p4zbFNIVvGremZC5hViNswi9q24mCxCEg
zR1sV/5t8nI3jky5Ou9Ud7IYC8E8nkQnvRIW9lG7nbA
-> ssh-ed25519 9JjquQ P5F2UqVRXkySbbI4OHM6rChELU0wpx6Stpvz78Ie1yY
uWOhkO0vx0anNHA5EWuLmDmTQvoY/c1iSzlVl2xldC4
--- BARoI30iwdy5g5hWJoHpVlA6Hlhu4SBpGhxrTPvG8ok
´•µãØÄ;”Ö&ß_xIúXÛRŸøóÏ£ÂĴ螞ܾ]¹9ÅÏ'La§1ø÷¡Q )ê@
°WMeÎ%€3¼K
-> ssh-ed25519 XInHQA UWrsDGlrkZ6xmFFSOCrAZbybIvIYQc1QKhgXhdDSoxY
5Je6sUO8h71WJkFpof3XcxnIUEexutrEz5TXT1Bwobg
-> ssh-ed25519 K8TEKA Kxxgpb4qEFVQ+KJpb2wBwKjQc22PwjEEB3Y3ERmm924
2O4zzOOyH8SeRScBhGFKopMD5eZKtOF63fWs3YjqC5Q
-> ssh-ed25519 7+Zv5Q 3A3v+goiSRXpBhb3hAVJXbHuHdT+L4Xr178ML/pfG2s
Ds1qBZlDl2mnlZvRcI0fEvDQ79KmUFAYICoVrcoA+Oc
-> ssh-ed25519 9JjquQ 0p+mZLwhphoGDdmpOxgQrzIX+Y2w0RvIdNMlSarL90s
8P+l4oPQ3qEtR4KWk7W7wkxGEjroqMA5f70+1eUjdY8
-> ssh-ed25519 8S096g 5cTN3f5x+9Qizop1nRdjkqe0pa1S3LjR0pbMTccsPWM
gGn24WckcR1iCNJH2oB8gekTTty/a4asssRmDlgEpwU
--- LCrdBMibVYcT7SAS+jw+IBSb8nHdqvCpP0oe4fVc9OQ
<1F>æèQÐÒ<C390>x¥Q,•¹ºÓéS­<53>WŠõ<C5A0>$2È­Ó3E“Aîß-×fc‰dæ•wV¿i2ÌvÏŸê >Z

View File

@ -0,0 +1,12 @@
age-encryption.org/v1
-> ssh-ed25519 XInHQA bMzwX3D3LAeB2oFjeCgQy6NtXfde87lGBBhJN7Nrox4
h6hwikEijHYMUTWhBuSgz+nxnnj00VlSibTZc2JmnBY
-> ssh-ed25519 K8TEKA s2cQpiLdC+1XBH5cIE5Z/IUEpsk564jYrsafVZSMgVQ
d5qPoJhyUToxN639uoR0J9kcfvubItuzXGoVk6Sewao
-> ssh-ed25519 7+Zv5Q pdOyuEw0qr/owYTSBq1Ewmge/0iGrf5PVQe8nSRKRhk
WWnMY5blWR6JOEz8dcOXdFoz9Vfj7J3EmVfVfb0qAmQ
-> ssh-ed25519 9JjquQ V82cwaqtAmVTMeyWvd23c0xOUk38tnmwFMKPeNZbbik
iWuQQSWFGf5ZqTyv78YRk7D96W8UXTnbaMLZ6F0ctj8
--- PtBBUhavizHrdmvxBF9qcB4rYEcB0A4AWqRl1Wp1Hic
ÅêÞ`ÐXj*Ä3U ±Ë÷ :¢7…ä´s<C2B4>Zž1eA«
ø‰µýíRú#ì

View File

@ -1,4 +1,5 @@
{
config,
lib,
pkgs,
userdata,
@ -12,14 +13,11 @@
networking = {
hostName = "bicboye";
useDHCP = lib.mkDefault false;
interfaces.enp6s0 = {
interfaces.enp2s0 = {
useDHCP = lib.mkDefault true;
wakeOnLan.enable = true;
};
firewall.allowedTCPPorts = [
80
443
];
firewall.allowedTCPPorts = [80 443];
};
# Enable weekly btrfs auto-scrub.
@ -35,33 +33,93 @@
# TODO: move to module
security.acme.defaults.email = "chinmaydpai@gmail.com";
security.dhparams = {
enable = true;
params.nginx = {};
};
services.nginx = {
enable = true;
recommendedProxySettings = true;
recommendedOptimisation = true;
recommendedGzipSettings = true;
recommendedTlsSettings = true;
sslDhparam = config.security.dhparams.params.nginx.path;
# Disable default_server access and return HTTP 444.
appendHttpConfig = ''
server {
listen 80 http2 default_server;
listen 443 ssl http2 default_server;
ssl_reject_handshake on;
return 444;
}
'';
};
snowflake = {
stateVersion = "24.05";
extraPackages = with pkgs; [
nmap
recyclarr
];
core.docker.enable = true;
core.docker.storageDriver = "btrfs";
core.security.sysctl.enable = lib.mkForce false;
networking.networkManager.enable = true;
networking.resolved.enable = true;
hardware.initrd-luks = {
enable = true;
authorizedKeys = [
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIG3PeMbehJBkmv8Ee7xJimTzXoSdmAnxhBatHSdS+saM"
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOyY8ZkhwWiqJCiTqXvHnLpXQb1qWwSZAoqoSWJI1ogP"
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJQWA+bAwpm9ca5IhC6q2BsxeQH4WAiKyaht48b7/xkN"
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKJnFvU6nBXEuZF08zRLFfPpxYjV3o0UayX0zTPbDb7C"
];
availableKernelModules = ["r8169"];
};
monitoring = {
enable = true;
grafana = {
domain = "lens.deku.moe";
adminPasswordFile = userdata.secrets.monitoring.grafana.password;
};
victoriametrics.extraPrometheusConfig = [
{
job_name = "unpoller";
static_configs = [
{
targets = ["127.0.0.1:${toString config.services.prometheus.exporters.unpoller.port}"];
}
];
}
{
job_name = "router";
static_configs = [
{
targets = ["192.168.69.1:9100"];
}
];
relabel_configs = [
{
source_labels = ["__address__"];
target_label = "instance";
regex = "([^:]+)(:[0-9]+)?";
replacement = "openwrt";
}
];
}
];
};
services = {
arr.enable = true;
gitea = {
enable = true;
domain = "git.deku.moe";
@ -75,6 +133,11 @@
adminTokenFile = userdata.secrets.services.miniflux.password;
};
ntfy-sh = {
enable = true;
domain = "ntfy.deku.moe";
};
paperless = {
enable = true;
domain = "docs.deku.moe";
@ -93,7 +156,13 @@
package = pkgs.maych-in;
domain = "maych.in";
};
unifi-controller.enable = true;
unifi-controller = {
enable = true;
unpoller = {
enable = true;
passwordFile = userdata.secrets.services.unifi-unpoller.password;
};
};
};
user = {
@ -105,6 +174,8 @@
extraAuthorizedKeys = [
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIG3PeMbehJBkmv8Ee7xJimTzXoSdmAnxhBatHSdS+saM"
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOyY8ZkhwWiqJCiTqXvHnLpXQb1qWwSZAoqoSWJI1ogP"
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJQWA+bAwpm9ca5IhC6q2BsxeQH4WAiKyaht48b7/xkN"
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKJnFvU6nBXEuZF08zRLFfPpxYjV3o0UayX0zTPbDb7C"
];
};
};

View File

@ -10,14 +10,14 @@ _: {
"usb_storage"
"sd_mod"
];
luks.devices."root".device = "/dev/disk/by-uuid/e70bfc3c-1147-4af7-9bae-69f70146953f";
luks.devices."cryptroot".device = "/dev/disk/by-uuid/e570c2be-65df-4208-9cac-a03de08a6209";
};
kernelModules = ["kvm-intel"];
};
fileSystems = {
"/" = {
device = "/dev/disk/by-uuid/5cabc339-898c-4604-9bfc-0a2cf17e44ca";
device = "/dev/disk/by-uuid/a1b57a56-16d4-45ea-bac3-daeacd3dbcb2";
fsType = "btrfs";
options = [
"defaults"
@ -30,7 +30,7 @@ _: {
};
"/home" = {
device = "/dev/disk/by-uuid/5cabc339-898c-4604-9bfc-0a2cf17e44ca";
device = "/dev/disk/by-uuid/a1b57a56-16d4-45ea-bac3-daeacd3dbcb2";
fsType = "btrfs";
options = [
"defaults"
@ -42,7 +42,7 @@ _: {
};
"/.snapshots" = {
device = "/dev/disk/by-uuid/5cabc339-898c-4604-9bfc-0a2cf17e44ca";
device = "/dev/disk/by-uuid/a1b57a56-16d4-45ea-bac3-daeacd3dbcb2";
fsType = "btrfs";
options = [
"defaults"
@ -54,7 +54,7 @@ _: {
};
"/var/log" = {
device = "/dev/disk/by-uuid/5cabc339-898c-4604-9bfc-0a2cf17e44ca";
device = "/dev/disk/by-uuid/a1b57a56-16d4-45ea-bac3-daeacd3dbcb2";
fsType = "btrfs";
options = [
"defaults"
@ -66,7 +66,7 @@ _: {
};
"/etc/nixos" = {
device = "/dev/disk/by-uuid/5cabc339-898c-4604-9bfc-0a2cf17e44ca";
device = "/dev/disk/by-uuid/a1b57a56-16d4-45ea-bac3-daeacd3dbcb2";
fsType = "btrfs";
options = [
"defaults"
@ -78,7 +78,7 @@ _: {
};
"/var/cache" = {
device = "/dev/disk/by-uuid/5cabc339-898c-4604-9bfc-0a2cf17e44ca";
device = "/dev/disk/by-uuid/a1b57a56-16d4-45ea-bac3-daeacd3dbcb2";
fsType = "btrfs";
options = [
"defaults"
@ -90,24 +90,13 @@ _: {
};
"/boot" = {
device = "/dev/disk/by-uuid/1C6C-122C";
device = "/dev/disk/by-uuid/B731-09A3";
fsType = "vfat";
options = ["fmask=0022" "dmask=0022"];
};
"/storage/immich" = {
device = "/dev/disk/by-uuid/bae65b7a-4f08-4b0d-963c-72e71bfcff46";
fsType = "btrfs";
options = [
"defaults"
"compress-force=zstd"
"noatime"
"user"
];
};
# TODO: delete btrfs subvolume
"/storage/syncthing" = {
device = "/dev/disk/by-uuid/e3a4c251-a3e2-4b5e-a63b-70f53b51836a";
"/storage/media" = {
device = "/dev/disk/by-uuid/f8aadf58-d561-476b-a2c5-64b266dc5755";
fsType = "btrfs";
options = [
"defaults"

View File

@ -31,7 +31,6 @@ _: {
fsType = "btrfs";
options = [
"defaults"
# "autodefrag"
"compress-force=zstd"
"noatime"
"ssd"
@ -46,7 +45,6 @@ _: {
fsType = "btrfs";
options = [
"defaults"
# "autodefrag"
"compress-force=zstd"
"noatime"
"ssd"
@ -73,7 +71,6 @@ _: {
fsType = "btrfs";
options = [
"defaults"
# "autodefrag"
"compress-force=zstd"
"noatime"
"ssd"
@ -87,7 +84,6 @@ _: {
fsType = "btrfs";
options = [
"defaults"
# "autodefrag"
"compress-force=zstd"
"noatime"
"ssd"
@ -113,7 +109,6 @@ _: {
fsType = "btrfs";
options = [
"defaults"
# "autodefrag"
"compress-force=zstd"
"noatime"
"ssd"