Compare commits

..

2 commits

Author SHA1 Message Date
Patrick b2256f2459
feat: more homeassistant 2025-01-07 21:23:06 +01:00
Patrick 0a11ac5c48
feat: avahi zeroconfig
fix: printer smb
2025-01-06 19:57:05 +01:00
12 changed files with 93 additions and 31 deletions

View file

@ -7,7 +7,12 @@
{ {
wireguard.services = { wireguard.services = {
client.via = "nucnix"; client.via = "nucnix";
firewallRuleForNode.nucnix-nginx.allowedTCPPorts = [ config.services.adguardhome.port ]; firewallRuleForNode.${globals.services.nginx.host}.allowedTCPPorts = [
config.services.adguardhome.port
];
firewallRuleForNode.${globals.services.homeassistant.host}.allowedTCPPorts = [
config.services.adguardhome.port
];
}; };
services.adguardhome = { services.adguardhome = {
enable = true; enable = true;

View file

@ -1,8 +1,8 @@
{ {
config, config,
globals,
nodes, nodes,
lib, lib,
pkgs,
... ...
}: }:
{ {
@ -25,9 +25,11 @@
"met" "met"
"esphome" "esphome"
"fritzbox" "fritzbox"
"homematic"
"soundtouch" "soundtouch"
"spotify" "spotify"
"matter" "matter"
"esphome"
#"zha" #"zha"
"mqtt" "mqtt"
]; ];
@ -76,22 +78,29 @@
python3Packages: with python3Packages; [ python3Packages: with python3Packages; [
psycopg2 psycopg2
gtts gtts
fritzconnection
adguardhome
]; ];
}; };
networking.hosts = {
"${nodes.${globals.services.adguardhome.host}.config.wireguard.services.ipv4}" = [
"adguardhome.internal"
];
};
age.secrets."home-assistant-secrets.yaml" = { age.secrets."home-assistant-secrets.yaml" = {
rekeyFile = "${config.node.secretsDir}/secrets.yaml.age"; rekeyFile = "${config.node.secretsDir}/secrets.yaml.age";
owner = "hass"; owner = "hass";
}; };
systemd.services.home-assistant = { systemd.services.home-assistant = {
# Update influxdb token
# We don't use -i because it would require chown with is a @privileged syscall
# INFLUXDB_TOKEN="$(cat ${config.age.secrets.hass-influxdb-token.path})" \
# ${lib.getExe pkgs.yq-go} '.influxdb_token = strenv(INFLUXDB_TOKEN)'
preStart = lib.mkBefore '' preStart = lib.mkBefore ''
if [[ -e ${config.services.home-assistant.configDir}/secrets.yaml ]]; then if [[ -e ${config.services.home-assistant.configDir}/secrets.yaml ]]; then
rm ${config.services.home-assistant.configDir}/secrets.yaml rm ${config.services.home-assistant.configDir}/secrets.yaml
fi fi
# Update influxdb token
# We don't use -i because it would require chown with is a @privileged syscall
# INFLUXDB_TOKEN="$(cat ${config.age.secrets.hass-influxdb-token.path})" \
# ${lib.getExe pkgs.yq-go} '.influxdb_token = strenv(INFLUXDB_TOKEN)'
cat ${ cat ${
config.age.secrets."home-assistant-secrets.yaml".path config.age.secrets."home-assistant-secrets.yaml".path
} > ${config.services.home-assistant.configDir}/secrets.yaml } > ${config.services.home-assistant.configDir}/secrets.yaml

View file

@ -116,6 +116,29 @@ in
enable = true; enable = true;
recommendedSetup = true; recommendedSetup = true;
virtualHosts."${globals.services.netbird.domain}".useACMEHost = "web"; virtualHosts."${globals.services.netbird.domain}".useACMEHost = "web";
upstreams.fritz = {
servers."${lib.net.cidr.host 1 "10.99.2.0/24"}" = { };
extraConfig = ''
zone fritz 64k ;
keepalive 5 ;
'';
};
virtualHosts.${globals.services.fritz.domain} = {
forceSSL = true;
useACMEHost = "web";
locations."/" = {
proxyPass = "https://fritz";
proxyWebsockets = true;
X-Frame-Options = "SAMEORIGIN";
};
extraConfig = ''
client_max_body_size 512M ;
proxy_ssl_verify off ;
allow ${globals.net.vlans.home.cidrv4} ;
allow ${globals.net.vlans.home.cidrv6} ;
deny all ;
'';
};
} }
(blockOf "vaultwarden" { maxBodySize = "1G"; }) (blockOf "vaultwarden" { maxBodySize = "1G"; })
(blockOf "forgejo" { maxBodySize = "1G"; }) (blockOf "forgejo" { maxBodySize = "1G"; })

View file

@ -8,6 +8,8 @@ let
shares = lib.removeAttrs config.services.samba.settings [ "global" ]; shares = lib.removeAttrs config.services.samba.settings [ "global" ];
in in
{ {
# allow direct access to shares
networking.nftables.firewall.zones.untrusted.interfaces = [ "mv-home" ];
services.samba-wsdd = { services.samba-wsdd = {
enable = true; # make shares visible for windows 10 clients enable = true; # make shares visible for windows 10 clients
openFirewall = true; openFirewall = true;
@ -119,7 +121,8 @@ in
# clients hardcode the host and share names. # clients hardcode the host and share names.
"disable netbios" = "yes"; "disable netbios" = "yes";
# Allow access to local network # Allow access to local network
"hosts allow" = "10.99.10. localhost"; # Also allow printer access
"hosts allow" = "10.99.10. ${lib.net.cidr.host 32 globals.net.vlans.devices.cidrv4} localhost";
"guest account" = "nobody"; "guest account" = "nobody";
"map to guest" = "bad user"; "map to guest" = "bad user";
@ -176,8 +179,6 @@ in
group = "printer"; group = "printer";
} }
{ {
# Also allow printer access
"hosts allow" = "10.99.10. ${lib.net.cidr.host 32 globals.net.vlans.home.cidrv4} localhost";
} }
) )
(mkShare { (mkShare {

View file

@ -16,8 +16,8 @@ lib.optionalAttrs (!minimal) {
text = '' text = ''
rm -r /var/lib/sbctl || true rm -r /var/lib/sbctl || true
mkdir -p /var/lib/sbctl mkdir -p /var/lib/sbctl
chmod 700 /var/lib/sbctl
${pkgs.gnutar}/bin/tar xf ${config.age.secrets.secureboot.path} -C /var/lib/sbctl || true ${pkgs.gnutar}/bin/tar xf ${config.age.secrets.secureboot.path} -C /var/lib/sbctl || true
chmod 700 /var/lib/sbctl
''; '';
deps = [ "agenix" ]; deps = [ "agenix" ];
}; };

View file

@ -38,6 +38,7 @@ in
id = 40; id = 40;
cidrv4 = "10.99.${toString id}.0/24"; cidrv4 = "10.99.${toString id}.0/24";
cidrv6 = "fd${toString id}::/64"; cidrv6 = "fd${toString id}::/64";
internet = false;
}; };
guests = rec { guests = rec {
id = 50; id = 50;
@ -72,6 +73,9 @@ in
domain = "ppl.${globals.domains.web}"; domain = "ppl.${globals.domains.web}";
host = "elisabeth-paperless"; host = "elisabeth-paperless";
}; };
fritz = {
domain = "fritz.${globals.domains.web}";
};
ttrss = { ttrss = {
domain = "rss.${globals.domains.web}"; domain = "rss.${globals.domains.web}";
host = "elisabeth-ttrss"; host = "elisabeth-ttrss";

View file

@ -53,9 +53,7 @@
../../config/services/${guestName}.nix ../../config/services/${guestName}.nix
{ {
node.secretsDir = config.node.secretsDir + "/${guestName}"; node.secretsDir = config.node.secretsDir + "/${guestName}";
networking.nftables.firewall.zones.untrusted.interfaces = lib.mkIf ( networking.nftables.firewall.zones.untrusted.interfaces = [ "mv-services" ];
lib.length config.guests.${guestName}.networking.links == 1
) config.guests.${guestName}.networking.links;
systemd.network.networks = lib.mkIf (globals.services.${guestName}.ip != null) ( systemd.network.networks = lib.mkIf (globals.services.${guestName}.ip != null) (
lib.listToAttrs ( lib.listToAttrs (
lib.flip map vlans ( lib.flip map vlans (
@ -67,7 +65,7 @@
(lib.net.cidr.hostCidr globals.services.${guestName}.ip globals.net.vlans.${name}.cidrv4) (lib.net.cidr.hostCidr globals.services.${guestName}.ip globals.net.vlans.${name}.cidrv4)
(lib.net.cidr.hostCidr globals.services.${guestName}.ip globals.net.vlans.${name}.cidrv6) (lib.net.cidr.hostCidr globals.services.${guestName}.ip globals.net.vlans.${name}.cidrv6)
]; ];
gateway = [ gateway = lib.optionals globals.net.vlans.${name}.internet [
(lib.net.cidr.host 1 globals.net.vlans.${name}.cidrv4) (lib.net.cidr.host 1 globals.net.vlans.${name}.cidrv4)
(lib.net.cidr.host 1 globals.net.vlans.${name}.cidrv6) (lib.net.cidr.host 1 globals.net.vlans.${name}.cidrv6)
]; ];
@ -127,7 +125,13 @@
// mkContainer "netbird" { } // mkContainer "netbird" { }
// mkContainer "blog" { } // mkContainer "blog" { }
// mkContainer "kanidm" { } // mkContainer "kanidm" { }
// mkContainer "homeassistant" { } // mkContainer "homeassistant" {
vlans = [
"services"
"devices"
"iot"
];
}
// mkContainer "nextcloud" { enablePanzer = true; } // mkContainer "nextcloud" { enablePanzer = true; }
// mkContainer "paperless" { enableSharedPaperless = true; } // mkContainer "paperless" { enableSharedPaperless = true; }
// mkContainer "forgejo" { enablePanzer = true; } // mkContainer "forgejo" { enablePanzer = true; }
@ -137,6 +141,8 @@
enableRenaultFT = true; enableRenaultFT = true;
enableBunker = true; enableBunker = true;
enableSharedPaperless = true; enableSharedPaperless = true;
vlans = [ "home" ]; vlans = [
"home"
];
}; };
} }

View file

@ -0,0 +1 @@
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPs0YXOrMxHFly+lpB0NtZWuuz1JwRKU2ZCOe4Xhz1T5

View file

@ -38,9 +38,7 @@ in
../../config/services/${guestName}.nix ../../config/services/${guestName}.nix
{ {
node.secretsDir = config.node.secretsDir + "/${guestName}"; node.secretsDir = config.node.secretsDir + "/${guestName}";
networking.nftables.firewall.zones.untrusted.interfaces = lib.mkIf ( networking.nftables.firewall.zones.untrusted.interfaces = [ "mv-services" ];
lib.length config.guests.${guestName}.networking.links == 1
) config.guests.${guestName}.networking.links;
systemd.network.networks = lib.mkIf (globals.services.${guestName}.ip != null) ( systemd.network.networks = lib.mkIf (globals.services.${guestName}.ip != null) (
lib.listToAttrs ( lib.listToAttrs (
lib.flip map vlans ( lib.flip map vlans (
@ -52,7 +50,7 @@ in
(lib.net.cidr.hostCidr globals.services.${guestName}.ip globals.net.vlans.${name}.cidrv4) (lib.net.cidr.hostCidr globals.services.${guestName}.ip globals.net.vlans.${name}.cidrv4)
(lib.net.cidr.hostCidr globals.services.${guestName}.ip globals.net.vlans.${name}.cidrv6) (lib.net.cidr.hostCidr globals.services.${guestName}.ip globals.net.vlans.${name}.cidrv6)
]; ];
gateway = [ gateway = lib.optionals globals.net.vlans.${name}.internet [
(lib.net.cidr.host 1 globals.net.vlans.${name}.cidrv4) (lib.net.cidr.host 1 globals.net.vlans.${name}.cidrv4)
(lib.net.cidr.host 1 globals.net.vlans.${name}.cidrv6) (lib.net.cidr.host 1 globals.net.vlans.${name}.cidrv6)
]; ];

View file

@ -35,7 +35,12 @@ in
}; };
subnet4 = flip mapAttrsToList globals.net.vlans ( subnet4 = flip mapAttrsToList globals.net.vlans (
name: name:
{ id, cidrv4, ... }: {
id,
cidrv4,
internet,
...
}:
rec { rec {
inherit id; inherit id;
interface = "lan-${name}"; interface = "lan-${name}";
@ -45,16 +50,17 @@ in
pool = "${net.cidr.host 50 subnet} - ${net.cidr.host (-6) subnet}"; pool = "${net.cidr.host 50 subnet} - ${net.cidr.host (-6) subnet}";
} }
]; ];
option-data = [ option-data =
{ [
{
name = "domain-name-servers";
data = "${net.cidr.host globals.services.adguardhome.ip globals.net.vlans.services.cidrv4}";
}
]
++ lib.optional internet {
name = "routers"; name = "routers";
data = "${net.cidr.host 1 subnet}"; data = "${net.cidr.host 1 subnet}";
} };
{
name = "domain-name-servers";
data = "${net.cidr.host globals.services.adguardhome.ip globals.net.vlans.services.cidrv4}";
}
];
reservations = [ reservations = [
{ {
# homematic # homematic

View file

@ -29,6 +29,9 @@ in
printer.ipv4Addresses = [ printer.ipv4Addresses = [
(lib.net.cidr.host 32 globals.net.vlans.devices.cidrv4) (lib.net.cidr.host 32 globals.net.vlans.devices.cidrv4)
]; ];
smb.ipv4Addresses = [
(lib.net.cidr.host globals.services.samba.ip globals.net.vlans.home.cidrv4)
];
adguard.ipv4Addresses = [ adguard.ipv4Addresses = [
(lib.net.cidr.host globals.services.adguardhome.ip globals.net.vlans.services.cidrv4) (lib.net.cidr.host globals.services.adguardhome.ip globals.net.vlans.services.cidrv4)
]; ];
@ -170,7 +173,7 @@ in
"printer" "printer"
]; ];
to = [ "smb" ]; to = [ "smb" ];
allowedUDPPorts = [ 445 ]; allowedTCPPorts = [ 445 ];
}; };
ssh = { ssh = {
from = [ from = [

View file

@ -109,6 +109,11 @@ in
default = null; default = null;
description = "The CIDRv6 of this vlan"; description = "The CIDRv6 of this vlan";
}; };
internet = mkOption {
type = types.bool;
default = true;
description = "Whether this vlan is connected to the internet";
};
name = mkOption { name = mkOption {
description = "The name of this VLAN"; description = "The name of this VLAN";
@ -130,7 +135,8 @@ in
default = null; default = null;
}; };
host = mkOption { host = mkOption {
type = types.str; type = types.nullOr types.str;
default = null;
description = "The node-name on which this service runs"; description = "The node-name on which this service runs";
}; };
ip = mkOption { ip = mkOption {