19 Commits

Author SHA1 Message Date
5c79cbf694 router: firewall: allow ssh, wireguard input globally 2025-05-21 00:19:12 -07:00
cfe8ffa759 router: firewall: add entries for wireguard 2025-05-21 00:15:28 -07:00
ff2f6d28bb router: wireguard: add wg0 interface with some peers for testing 2025-05-21 00:15:05 -07:00
fce994ae9f flake: fix vm-proxmox package 2025-05-20 23:30:14 -07:00
e0af380656 updates: linux 6.14, nixpkgs, home-manager, nixos-generators 2025-05-20 21:58:24 -07:00
585ff678b8 refactor: add encrypted private.nix to hold private values 2025-05-18 01:07:48 -07:00
80b7bf0ed4 refactor: move user configs into separate dir 2025-05-18 00:00:00 -07:00
4807a091c4 router: add glance (very pretty) 2025-05-15 01:32:38 -07:00
9cee4d75c4 router: dns: remove default adguard rate limit to fix intermittent slow queries 2025-05-13 02:10:38 -07:00
4ffdb4da4f router: caddy http3 and compression 2025-05-12 00:11:03 -07:00
4fce23e446 renovate: add nix lock file to config 2025-05-11 21:41:34 -07:00
49c781c1a8 router: option to disable desktop to save space
# Conflicts:
#	hosts/router/default.nix
2025-05-11 21:36:28 -07:00
1fbba65785 router: add secrix for secrets; add cloudflare api key 2025-05-11 21:35:03 -07:00
bb633e5bce router: services: caddy acme dns provider cloudflare 2025-05-11 20:29:16 -07:00
2aa3d87184 router: services: caddy subpath proxies for grafana and adguardhome 2025-05-11 18:41:59 -07:00
05d558e836 router: refactor firewall nftables config 2025-05-11 17:56:17 -07:00
8f7e00f27a router: add vnStat service 2025-05-11 15:58:51 -07:00
renovate[bot]
5e023e2982 Add renovate.json 2025-05-06 00:27:13 -07:00
0674c870c7 updates: nixpkgs, home-manager; add texlive 2025-04-30 16:58:15 -07:00
25 changed files with 568 additions and 217 deletions

1
.gitattributes vendored Normal file
View File

@@ -0,0 +1 @@
private.nix filter=crypt diff=crypt merge=crypt

41
flake.lock generated
View File

@@ -7,11 +7,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1745001336, "lastModified": 1747793476,
"narHash": "sha256-R4HuzrgYtOYBNmB3lfRxcieHEBO4uSfgHNz4MzWkZ5M=", "narHash": "sha256-2qAOSixSrbb9l6MI+SI4zGineOzDcc2dgOOFK9Dx+IY=",
"owner": "nix-community", "owner": "nix-community",
"repo": "home-manager", "repo": "home-manager",
"rev": "fc09cb7aaadb70d6c4898654ffc872f0d2415df9", "rev": "2468b2d35512d093aeb04972a1d8c20a0735793f",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -43,11 +43,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1742568034, "lastModified": 1747663185,
"narHash": "sha256-QaMEhcnscfF2MqB7flZr+sLJMMYZPnvqO4NYf9B4G38=", "narHash": "sha256-Obh50J+O9jhUM/FgXtI3he/QRNiV9+J53+l+RlKSaAk=",
"owner": "nix-community", "owner": "nix-community",
"repo": "nixos-generators", "repo": "nixos-generators",
"rev": "42ee229088490e3777ed7d1162cb9e9d8c3dbb11", "rev": "ee07ba0d36c38e9915c55d2ac5a8fb0f05f2afcc",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -58,11 +58,11 @@
}, },
"nixpkgs": { "nixpkgs": {
"locked": { "locked": {
"lastModified": 1744932701, "lastModified": 1747744144,
"narHash": "sha256-fusHbZCyv126cyArUwwKrLdCkgVAIaa/fQJYFlCEqiU=", "narHash": "sha256-W7lqHp0qZiENCDwUZ5EX/lNhxjMdNapFnbErcbnP11Q=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "b024ced1aac25639f8ca8fdfc2f8c4fbd66c48ef", "rev": "2795c506fe8fb7b03c36ccb51f75b6df0ab2553f",
"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";
@@ -28,6 +34,7 @@
./modules ./modules
./hosts/common.nix ./hosts/common.nix
./hosts/Yura-PC ./hosts/Yura-PC
./users/cazzzer
# https://nix-community.github.io/home-manager/index.xhtml#sec-flakes-nixos-module # https://nix-community.github.io/home-manager/index.xhtml#sec-flakes-nixos-module
home-manager.nixosModules.home-manager home-manager.nixosModules.home-manager
{ {
@@ -46,15 +53,19 @@
modules = [ modules = [
./modules ./modules
./hosts/common.nix ./hosts/common.nix
./hosts/hw-vm.nix
./hosts/vm ./hosts/vm
./users/cazzzer
]; ];
}; };
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
./users/cazzzer
]; ];
}; };
}; };
@@ -65,11 +76,25 @@
modules = [ modules = [
./modules ./modules
./hosts/common.nix ./hosts/common.nix
./hosts/vm/proxmox.nix ./hosts/hw-proxmox.nix
./hosts/vm ./hosts/vm
./users/cazzzer
]; ];
format = "proxmox"; format = "proxmox";
}; };
vm-proxmox = let
image = nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
modules = [
./modules
./hosts/common.nix
./hosts/hw-proxmox.nix
./hosts/vm
./users/cazzzer
];
};
in
image.config.system.build.VMA;
}; };
}; };
} }

View File

@@ -1,15 +1,12 @@
{ config, lib, pkgs, ... }: { config, lib, pkgs, ... }:
let let
defaultFont = { username = "cazzzer";
family = "Noto Sans";
pointSize = 14;
};
in in
{ {
# Home Manager needs a bit of information about you and the paths it should # Home Manager needs a bit of information about you and the paths it should
# manage. # manage.
home.username = "cazzzer"; home.username = username;
home.homeDirectory = "/home/cazzzer"; home.homeDirectory = "/home/${username}";
# Let Home Manager install and manage itself. # Let Home Manager install and manage itself.
programs.home-manager.enable = true; programs.home-manager.enable = true;
@@ -126,8 +123,15 @@ in
programs.plasma = { programs.plasma = {
enable = true; enable = true;
overrideConfig = true; overrideConfig = true;
# TODO: figure out how to enable tela-circle icon theme if installed in systemPackages
# workspace.iconTheme = if builtins.elem pkgs.tela-circle-icon-theme config.environment.systemPackages then "Tela-circle" else null;
workspace.iconTheme = "Tela-circle"; workspace.iconTheme = "Tela-circle";
fonts = { fonts = let
defaultFont = {
family = "Noto Sans";
pointSize = 14;
};
in {
general = defaultFont; general = defaultFont;
fixedWidth = defaultFont // { family = "Hack"; }; fixedWidth = defaultFont // { family = "Hack"; };
small = defaultFont // { pointSize = defaultFont.pointSize - 2; }; small = defaultFont // { pointSize = defaultFont.pointSize - 2; };

View File

@@ -32,7 +32,7 @@
boot.loader.timeout = 3; boot.loader.timeout = 3;
boot.loader.systemd-boot.configurationLimit = 5; boot.loader.systemd-boot.configurationLimit = 5;
boot.kernelPackages = pkgs.linuxKernel.packages.linux_6_13; boot.kernelPackages = pkgs.linuxKernel.packages.linux_6_14;
# https://nixos.wiki/wiki/Accelerated_Video_Playback # https://nixos.wiki/wiki/Accelerated_Video_Playback
hardware.graphics = { hardware.graphics = {
@@ -88,7 +88,7 @@
services.openssh.enable = true; services.openssh.enable = true;
services.flatpak.enable = true; services.flatpak.enable = true;
# services.geoclue2.enable = true; # services.geoclue2.enable = true;
location.provider = "geoclue2"; # location.provider = "geoclue2";
# services.gnome.gnome-keyring.enable = true; # services.gnome.gnome-keyring.enable = true;
security.pam.services.sddm.enableGnomeKeyring = true; security.pam.services.sddm.enableGnomeKeyring = true;
# security.pam.services.sddm.gnupg.enable = true; # security.pam.services.sddm.gnupg.enable = true;
@@ -97,42 +97,6 @@
# Enable touchpad support (enabled default in most desktopManager). # Enable touchpad support (enabled default in most desktopManager).
# services.xserver.libinput.enable = true; # services.xserver.libinput.enable = true;
# Define a user account. Don't forget to set a password with passwd.
users.groups = {
cazzzer = {
gid = 1000;
};
};
users.users.cazzzer = {
isNormalUser = true;
description = "Yura";
uid = 1000;
group = "cazzzer";
extraGroups = [ "networkmanager" "wheel" "docker" "wireshark" "geoclue" ];
packages = with pkgs; [
# Python
python3
poetry
# Haskell
haskellPackages.ghc
haskellPackages.stack
# Node
nodejs_22
pnpm
bun
# Nix
nixd
nil
# Gleam
gleam
beamMinimal26Packages.erlang
];
};
hardware.bluetooth.enable = true; hardware.bluetooth.enable = true;
hardware.bluetooth.powerOnBoot = false; hardware.bluetooth.powerOnBoot = false;
# Install firefox. # Install firefox.
@@ -168,9 +132,6 @@
# }; # };
# }; # };
# Allow unfree packages
nixpkgs.config.allowUnfree = true;
# List packages installed in system profile. To search, run: # List packages installed in system profile. To search, run:
# $ nix search wget # $ nix search wget
@@ -216,9 +177,11 @@
fd fd
helix helix
micro micro
openssl
ripgrep ripgrep
starship starship
tealdeer tealdeer
transcrypt
] ++ [ ] ++ [
efibootmgr efibootmgr
ffmpeg ffmpeg

16
hosts/hw-proxmox.nix Normal file
View File

@@ -0,0 +1,16 @@
{ config, lib, pkgs, modulesPath, ... }:
{
imports = [
"${modulesPath}/virtualisation/proxmox-image.nix"
];
# boot.kernelParams = [ "console=tty0" ];
proxmox.qemuConf.bios = "ovmf";
proxmox.qemuExtraConf = {
machine = "q35";
# efidisk0 = "local-lvm:vm-9999-disk-1";
cpu = "host";
};
proxmox.cloudInit.enable = false;
}

26
hosts/hw-vm.nix Normal file
View File

@@ -0,0 +1,26 @@
{ config, lib, pkgs, modulesPath, ... }: {
imports = [
"${modulesPath}/profiles/qemu-guest.nix"
];
boot.initrd.availableKernelModules = lib.mkDefault [ "uhci_hcd" "ehci_pci" "ahci" "virtio_pci" "virtio_scsi" "sd_mod" "sr_mod" ];
fileSystems."/" = lib.mkDefault {
device = "/dev/disk/by-label/nixos";
autoResize = true;
fsType = "ext4";
};
fileSystems."/boot" = lib.mkDefault {
device = "/dev/disk/by-label/ESP";
fsType = "vfat";
};
# Enables DHCP on each ethernet and wireless interface. In case of scripted networking
# (the default) this is the recommended approach. When using systemd-networkd it's
# still possible to use this option, but it's recommended to use it in conjunction
# with explicit per-interface declarations with `networking.interfaces.<interface>.useDHCP`.
networking.useDHCP = lib.mkDefault true;
# networking.interfaces.enp6s18.useDHCP = lib.mkDefault true;
# nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
}

View File

@@ -1,15 +1,22 @@
{ 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.
./hardware-configuration.nix ./hardware-configuration.nix
./ifconfig.nix ./ifconfig.nix
./wireguard.nix
./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 +38,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;
@@ -47,24 +54,6 @@
security.sudo.wheelNeedsPassword = false; security.sudo.wheelNeedsPassword = false;
users.groups = {
cazzzer = {
gid = 1000;
};
};
users.users.cazzzer = {
password = "";
openssh.authorizedKeys.keys = [
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPWgEzbEjbbu96MVQzkiuCrw+UGYAXN4sRe2zM6FVopq cazzzer@Yura-PC"
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIApFeLVi3BOquL0Rt+gQK2CutNHaBDQ0m4PcGWf9Bc43 cazzzer@Yura-TPX13"
];
isNormalUser = true;
description = "Yura";
uid = 1000;
group = "cazzzer";
extraGroups = [ "wheel" "wireshark" ];
};
programs.firefox.enable = true; programs.firefox.enable = true;
programs.fish.enable = true; programs.fish.enable = true;
programs.git.enable = true; programs.git.enable = true;
@@ -79,17 +68,17 @@
eza eza
fastfetch fastfetch
fd fd
kdePackages.filelight
kdePackages.kate kdePackages.kate
kdePackages.yakuake
ldns ldns
lsof lsof
micro micro
mpv mpv
openssl
ripgrep ripgrep
rustscan rustscan
starship starship
tealdeer tealdeer
transcrypt
waypipe waypipe
whois whois
]; ];

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,54 +4,98 @@ let
links = vars.links; links = vars.links;
ifs = vars.ifs; ifs = vars.ifs;
pdFromWan = vars.pdFromWan; pdFromWan = vars.pdFromWan;
nftIdentifiers = ''
define ZONE_WAN_IFS = { ${ifs.wan.name} }
define ZONE_LAN_IFS = {
${ifs.lan.name},
${ifs.lan10.name},
${ifs.lan20.name},
${ifs.lan30.name},
${ifs.lan40.name},
${ifs.lan50.name},
}
define OPNSENSE_NET6 = ${vars.extra.opnsense.net6}
define ZONE_LAN_EXTRA_NET6 = {
# TODO: reevaluate this statement
${ifs.lan20.net6}, # needed since packets can come in from wan on these addrs
$OPNSENSE_NET6,
}
define RFC1918 = { 10.0.0.0/8, 172.12.0.0/12, 192.168.0.0/16 }
define CLOUDFLARE_NET6 = {
# https://www.cloudflare.com/ips-v6
# TODO: figure out a better way to get addrs dynamically from url
# perhaps building a nixos module/package that fetches the ips?
2400:cb00::/32,
2606:4700::/32,
2803:f800::/32,
2405:b500::/32,
2405:8100::/32,
2a06:98c0::/29,
2c0f:f248::/32,
}
'';
in in
{ {
networking.firewall.enable = false; networking.firewall.enable = false;
networking.nftables.enable = true; networking.nftables.enable = true;
networking.nftables.tables.firewall = { # networking.nftables.ruleset = nftIdentifiers; #doesn't work because it's appended to the end
family = "inet"; networking.nftables.tables.nat4 = {
family = "ip";
content = '' content = ''
define ZONE_WAN_IFS = { ${ifs.wan.name} } ${nftIdentifiers}
define ZONE_LAN_IFS = { map port_forward {
${ifs.lan.name},
${ifs.lan10.name},
${ifs.lan20.name},
${ifs.lan30.name},
${ifs.lan40.name},
${ifs.lan50.name},
}
define OPNSENSE_NET6 = ${vars.extra.opnsense.net6}
define ZONE_LAN_EXTRA_NET6 = {
# TODO: reevaluate this statement
${ifs.lan20.net6}, # needed since packets can come in from wan on these addrs
$OPNSENSE_NET6,
}
define RFC1918 = { 10.0.0.0/8, 172.12.0.0/12, 192.168.0.0/16 }
define CLOUDFLARE_NET6 = {
# https://www.cloudflare.com/ips-v6
# TODO: figure out a better way to get addrs dynamically from url
# perhaps building a nixos module/package that fetches the ips?
2400:cb00::/32,
2606:4700::/32,
2803:f800::/32,
2405:b500::/32,
2405:8100::/32,
2a06:98c0::/29,
2c0f:f248::/32,
}
define ALLOWED_TCP_PORTS = { ssh, https }
define ALLOWED_UDP_PORTS = { bootps, dhcpv6-server, domain }
map port_forward_v4 {
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 }
define ALLOWED_UDP_PORTS = { 18596 }
define ALLOWED_TCP_LAN_PORTS = { ssh, https }
define ALLOWED_UDP_LAN_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
@@ -91,10 +135,14 @@ in
# but apparently not. # but apparently not.
ip6 daddr { fe80::/10, ff02::/16 } th dport { dhcpv6-client, dhcpv6-server } accept ip6 daddr { fe80::/10, ff02::/16 } th dport { dhcpv6-client, dhcpv6-server } accept
# Global input rules
tcp dport $ALLOWED_TCP_PORTS accept
udp dport $ALLOWED_UDP_PORTS accept
# 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
@@ -115,8 +163,7 @@ in
} }
chain zone_wan_input { chain zone_wan_input {
# Allow SSH from WAN (if needed) # Allow specific stuff from WAN
tcp dport ssh accept
} }
chain zone_wan_forward { chain zone_wan_forward {
@@ -138,8 +185,8 @@ in
ip protocol icmp accept ip protocol icmp accept
# Allow specific services from LAN # Allow specific services from LAN
tcp dport $ALLOWED_TCP_PORTS accept tcp dport $ALLOWED_TCP_LAN_PORTS accept
udp dport $ALLOWED_UDP_PORTS accept udp dport $ALLOWED_UDP_LAN_PORTS accept
} }
chain zone_lan_forward { chain zone_lan_forward {
@@ -160,25 +207,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 = "";
}
];
}
];
}
];
}

2
hosts/router/private.nix Normal file
View File

@@ -0,0 +1,2 @@
U2FsdGVkX1/98w32OE1ppwT0I5A3UOTKCLJfvk+TQdrbf0TLfYNZ9TC9n8cH2hC9
ObKVuFlOLwHlzeBy7MXaLg==

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>

View File

@@ -0,0 +1,5 @@
age-encryption.org/v1
-> ssh-ed25519 D2MY/A YAk0egMScFdPo0uAZzITtgQyPAifDcVUfb957Zhz9Ec
pAEM+7sbPE8rHBhRV7mTmH1w4mbfKFopMWbwu/3KHCw
--- ykshsqEqKvCCE2kWIPAJPA/DFW7mu6+0x4MQhHgi1yU
'<27>zƀ{g<>id\{<7B>E<EFBFBD><45><EFBFBD>tp<74>U<>g2QC3g<33><08>JG<4A>V1<56>6<>WG_E&<26>v<EFBFBD><76>)<29>&<26><><EFBFBD>ޑ N"<22><><EFBFBD>n<EFBFBD>_T͒<54>

View File

@@ -0,0 +1,6 @@
age-encryption.org/v1
-> ssh-ed25519 D2MY/A P88M0uj4ZphVo3WrRYDu+c7B0Dl7ncctbYkByYmU2wg
DV3Gn6TQ6iByAlNt0gg8kSZ2r0Gie/wcznZx9M+CC2g
--- KhwGM50BVql02Jq0do2uhXMfgWPPDfbodzDRmZ9n0O4
r<EFBFBD><EFBFBD><EFBFBD>Զa<EFBFBD>yY/C<><43>J<EFBFBD>B<EFBFBD>X<EFBFBD>!<21>"F
<EFBFBD>h<EFBFBD><EFBFBD><EFBFBD>(<28>L><3E>()<29><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>S;<3B>}}2ОO.<2E><13>hoqY<19>K"c<>E<EFBFBD><45>JM?-<2D>O

View File

@@ -0,0 +1,5 @@
age-encryption.org/v1
-> ssh-ed25519 D2MY/A tvRtTGWnaB0zxqZRba4/XpzwPa61RrnHCk4tT8OfnGQ
IX85Q5VKxQTl+MnhzwiuTnNMVkR9QrYo/1njrbZeBnQ
--- dmlPIL2T+RFhbO2iLDRa4BxxYSSUQdedV3TK83ooFdA
<18>gE 7<><37>0`d<>V(o<>W<EFBFBD><57><EFBFBD>S@<01>ۭ<EFBFBD><DBAD><EFBFBD>p<EFBFBD><70><EFBFBD><EFBFBD><EFBFBD>Z<EFBFBD><5A>ЃT<D083><54><EFBFBD><EFBFBD><14>U<EFBFBD><55>+*<2A>\Q<><51>[<5B><><EFBFBD><EFBFBD>x<><78>29<32>i5<69>k

View File

@@ -4,6 +4,10 @@ let
domain = vars.domain; domain = vars.domain;
in in
{ {
# vnStat for tracking network interface stats
services.vnstat.enable = true;
# https://wiki.nixos.org/wiki/Prometheus # https://wiki.nixos.org/wiki/Prometheus
services.prometheus = { services.prometheus = {
enable = true; enable = true;
@@ -27,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 = [
@@ -40,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-Gsuo+ripJSgKSYOM9/yl6Kt/6BFCA6BuTDvPdteinAI=";
};
virtualHosts."grouter.${domain}".extraConfig = '' virtualHosts."grouter.${domain}".extraConfig = ''
reverse_proxy localhost:${toString config.services.grafana.settings.server.http_port} encode
tls internal 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}
}
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

@@ -1,4 +1,6 @@
let let
private = import ./private.nix;
mkIfConfig = { mkIfConfig = {
name_, name_,
domain_, domain_,
@@ -31,6 +33,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}";
@@ -42,7 +45,7 @@ rec {
}; };
p4 = "10.17"; # .0.0/16 p4 = "10.17"; # .0.0/16
pdFromWan = ""; # ::/60 pdFromWan = private.pdFromWan; # ::/60
ulaPrefix = "fdab:07d3:581d"; # ::/48 ulaPrefix = "fdab:07d3:581d"; # ::/48
ifs = rec { ifs = rec {
wan = rec { wan = rec {

View File

@@ -0,0 +1,57 @@
{ config, lib, pkgs, ... }:
let
vars = import ./vars.nix;
wg0Peers = [
{
name = "Yura-TPX13";
allowedIPs = [ "10.6.0.3/32" "${vars.extra.opnsense.p6}::6:3:0/112" ];
publicKey = "iJa5JmJbMHNlbEluNwoB2Q8LyrPAfb7S/mluanMcI08=";
pskEnabled = true;
}
{
name = "Yura-Pixel7Pro";
allowedIPs = [ "10.6.0.4/32" "${vars.extra.opnsense.p6}::6:4:0/112" ];
publicKey = "UjZlsukmAsX60Z5FnZwKCSu141Gjj74+hBVT3TRhwT4=";
pskEnabled = true;
}
{
name = "AsusS513";
allowedIPs = [ "10.6.0.100/32" ];
publicKey = "XozJ7dHdJfkLORkCVxaB1VmvHEOAA285kRZcmzfPl38=";
pskEnabled = true;
}
];
in
{
secrix.services.systemd-networkd.secrets = let
pskEnabledPeers = builtins.filter (peer: peer.pskEnabled) wg0Peers;
peerToSecretAttrs = peer: {
name = "wg0-peer-${peer.name}-psk";
value.encrypted.file = ./secrets/wireguard/wg0-peer-${peer.name}-psk.age;
};
peerSecretsList = map peerToSecretAttrs pskEnabledPeers;
peerSecrets = builtins.listToAttrs peerSecretsList;
in
{
wg0-private-key.encrypted.file = ./secrets/wireguard/wg0-private-key.age;
} // peerSecrets;
systemd.network.netdevs = {
"10-wg0" = {
netdevConfig = {
Kind = "wireguard";
Name = "wg0";
};
wireguardConfig = {
PrivateKeyFile = config.secrix.services.systemd-networkd.secrets.wg0-private-key.decrypted.path;
ListenPort = 18596;
};
wireguardPeers = map (peer: {
AllowedIPs = lib.strings.concatStringsSep "," peer.allowedIPs;
PublicKey = peer.publicKey;
PresharedKeyFile = if peer.pskEnabled then config.secrix.services.systemd-networkd.secrets."wg0-peer-${peer.name}-psk".decrypted.path else null;
}) wg0Peers;
};
};
}

View File

@@ -7,7 +7,7 @@
{ {
imports = imports =
[ # Include the results of the hardware scan. [ # Include the results of the hardware scan.
# ./hardware-configuration-vm.nix # ./hardware-configuration.nix
]; ];
mods.kb-input.enable = false; mods.kb-input.enable = false;
@@ -47,8 +47,8 @@
services.flatpak.enable = true; services.flatpak.enable = true;
# VM services # VM services
services.cloud-init.enable = true; # services.cloud-init.enable = false;
# services.cloud-init.network.enable = false; # services.cloud-init.network.enable = false;
services.qemuGuest.enable = true; services.qemuGuest.enable = true;
services.spice-vdagentd.enable = true; services.spice-vdagentd.enable = true;
services.openssh.enable = true; services.openssh.enable = true;
@@ -57,24 +57,6 @@
security.sudo.wheelNeedsPassword = false; security.sudo.wheelNeedsPassword = false;
users.groups = {
cazzzer = {
gid = 1000;
};
};
users.users.cazzzer = {
password = "";
openssh.authorizedKeys.keys = [
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPWgEzbEjbbu96MVQzkiuCrw+UGYAXN4sRe2zM6FVopq cazzzer@Yura-PC"
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIApFeLVi3BOquL0Rt+gQK2CutNHaBDQ0m4PcGWf9Bc43 cazzzer@Yura-TPX13"
];
isNormalUser = true;
description = "Yura";
uid = 1000;
group = "cazzzer";
extraGroups = [ "wheel" "docker" "wireshark" ];
};
# Install firefox. # Install firefox.
programs.firefox.enable = true; programs.firefox.enable = true;
programs.fish.enable = true; programs.fish.enable = true;
@@ -113,9 +95,11 @@
ldns ldns
micro micro
mpv mpv
openssl
ripgrep ripgrep
starship starship
tealdeer tealdeer
transcrypt
waypipe waypipe
whois whois
zfs zfs

View File

@@ -1,37 +0,0 @@
# Do not modify this file! It was generated by nixos-generate-config
# and may be overwritten by future invocations. Please make changes
# to /etc/nixos/configuration.nix instead.
{ config, lib, pkgs, modulesPath, ... }:
{
imports =
[ (modulesPath + "/profiles/qemu-guest.nix")
];
boot.initrd.availableKernelModules = [ "uhci_hcd" "ehci_pci" "ahci" "virtio_pci" "virtio_scsi" "sd_mod" "sr_mod" ];
boot.initrd.kernelModules = [ ];
boot.kernelModules = [ ];
boot.extraModulePackages = [ ];
fileSystems."/" =
{ device = "/dev/disk/by-uuid/da85e220-e2b0-443a-9a0c-a9516b8e5030";
fsType = "ext4";
};
fileSystems."/boot" =
{ device = "/dev/disk/by-uuid/3F96-8974";
fsType = "vfat";
options = [ "fmask=0022" "dmask=0022" ];
};
swapDevices = [ ];
# Enables DHCP on each ethernet and wireless interface. In case of scripted networking
# (the default) this is the recommended approach. When using systemd-networkd it's
# still possible to use this option, but it's recommended to use it in conjunction
# with explicit per-interface declarations with `networking.interfaces.<interface>.useDHCP`.
networking.useDHCP = lib.mkDefault true;
# networking.interfaces.enp6s18.useDHCP = lib.mkDefault true;
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
}

View File

@@ -1,11 +0,0 @@
{ ... }:
{
# boot.kernelParams = [ "console=tty0" ];
proxmox.qemuConf.bios = "ovmf";
proxmox.qemuExtraConf = {
machine = "q35";
# efidisk0 = "local-lvm:vm-9999-disk-1";
cpu = "host";
};
}

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
}
}

42
users/cazzzer/default.nix Normal file
View File

@@ -0,0 +1,42 @@
{ config, lib, pkgs, ... }: {
users.groups.cazzzer.gid = 1000;
users.users.cazzzer = {
uid = 1000;
isNormalUser = true;
description = "Yura";
group = "cazzzer";
extraGroups = [ "wheel" ]
++ lib.optionals config.networking.networkmanager.enable [ "networkmanager" ]
++ lib.optionals config.virtualisation.docker.enable [ "docker" ]
++ lib.optionals config.programs.wireshark.enable [ "wireshark" ]
;
openssh.authorizedKeys.keys = [
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIE02AhJIZtrtZ+5sZhna39LUUCEojQzmz2BDWguT9ZHG yuri@tati.sh"
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHczlipzGWv8c6oYwt2/9ykes5ElfneywDXBTOYbfSfn Pixel7Pro"
];
# TODO: think of a better way to do this
packages = with pkgs; lib.optionals (config.networking.hostName == "Yura-PC") [
# Python
python3
poetry
# Haskell
haskellPackages.ghc
haskellPackages.stack
# Node
nodejs_22
pnpm
bun
# Nix
nil
nixd
nixfmt-rfc-style
# Gleam
gleam
beamMinimal26Packages.erlang
];
};
}