feat: implement dnsmasq for DHCP and DNS management, remove unbound and dhcp configurations
This commit is contained in:
12
candle-sensor
Normal file
12
candle-sensor
Normal file
@@ -0,0 +1,12 @@
|
||||
it does not work if the sensor is underneath
|
||||
|
||||
i could build a device which you can put on the table and looks to the candles
|
||||
it has 80cm of recognizing a flame.
|
||||
|
||||
it would use the following components
|
||||
Adafruit ESP32 Feather V2
|
||||
ANGEEK KY-026 Flame Sensor Module
|
||||
2000 - 3000 mah LiPo
|
||||
|
||||
battery life would be 20 Days, cost would be around 35€ just plain devices cost without work time
|
||||
3d printed housing would be needed
|
||||
@@ -1,9 +1,8 @@
|
||||
{ ... }: {
|
||||
imports = [
|
||||
./interfaces.nix
|
||||
./dhcp.nix
|
||||
./firewall.nix
|
||||
./unbound.nix
|
||||
./dnsmasq.nix # New dnsmasq configuration
|
||||
./wireguard.nix
|
||||
];
|
||||
}
|
||||
|
||||
@@ -1,187 +0,0 @@
|
||||
{ config, lib, ... }:
|
||||
{
|
||||
services.kea.dhcp4 = lib.mkIf config.cloonar-assistant.firewall.enable {
|
||||
enable = true;
|
||||
settings = {
|
||||
interfaces-config = {
|
||||
interfaces = [
|
||||
"lan"
|
||||
"server"
|
||||
"infrastructure"
|
||||
"multimedia"
|
||||
"smart"
|
||||
"guest"
|
||||
];
|
||||
};
|
||||
lease-database = {
|
||||
name = "/var/lib/kea/dhcp4.leases";
|
||||
persist = true;
|
||||
type = "memfile";
|
||||
};
|
||||
rebind-timer = 2000;
|
||||
renew-timer = 1000;
|
||||
subnet4 = [
|
||||
{
|
||||
id = 96;
|
||||
pools = [
|
||||
{
|
||||
pool = "${config.cloonar-assistant.networkPrefix}.96.100 - ${config.cloonar-assistant.networkPrefix}.96.240";
|
||||
}
|
||||
];
|
||||
subnet = "${config.cloonar-assistant.networkPrefix}.96.0/24";
|
||||
interface = "lan";
|
||||
option-data = [
|
||||
{
|
||||
name = "routers";
|
||||
data = "${config.cloonar-assistant.networkPrefix}.96.1";
|
||||
}
|
||||
{
|
||||
name = "domain-name";
|
||||
data = config.cloonar-assistant.domain;
|
||||
}
|
||||
{
|
||||
name = "domain-search";
|
||||
data = config.cloonar-assistant.domain;
|
||||
}
|
||||
{
|
||||
name = "domain-name-servers";
|
||||
data = "${config.cloonar-assistant.networkPrefix}.96.1";
|
||||
}
|
||||
];
|
||||
reservations = [
|
||||
];
|
||||
}
|
||||
{
|
||||
id = 97;
|
||||
pools = [
|
||||
{
|
||||
pool = "${config.cloonar-assistant.networkPrefix}.97.100 - ${config.cloonar-assistant.networkPrefix}.97.240";
|
||||
}
|
||||
];
|
||||
subnet = "${config.cloonar-assistant.networkPrefix}.97.0/24";
|
||||
interface = "server";
|
||||
option-data = [
|
||||
{
|
||||
name = "routers";
|
||||
data = "${config.cloonar-assistant.networkPrefix}.97.1";
|
||||
}
|
||||
{
|
||||
name = "domain-name";
|
||||
data = config.cloonar-assistant.domain;
|
||||
}
|
||||
{
|
||||
name = "domain-name-servers";
|
||||
data = "${config.cloonar-assistant.networkPrefix}.97.1";
|
||||
}
|
||||
];
|
||||
reservations = [
|
||||
];
|
||||
}
|
||||
{
|
||||
id = 101;
|
||||
pools = [
|
||||
{
|
||||
pool = "${config.cloonar-assistant.networkPrefix}.101.100 - ${config.cloonar-assistant.networkPrefix}.101.240";
|
||||
}
|
||||
];
|
||||
subnet = "${config.cloonar-assistant.networkPrefix}.101.0/24";
|
||||
interface = "infrastructure";
|
||||
option-data = [
|
||||
{
|
||||
name = "routers";
|
||||
data = "${config.cloonar-assistant.networkPrefix}.101.1";
|
||||
}
|
||||
{
|
||||
name = "domain-name";
|
||||
data = config.cloonar-assistant.domain;
|
||||
}
|
||||
{
|
||||
name = "domain-name-servers";
|
||||
data = "${config.cloonar-assistant.networkPrefix}.101.1";
|
||||
}
|
||||
{
|
||||
name = "capwap-ac-v4";
|
||||
code = 138;
|
||||
data = "${config.cloonar-assistant.networkPrefix}.97.2";
|
||||
}
|
||||
];
|
||||
reservations = [
|
||||
];
|
||||
}
|
||||
{
|
||||
id = 99;
|
||||
pools = [
|
||||
{
|
||||
pool = "${config.cloonar-assistant.networkPrefix}.99.100 - ${config.cloonar-assistant.networkPrefix}.99.240";
|
||||
}
|
||||
];
|
||||
subnet = "${config.cloonar-assistant.networkPrefix}.99.0/24";
|
||||
interface = "multimedia";
|
||||
option-data = [
|
||||
{
|
||||
name = "routers";
|
||||
data = "${config.cloonar-assistant.networkPrefix}.99.1";
|
||||
}
|
||||
{
|
||||
name = "domain-name";
|
||||
data = config.cloonar-assistant.domain;
|
||||
}
|
||||
{
|
||||
name = "domain-name-servers";
|
||||
data = "${config.cloonar-assistant.networkPrefix}.99.1";
|
||||
}
|
||||
];
|
||||
reservations = [
|
||||
];
|
||||
}
|
||||
{
|
||||
id = 254;
|
||||
pools = [
|
||||
{
|
||||
pool = "${config.cloonar-assistant.networkPrefix}.254.10 - ${config.cloonar-assistant.networkPrefix}.254.254";
|
||||
}
|
||||
];
|
||||
subnet = "${config.cloonar-assistant.networkPrefix}.254.0/24";
|
||||
interface = "guest";
|
||||
option-data = [
|
||||
{
|
||||
name = "routers";
|
||||
data = "${config.cloonar-assistant.networkPrefix}.254.1";
|
||||
}
|
||||
{
|
||||
name = "domain-name-servers";
|
||||
data = "9.9.9.9";
|
||||
}
|
||||
];
|
||||
}
|
||||
{
|
||||
id = 100;
|
||||
pools = [
|
||||
{
|
||||
pool = "${config.cloonar-assistant.networkPrefix}.100.100 - ${config.cloonar-assistant.networkPrefix}.100.240";
|
||||
}
|
||||
];
|
||||
subnet = "${config.cloonar-assistant.networkPrefix}.100.0/24";
|
||||
interface = "smart";
|
||||
option-data = [
|
||||
{
|
||||
name = "routers";
|
||||
data = "${config.cloonar-assistant.networkPrefix}.100.1";
|
||||
}
|
||||
{
|
||||
name = "domain-name";
|
||||
data = config.cloonar-assistant.domain;
|
||||
}
|
||||
{
|
||||
name = "domain-name-servers";
|
||||
data = "${config.cloonar-assistant.networkPrefix}.100.1";
|
||||
}
|
||||
];
|
||||
reservations = [
|
||||
];
|
||||
}
|
||||
];
|
||||
valid-lifetime = 4000;
|
||||
};
|
||||
};
|
||||
}
|
||||
98
modules/cloonar-assistant/networking/dnsmasq.nix
Normal file
98
modules/cloonar-assistant/networking/dnsmasq.nix
Normal file
@@ -0,0 +1,98 @@
|
||||
{ config, lib, ... }:
|
||||
|
||||
{
|
||||
# Disable systemd-resolved (same as current unbound.nix)
|
||||
services.resolved.enable = false;
|
||||
|
||||
# Main dnsmasq service with preserved conditional enablement
|
||||
services.dnsmasq = lib.mkIf config.cloonar-assistant.firewall.enable {
|
||||
enable = true;
|
||||
resolveLocalQueries = false; # We handle DNS manually
|
||||
|
||||
settings = {
|
||||
# Interface binding
|
||||
interface = [
|
||||
"lan"
|
||||
"server"
|
||||
"infrastructure"
|
||||
"multimedia"
|
||||
"smart"
|
||||
"guest"
|
||||
];
|
||||
|
||||
# DHCP ranges per VLAN
|
||||
dhcp-range = [
|
||||
"${config.cloonar-assistant.networkPrefix}.96.100,${config.cloonar-assistant.networkPrefix}.96.240,24h"
|
||||
"${config.cloonar-assistant.networkPrefix}.97.100,${config.cloonar-assistant.networkPrefix}.97.240,24h"
|
||||
"${config.cloonar-assistant.networkPrefix}.101.100,${config.cloonar-assistant.networkPrefix}.101.240,24h"
|
||||
"${config.cloonar-assistant.networkPrefix}.99.100,${config.cloonar-assistant.networkPrefix}.99.240,24h"
|
||||
"${config.cloonar-assistant.networkPrefix}.100.100,${config.cloonar-assistant.networkPrefix}.100.240,24h"
|
||||
"${config.cloonar-assistant.networkPrefix}.254.10,${config.cloonar-assistant.networkPrefix}.254.254,24h"
|
||||
];
|
||||
|
||||
# DHCP options with VLAN tagging
|
||||
dhcp-option = [
|
||||
# LAN VLAN (.96)
|
||||
"tag:lan,option:router,${config.cloonar-assistant.networkPrefix}.96.1"
|
||||
"tag:lan,option:dns-server,${config.cloonar-assistant.networkPrefix}.96.1"
|
||||
"tag:lan,option:domain-name,${config.cloonar-assistant.domain}"
|
||||
|
||||
# Server VLAN (.97)
|
||||
"tag:server,option:router,${config.cloonar-assistant.networkPrefix}.97.1"
|
||||
"tag:server,option:dns-server,${config.cloonar-assistant.networkPrefix}.97.1"
|
||||
"tag:server,option:domain-name,${config.cloonar-assistant.domain}"
|
||||
|
||||
# Infrastructure VLAN (.101) with CAPWAP option
|
||||
"tag:infrastructure,option:router,${config.cloonar-assistant.networkPrefix}.101.1"
|
||||
"tag:infrastructure,option:dns-server,${config.cloonar-assistant.networkPrefix}.101.1"
|
||||
"tag:infrastructure,option:domain-name,${config.cloonar-assistant.domain}"
|
||||
"tag:infrastructure,138,${config.cloonar-assistant.networkPrefix}.97.2" # CAPWAP
|
||||
|
||||
# Multimedia VLAN (.99)
|
||||
"tag:multimedia,option:router,${config.cloonar-assistant.networkPrefix}.99.1"
|
||||
"tag:multimedia,option:dns-server,${config.cloonar-assistant.networkPrefix}.99.1"
|
||||
"tag:multimedia,option:domain-name,${config.cloonar-assistant.domain}"
|
||||
|
||||
# Smart VLAN (.100)
|
||||
"tag:smart,option:router,${config.cloonar-assistant.networkPrefix}.100.1"
|
||||
"tag:smart,option:dns-server,${config.cloonar-assistant.networkPrefix}.100.1"
|
||||
"tag:smart,option:domain-name,${config.cloonar-assistant.domain}"
|
||||
|
||||
# Guest VLAN (.254) - DNS isolation
|
||||
"tag:guest,option:router,${config.cloonar-assistant.networkPrefix}.254.1"
|
||||
"tag:guest,option:dns-server,9.9.9.9" # External DNS only
|
||||
];
|
||||
|
||||
# Static DNS records
|
||||
address = [
|
||||
"/fw.${config.cloonar-assistant.domain}/${config.cloonar-assistant.networkPrefix}.97.1"
|
||||
"/fw/${config.cloonar-assistant.networkPrefix}.97.1"
|
||||
"/home-assistant.${config.cloonar-assistant.domain}/${config.cloonar-assistant.networkPrefix}.97.20"
|
||||
"/mopidy.${config.cloonar-assistant.domain}/${config.cloonar-assistant.networkPrefix}.97.21"
|
||||
"/snapcast.${config.cloonar-assistant.domain}/${config.cloonar-assistant.networkPrefix}.97.21"
|
||||
"/localhost/127.0.0.1"
|
||||
"/localhost.${config.cloonar-assistant.domain}/127.0.0.1"
|
||||
];
|
||||
|
||||
# Domain configuration
|
||||
domain = "${config.cloonar-assistant.domain}";
|
||||
expand-hosts = true;
|
||||
|
||||
# Upstream DNS servers (plain DNS, no DoT support in dnsmasq)
|
||||
server = [
|
||||
"9.9.9.9"
|
||||
"149.112.112.11"
|
||||
];
|
||||
|
||||
# Performance and security
|
||||
cache-size = 1000;
|
||||
neg-ttl = 60;
|
||||
domain-needed = true; # Don't forward plain names
|
||||
bogus-priv = true; # Don't forward RFC1918 reverse lookups
|
||||
bind-interfaces = true; # Only bind to specified interfaces
|
||||
};
|
||||
};
|
||||
|
||||
# Firewall configuration (preserve existing)
|
||||
networking.firewall.allowedUDPPorts = [ 53 5353 ];
|
||||
}
|
||||
@@ -1,138 +0,0 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
let
|
||||
cfg = {
|
||||
remote-control.control-enable = true;
|
||||
server = {
|
||||
interface = [ "0.0.0.0" "::0" ];
|
||||
interface-automatic = "yes";
|
||||
access-control = [
|
||||
"127.0.0.0/8 allow"
|
||||
"${config.cloonar-assistant.networkPrefix}.96.0/24 allow"
|
||||
"${config.cloonar-assistant.networkPrefix}.97.0/24 allow"
|
||||
"${config.cloonar-assistant.networkPrefix}.98.0/24 allow"
|
||||
"${config.cloonar-assistant.networkPrefix}.99.0/24 allow"
|
||||
"${config.cloonar-assistant.networkPrefix}.101.0/24 allow"
|
||||
"0.0.0.0/0 allow"
|
||||
];
|
||||
tls-cert-bundle = "/etc/ssl/certs/ca-certificates.crt";
|
||||
local-zone = "\"${config.cloonar-assistant.domain}\" transparent";
|
||||
local-data = [
|
||||
"\"localhost A 127.0.0.1\""
|
||||
"\"localhost.${config.cloonar-assistant.domain} A 127.0.0.1\""
|
||||
"\"localhost AAAA ::1\""
|
||||
"\"localhost.${config.cloonar-assistant.domain} AAAA ::1\""
|
||||
"\"fw.${config.cloonar-assistant.domain} A ${config.cloonar-assistant.networkPrefix}.97.1\""
|
||||
"\"fw A ${config.cloonar-assistant.networkPrefix}.97.1\""
|
||||
|
||||
"\"mopidy.${config.cloonar-assistant.domain} IN A ${config.cloonar-assistant.networkPrefix}.97.21\""
|
||||
"\"snapcast.${config.cloonar-assistant.domain} IN A ${config.cloonar-assistant.networkPrefix}.97.21\""
|
||||
"\"home-assistant.${config.cloonar-assistant.domain} IN A ${config.cloonar-assistant.networkPrefix}.97.20\""
|
||||
];
|
||||
local-data-ptr = [
|
||||
"\"127.0.0.1 localhost\""
|
||||
"\"::1 localhost\""
|
||||
"\"${config.cloonar-assistant.networkPrefix}.97.1 fw.${config.cloonar-assistant.domain}\""
|
||||
"\"${config.cloonar-assistant.networkPrefix}.97.20 home-assistant.${config.cloonar-assistant.domain}\""
|
||||
"\"${config.cloonar-assistant.networkPrefix}.97.21 snapcast.${config.cloonar-assistant.domain}\""
|
||||
];
|
||||
# ssl-upstream = "yes";
|
||||
};
|
||||
forward-zone = [
|
||||
{
|
||||
name = ".";
|
||||
forward-tls-upstream = "yes";
|
||||
forward-first = "no";
|
||||
forward-addr = [
|
||||
"9.9.9.9@853#dns9.quad9.net"
|
||||
"149.112.112.11@853#dns11.quad9.net"
|
||||
];
|
||||
}
|
||||
];
|
||||
};
|
||||
in {
|
||||
users.users.unbound = {
|
||||
group = "unbound";
|
||||
isSystemUser = true;
|
||||
extraGroups = [ "ssl-users" ];
|
||||
};
|
||||
users.groups.unbound = { };
|
||||
|
||||
services.resolved.enable = false;
|
||||
|
||||
services.unbound = {
|
||||
enable = true;
|
||||
settings = cfg;
|
||||
};
|
||||
|
||||
systemd.services.unbound-sync = lib.mkIf config.cloonar-assistant.firewall.enable {
|
||||
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 echo "''\${1}" | grep -Eq '.*\.(${config.cloonar-assistant.domain})'; then
|
||||
echo ''\${hostname} ''\$2 ''\${address}
|
||||
unbound-control local_data ''\${hostname} ''\$2 ''\${address} > /dev/null 2>&1
|
||||
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} > /dev/null 2>&1
|
||||
unbound-control local_data ''\${ip3}.''\${ip2}.''\${ip1}.''\${ip0}.in-addr.arpa. PTR ''\${hostname} > /dev/null 2>&1
|
||||
done
|
||||
fi
|
||||
else
|
||||
if [[ "''\$2" == "A" ]] ; then
|
||||
echo ''\${address} | while IFS=. read -r ip0 ip1 ip2 ip3
|
||||
do
|
||||
if [[ "''\${hostname}" != "" ]]; then
|
||||
domain=${config.cloonar-assistant.domain}
|
||||
if [[ "''\${hostname}" != *. ]]; then
|
||||
unbound-control local_data ''\${hostname}.''\${domain} ''\$2 ''\${address} > /dev/null 2>&1
|
||||
else
|
||||
unbound-control local_data ''\${hostname}''\${domain} ''\$2 ''\${address} > /dev/null 2>&1
|
||||
fi
|
||||
|
||||
fi
|
||||
unbound-control local_data ''\${ip3}.''\${ip2}.''\${ip1}.''\${ip0}.ip4.arpa. PTR ''\${hostname} > /dev/null 2>&1
|
||||
unbound-control local_data ''\${ip3}.''\${ip2}.''\${ip1}.''\${ip0}.in-addr.arpa. PTR ''\${hostname} > /dev/null 2>&1
|
||||
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" ];
|
||||
};
|
||||
|
||||
networking.firewall.allowedUDPPorts = [ 53 5353 ];
|
||||
}
|
||||
Reference in New Issue
Block a user