14 Commits

10 changed files with 350 additions and 82 deletions

35
flake.lock generated
View File

@@ -7,11 +7,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1745001336, "lastModified": 1747009742,
"narHash": "sha256-R4HuzrgYtOYBNmB3lfRxcieHEBO4uSfgHNz4MzWkZ5M=", "narHash": "sha256-TNhbM7R45fpq2cdWzvFj+H5ZTcE//I5XSe78GFh0cDY=",
"owner": "nix-community", "owner": "nix-community",
"repo": "home-manager", "repo": "home-manager",
"rev": "fc09cb7aaadb70d6c4898654ffc872f0d2415df9", "rev": "c74665abd6e4e37d3140e68885bc49a994ffa53c",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -58,11 +58,11 @@
}, },
"nixpkgs": { "nixpkgs": {
"locked": { "locked": {
"lastModified": 1744932701, "lastModified": 1746904237,
"narHash": "sha256-fusHbZCyv126cyArUwwKrLdCkgVAIaa/fQJYFlCEqiU=", "narHash": "sha256-3e+AVBczosP5dCLQmMoMEogM57gmZ2qrVSrmq9aResQ=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "b024ced1aac25639f8ca8fdfc2f8c4fbd66c48ef", "rev": "d89fc19e405cb2d55ce7cc114356846a0ee5e956",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -100,7 +100,28 @@
"home-manager": "home-manager", "home-manager": "home-manager",
"nixos-generators": "nixos-generators", "nixos-generators": "nixos-generators",
"nixpkgs": "nixpkgs", "nixpkgs": "nixpkgs",
"plasma-manager": "plasma-manager" "plasma-manager": "plasma-manager",
"secrix": "secrix"
}
},
"secrix": {
"inputs": {
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1746643487,
"narHash": "sha256-dcB/DArJObCvqE/ZEdQSDW2BZMeDyF83Se5KPfJvz60=",
"owner": "Platonic-Systems",
"repo": "secrix",
"rev": "4c64203fa5b377953b1fb6d5388187df8b60c6d5",
"type": "github"
},
"original": {
"owner": "Platonic-Systems",
"repo": "secrix",
"type": "github"
} }
} }
}, },

View File

@@ -18,9 +18,15 @@
url = "github:nix-community/nixos-generators"; url = "github:nix-community/nixos-generators";
inputs.nixpkgs.follows = "nixpkgs"; inputs.nixpkgs.follows = "nixpkgs";
}; };
secrix = {
url = "github:Platonic-Systems/secrix";
inputs.nixpkgs.follows = "nixpkgs";
};
}; };
outputs = { self, nixpkgs, home-manager, plasma-manager, nixos-generators }: { outputs = { self, nixpkgs, home-manager, plasma-manager, nixos-generators, secrix }: {
apps.x86_64-linux.secrix = secrix.secrix self;
nixosConfigurations = { nixosConfigurations = {
Yura-PC = nixpkgs.lib.nixosSystem { Yura-PC = nixpkgs.lib.nixosSystem {
system = "x86_64-linux"; system = "x86_64-linux";
@@ -52,6 +58,7 @@
router = nixpkgs.lib.nixosSystem { router = nixpkgs.lib.nixosSystem {
system = "x86_64-linux"; system = "x86_64-linux";
modules = [ modules = [
secrix.nixosModules.default
./modules ./modules
./hosts/common.nix ./hosts/common.nix
./hosts/router ./hosts/router

View File

@@ -1,5 +1,8 @@
{ config, lib, pkgs, ... }: { config, lib, pkgs, ... }:
let
vars = import ./vars.nix;
enableDesktop = false;
in
{ {
imports = imports =
[ # Include the results of the hardware scan. [ # Include the results of the hardware scan.
@@ -8,8 +11,11 @@
./firewall.nix ./firewall.nix
./dns.nix ./dns.nix
./kea.nix ./kea.nix
./glance.nix
./services.nix ./services.nix
]; ];
# Secrix for secrets management
secrix.hostPubKey = vars.pubkey;
# Bootloader. # Bootloader.
boot.loader.systemd-boot.enable = true; boot.loader.systemd-boot.enable = true;
@@ -31,10 +37,10 @@
# Enable the KDE Plasma Desktop Environment. # Enable the KDE Plasma Desktop Environment.
# Useful for debugging with wireshark. # Useful for debugging with wireshark.
# services.displayManager.sddm.enable = true;
hardware.graphics.enable = true; hardware.graphics.enable = true;
services.displayManager.sddm.wayland.enable = true; services.displayManager.sddm.enable = enableDesktop;
services.desktopManager.plasma6.enable = true; services.displayManager.sddm.wayland.enable = enableDesktop;
services.desktopManager.plasma6.enable = enableDesktop;
# No need for audio in VM # No need for audio in VM
services.pipewire.enable = false; services.pipewire.enable = false;
@@ -79,9 +85,7 @@
eza eza
fastfetch fastfetch
fd fd
kdePackages.filelight
kdePackages.kate kdePackages.kate
kdePackages.yakuake
ldns ldns
lsof lsof
micro micro

View File

@@ -42,8 +42,12 @@ in
services.adguardhome.enable = true; services.adguardhome.enable = true;
services.adguardhome.mutableSettings = false; services.adguardhome.mutableSettings = false;
# https://github.com/AdguardTeam/Adguardhome/wiki/Configuration
services.adguardhome.settings = { services.adguardhome.settings = {
dns = { dns = {
# Disable rate limit, default of 20 is too low
# https://github.com/AdguardTeam/AdGuardHome/issues/6726
ratelimit = 0;
bootstrap_dns = [ "1.1.1.1" "9.9.9.9" ]; bootstrap_dns = [ "1.1.1.1" "9.9.9.9" ];
upstream_dns = [ upstream_dns = [
# Default upstreams # Default upstreams

View File

@@ -4,13 +4,7 @@ let
links = vars.links; links = vars.links;
ifs = vars.ifs; ifs = vars.ifs;
pdFromWan = vars.pdFromWan; pdFromWan = vars.pdFromWan;
in nftIdentifiers = ''
{
networking.firewall.enable = false;
networking.nftables.enable = true;
networking.nftables.tables.firewall = {
family = "inet";
content = ''
define ZONE_WAN_IFS = { ${ifs.wan.name} } define ZONE_WAN_IFS = { ${ifs.wan.name} }
define ZONE_LAN_IFS = { define ZONE_LAN_IFS = {
${ifs.lan.name}, ${ifs.lan.name},
@@ -39,19 +33,67 @@ in
2a06:98c0::/29, 2a06:98c0::/29,
2c0f:f248::/32, 2c0f:f248::/32,
} }
'';
define ALLOWED_TCP_PORTS = { ssh, https } in
define ALLOWED_UDP_PORTS = { bootps, dhcpv6-server, domain } {
networking.firewall.enable = false;
map port_forward_v4 { networking.nftables.enable = true;
# networking.nftables.ruleset = nftIdentifiers; #doesn't work because it's appended to the end
networking.nftables.tables.nat4 = {
family = "ip";
content = ''
${nftIdentifiers}
map port_forward {
type inet_proto . inet_service : ipv4_addr . inet_service type inet_proto . inet_service : ipv4_addr . inet_service
elements = { elements = {
tcp . 8006 : ${ifs.lan50.p4}.10 . 8006 tcp . 8006 : ${ifs.lan50.p4}.10 . 8006
} }
} }
chain prerouting {
# Initial step, accept by default
type nat hook prerouting priority dstnat; policy accept;
# Port forwarding
fib daddr type local dnat ip to meta l4proto . th dport map @port_forward
}
chain postrouting {
# Last step, accept by default
type nat hook postrouting priority srcnat; policy accept;
# Masquerade LAN addrs
oifname $ZONE_WAN_IFS ip saddr $RFC1918 masquerade
}
'';
};
# Optional IPv6 masquerading (big L if enabled, don't forget to allow forwarding)
networking.nftables.tables.nat6 = {
family = "ip6";
enable = false;
content = ''
${nftIdentifiers}
chain postrouting {
type nat hook postrouting priority srcnat; policy accept;
oifname $ZONE_WAN_IFS ip6 saddr fd00::/8 masquerade
}
'';
};
networking.nftables.tables.firewall = {
family = "inet";
content = ''
${nftIdentifiers}
define ALLOWED_TCP_PORTS = { ssh, https }
define ALLOWED_UDP_PORTS = { bootps, dhcpv6-server, domain, https }
set port_forward_v6 { set port_forward_v6 {
type inet_proto . ipv6_addr . inet_service type inet_proto . ipv6_addr . inet_service
# elements = {} elements = {
# syncthing on alpina
tcp . ${ifs.lan.p6}::11:1 . 22000 ,
udp . ${ifs.lan.p6}::11:1 . 22000 ,
}
} }
set cloudflare_forward_v6 { set cloudflare_forward_v6 {
type ipv6_addr type ipv6_addr
@@ -94,7 +136,7 @@ in
# WAN zone input rules # WAN zone input rules
iifname $ZONE_WAN_IFS jump zone_wan_input iifname $ZONE_WAN_IFS jump zone_wan_input
# LAN zone input rules # LAN zone input rules
iifname $ZONE_LAN_IFS accept # iifname $ZONE_LAN_IFS accept
iifname $ZONE_LAN_IFS jump zone_lan_input iifname $ZONE_LAN_IFS jump zone_lan_input
ip6 saddr $ZONE_LAN_EXTRA_NET6 jump zone_lan_input ip6 saddr $ZONE_LAN_EXTRA_NET6 jump zone_lan_input
@@ -160,25 +202,6 @@ in
# NAT reflection # NAT reflection
# oif lo ip daddr != 127.0.0.0/8 dnat ip to meta l4proto . th dport map @port_forward_v4 # oif lo ip daddr != 127.0.0.0/8 dnat ip to meta l4proto . th dport map @port_forward_v4
} }
chain prerouting {
# Initial step, accept by default
type nat hook prerouting priority dstnat; policy accept;
# Port forwarding
fib daddr type local dnat ip to meta l4proto . th dport map @port_forward_v4
}
chain postrouting {
# Last step, accept by default
type nat hook postrouting priority srcnat; policy accept;
# Masquerade LAN addrs
oifname $ZONE_WAN_IFS ip saddr $RFC1918 masquerade
# Optional IPv6 masquerading (big L if enabled, don't forget to allow forwarding)
# oifname $ZONE_WAN_IFS ip6 saddr fd00::/8 masquerade
}
''; '';
}; };
} }

166
hosts/router/glance.nix Normal file
View File

@@ -0,0 +1,166 @@
{ config, lib, pkgs, ... }:
let
vars = import ./vars.nix;
domain = vars.domain;
in
{
# Glance dashboard
services.glance.enable = true;
services.glance.settings.pages = [
{
name = "Home";
# hideDesktopNavigation = true; # Uncomment if needed
columns = [
{
size = "small";
widgets = [
{
type = "calendar";
firstDayOfWeek = "monday";
}
{
type = "rss";
limit = 10;
collapseAfter = 3;
cache = "12h";
feeds = [
{ url = "https://rtk0c.pages.dev/index.xml"; }
{ url = "https://www.yegor256.com/rss.xml"; }
{ url = "https://selfh.st/rss/"; title = "selfh.st"; }
{ url = "https://ciechanow.ski/atom.xml"; }
{ url = "https://www.joshwcomeau.com/rss.xml"; title = "Josh Comeau"; }
{ url = "https://samwho.dev/rss.xml"; }
{ url = "https://ishadeed.com/feed.xml"; title = "Ahmad Shadeed"; }
];
}
{
type = "twitch-channels";
channels = [
"theprimeagen"
"j_blow"
"piratesoftware"
"cohhcarnage"
"christitustech"
"EJ_SA"
];
}
];
}
{
size = "full";
widgets = [
{
type = "group";
widgets = [
{ type = "hacker-news"; }
{ type = "lobsters"; }
];
}
{
type = "videos";
channels = [
"UCXuqSBlHAE6Xw-yeJA0Tunw" # Linus Tech Tips
"UCR-DXc1voovS8nhAvccRZhg" # Jeff Geerling
"UCsBjURrPoezykLs9EqgamOA" # Fireship
"UCBJycsmduvYEL83R_U4JriQ" # Marques Brownlee
"UCHnyfMqiRRG1u-2MsSQLbXA" # Veritasium
];
}
{
type = "group";
widgets = [
{
type = "reddit";
subreddit = "technology";
showThumbnails = true;
}
{
type = "reddit";
subreddit = "selfhosted";
showThumbnails = true;
}
];
}
];
}
{
size = "small";
widgets = [
{
type = "weather";
location = "San Jose, California, United States";
units = "metric";
hourFormat = "12h";
# hideLocation = true; # Uncomment if needed
}
{
type = "markets";
markets = [
{ symbol = "SPY"; name = "S&P 500"; }
{ symbol = "BTC-USD"; name = "Bitcoin"; }
{ symbol = "NVDA"; name = "NVIDIA"; }
{ symbol = "AAPL"; name = "Apple"; }
{ symbol = "MSFT"; name = "Microsoft"; }
];
}
{
type = "releases";
cache = "1d";
# token = "..."; # Uncomment and set if needed
repositories = [
"glanceapp/glance"
"go-gitea/gitea"
"immich-app/immich"
"syncthing/syncthing"
];
}
];
}
];
}
{
name = "Infrastructure";
columns = [
{
size = "small";
widgets = [
{
type = "server-stats";
servers = [
{
type = "local";
name = "Router";
mountpoints."/nix/store".hide = true;
}
];
}
];
}
{
size = "full";
widgets = [
{
type = "iframe";
title = "Grafana";
title-url = "/grafana/";
source = "/grafana/d-solo/rYdddlPWk/node-exporter-full?orgId=1&from=1747211119196&to=1747297519196&timezone=browser&var-datasource=PBFA97CFB590B2093&var-job=node&var-node=localhost:9100&var-diskdevices=%5Ba-z%5D%2B%7Cnvme%5B0-9%5D%2Bn%5B0-9%5D%2B%7Cmmcblk%5B0-9%5D%2B&refresh=1m&panelId=74&__feature.dashboardSceneSolo";
height = 400;
}
];
}
{
size = "small";
widgets = [
{
type = "dns-stats";
service = "adguard";
url = "http://localhost:${toString config.services.adguardhome.port}";
username = "";
password = "";
}
];
}
];
}
];
}

View File

@@ -4,15 +4,9 @@ let
domain = vars.domain; domain = vars.domain;
in in
{ {
services.miniupnpd = {
enable = true; # vnStat for tracking network interface stats
natpmp = true; services.vnstat.enable = true;
externalInterface = vars.ifs.wan.name;
internalIPs = [
vars.ifs.lan.name
vars.ifs.lan20.name
];
};
# https://wiki.nixos.org/wiki/Prometheus # https://wiki.nixos.org/wiki/Prometheus
services.prometheus = { services.prometheus = {
@@ -37,7 +31,15 @@ in
# https://wiki.nixos.org/wiki/Grafana#Declarative_configuration # https://wiki.nixos.org/wiki/Grafana#Declarative_configuration
services.grafana = { services.grafana = {
enable = true; enable = true;
settings.server.http_port = 3001; settings = {
security.allow_embedding = true;
server = {
http_port = 3001;
domain = "grouter.${domain}";
root_url = "https://%(domain)s/grafana/";
serve_from_sub_path = true;
};
};
provision = { provision = {
enable = true; enable = true;
datasources.settings.datasources = [ datasources.settings.datasources = [
@@ -50,11 +52,34 @@ in
}; };
}; };
secrix.system.secrets.cf-api-key.encrypted.file = ../../secrets/cf_api_key.age;
systemd.services.caddy.serviceConfig.EnvironmentFile = config.secrix.system.secrets.cf-api-key.decrypted.path;
services.caddy = { services.caddy = {
enable = true; enable = true;
package = pkgs.caddy.withPlugins {
plugins = [ "github.com/caddy-dns/cloudflare@v0.2.1" ];
hash = "sha256-saKJatiBZ4775IV2C5JLOmZ4BwHKFtRZan94aS5pO90=";
};
virtualHosts."grouter.${domain}".extraConfig = '' virtualHosts."grouter.${domain}".extraConfig = ''
encode
tls {
dns cloudflare {env.CF_API_KEY}
resolvers 1.1.1.1
}
@grafana path /grafana /grafana/*
handle @grafana {
reverse_proxy localhost:${toString config.services.grafana.settings.server.http_port} reverse_proxy localhost:${toString config.services.grafana.settings.server.http_port}
tls internal }
redir /adghome /adghome/
handle_path /adghome/* {
reverse_proxy localhost:${toString config.services.adguardhome.port}
basic_auth {
Bob $2a$14$HsWmmzQTN68K3vwiRAfiUuqIjKoXEXaj9TOLUtG2mO1vFpdovmyBy
}
}
handle /* {
reverse_proxy localhost:${toString config.services.glance.settings.server.port}
}
''; '';
}; };
} }

View File

@@ -31,6 +31,7 @@ let
}; };
in in
rec { rec {
pubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFobB87yYVwhuYrA+tfztLuks3s9jZOqEFktwGw1mo83 root@grouter";
domain = "cazzzer.com"; domain = "cazzzer.com";
ldomain = "l.${domain}"; ldomain = "l.${domain}";
sysdomain = "sys.${domain}"; sysdomain = "sys.${domain}";

12
renovate.json Normal file
View File

@@ -0,0 +1,12 @@
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": [
"config:recommended"
],
"lockFileMaintenance": {
"enabled": true
},
"nix": {
"enabled": true
}
}

5
secrets/cf_api_key.age Normal file
View File

@@ -0,0 +1,5 @@
age-encryption.org/v1
-> ssh-ed25519 D2MY/A Kj69kavxx+ATNHP5pX0JtGggU76f9uRwkZp2HbjwiWc
SbU3jIcQzUzaQjRHzVSoW1WKiUj+1ijbkUKqVb406fY
--- vMV0TcchFvxw1xetQQZ0xVi2KwjLFRfZBM1gl7BGbGI
<EFBFBD><EFBFBD>1<10><><EFBFBD><EFBFBD>K<EFBFBD><<3C>