many changes

This commit is contained in:
2024-02-16 22:24:54 +01:00
parent b4bf0ee486
commit 5ebcd0818b
22 changed files with 532 additions and 338 deletions

View File

@@ -22,6 +22,7 @@
./modules/wireguard.nix
./modules/podman.nix
./modules/omada.nix
./modules/ddclient.nix
# git
./modules/gitea.nix
@@ -38,6 +39,10 @@
./modules/snapserver.nix
# ./modules/deconz
# gaming
./modules/palworld.nix
./hardware-configuration.nix
];

View File

@@ -3,7 +3,7 @@
boot.loader.systemd-boot.enable = true;
boot.initrd.availableKernelModules = [ "ata_piix" "uhci_hcd" "vmw_pvscsi" "xen_blkfront" ];
boot.initrd.kernelModules = [ "nvme" ];
boot.initrd.kernelModules = [ "nvme" "kvm-intel" ];
fileSystems."/boot" = {
device = "/dev/disk/by-label/boot";

View File

@@ -3,8 +3,8 @@
enable = true;
reflector = true;
allowInterfaces = [
"server"
"lan"
"multimedia"
];
};
}

View File

@@ -0,0 +1,21 @@
{ config, ... }:
{
services.ddclient = {
enable = true;
use = "if, if=wan";
protocol = "hetzner";
# server = "https://dns.hetzner.com/api/v1/";
username = "dominik.polakovics@cloonar.com";
passwordFile = config.sops.secrets.ddclient.path;
zone = "cloonar.com";
domains = [
"vpn.cloonar.com"
"git.cloonar.com"
"palworld.cloonar.com"
];
};
sops.secrets.ddclient = {
# owner = config.systemd.services.ddclient.serviceConfig.User;
};
}

View File

@@ -1,13 +1,4 @@
{ config, pkgs, ... }: {
users.users.deconz = {
isSystemUser = true;
group = "omada";
home = "/var/lib/deconz";
createHome = true;
};
users.groups.omada = { };
# TODO: check if we can run docker service as other user than root
virtualisation = {
oci-containers.containers = {
deconz = {
@@ -23,7 +14,7 @@
};
extraOptions = [
"--network=server"
"--mac-address=1a:c4:04:6e:29:02"
"--ip=10.42.97.22"
"--device=/dev/ttyACM0"
"--hostname=deconz"
];

View File

@@ -44,7 +44,7 @@
}
{
name = "domain-name-servers";
data = "10.42.97.10";
data = "10.42.96.1";
}
];
reservations = [
@@ -84,7 +84,7 @@
}
{
name = "domain-name-servers";
data = "10.42.97.10";
data = "10.42.97.1";
}
];
reservations = [
@@ -129,7 +129,7 @@
}
{
name = "domain-name-servers";
data = "10.42.97.10";
data = "10.42.101.1";
}
];
reservations = [
@@ -164,7 +164,7 @@
}
{
name = "domain-name-servers";
data = "10.42.97.10";
data = "10.42.99.1";
}
];
}
@@ -206,7 +206,7 @@
}
{
name = "domain-name-servers";
data = "10.42.97.10";
data = "10.42.100.1";
}
];
reservations = [

View File

@@ -1,7 +1,8 @@
{ ... }: {
{ pkgs, ... }: {
networking = {
firewall.checkReversePath = false;
nat.enable = false;
nftables = {
# nftables = {
# enable = true;
# tables = {
# "cloonar-fw" = {
@@ -102,7 +103,7 @@
# ''
# };
# };
};
# };
nftables = {
enable = true;
ruleset = ''
@@ -117,18 +118,38 @@
type filter hook output priority 100; policy accept;
}
chain rpfilter {
type filter hook prerouting priority mangle + 10; policy drop;
meta nfproto ipv4 udp sport . udp dport { 68 . 67, 67 . 68 } accept comment "DHCPv4 client/server"
fib saddr . mark . iif oif exists accept
}
chain input {
type filter hook input priority filter; policy drop;
iifname "lo" accept comment "trusted interfaces"
ct state vmap { invalid : drop, established : accept, related : accept, new : jump input-allow, untracked : jump input-allow }
tcp flags syn / fin,syn,rst,ack log prefix "refused connection: " level info
}
chain input-allow {
iifname "wan" udp dport 51820 counter accept comment "Wireguard traffic"
iifname "wg_cloonar" counter accept comment "test wireguard"
# drop new connections over rate limit
udp dport != { 53, 5353 } ct state new limit rate over 1/second burst 10 packets drop
# accept any localhost traffic
iifname lo accept
# Allow trusted networks to access the router
iifname {
"wg_cloonar"
} counter accept
iifname {
"server",
"vserver",
"lan",
"wg_cloonar"
} counter accept
# Allow networks to access dhcp
@@ -137,29 +158,43 @@
"server",
"vserver",
"infrastructure",
"wg_cloonar",
"smart",
"podman*",
"multimedia"
} udp dport { 67, 68 } counter accept
# Allow networks to access dns
iifname {
"lan",
"server",
"vserver",
"infrastructure",
"smart",
"podman*",
"multimedia"
} udp dport { 53 } counter accept
# allow audio system to access snapserver
iifname {
"server"
} tcp dport { 1704 } counter accept
"server",
"smart",
"multimedia"
} tcp dport { 1704, 1705 } counter accept
# allow airplay access
iifname "lan" tcp dport { 5000, 5353 } counter accept
iifname "lan" udp dport { 5000, 5353, 6001 - 6011 } counter accept
# Accept mDNS for avahi reflection
# iifname "multimedia" ip saddr <chromecast IP> tcp dport { llmnr } counter accept
# iifname "multimedia" ip saddr <chromecast IP> udp dport { mdns, llmnr } counter accept
iifname "server" ip saddr 10.42.97.20/32 tcp dport { llmnr } counter accept
iifname "server" ip saddr 10.42.97.20/32 udp dport { mdns, llmnr } counter accept
# accept palword server
iifname { "wan", "lan" } udp dport { 8211, 27015 } counter accept
# Allow all returning traffic
ct state { established, related } counter accept
# Allow returning traffic from wg_cloonar and drop everthing else
iifname "wg_cloonar" ct state { established, related } counter accept
iifname "wg_cloonar" drop
# Allow returning traffic from wrwks and drop everthing else
iifname "wrwks" ct state { established, related } counter accept
iifname "wrwks" drop
@@ -176,29 +211,42 @@
iifname "wan" ct state { established, related } accept comment "Allow established traffic"
iifname "wan" icmp type { echo-request, destination-unreachable, time-exceeded } counter accept comment "Allow select ICMP"
iifname "wan" counter drop comment "Drop all other unsolicited traffic from wan"
limit rate 60/minute burst 100 packets log prefix "Input - Drop: " comment "Log any unmatched traffic"
}
chain forward {
type filter hook forward priority filter; policy drop;
iifname "wg_cloonar" counter accept comment "test wireguard"
iifname "wg_cloonar" oifname lo counter accept comment "wireguard to server"
# enable flow offloading for better throughput
# ip protocol { tcp, udp } flow offload @f
# multimedia airplay
iifname "multimedia" oifname { "lan" } counter accept
iifname "multimedia" oifname "server" tcp dport { 1704, 1705 } counter accept
iifname "lan" oifname "server" udp dport { 5000, 5353, 6001 - 6011 } counter accept
# avahi
iifname "server" ip saddr 10.42.97.20/32 oifname { "lan" } counter accept
# smart home coap
iifname "smart" oifname "server" ip daddr 10.42.97.20/32 udp dport { 5683 } counter accept
# Forward to git server
oifname "server" ip daddr 10.42.97.50 tcp dport { 22, 80, 443 } counter accept
# Forward to dns server
oifname "server" ip daddr 10.42.97.10 udp dport { 53 } accept
# lan and vpn to any
# TODO: disable wan when finished
iifname { "lan", "server", "vserver", "wg_cloonar" } oifname { "lan", "vb-*", "server", "vserver", "infrastructure", "multimedia", "smart", "wg_cloonar" } counter accept
iifname { "lan", "server", "wg_cloonar" } oifname { "wrwks", "wg_epicenter", "wg_ghetto_at" } counter accept
iifname { "infrastructure" } oifname { "server", "vserver" } counter accept
# accept palword server
iifname { "wan", "lan" } oifname "podman0" udp dport { 8211, 27015 } counter accept
# allow all established, related
ct state { established, related } accept comment "Allow established traffic"
@@ -213,9 +261,13 @@
"wg_cloonar",
"podman*",
"guest",
"vb-*",
"ve-*",
} oifname {
"wan",
} counter accept comment "Allow trusted LAN to WAN"
limit rate 60/minute burst 100 packets log prefix "Forward - Drop: " comment "Log any unmatched traffic"
}
}
@@ -228,11 +280,35 @@
# Setup NAT masquerading on external interfaces
chain postrouting {
type nat hook postrouting priority filter; policy accept;
oifname { "wan", "wrwks", "wg_epicenter", "wg_ghetto_at" } masquerade
oifname { "wan", "wg_cloonar", "wrwks", "wg_epicenter", "wg_ghetto_at" } masquerade
ip daddr 10.42.97.50 masquerade
}
}
'';
};
};
systemd.services.nftables-fix = {
description = "Delete nixos-fw table";
after = [ "nftables.service" ];
serviceConfig = let
fixScript = pkgs.writeTextFile {
name = "nftables-fix";
executable = true;
text = ''
#! ${pkgs.nftables}/bin/nft -f
delete table inet nixos-fw
'';
};
in {
Name = "nftables-fix";
PartOf = "nftables.service";
Type = "oneshot";
ExecStart= [ fixScript ];
StateDirectory = "nftables";
};
};
}

View File

@@ -1,4 +1,4 @@
{ config, ... }:
{ config, pkgs, ... }:
let
cids = import ../modules/staticids.nix;
domain = "git.cloonar.com";
@@ -25,7 +25,10 @@ in
containers.git = {
autoStart = true;
ephemeral = false; # because of ssh key
macvlans = [ "vserver" ];
privateNetwork = true;
hostBridge = "server";
hostAddress = "10.42.97.1";
localAddress = "10.42.97.50/24";
bindMounts = {
"/var/lib/gitea" = {
hostPath = "/var/lib/gitea/";
@@ -41,16 +44,19 @@ in
../fleet.nix
];
environment.systemPackages = with pkgs; [
vim # my preferred editor
];
networking = {
hostName = "git";
nameservers = [ "10.42.97.10" ];
interfaces.mv-vserver = {
useDHCP = true;
};
firewall = {
enable = true;
allowedTCPPorts = [ 22 80 443 ];
useHostResolvConf = false;
defaultGateway = {
address = "10.42.96.1";
interface = "eth0";
};
firewall.enable = false;
nameservers = [ "10.42.97.1" ];
};
services.nginx.enable = true;

View File

@@ -1,6 +1,7 @@
{
services.home-assistant.extraComponents = [
"daikin"
"enocean"
];
services.home-assistant.config = {

View File

@@ -28,7 +28,10 @@ in
containers.hass = {
autoStart = true;
ephemeral = false;
macvlans = [ "vserver" ];
privateNetwork = true;
hostBridge = "server";
hostAddress = "10.42.97.1";
localAddress = "10.42.97.20/24";
allowedDevices = [
{
modifier = "rwm";
@@ -82,15 +85,13 @@ in
networking = {
hostName = "home-assistant";
nameservers = [ "10.42.97.10" ];
interfaces.mv-vserver = {
useDHCP = true;
};
firewall = {
enable = true;
allowedTCPPorts = [ 80 443 ];
allowedUDPPorts = [ 5683 ];
useHostResolvConf = false;
defaultGateway = {
address = "10.42.96.1";
interface = "eth0";
};
firewall.enable = false;
nameservers = [ "10.42.97.1" ];
};
services.nginx.enable = true;
@@ -145,6 +146,14 @@ in
time_zone = "Europe/Vienna";
external_url = "https://${domain}";
};
zone = {
name = "Home";
latitude = "!secret home_latitude";
longitude = "!secret home_longitude";
radius = 35;
icon = "mdi:account-multiple";
};
automation = "!include automations.yaml";
frontend = { };
http = {

View File

@@ -23,7 +23,7 @@
networking = {
useDHCP = false;
# Define VLANS
nameservers = [ "10.42.97.10" ];
nameservers = [ "10.42.97.1" ];
# resolvconf.enable = false;
vlans = {
infrastructure = {
@@ -47,9 +47,14 @@
interface = "enp5s0";
};
};
macvlans.server = {
interface = "vserver";
mode = "bridge";
# macvlans.server = {
# interface = "vserver";
# mode = "bridge";
# };
bridges = {
server = {
interfaces = [ "vserver" ];
};
};
interfaces = {

View File

@@ -0,0 +1,25 @@
{ config, pkgs, ... }:
{
virtualisation.oci-containers.backend = "podman";
virtualisation.oci-containers.containers = {
palworld = {
image = "thijsvanloef/palworld-server-docker:v0.24.2";
autoStart = true;
ports = [
"8211:8211/udp"
"27015:27015/udp"
];
environmentFiles = [
config.sops.secrets.palworld.path
];
volumes = [
"/var/lib/palworld/:/palworld/"
];
};
};
sops.secrets.palworld = {
# owner = config.systemd.services.ddclient.serviceConfig.User;
};
}

View File

@@ -6,13 +6,13 @@ in {
users.groups.podman.gid = cids.gids.podman;
virtualisation = {
containers.containersConf.settings = {
containers.dns_servers = [ "10.42.97.10" ];
containers.dns_servers = [ "10.42.97.1" ];
};
podman = {
enable = true;
dockerCompat = true;
defaultNetwork.settings = {
dns_enabled = false; # Enable DNS resolution in the podman network.
dns_enabled = true; # Enable DNS resolution in the podman network.
};
};
};
@@ -21,37 +21,43 @@ in {
source = json.generate "server.json" ({
name = "server";
id = "d3a55d6bcc28571c124b4e65cdf1831339045d296858f79e7130fa70da9c0904";
driver = "macvlan";
driver = "bridge";
network_interface = "server";
ipv6_enabled = false;
internal = false;
dns_enabled = false;
subnets = [
{
subnet = "10.42.97.0/24";
gateway = "10.42.97.1";
}
];
ipam_options = {
driver = "dhcp";
driver = "host-local";
};
});
};
systemd.sockets."netavark-dhcp-proxy" = {
description = "Netavark DHCP proxy socket";
socketConfig = {
ListenStream = "%t/podman/nv-proxy.sock";
SocketMode = 0660;
};
wantedBy = [ "sockets.target" ];
};
systemd.services."netavark-dhcp-proxy" = {
description = "Netavark DHCP proxy service";
after = [ "netavark-dhcp-proxy.socket" ];
requires = [ "netavark-dhcp-proxy.socket" ];
wantedBy = [ "multi-user.target" "netavark-dhcp-proxy.socket" ];
path = [ pkgs.netavark ];
startLimitIntervalSec = 0;
serviceConfig = {
Type = "exec";
ExecStart= "${pkgs.netavark}/bin/netavark dhcp-proxy -a 30";
};
};
#
# systemd.sockets."netavark-dhcp-proxy" = {
# description = "Netavark DHCP proxy socket";
# socketConfig = {
# ListenStream = "%t/podman/nv-proxy.sock";
# SocketMode = 0660;
# };
# wantedBy = [ "sockets.target" ];
# };
#
# systemd.services."netavark-dhcp-proxy" = {
# description = "Netavark DHCP proxy service";
# after = [ "netavark-dhcp-proxy.socket" ];
# requires = [ "netavark-dhcp-proxy.socket" ];
# wantedBy = [ "multi-user.target" "netavark-dhcp-proxy.socket" ];
# path = [ pkgs.netavark ];
# startLimitIntervalSec = 0;
#
# serviceConfig = {
# Type = "exec";
# ExecStart= "${pkgs.netavark}/bin/netavark dhcp-proxy -a 30";
# };
# };
}

View File

@@ -1,128 +1,115 @@
{ pkgs, config, python3Packages, ... }:
let
shairport-sync = pkgs.shairport-sync.overrideAttrs (_: {
configureFlags = [
"--with-alsa" "--with-pipe" "--with-pa" "--with-stdout"
"--with-avahi" "--with-ssl=openssl" "--with-soxr"
# "--with-mqtt-client"
"--without-configfiles"
"--sysconfdir=/etc"
"--with-metadata"
];
# buildInputs = [
# pkgs.openssl
# pkgs.avahi
# pkgs.popt
# pkgs.libconfig
# pkgs.mosquitto
# pkgs.alsa-lib
# pkgs.libpulseaudio
# pkgs.pipewire
# pkgs.libjack2
# pkgs.soxr
# ];
});
domain = "snapcast.cloonar.com";
in
{
environment.etc = {
# Creates /etc/nanorc
shairport = {
text = ''
whatever you want to put in the file goes here.
metadata =
{
enabled = "yes"; // set this to yes to get Shairport Sync to solicit metadata from the source and to pass it on via a pipe
include_cover_art = "yes"; // set to "yes" to get Shairport Sync to solicit cover art from the source and pass it via the pipe. You must also set "enabled" to "yes".
cover_art_cache_directory = "/tmp/shairport-sync/.cache/coverart"; // artwork will be stored in this directory if the dbus or MPRIS interfaces are enabled or if the MQTT client is in use. Set it to "" to prevent caching, which may be useful on some systems
pipe_name = "/tmp/shairport-sync-metadata";
pipe_timeout = 5000; // wait for this number of milliseconds for a blocked pipe to unblock before giving up
};
mqtt =
{
enabled = "yes"; // set this to yes to enable the mqtt-metadata-service
hostname = "127.0.0.1"; // Hostname of the MQTT Broker
port = 1883; // Port on the MQTT Broker to connect to
username = "espresense"; //set this to a string to your username in order to enable username authentication
password = "insecure-password"; //set this to a string you your password in order to enable username & password authentication
topic = "shairport"; //MQTT topic where this instance of shairport-sync should publish. If not set, the general.name value is used.
// publish_raw = "no"; //whether to publish all available metadata under the codes given in the 'metadata' docs.
publish_parsed = "yes"; //whether to publish a small (but useful) subset of metadata under human-understandable topics
publish_cover = "yes"; //whether to publish the cover over mqtt in binary form. This may lead to a bit of load on the broker
// enable_remote = "no"; //whether to remote control via MQTT. RC is available under `topic`/remote.
};
'';
# The UNIX file mode bits
mode = "0440";
};
security.acme.certs."${domain}" = {
group = "nginx";
};
services.snapserver = {
enable = true;
codec = "flac";
http.docRoot = "${pkgs.snapcast}/share/snapserver/snapweb";
streams.mopidy = {
type = "pipe";
location = "/run/snapserver/mopidy";
};
streams.airplay = {
type = "airplay";
location = "${shairport-sync}/bin/shairport-sync";
query = {
devicename = "Multi Room";
port = "5000";
params = "--mdns=avahi";
containers.snapcast = {
autoStart = true;
ephemeral = false; # because of ssh key
privateNetwork = true;
hostBridge = "server";
hostAddress = "10.42.97.1";
localAddress = "10.42.97.21/24";
bindMounts = {
"/var/lib/acme/snapcast/" = {
hostPath = "${config.security.acme.certs.${domain}.directory}";
isReadOnly = true;
};
};
streams.mixed = {
type = "meta";
location = "/airplay/mopidy";
config = { lib, config, pkgs, python3Packages, ... }:
let
shairport-sync = pkgs.shairport-sync.overrideAttrs (_: {
configureFlags = [
"--with-alsa" "--with-pipe" "--with-pa" "--with-stdout"
"--with-avahi" "--with-ssl=openssl" "--with-soxr"
"--without-configfiles"
"--sysconfdir=/etc"
"--with-metadata"
];
});
in
{
networking = {
hostName = "snapcast";
useHostResolvConf = false;
defaultGateway = {
address = "10.42.96.1";
interface = "eth0";
};
nameservers = [ "10.42.97.1" ];
firewall.enable = false;
};
environment.etc = {
# Creates /etc/nanorc
shairport = {
text = ''
whatever you want to put in the file goes here.
metadata =
{
enabled = "yes"; // set this to yes to get Shairport Sync to solicit metadata from the source and to pass it on via a pipe
include_cover_art = "yes"; // set to "yes" to get Shairport Sync to solicit cover art from the source and pass it via the pipe. You must also set "enabled" to "yes".
cover_art_cache_directory = "/tmp/shairport-sync/.cache/coverart"; // artwork will be stored in this directory if the dbus or MPRIS interfaces are enabled or if the MQTT client is in use. Set it to "" to prevent caching, which may be useful on some systems
pipe_name = "/tmp/shairport-sync-metadata";
pipe_timeout = 5000; // wait for this number of milliseconds for a blocked pipe to unblock before giving up
};
'';
# The UNIX file mode bits
mode = "0440";
};
};
services.snapserver = {
enable = true;
codec = "flac";
http.docRoot = "${pkgs.snapcast}/share/snapserver/snapweb";
streams.mopidy = {
type = "pipe";
location = "/run/snapserver/mopidy";
};
streams.airplay = {
type = "airplay";
location = "${shairport-sync}/bin/shairport-sync";
query = {
devicename = "Multi Room New";
port = "5000";
params = "--mdns=avahi";
};
};
streams.mixed = {
type = "meta";
location = "/airplay/mopidy";
};
};
services.avahi.enable = true;
services.avahi.publish.enable = true;
services.avahi.publish.userServices = true;
services.nginx.virtualHosts."snapcast.cloonar.com" = {
sslCertificate = "/var/lib/acme/snapcast/fullchain.pem";
sslCertificateKey = "/var/lib/acme/snapcast/key.pem";
sslTrustedCertificate = "/var/lib/acme/snapcast/chain.pem";
forceSSL = true;
extraConfig = ''
proxy_buffering off;
'';
locations."/".extraConfig = ''
proxy_pass http://127.0.0.1:1780;
proxy_set_header Host $host;
proxy_redirect http:// https://;
proxy_http_version 1.1;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
'';
};
system.stateVersion = "23.05";
};
};
services.avahi.enable = true;
services.avahi.publish.enable = true;
services.avahi.publish.userServices = true;
# services.shairport-sync = {
# enable = true;
# arguments = "-v -o=pipe -- pipe:name=/run/snapserver/airplay";
# };
services.nginx.virtualHosts."snapcast.cloonar.com" = {
forceSSL = true;
enableACME = true;
acmeRoot = null;
extraConfig = ''
proxy_buffering off;
'';
locations."/".extraConfig = ''
proxy_pass http://127.0.0.1:1780;
proxy_set_header Host $host;
proxy_redirect http:// https://;
proxy_http_version 1.1;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
'';
};
# networking.firewall.allowedTCPPorts = [
# 80 # http
# 443 # https
# 1704 # snapcast
# 1705 # snapcast
# 5000 # airplay
# 5353 # airplay
# ];
# networking.firewall.allowedUDPPorts = [
# 5000 # airplay
# 5353 # airplay
# ];
# networking.firewall.allowedUDPPortRanges = [
# { from = 6001; to = 6011; } # airplay
# ];
}

View File

@@ -19,7 +19,7 @@ let
"10.42.101.0/24 allow"
"0.0.0.0/0 allow"
];
tls-cert-bundle = "/var/lib/acme/unbound/fullchain.pem";
tls-cert-bundle = "/var/lib/acme/ns.cloonar.com/fullchain.pem";
local-zone = "\"cloonar.com\" transparent";
local-data = [
"\"localhost A 127.0.0.1\""
@@ -31,9 +31,11 @@ let
"\"omada.cloonar.com IN A 10.42.97.2\""
"\"switch.cloonar.com IN A 10.42.97.10\""
"\"mopidy.cloonar.com IN A 10.42.97.20\""
"\"deconz.cloonar.com IN A 10.42.97.25\""
"\"snapcast.cloonar.com IN A 10.42.97.20\""
"\"mopidy.cloonar.com IN A 10.42.97.21\""
"\"deconz.cloonar.com IN A 10.42.97.22\""
"\"snapcast.cloonar.com IN A 10.42.97.21\""
"\"home-assistant.cloonar.com IN A 10.42.97.20\""
"\"git.cloonar.com IN A 10.42.97.50\""
"\"stage.wsw.at IN A 10.254.235.22\""
"\"prod.wsw.at IN A 10.254.217.23\""
@@ -88,7 +90,10 @@ let
"\"127.0.0.1 localhost\""
"\"::1 localhost\""
"\"10.42.97.1 fw.cloonar.com\""
"\"10.42.97.25 deconz.cloonar.com\""
"\"10.42.97.20 home-assistant.cloonar.com\""
"\"10.42.97.21 snapcast.cloonar.com\""
"\"10.42.97.22 deconz.cloonar.com\""
"\"10.42.97.50 git.cloonar.com\""
"\"10.254.235.22 stage.wsw.at\""
"\"10.254.217.23 prod.wsw.at\""
@@ -154,105 +159,65 @@ in {
security.acme.certs."${domain}" = {
group = "unbound";
};
security.acme.certs."fw.cloonar.com" = {
group = "unbound";
};
containers.ns = {
autoStart = true;
ephemeral = true;
macvlans = [ "vserver" ];
bindMounts = {
"/var/lib/acme/unbound/" = {
hostPath = "${config.security.acme.certs.${domain}.directory}";
isReadOnly = true;
};
"/var/lib/kea" = {
hostPath = "/var/lib/kea";
isReadOnly = true;
};
};
config = { lib, config, pkgs, ... }: {
networking = {
hostName = "ns";
defaultGateway = {
address = "10.42.97.1";
interface = "mv-vserver";
};
interfaces.mv-vserver = {
ipv4.addresses = [{
address = "10.42.97.10";
prefixLength = 24;
}];
};
firewall = {
enable = true;
allowedUDPPorts = [ 53 ];
allowedTCPPorts = [ 853 ];
};
};
users.users.unbound = {
group = "unbound";
isSystemUser = true;
uid = cids.uids.unbound;
};
users.groups.unbound = {
gid = cids.gids.unbound;
};
services.unbound = {
enable = true;
settings = cfg;
};
systemd.services.unbound-sync = {
enable = true;
path = with pkgs; [ unbound inotify-tools ];
script = ''
function readFile() {
if [[ "''\$2" == "A" ]] ; then
cat "''\$1" | tail -n +2 | while IFS=, read -r address hwaddr client_id valid_lifetime expire subnet_id fqdn_fwd fqdn_rev hostname state user_context
do
echo "''\${address},''\${hostname}"
done
else
cat "''\$1" | tail -n +2 | while IFS=, read -r address duid valid_lifetime expire subnet_id pref_lifetime lease_type iaid prefix_len fqdn_fwd fqdn_rev hostname hwaddr state user_context hwtype hwaddr_source
do
echo "''\${address},''\${hostname}"
done
fi
}
function readFileUnique() {
readFile "''\$1" ''\$2 | uniq | while IFS=, read -r address hostname
do
if [[ "''\${hostname}" == *.cloonar.com ]] ; then
echo ''\${hostname} ''\$2 ''\${address}
unbound-control local_data ''\${hostname} ''\$2 ''\${address}
if [[ "''\$2" == "A" ]] ; then
echo ''\${address} | while IFS=. read -r ip0 ip1 ip2 ip3
do
unbound-control local_data ''\${ip3}.''\${ip2}.''\${ip1}.''\${ip0}.ip4.arpa. PTR ''\${hostname}
unbound-control local_data ''\${ip3}.''\${ip2}.''\${ip1}.''\${ip0}.in-addr.arpa. PTR ''\${hostname}
done
fi
fi
done
}
services.unbound = {
enable = true;
settings = cfg;
};
systemd.services.unbound-sync = {
enable = true;
path = with pkgs; [ unbound inotify-tools ];
script = ''
function readFile() {
if [[ "''\$2" == "A" ]] ; then
cat "''\$1" | tail -n +2 | while IFS=, read -r address hwaddr client_id valid_lifetime expire subnet_id fqdn_fwd fqdn_rev hostname state user_context
do
echo "''\${address},''\${hostname}"
done
else
cat "''\$1" | tail -n +2 | while IFS=, read -r address duid valid_lifetime expire subnet_id pref_lifetime lease_type iaid prefix_len fqdn_fwd fqdn_rev hostname hwaddr state user_context hwtype hwaddr_source
do
echo "''\${address},''\${hostname}"
done
fi
}
function syncFile() {
# readFileUnique "''\$1" "''\$2"
while true; do
readFileUnique "''\$1" "''\$2"
sleep 10
done
}
function readFileUnique() {
readFile "''\$1" ''\$2 | uniq | while IFS=, read -r address hostname
do
if [[ "''\${hostname}" == *.cloonar.com ]] ; then
echo ''\${hostname} ''\$2 ''\${address}
unbound-control local_data ''\${hostname} ''\$2 ''\${address}
if [[ "''\$2" == "A" ]] ; then
echo ''\${address} | while IFS=. read -r ip0 ip1 ip2 ip3
do
unbound-control local_data ''\${ip3}.''\${ip2}.''\${ip1}.''\${ip0}.ip4.arpa. PTR ''\${hostname}
unbound-control local_data ''\${ip3}.''\${ip2}.''\${ip1}.''\${ip0}.in-addr.arpa. PTR ''\${hostname}
done
fi
fi
done
}
function syncFile() {
# readFileUnique "''\$1" "''\$2"
while true; do
readFileUnique "''\$1" "''\$2"
sleep 10
done
}
syncFile "/var/lib/kea/dhcp4.leases" A &
# syncFile "/var/lib/kea/dhcp6.leases" AAAA &
wait
'';
wants = [ "network-online.target" "unbound.service" ];
after = [ "network-online.target" "unbound.service" ];
partOf = [ "unbound.service" ];
wantedBy = [ "multi-user.target" ];
};
system.stateVersion = "23.05";
};
syncFile "/var/lib/kea/dhcp4.leases" A &
# syncFile "/var/lib/kea/dhcp6.leases" AAAA &
wait
'';
wants = [ "network-online.target" "unbound.service" ];
after = [ "network-online.target" "unbound.service" ];
partOf = [ "unbound.service" ];
wantedBy = [ "multi-user.target" ];
};
}

View File

@@ -4,6 +4,8 @@
sops.secrets.wg_epicenter_works_psk = {};
sops.secrets.wg_ghetto_at_key = {};
# https://wiki.archlinux.org/title/WireGuard#Loop_routing
networking.wireguard.interfaces = {
wg_cloonar = {
ips = [ "10.42.98.1/24" ];

View File

@@ -1,5 +1,6 @@
borg-passphrase: ENC[AES256_GCM,data:jHb+yXK0RqNdVYtWiueztZFlHC/xQ6ZiAOUcLt6BxmZQewuL3mh4AZ+lQdmA/4EaaTTIhVMR3xFx5fU6b2CtNLiGb/0=,iv:IW09B1EE1OupMCOvv13MXRYiMsD4VmIfyYONUyrPX1c=,tag:3ankeLOaDJkwRUGCd72DuA==,type:str]
borg-ssh-key: ENC[AES256_GCM,data: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,iv:9E1uiPqM3Hh4KWtL8haxm6PRm2VPc+DggrA135FvfB8=,tag:QSOgzVH9IBMgZxJvUhvY2w==,type:str]
ddclient: ENC[AES256_GCM,data:EaXjXS/bwL3S/Fr+rzQ7dXA1eIzeFpHH7H+SvoNhVSg=,iv:3BzjnJG5yT1W8ob2nm0oUlr+sSJ73W/ctl48xyxeeWM=,tag:TqKSwfxF0V1v5T8VT/qblw==,type:str]
wrwks_vpn_key: ENC[AES256_GCM,data:gGipXC8JJO59b4KWMSo0+r761raQl7RzgBuUbXmPEKlZR21bs5XRAQalzDCFNtjcpNkXiGqAHCLkDTtjPagMsw==,iv:MH1EBJEOdQDEgm9E0F884fynhsH8KiS5QSc605XbASQ=,tag:FUM1eptHS0rpt6ILyQjGOg==,type:str]
wg_cloonar_key: ENC[AES256_GCM,data:Dtp6I5J0jU5LLVwEFU4DFCpUngPRmFMebGXnk2oSwsKtsir/DtRBFG7ictM=,iv:1Abx/EAZRJrRQURljofzUYDgJpuREriX0nSrFbH5Npw=,tag:l4uFl9Uc+W0XeLVfLGmgZA==,type:str]
wg_epicenter_works_key: ENC[AES256_GCM,data:LeLjfwfaz+loWyHYRgIMIPzHzlOnhl9tluKcQFgdes6r+deft1JfnUzDuF0=,iv:DKrc3I+U2hWDH8nnc8ZQeaVtA1eVXu7SXdTn1fxHoH4=,tag:V0PL0GrL2NEPVslAZa801A==,type:str]
@@ -9,6 +10,7 @@ gitea-runner-token: ENC[AES256_GCM,data:Nd0vsnuJficsdZaqeBZXa9vD7PLMdDtV9sMX0TxU
drone: ENC[AES256_GCM,data:S8WTZqGHfcdpSojavZ87GdE5dagcTAdHBVQEbHHgnB4V7aczS6c5QdEJxK920Pjpf6o54OOQYniVsPiiXSxwjExDKPzhs/DG2hfigmf8RgfkP+3tF2W0KiPmV2jxog8w226ZKnI+hSBs8tuIfJBhrpY7Y/YNmTPfq+cnnLS8ibYqytcpzoogI9I8THzHCu3r+yejoGSyTMs9L4gPhOjz5aK4UV6V,iv:zqN/aSBI3xGGNDnpHPGyQnQP2YZOGUk6dAGtON/QlHU=,tag:o9YFDKAB5uR9lPmChyxB8g==,type:str]
home-assistant-ldap: ENC[AES256_GCM,data:uZEPbSnkgQYSd8ev6FD8TRHWWr+vusadtMcvP7KKL2AZAV0h1hga5fODN6I5u0DNL9hq2pNM+FwU0E/svWLRww==,iv:IhmUgSu34NaAY+kUZehx40uymydUYYAyte1aGqQ33/8=,tag:BKFCJPr7Vz4EG78ry/ZD7g==,type:str]
home-assistant-secrets.yaml: ENC[AES256_GCM,data:m7uOVo7hPk/RmqqRS6y7NKoMKsR9Bdi1ntatsZdDOAbJMjZmZL2FgPEHi/zF73zCfRfTOca3dwpulR3WXZ9Ic1sbUIggmusJMg4Gellw1CUhx7SbQN5nieAbPbB9GVxMuV4OakD1u7Swz8JggDT6IwojSnuD5omCRCyUH1wvKB+Re59q6EStderlm5MJNVFlVrbKVbLKLcw4yRgTh34BGnTTjcJmgSlQjO1ciu2B7YQmdl0Fw6d8AdbEzgB5TFG5ONc85UhJDE8Wlw==,iv:GCtpcVChN2UMWtfnWURozCfVj2YbRPqp/bH4Jjntybs=,tag:pcxP7gTBtXMNT5iyW5YXTw==,type:str]
palworld: ENC[AES256_GCM,data:93LMjHr7zEI67ZDHNr/MErZ+EIey8YccvemvwVbnql7WaJ3ynMMkowmJALCwsD8DfvHqSSLzR1Uz3roIx3FEhBBhiAXY0uDEvuvlG3LB4XS2FefTnuDAxyRKe9S8E7zMH3U5lYEMFhmXdkH3ctXqhZWdB0aSXJesAQQ00EC3igMfezS2fa8=,iv:2Nd+PoCtNhTypGs2iAzFEZ8XTusFtvCDwCqyh9mn+D8=,tag:yVJ6bfU8YnKza0l3+b+stg==,type:str]
sops:
kms: []
gcp_kms: []
@@ -33,8 +35,8 @@ sops:
Tlo3NHBlMkJEaXNOZkxSKytGSDNEMWcKquNuAzbPWwAjqc65BcAA/DMltFjC6Ayb
CKmJ7kaYFFUAIuBXhksvlH2b7vRZLT1QlwqUcRIRjxe+mZnsMIqE7w==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2023-12-09T21:02:39Z"
mac: ENC[AES256_GCM,data:fgpga0FpOsVvBOOkx5mr7U/mcQ/2o3+SED8/Iv9LuGkdg2MBAloIvUWOTgw9AP/OHIj41KMQUYlapNWHXDFd4hd3Vib1Fsk4x856v3sL7TgtwJW6/cvP1D99rV76NolJ3cNH9GNDdI50Bx/prZCB8E/Izyu4jwKWmck8ByRGkZE=,iv:mBGOvop4oLX1an4D6R08p8502EWsMBWFrnrM52T7pB4=,tag:uWtJjQ3iUj1/3BOOyD6nhw==,type:str]
lastmodified: "2024-02-09T22:05:20Z"
mac: ENC[AES256_GCM,data:6vieCZv+E6wHG+vkTg6V+fzuGlRBG91sWUrfIvAY1qSZ7sm1OdRsEhnjCJXnYwO8FCHx/GZRZDJqmDl6Iz21tbGQkul8rn3VV0qgslBWEHYCvKiULVfa78Ep3uDEu3Mqtsr3dNbQS6faTPNgpZIVFdZZzcKJfoaQVzzS98fJEno=,iv:pKpRATCTAe6zTXC7fl9uh6NIB+BKtdxOmfa+j7wftWU=,tag:4PYkA3ILTgHcj5HjOCeFgQ==,type:str]
pgp: []
unencrypted_suffix: _unencrypted
version: 3.8.1