nixos-config/config/host-config/wormhole0.nix

305 lines
8.6 KiB
Nix

{ config, lib, pkgs, ... }:
with lib;
let
hostname = "wormhole0";
primary-ip = "10.0.0.3";
state-dir = "/state";
zigbee2mqtt-statedir = "${state-dir}/services/zigbee2mqtt";
home-assistant-port = 8123;
zigbee2mqtt-user = config.systemd.services.zigbee2mqtt.serviceConfig.User;
zigbee2mqtt-passwd-file =
pkgs.lib.passwd.stablerandom-passwd-file "zigbee2mqtt-passwd"
config.instance.build-seed;
teslaMateMqttPasswdFile =
pkgs.lib.passwd.stablerandom-passwd-file "tesla-mate-mqtt-passwd"
config.instance.build-seed;
nitenMqttPasswdFile =
pkgs.lib.passwd.stablerandom-passwd-file "niten-mqtt-passwd"
config.instance.build-seed;
nodeRedPasswdFile =
pkgs.lib.passwd.stablerandom-passwd-file "node-red-mqtt-passwd"
config.instance.build-seed;
teslaMatePort = 4400;
teslaGraphPort = 4401;
nodeRedPort = 1880;
host-secrets = config.fudo.secrets.host-secrets.${hostname};
host-passwds = config.fudo.secrets.files.service-passwords.${hostname};
in {
imports = [
(import ./wormhole0/home-assistant.nix {
homeAssistantImage = "ghcr.io/home-assistant/home-assistant:2023.9";
nodeRedImage = "nodered/node-red:3.1.0-14";
inherit nodeRedPort;
stateDirectory = "/state/services/arion-home-assistant";
})
];
config = {
boot.kernel.sysctl = { "net.ipv4.ip_forward" = true; };
networking = {
hostName = hostname;
firewall = { enable = false; };
defaultGateway = {
address = "10.0.0.1";
interface = "intif0";
};
nameservers = [ "10.0.0.1" ];
interfaces = {
intif0 = {
useDHCP = false;
ipv4 = {
addresses = [{
address = primary-ip;
prefixLength = 16;
}];
};
};
wormif0.useDHCP = true;
wlp2s0.useDHCP = false;
};
dhcpcd.extraConfig = concatStringsSep "\n" [ "nogateway" ];
};
fudo.services.mqtt = {
enable = true;
state-directory = "${state-dir}/services/mosquitto";
private = {
enable = true;
users = {
zigbee2mqtt = {
password-file = zigbee2mqtt-passwd-file;
acl = [ "readwrite #" ];
};
home-assistant = {
password-file = host-passwds.mosquitto-home-assistant;
acl = [ "readwrite #" ];
};
tesla-mate = {
password-file = teslaMateMqttPasswdFile;
acl = [ "readwrite teslamate/cars/#" ];
};
niten = {
password-file = nitenMqttPasswdFile;
acl = [ "readwrite #" ];
};
node-red = {
password-file = nodeRedPasswdFile;
acl = [ "readwrite #" ];
};
};
};
};
systemd = {
services = {
wormhole-route = {
wantedBy = [ "multi-user.target" ];
after = [ "network-online.target" ];
serviceConfig = {
ExecStart =
"${pkgs.iproute2}/bin/ip route add 192.168.86.0/24 dev wormif0";
ExecStop =
"${pkgs.iproute2}/bin/ip route del 192.168.86.0/24 dev wormif0";
RemainAfterExit = true;
};
};
};
tmpfiles.rules = [
"L /root/.gnupg - - - - ${state-dir}/user/root/gnupg"
"L /root/.ssh/id_rsa - - - - ${state-dir}/user/root/ssh/id_rsa"
"L /root/.ssh/id_rsa.pub - - - - ${state-dir}/user/root/ssh/id_rsa.pub"
"L /root/.ssh/known_hosts - - - - ${state-dir}/user/root/ssh/known_hosts"
"L /etc/adjtime - - - - ${state-dir}/etc/adjtime"
"d /state/services 0711 root root - -"
"d ${zigbee2mqtt-statedir} 0700 ${zigbee2mqtt-user} - - -"
];
};
users.groups = let
zigbee2mqtt-user = config.systemd.services.zigbee2mqtt.serviceConfig.User;
in { dialout.members = [ zigbee2mqtt-user ]; };
services = {
openssh.hostKeys = [
{
path = "${state-dir}/ssh/ssh_host_rsa_key";
type = "rsa";
bits = 4096;
}
{
path = "${state-dir}/ssh/ssh_host_ed25519_key";
type = "ed25519";
}
];
nginx = {
enable = true;
recommendedOptimisation = true;
recommendedProxySettings = true;
recommendedGzipSettings = true;
virtualHosts = {
"home-assist.sea.fudo.org" = {
locations."/" = {
proxyPass = "http://localhost:${toString home-assistant-port}";
proxyWebsockets = true;
};
};
"node-red.sea.fudo.org" = {
locations."/" = {
proxyPass = "http://localhost:${toString nodeRedPort}";
proxyWebsockets = true;
};
};
"tesla-mate.sea.fudo.org" = {
locations."/" = {
proxyPass = "http://localhost:${toString teslaMatePort}";
proxyWebsockets = true;
};
};
"tesla-graph.sea.fudo.org" = {
locations."/" = {
proxyPass = "http://localhost:${toString teslaGraphPort}";
proxyWebsockets = true;
};
};
};
};
# mosquitto = {
# enable = true;
# dataDir = mosquitto-statedir;
# listeners = [{
# settings.allow_anonymous = false;
# port = 1883;
# address = "0.0.0.0";
# users = {
# zigbee2mqtt = {
# passwordFile =
# host-secrets.mosquitto-zigbee2mqtt-passwd.target-file;
# acl = [ "readwrite #" ];
# };
# home-assistant = {
# passwordFile =
# host-secrets.mosquitto-home-assistant-passwd.target-file;
# acl = [ "readwrite #" ];
# };
# niten = {
# passwordFile = host-secrets.mosquitto-niten-passwd.target-file;
# acl = [ "readwrite #" ];
# };
# # xiaoxuan = {
# # passwordFile = host-secrets.mosquitto-xiaoxuan-passwd.target-file;
# # acl = [ "readwrite #" ];
# # };
# # wallfly = {
# # passwordFile = host-secrets.mosquitto-wallfly-passwd.target-file;
# # acl = [ "readwrite homeassistant/binary_sensor/#" ];
# # };
# };
# }];
# };
zigbee2mqtt = {
enable = true;
dataDir = zigbee2mqtt-statedir;
package = pkgs.pkgsUnstable.zigbee2mqtt;
settings = {
homeassistant = true;
permit_join = true;
serial.port = "/dev/ttyUSB0";
mqtt = let
mqttHost = config.fudo.services.mqtt.mqtt-hostname;
mqttPort = config.fudo.services.mqtt.private.port;
in {
server = "mqtt://${mqttHost}:${toString mqttPort}";
user = "zigbee2mqtt";
password = readFile zigbee2mqtt-passwd-file;
# TODO: could make a yaml file containing password
# described https://www.zigbee2mqtt.io/guide/configuration/mqtt.html#server-connection
# Weird, though.
};
advanced.log_level = "debug";
};
};
avahi = {
enable = true;
reflector = true;
interfaces = [ "intif0" "worm0" ];
};
teslaMateContainer = {
enable = true;
mqtt = {
host = config.fudo.services.mqtt.mqtt-hostname;
port = config.fudo.services.mqtt.private.port;
user = "tesla-mate";
password = readFile teslaMateMqttPasswdFile;
};
port = teslaMatePort;
grafana-port = teslaGraphPort;
state-directory = "/state/services/tesla-mate";
};
};
virtualisation = {
docker = {
enable = false;
#enableOnBoot = true;
#autoPrune.enable = true;
};
podman = {
enable = true;
dockerSocket.enable = true;
autoPrune.enable = true;
};
arion.backend = "podman-socket";
# oci-containers = {
# backend = "podman";
# containers = {
# home-assistant = {
# image = "homeassistant/home-assistant:stable";
# autoStart = true;
# environment.TZ = config.time.timeZone;
# #ports = [ "${toString home-assistant-port}:8123" ];
# volumes = [ "/state/services/home-assistant:/config" ];
# extraOptions = [ "--network=host" ];
# };
# };
# };
};
security.sudo.extraConfig = ''
# Due to rollback, sudo will lecture after every reboot
Defaults lecture = never
'';
};
}