remove old hosts
This commit is contained in:
@@ -1 +0,0 @@
|
||||
https://channels.nixos.org/nixos-23.11
|
||||
@@ -1,109 +0,0 @@
|
||||
{ lib, pkgs, ... }: {
|
||||
|
||||
imports = [
|
||||
./fleet.nix
|
||||
./utils/bento.nix
|
||||
./utils/modules/sops.nix
|
||||
./utils/modules/lego/lego.nix
|
||||
|
||||
./utils/modules/nginx.nix
|
||||
|
||||
./utils/modules/autoupgrade.nix
|
||||
./utils/modules/promtail
|
||||
# ./utils/modules/borgbackup.nix
|
||||
# ./utils/modules/netdata.nix
|
||||
|
||||
# fw
|
||||
./modules/networking.nix
|
||||
./modules/firewall.nix
|
||||
# ./modules/dhcp4.nix
|
||||
./modules/unbound.nix
|
||||
./modules/avahi.nix
|
||||
./modules/openconnect.nix
|
||||
./modules/wireguard.nix
|
||||
./modules/podman.nix
|
||||
./modules/omada.nix
|
||||
# ./modules/ddclient.nix
|
||||
# ./modules/wol.nix
|
||||
|
||||
# microvm
|
||||
./modules/microvm.nix
|
||||
./modules/gitea-vm.nix
|
||||
|
||||
# web
|
||||
./modules/web
|
||||
|
||||
# git
|
||||
# ./modules/gitea.nix
|
||||
./modules/fwmetrics.nix
|
||||
|
||||
# ./modules/firefox-sync.nix
|
||||
|
||||
# home assistant
|
||||
./modules/home-assistant
|
||||
# ./modules/deconz.nix
|
||||
# ./modules/mopidy.nix
|
||||
./modules/mosquitto.nix
|
||||
./modules/snapserver.nix
|
||||
|
||||
# gaming
|
||||
# ./modules/palworld.nix
|
||||
# ./modules/ark-survival-evolved.nix
|
||||
|
||||
|
||||
./hardware-configuration.nix
|
||||
];
|
||||
|
||||
nixpkgs.config.permittedInsecurePackages = [
|
||||
"openssl-1.1.1w"
|
||||
];
|
||||
|
||||
nixpkgs.config.allowUnfreePredicate = pkg: builtins.elem (lib.getName pkg) [
|
||||
"mongodb"
|
||||
];
|
||||
|
||||
time.timeZone = "Europe/Vienna";
|
||||
|
||||
sops.age.sshKeyPaths = [ "/etc/ssh/ssh_host_ed25519_key" ];
|
||||
sops.defaultSopsFile = ./secrets.yaml;
|
||||
|
||||
environment.systemPackages = with pkgs; [
|
||||
# bento
|
||||
conntrack-tools # view network connection states
|
||||
ethtool # manage NIC settings (offload, NIC feeatures, ...)
|
||||
git
|
||||
htop # to see the system load
|
||||
tcpdump # view network traffic
|
||||
vim # my preferred editor
|
||||
wol
|
||||
inotify-tools
|
||||
];
|
||||
|
||||
nix.gc = {
|
||||
automatic = true;
|
||||
options = "--delete-older-than 60d";
|
||||
};
|
||||
|
||||
# services.auto-cpufreq.enable = true;
|
||||
# services.auto-cpufreq.settings = {
|
||||
# charger = {
|
||||
# governor = "powersave";
|
||||
# turbo = "auto";
|
||||
# };
|
||||
# };
|
||||
|
||||
# zramSwap.enable = true;
|
||||
networking.hostName = "fw-new";
|
||||
services.openssh.enable = true;
|
||||
users.users.root.openssh.authorizedKeys.keys = [
|
||||
"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDN/2SAFm50kraB1fepAizox/QRXxB7WbqVbH+5OPalDT47VIJGNKOKhixQoqhABHxEoLxdf/C83wxlCVlPV9poLfDgVkA3Lyt5r3tSFQ6QjjOJAgchWamMsxxyGBedhKvhiEzcr/Lxytnoz3kjDG8fqQJwEpdqMmJoMUfyL2Rqp16u+FQ7d5aJtwO8EUqovhMaNO7rggjPpV/uMOg+tBxxmscliN7DLuP4EMTA/FwXVzcFNbOx3K9BdpMRAaSJt4SWcJO2cS2KHA5n/H+PQI7nz5KN3Yr/upJN5fROhi/SHvK39QOx12Pv7FCuWlc+oR68vLaoCKYhnkl3DnCfc7A7"
|
||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIRQuPqH5fdX3KEw7DXzWEdO3AlUn1oSmtJtHB71ICoH Generated By Termius"
|
||||
];
|
||||
|
||||
services.logind.extraConfig = "RuntimeDirectorySize=8G";
|
||||
|
||||
# backups
|
||||
# borgbackup.repo = "u149513-sub2@u149513-sub2.your-backup.de:borg";
|
||||
|
||||
system.stateVersion = "23.11";
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
../../fleet.nix
|
||||
@@ -1,97 +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, ... }:
|
||||
|
||||
{
|
||||
powerManagement.cpuFreqGovernor = lib.mkDefault "ondemand";
|
||||
|
||||
boot = {
|
||||
loader.systemd-boot.enable = true;
|
||||
loader.efi.canTouchEfiVariables = true;
|
||||
|
||||
kernelPackages = pkgs.linuxPackagesFor (pkgs.callPackage ./pkgs/kernel/vendor.nix {});
|
||||
kernel.sysctl = {
|
||||
"kernel.printk" = "1 4 1 7";
|
||||
};
|
||||
supportedFilesystems = lib.mkForce [ "vfat" "fat32" "exfat" "ext4" "btrfs" ];
|
||||
initrd.includeDefaultModules = lib.mkForce false;
|
||||
initrd.availableKernelModules = lib.mkForce [ "nvme" "mmc_block" "hid" "dm_mod" "dm_crypt" "input_leds" ];
|
||||
|
||||
# kernelParams copy from Armbian's /boot/armbianEnv.txt & /boot/boot.cmd
|
||||
kernelParams = [
|
||||
"rootwait"
|
||||
|
||||
"earlycon" # enable early console, so we can see the boot messages via serial port / HDMI
|
||||
"consoleblank=0" # disable console blanking(screen saver)
|
||||
"console=ttyS2,1500000" # serial port
|
||||
"console=tty1" # HDMI
|
||||
|
||||
# docker optimizations
|
||||
"cgroup_enable=cpuset"
|
||||
"cgroup_memory=1"
|
||||
"cgroup_enable=memory"
|
||||
"swapaccount=1"
|
||||
];
|
||||
};
|
||||
|
||||
hardware = {
|
||||
deviceTree = {
|
||||
# https://github.com/armbian/build/blob/f9d7117/config/boards/orangepi5-plus.wip#L10C51-L10C51
|
||||
name = "rockchip/rk3588-orangepi-5-plus.dtb";
|
||||
overlays = [
|
||||
];
|
||||
};
|
||||
|
||||
enableRedistributableFirmware = lib.mkForce true;
|
||||
firmware = [
|
||||
(pkgs.callPackage ./pkgs/orangepi-firmware {})
|
||||
];
|
||||
|
||||
opengl.package =
|
||||
(
|
||||
(pkgs.mesa.override {
|
||||
galliumDrivers = ["panfrost" "swrast"];
|
||||
vulkanDrivers = ["swrast"];
|
||||
})
|
||||
.overrideAttrs (_: {
|
||||
pname = "mesa-panfork";
|
||||
version = "23.0.0-panfork";
|
||||
src = pkgs.fetchFromGitLab {
|
||||
owner = "panfork";
|
||||
repo = "mesa";
|
||||
rev = "120202c675749c5ef81ae4c8cdc30019b4de08f4"; # branch: csf
|
||||
hash = "sha256-4eZHMiYS+sRDHNBtLZTA8ELZnLns7yT3USU5YQswxQ0=";
|
||||
};
|
||||
})
|
||||
)
|
||||
.drivers;
|
||||
};
|
||||
|
||||
|
||||
fileSystems."/" =
|
||||
{ device = "/dev/disk/by-uuid/c49c99cd-9a91-485d-8572-8f83df262907";
|
||||
fsType = "ext4";
|
||||
};
|
||||
|
||||
fileSystems."/boot" =
|
||||
{ device = "/dev/disk/by-uuid/12CE-A600";
|
||||
fsType = "vfat";
|
||||
};
|
||||
|
||||
swapDevices =
|
||||
[ { device = "/dev/disk/by-uuid/1f3fe124-c1f6-4e3f-9e89-4aa6d87d9853"; }
|
||||
];
|
||||
|
||||
# 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.enP3p49s0.useDHCP = lib.mkDefault true;
|
||||
# networking.interfaces.enP4p65s0.useDHCP = lib.mkDefault true;
|
||||
# networking.interfaces.enu1u3c2.useDHCP = lib.mkDefault true;
|
||||
# networking.interfaces.wlP2p33s0.useDHCP = lib.mkDefault true;
|
||||
|
||||
nixpkgs.hostPlatform = lib.mkDefault "aarch64-linux";
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
{ config, pkgs, ... }:
|
||||
|
||||
{
|
||||
virtualisation.oci-containers.backend = "podman";
|
||||
virtualisation.oci-containers.containers = {
|
||||
ark = {
|
||||
image = "hermsi/ark-server:latest";
|
||||
autoStart = true;
|
||||
environmentFiles = [
|
||||
config.sops.secrets.ark.path
|
||||
];
|
||||
volumes = [
|
||||
"/var/lib/ark/app:/app/"
|
||||
"/var/lib/ark/backup:/home/steam/ARK-Backups"
|
||||
];
|
||||
extraOptions = [
|
||||
"--network=server"
|
||||
"--ip=10.42.97.201"
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
sops.secrets.ark = {};
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
{ ... }: {
|
||||
services.avahi = {
|
||||
enable = true;
|
||||
reflector = true;
|
||||
allowInterfaces = [
|
||||
"server"
|
||||
"lan"
|
||||
];
|
||||
};
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
{ 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 = [
|
||||
"fw.cloonar.com"
|
||||
"vpn.cloonar.com"
|
||||
"git.cloonar.com"
|
||||
"palworld.cloonar.com"
|
||||
"matrix.cloonar.com"
|
||||
];
|
||||
};
|
||||
|
||||
sops.secrets.ddclient = {
|
||||
# owner = config.systemd.services.ddclient.serviceConfig.User;
|
||||
};
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
{ config, pkgs, ... }: {
|
||||
virtualisation = {
|
||||
oci-containers.containers = {
|
||||
deconz = {
|
||||
autoStart = false;
|
||||
image = "marthoc/deconz";
|
||||
volumes = [
|
||||
"/etc/localtime:/etc/localtime:ro"
|
||||
"/var/lib/deconz:/root/.local/share/dresden-elektronik/deCONZ"
|
||||
];
|
||||
environment = {
|
||||
DECONZ_DEVICE = "/dev/ttyACM0";
|
||||
TZ = "Europe/Vienna";
|
||||
};
|
||||
extraOptions = [
|
||||
"--network=server"
|
||||
"--ip=10.42.97.22"
|
||||
"--device=/dev/ttyACM0"
|
||||
"--hostname=deconz"
|
||||
];
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -1,376 +0,0 @@
|
||||
{ ... }: {
|
||||
services.kea.dhcp4 = {
|
||||
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 = [
|
||||
{
|
||||
pools = [
|
||||
{
|
||||
pool = "10.42.112.100 - 10.42.112.240";
|
||||
}
|
||||
];
|
||||
subnet = "10.42.112.0/24";
|
||||
interface = "lan";
|
||||
option-data = [
|
||||
{
|
||||
name = "routers";
|
||||
data = "10.42.112.1";
|
||||
}
|
||||
{
|
||||
name = "domain-name";
|
||||
data = "cloonar.com";
|
||||
}
|
||||
{
|
||||
name = "domain-search";
|
||||
data = "cloonar.com";
|
||||
}
|
||||
{
|
||||
name = "domain-name-servers";
|
||||
data = "10.42.112.1";
|
||||
}
|
||||
];
|
||||
reservations = [
|
||||
{
|
||||
hw-address = "04:7c:16:d5:63:5e";
|
||||
ip-address = "10.42.112.5";
|
||||
server-hostname = "omada.cloonar.com";
|
||||
}
|
||||
{
|
||||
hw-address = "30:05:5c:56:62:37";
|
||||
ip-address = "10.42.112.100";
|
||||
server-hostname = "brn30055c566237.cloonar.com";
|
||||
}
|
||||
];
|
||||
}
|
||||
{
|
||||
pools = [
|
||||
{
|
||||
pool = "10.42.113.100 - 10.42.113.240";
|
||||
}
|
||||
];
|
||||
subnet = "10.42.113.0/24";
|
||||
interface = "server";
|
||||
option-data = [
|
||||
{
|
||||
name = "routers";
|
||||
data = "10.42.113.1";
|
||||
}
|
||||
{
|
||||
name = "domain-name";
|
||||
data = "cloonar.com";
|
||||
}
|
||||
{
|
||||
name = "domain-name-servers";
|
||||
data = "10.42.113.1";
|
||||
}
|
||||
];
|
||||
reservations = [
|
||||
{
|
||||
hw-address = "1a:c4:04:6e:29:bd";
|
||||
ip-address = "10.42.113.2";
|
||||
server-hostname = "omada.cloonar.com";
|
||||
}
|
||||
{
|
||||
hw-address = "02:00:00:00:00:03";
|
||||
ip-address = "10.42.113.5";
|
||||
server-hostname = "web-02.cloonar.com";
|
||||
}
|
||||
{
|
||||
hw-address = "ea:db:d4:c1:18:ba";
|
||||
ip-address = "10.42.113.50";
|
||||
server-hostname = "git.cloonar.com";
|
||||
}
|
||||
{
|
||||
hw-address = "c2:4f:64:dd:13:0c";
|
||||
ip-address = "10.42.113.20";
|
||||
server-hostname = "home-assistant.cloonar.com";
|
||||
}
|
||||
{
|
||||
hw-address = "1a:c4:04:6e:29:02";
|
||||
ip-address = "10.42.113.25";
|
||||
server-hostname = "deconz.cloonar.com";
|
||||
}
|
||||
];
|
||||
}
|
||||
{
|
||||
pools = [
|
||||
{
|
||||
pool = "10.42.117.100 - 10.42.117.240";
|
||||
}
|
||||
];
|
||||
subnet = "10.42.117.0/24";
|
||||
interface = "infrastructure";
|
||||
option-data = [
|
||||
{
|
||||
name = "routers";
|
||||
data = "10.42.117.1";
|
||||
}
|
||||
{
|
||||
name = "domain-name";
|
||||
data = "cloonar.com";
|
||||
}
|
||||
{
|
||||
name = "domain-name-servers";
|
||||
data = "10.42.117.1";
|
||||
}
|
||||
{
|
||||
name = "capwap-ac-v4";
|
||||
code = 138;
|
||||
data = "10.42.117.2";
|
||||
}
|
||||
];
|
||||
reservations = [
|
||||
];
|
||||
}
|
||||
{
|
||||
pools = [
|
||||
{
|
||||
pool = "10.42.115.100 - 10.42.115.240";
|
||||
}
|
||||
];
|
||||
subnet = "10.42.115.0/24";
|
||||
interface = "multimedia";
|
||||
option-data = [
|
||||
{
|
||||
name = "routers";
|
||||
data = "10.42.115.1";
|
||||
}
|
||||
{
|
||||
name = "domain-name";
|
||||
data = "cloonar.multimedia";
|
||||
}
|
||||
{
|
||||
name = "domain-name-servers";
|
||||
data = "10.42.115.1";
|
||||
}
|
||||
];
|
||||
reservations = [
|
||||
{
|
||||
hw-address = "c4:a7:2b:c7:ea:30";
|
||||
ip-address = "10.42.115.10";
|
||||
hostname = "metz.cloonar.multimedia";
|
||||
}
|
||||
{
|
||||
hw-address = "f0:2f:9e:d4:3b:21";
|
||||
ip-address = "10.42.115.11";
|
||||
hostname = "firetv-living";
|
||||
}
|
||||
{
|
||||
hw-address = "bc:33:29:ed:24:f0";
|
||||
ip-address = "10.42.115.12";
|
||||
hostname = "ps5";
|
||||
}
|
||||
{
|
||||
hw-address = "e4:2a:ac:32:3f:79";
|
||||
ip-address = "10.42.115.13";
|
||||
hostname = "xbox";
|
||||
}
|
||||
{
|
||||
hw-address = "98:b6:e9:b6:ef:f4";
|
||||
ip-address = "10.42.115.14";
|
||||
hostname = "switch";
|
||||
}
|
||||
{
|
||||
hw-address = "f0:2f:9e:c1:74:72";
|
||||
ip-address = "10.42.115.21";
|
||||
hostname = "firetv-bedroom";
|
||||
}
|
||||
{
|
||||
hw-address = "30:05:5c:56:62:37";
|
||||
ip-address = "10.42.115.100";
|
||||
server-hostname = "brn30055c566237";
|
||||
}
|
||||
];
|
||||
}
|
||||
{
|
||||
pools = [
|
||||
{
|
||||
pool = "10.42.127.10 - 10.42.127.254";
|
||||
}
|
||||
];
|
||||
subnet = "10.42.127.0/24";
|
||||
interface = "guest";
|
||||
option-data = [
|
||||
{
|
||||
name = "routers";
|
||||
data = "10.42.127.1";
|
||||
}
|
||||
{
|
||||
name = "domain-name-servers";
|
||||
data = "9.9.9.9";
|
||||
}
|
||||
];
|
||||
}
|
||||
{
|
||||
pools = [
|
||||
{
|
||||
pool = "10.42.116.100 - 10.42.116.240";
|
||||
}
|
||||
];
|
||||
subnet = "10.42.116.0/24";
|
||||
interface = "smart";
|
||||
option-data = [
|
||||
{
|
||||
name = "routers";
|
||||
data = "10.42.116.1";
|
||||
}
|
||||
{
|
||||
name = "domain-name";
|
||||
data = "cloonar.smart";
|
||||
}
|
||||
{
|
||||
name = "domain-name-servers";
|
||||
data = "10.42.116.1";
|
||||
}
|
||||
];
|
||||
reservations = [
|
||||
# need fixed ips for all shelly devices
|
||||
# living room 1 - 14
|
||||
# 10.42.100.2 # bulb1
|
||||
# 10.42.100.3 # bulb2
|
||||
# 10.42.100.4 # bulb3
|
||||
# 10.42.100.5 # bulb4
|
||||
# 10.42.100.6 # bulb5
|
||||
# 10.42.100.7 # bulb6
|
||||
# 10.42.100.8 # piano
|
||||
# 10.42.100.9 # switch
|
||||
# 10.42.100.10 # steamdeck
|
||||
# kitchen:
|
||||
# 10.42.100.17 # coffee
|
||||
# 10.42.100.18 # bar
|
||||
# bedroom:
|
||||
# 10.42.100.33 # switch
|
||||
# 10.42.100.34 # button1
|
||||
# 10.42.100.35 # button2
|
||||
# 10.42.100.36 # readingled1
|
||||
# 10.42.100.37 # readingled2
|
||||
# 10.42.100.38 # bedled
|
||||
# bath:
|
||||
# 10.42.100.49 # switch
|
||||
# 10.42.100.50 # bulb1
|
||||
# 10.42.100.51 # bulb2
|
||||
# 10.42.100.52 # smallswitch
|
||||
# 10.42.100.53 # ht
|
||||
# hallway:
|
||||
# 10.42.100.65 # switch
|
||||
# 10.42.100.66 # bulb1
|
||||
# 10.42.100.67 # bulb2
|
||||
# 10.42.100.68 # bulb3
|
||||
# 10.42.100.69 # bulb4
|
||||
# toilet:
|
||||
# 10.42.100.81 # switch
|
||||
# 10.42.100.82 # bulb
|
||||
# storage:
|
||||
# 10.42.100.97 # switch
|
||||
|
||||
{
|
||||
hw-address = "60:a4:23:97:4a:ec";
|
||||
ip-address = "10.42.116.21";
|
||||
server-hostname = "shellymotionsensor-60A423974AEC";
|
||||
}
|
||||
{
|
||||
hw-address = "8c:aa:b5:61:6f:e2";
|
||||
ip-address = "10.42.116.103";
|
||||
server-hostname = "ShellyBulbDuo-8CAAB5616FE2";
|
||||
}
|
||||
{
|
||||
hw-address = "8c:aa:b5:61:6e:9e";
|
||||
ip-address = "10.42.116.104";
|
||||
server-hostname = "ShellyBulbDuo-8CAAB5616E9E";
|
||||
}
|
||||
{
|
||||
hw-address = "cc:50:e3:bc:27:64";
|
||||
ip-address = "10.42.116.112";
|
||||
server-hostname = "Nuki_Bridge_1A753F72";
|
||||
}
|
||||
{
|
||||
hw-address = "e8:db:84:a9:ea:be";
|
||||
ip-address = "10.42.116.117";
|
||||
server-hostname = "ShellyBulbDuo-E8DB84A9EABE";
|
||||
}
|
||||
{
|
||||
hw-address = "e8:db:84:a9:d1:8b";
|
||||
ip-address = "10.42.116.119";
|
||||
server-hostname = "shellycolorbulb-E8DB84A9D18B";
|
||||
}
|
||||
{
|
||||
hw-address = "3c:61:05:e5:96:e0";
|
||||
ip-address = "10.42.116.120";
|
||||
server-hostname = "shellycolorbulb-3C6105E596E0";
|
||||
}
|
||||
{
|
||||
hw-address = "e8:db:84:a9:d7:ef";
|
||||
ip-address = "10.42.116.121";
|
||||
server-hostname = "shellycolorbulb-E8DB84A9D7EF";
|
||||
}
|
||||
{
|
||||
hw-address = "e8:db:84:aa:51:aa";
|
||||
ip-address = "10.42.116.122";
|
||||
server-hostname = "shellycolorbulb-E8DB84AA51AA";
|
||||
}
|
||||
|
||||
{
|
||||
hw-address = "34:94:54:79:bc:57";
|
||||
ip-address = "10.42.116.130";
|
||||
server-hostname = "shellycolorbulb-34945479bc57";
|
||||
}
|
||||
{
|
||||
hw-address = "48:55:19:d9:a1:b2";
|
||||
ip-address = "10.42.116.131";
|
||||
server-hostname = "shellycolorbulb-485519d9a1b2";
|
||||
}
|
||||
{
|
||||
hw-address = "48:55:19:d9:ae:95";
|
||||
ip-address = "10.42.116.132";
|
||||
server-hostname = "shellycolorbulb-485519d9ae95";
|
||||
}
|
||||
{
|
||||
hw-address = "48:55:19:d9:4a:28";
|
||||
ip-address = "10.42.116.133";
|
||||
server-hostname = "shellycolorbulb-485519d94a28";
|
||||
}
|
||||
{
|
||||
hw-address = "48:55:19:da:6b:6a";
|
||||
ip-address = "10.42.116.134";
|
||||
server-hostname = "shellycolorbulb-485519da6b6a";
|
||||
}
|
||||
{
|
||||
hw-address = "48:55:19:d9:e0:18";
|
||||
ip-address = "10.42.116.135";
|
||||
server-hostname = "shellycolorbulb-485519d9e018";
|
||||
}
|
||||
|
||||
{
|
||||
hw-address = "34:6f:24:f3:af:ad";
|
||||
ip-address = "10.42.116.137";
|
||||
server-hostname = "daikin86604";
|
||||
}
|
||||
{
|
||||
hw-address = "34:6f:24:c1:f8:54";
|
||||
ip-address = "10.42.116.139";
|
||||
server-hostname = "daikin53800";
|
||||
}
|
||||
];
|
||||
}
|
||||
];
|
||||
valid-lifetime = 4000;
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -1,83 +0,0 @@
|
||||
{ config, pkgs, ... }:
|
||||
let
|
||||
domain = "sync.cloonar.com";
|
||||
in {
|
||||
sops.secrets.firefox-sync = { };
|
||||
|
||||
security.acme.certs."${domain}" = {
|
||||
group = "nginx";
|
||||
};
|
||||
|
||||
containers."firefox-sync" = {
|
||||
autoStart = true;
|
||||
ephemeral = false; # because of ssh key
|
||||
privateNetwork = true;
|
||||
hostBridge = "server";
|
||||
hostAddress = "10.42.97.1";
|
||||
localAddress = "10.42.97.51/24";
|
||||
bindMounts = {
|
||||
"/run/secrets/firefox-sync" = {
|
||||
hostPath = "/run/secrets/firefox-sync";
|
||||
isReadOnly = true;
|
||||
};
|
||||
"/var/lib/acme/${domain}/" = {
|
||||
hostPath = "${config.security.acme.certs.${domain}.directory}";
|
||||
isReadOnly = true;
|
||||
};
|
||||
};
|
||||
config = { lib, config, pkgs, ... }: {
|
||||
networking = {
|
||||
hostName = "firefox-sync";
|
||||
useHostResolvConf = false;
|
||||
defaultGateway = {
|
||||
address = "10.42.97.1";
|
||||
interface = "eth0";
|
||||
};
|
||||
firewall.enable = false;
|
||||
nameservers = [ "10.42.97.1" ];
|
||||
};
|
||||
|
||||
services.nginx.enable = true;
|
||||
services.nginx.virtualHosts."${domain}" = {
|
||||
sslCertificate = "/var/lib/acme/${domain}/fullchain.pem";
|
||||
sslCertificateKey = "/var/lib/acme/${domain}/key.pem";
|
||||
sslTrustedCertificate = "/var/lib/acme/${domain}/chain.pem";
|
||||
listen = [
|
||||
{
|
||||
addr = "0.0.0.0";
|
||||
ssl = true;
|
||||
port = 5000;
|
||||
}
|
||||
];
|
||||
locations."/" = {
|
||||
proxyPass = "http://localhost:5001/";
|
||||
recommendedProxySettings = true;
|
||||
};
|
||||
};
|
||||
|
||||
services.mysql.package = pkgs.mariadb;
|
||||
services.firefox-syncserver = {
|
||||
enable = true;
|
||||
singleNode = {
|
||||
enable = true;
|
||||
enableNginx = false;
|
||||
hostname = domain;
|
||||
};
|
||||
settings = {
|
||||
port = 5001;
|
||||
tokenserver.enable = true;
|
||||
};
|
||||
secrets = "/run/secrets/firefox-sync";
|
||||
logLevel = "trace";
|
||||
};
|
||||
|
||||
services.openssh.enable = true;
|
||||
users.users.root.openssh.authorizedKeys.keys = [
|
||||
"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDN/2SAFm50kraB1fepAizox/QRXxB7WbqVbH+5OPalDT47VIJGNKOKhixQoqhABHxEoLxdf/C83wxlCVlPV9poLfDgVkA3Lyt5r3tSFQ6QjjOJAgchWamMsxxyGBedhKvhiEzcr/Lxytnoz3kjDG8fqQJwEpdqMmJoMUfyL2Rqp16u+FQ7d5aJtwO8EUqovhMaNO7rggjPpV/uMOg+tBxxmscliN7DLuP4EMTA/FwXVzcFNbOx3K9BdpMRAaSJt4SWcJO2cS2KHA5n/H+PQI7nz5KN3Yr/upJN5fROhi/SHvK39QOx12Pv7FCuWlc+oR68vLaoCKYhnkl3DnCfc7A7"
|
||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIRQuPqH5fdX3KEw7DXzWEdO3AlUn1oSmtJtHB71ICoH Generated By Termius"
|
||||
];
|
||||
|
||||
system.stateVersion = "23.05";
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -1,160 +0,0 @@
|
||||
{ pkgs, ... }: {
|
||||
networking = {
|
||||
firewall.checkReversePath = false;
|
||||
nat.enable = false;
|
||||
nftables = {
|
||||
enable = true;
|
||||
tables = {
|
||||
"cloonar-fw" = {
|
||||
family = "inet";
|
||||
content = ''
|
||||
chain output {
|
||||
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"
|
||||
iifname "lan" counter accept comment "Spice"
|
||||
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 {
|
||||
udp dport != { 53, 5353 } ct state new limit rate over 1/second burst 10 packets drop comment "rate limit for new connections"
|
||||
iifname lo accept
|
||||
iifname "wan" udp dport 51820 counter accept comment "Wireguard traffic"
|
||||
iifname "wan" tcp dport 9273 counter accept comment "Prometheus traffic"
|
||||
iifname "lan" tcp dport 5931 counter accept comment "Spice"
|
||||
iifname { "wan", "server", "vserver", "vm-*", "lan", "wg_cloonar" } counter accept comment "allow trusted to router"
|
||||
iifname { "multimedia", "smart", "infrastructure", "podman0" } udp dport { 53, 5353 } counter accept comment "DNS"
|
||||
iifname { "wan", "multimedia" } icmp type { echo-request, destination-unreachable, time-exceeded } counter accept comment "Allow select ICMP"
|
||||
|
||||
# Accept mDNS for avahi reflection
|
||||
iifname "server" ip saddr 10.42.113.20/32 tcp dport { llmnr } counter accept
|
||||
iifname "server" ip saddr 10.42.113.20/32 udp dport { mdns, llmnr } counter accept
|
||||
|
||||
# Allow all returning traffic
|
||||
ct state { established, related } counter accept
|
||||
|
||||
# Allow returning traffic from wrwks and drop everthing else
|
||||
iifname "wrwks" ct state { established, related } counter accept
|
||||
iifname "wrwks" drop
|
||||
|
||||
# Allow returning traffic from wg_epicenter and drop everthing else
|
||||
iifname "wg_epicenter" ct state { established, related } counter accept
|
||||
iifname "wg_epicenter" drop
|
||||
|
||||
# Allow returning traffic from wg_ghetto_at and drop everthing else
|
||||
iifname "wg_ghetto_at" ct state { established, related } counter accept
|
||||
iifname "wg_ghetto_at" drop
|
||||
|
||||
# Allow returning traffic from wan and drop everthing else
|
||||
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
|
||||
|
||||
# broadcast
|
||||
iifname "server" oifname { "lan", "multimedia" } udp dport { 9 } counter accept comment "wakeonlan"
|
||||
|
||||
# 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.113.20/32 oifname { "lan" } counter accept
|
||||
|
||||
# smart home coap
|
||||
iifname "smart" oifname "server" ip daddr 10.42.113.20/32 udp dport { 5683 } counter accept
|
||||
iifname "smart" oifname "server" ip daddr 10.42.113.20/32 tcp dport { 1883 } counter accept
|
||||
|
||||
# Forward to git server
|
||||
oifname "server" ip daddr 10.42.113.50 tcp dport { 22 } counter accept
|
||||
oifname "server" ip daddr 10.42.113.5 tcp dport { 80, 443 } counter accept
|
||||
|
||||
# lan and vpn to any
|
||||
# TODO: disable wan when finished
|
||||
iifname { "lan", "server", "vserver", "wg_cloonar" } oifname { "lan", "vb-*", "vm-*", "server", "vserver", "infrastructure", "multimedia", "smart", "wg_cloonar" } counter log prefix "basic forward allow rule" accept
|
||||
iifname { "lan", "server", "wg_cloonar" } oifname { "wrwks", "wg_epicenter", "wg_ghetto_at" } counter accept
|
||||
iifname { "infrastructure" } oifname { "server", "vserver" } counter accept
|
||||
iifname { "lan", "wan" } udp dport { 8211, 27015 } counter accept comment "palworld"
|
||||
|
||||
# accept palword server
|
||||
iifname { "wan", "lan" } oifname "podman0" udp dport { 8211, 27015 } counter accept comment "palworld"
|
||||
# forward to ark server
|
||||
oifname "server" ip daddr 10.42.113.201 tcp dport { 27020 } counter accept comment "ark survival evolved"
|
||||
oifname "server" ip daddr 10.42.113.201 udp dport { 7777, 7778, 27015 } counter accept comment "ark survival evolved"
|
||||
|
||||
# firefox-sync
|
||||
oifname "server" ip daddr 10.42.113.51 tcp dport { 5000 } counter accept comment "firefox-sync"
|
||||
|
||||
# allow all established, related
|
||||
ct state { established, related } accept comment "Allow established traffic"
|
||||
|
||||
# Allow trusted network WAN access
|
||||
iifname {
|
||||
"lan",
|
||||
"infrastructure",
|
||||
"server",
|
||||
"vserver",
|
||||
"multimedia",
|
||||
"smart",
|
||||
"wg_cloonar",
|
||||
"podman*",
|
||||
"guest",
|
||||
"vb-*",
|
||||
"vm-*",
|
||||
} 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"
|
||||
}
|
||||
'';
|
||||
};
|
||||
"cloonar-nat" = {
|
||||
family = "ip";
|
||||
content = ''
|
||||
chain prerouting {
|
||||
type nat hook prerouting priority filter; policy accept;
|
||||
iifname "server" ip daddr 10.42.96.255 udp dport { 9 } dnat to 10.42.96.255
|
||||
# iifname "wan" tcp dport { 22 } dnat to 10.42.113.50
|
||||
iifname "wan" tcp dport { 80, 443 } dnat to 10.42.113.5
|
||||
iifname "wan" tcp dport { 5000 } dnat to 10.42.113.51
|
||||
iifname { "wan", "lan" } udp dport { 7777, 7778, 27015 } dnat to 10.42.113.201
|
||||
iifname { "wan", "lan" } tcp dport { 27020 } dnat to 10.42.113.201
|
||||
}
|
||||
|
||||
# Setup NAT masquerading on external interfaces
|
||||
chain postrouting {
|
||||
type nat hook postrouting priority filter; policy accept;
|
||||
oifname { "wan", "wg_cloonar", "wrwks", "wg_epicenter", "wg_ghetto_at" } masquerade
|
||||
iifname { "wan", "wg_cloonar" } ip daddr 10.42.113.50 masquerade
|
||||
iifname { "wan", "wg_cloonar" } ip daddr 10.42.113.51 masquerade
|
||||
iifname { "wan", "wg_cloonar" } ip daddr 10.42.113.201 masquerade
|
||||
}
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
{ config, pkgs, ... }:
|
||||
let
|
||||
configure_prom = builtins.toFile "prometheus.yml" ''
|
||||
scrape_configs:
|
||||
- job_name: 'server'
|
||||
stream_parse: true
|
||||
static_configs:
|
||||
- targets:
|
||||
- ${config.networking.hostName}:9100
|
||||
'';
|
||||
in {
|
||||
sops.secrets.victoria-agent-env = {
|
||||
sopsFile = ../utils/modules/victoriametrics/secrets.yaml;
|
||||
};
|
||||
|
||||
services.prometheus.exporters.node.enable = true;
|
||||
|
||||
systemd.services.export-fw-to-prometheus = {
|
||||
path = with pkgs; [victoriametrics];
|
||||
enable = true;
|
||||
after = ["network-online.target"];
|
||||
wants = ["network-online.target"];
|
||||
wantedBy = ["multi-user.target"];
|
||||
script = "vmagent -promscrape.config=${configure_prom} -envflag.enable -remoteWrite.url=https://victoria-server.cloonar.com/api/v1/write";
|
||||
|
||||
serviceConfig = {
|
||||
EnvironmentFile=config.sops.secrets.victoria-agent-env.path;
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -1,175 +0,0 @@
|
||||
{ config, nixpkgs, pkgs, ... }: let
|
||||
hostname = "git";
|
||||
json = pkgs.formats.json { };
|
||||
pkgs-with-gitea = import (builtins.fetchGit {
|
||||
name = "new-gitea";
|
||||
url = "https://github.com/nixos/nixpkgs/";
|
||||
rev = "159be5db480d1df880a0135ca0bfed84c2f88353";
|
||||
}) {};
|
||||
in {
|
||||
microvm.vms = {
|
||||
gitea = {
|
||||
config = {
|
||||
microvm = {
|
||||
hypervisor = "cloud-hypervisor";
|
||||
shares = [
|
||||
{
|
||||
source = "/nix/store";
|
||||
mountPoint = "/nix/.ro-store";
|
||||
tag = "ro-store";
|
||||
proto = "virtiofs";
|
||||
}
|
||||
{
|
||||
source = "/var/lib/acme/git.cloonar.com";
|
||||
mountPoint = "/var/lib/acme/${hostname}.cloonar.com";
|
||||
tag = "ro-cert";
|
||||
proto = "virtiofs";
|
||||
}
|
||||
];
|
||||
interfaces = [
|
||||
{
|
||||
type = "tap";
|
||||
id = "vm-${hostname}";
|
||||
mac = "02:00:00:00:00:01";
|
||||
}
|
||||
];
|
||||
};
|
||||
|
||||
imports = [
|
||||
../fleet.nix
|
||||
];
|
||||
|
||||
environment.systemPackages = with pkgs; [
|
||||
vim # my preferred editor
|
||||
];
|
||||
|
||||
networking = {
|
||||
hostName = hostname;
|
||||
firewall = {
|
||||
enable = true;
|
||||
allowedTCPPorts = [ 22 80 443 ];
|
||||
};
|
||||
};
|
||||
|
||||
services.nginx.enable = true;
|
||||
services.nginx.virtualHosts."${hostname}.cloonar.com" = {
|
||||
sslCertificate = "/var/lib/acme/${hostname}.cloonar.com/fullchain.pem";
|
||||
sslCertificateKey = "/var/lib/acme/${hostname}.cloonar.com/key.pem";
|
||||
sslTrustedCertificate = "/var/lib/acme/${hostname}.cloonar.com/chain.pem";
|
||||
forceSSL = true;
|
||||
locations."/" = {
|
||||
proxyPass = "http://localhost:3001/";
|
||||
};
|
||||
};
|
||||
|
||||
services.gitea = {
|
||||
enable = true;
|
||||
package = pkgs-with-gitea.gitea;
|
||||
appName = "Cloonar Gitea server"; # Give the site a name
|
||||
settings = {
|
||||
server = {
|
||||
ROOT_URL = "https://${hostname}.cloonar.com/";
|
||||
HTTP_PORT = 3001;
|
||||
DOMAIN = "${hostname}.cloonar.com";
|
||||
};
|
||||
openid = {
|
||||
ENABLE_OPENID_SIGNIN = true;
|
||||
ENABLE_OPENID_SIGNUP = true;
|
||||
WHITELISTED_URIS = "auth.cloonar.com";
|
||||
};
|
||||
service = {
|
||||
DISABLE_REGISTRATION = true;
|
||||
ALLOW_ONLY_EXTERNAL_REGISTRATION = true;
|
||||
SHOW_REGISTRATION_BUTTON = false;
|
||||
};
|
||||
actions.ENABLED=true;
|
||||
};
|
||||
};
|
||||
|
||||
services.openssh.enable = true;
|
||||
users.users.root.openssh.authorizedKeys.keys = [
|
||||
"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDN/2SAFm50kraB1fepAizox/QRXxB7WbqVbH+5OPalDT47VIJGNKOKhixQoqhABHxEoLxdf/C83wxlCVlPV9poLfDgVkA3Lyt5r3tSFQ6QjjOJAgchWamMsxxyGBedhKvhiEzcr/Lxytnoz3kjDG8fqQJwEpdqMmJoMUfyL2Rqp16u+FQ7d5aJtwO8EUqovhMaNO7rggjPpV/uMOg+tBxxmscliN7DLuP4EMTA/FwXVzcFNbOx3K9BdpMRAaSJt4SWcJO2cS2KHA5n/H+PQI7nz5KN3Yr/upJN5fROhi/SHvK39QOx12Pv7FCuWlc+oR68vLaoCKYhnkl3DnCfc7A7"
|
||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIRQuPqH5fdX3KEw7DXzWEdO3AlUn1oSmtJtHB71ICoH Generated By Termius"
|
||||
];
|
||||
|
||||
system.stateVersion = "22.05";
|
||||
};
|
||||
};
|
||||
|
||||
gitea-runner = {
|
||||
config = {
|
||||
microvm = {
|
||||
mem = 12288;
|
||||
shares = [
|
||||
{
|
||||
source = "/nix/store";
|
||||
mountPoint = "/nix/.ro-store";
|
||||
tag = "ro-store";
|
||||
proto = "virtiofs";
|
||||
}
|
||||
{
|
||||
source = "/run/secrets";
|
||||
mountPoint = "/run/secrets";
|
||||
tag = "ro-token";
|
||||
proto = "virtiofs";
|
||||
}
|
||||
];
|
||||
volumes = [
|
||||
{
|
||||
image = "rootfs.img";
|
||||
mountPoint = "/";
|
||||
size = 102400;
|
||||
}
|
||||
];
|
||||
interfaces = [
|
||||
{
|
||||
type = "tap";
|
||||
id = "vm-gitea-runner";
|
||||
mac = "02:00:00:00:00:02";
|
||||
}
|
||||
];
|
||||
};
|
||||
|
||||
environment.systemPackages = with pkgs; [
|
||||
vim # my preferred editor
|
||||
];
|
||||
|
||||
networking.hostName = "gitea-runner";
|
||||
|
||||
virtualisation.podman.enable = true;
|
||||
|
||||
services.gitea-actions-runner.instances.vm = {
|
||||
enable = true;
|
||||
url = "https://git.cloonar.com";
|
||||
name = "vm";
|
||||
tokenFile = "/run/secrets/gitea-runner-token";
|
||||
labels = [
|
||||
"ubuntu-latest:docker://shivammathur/node:latest"
|
||||
];
|
||||
settings = {
|
||||
container = {
|
||||
network = "podman";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
services.openssh.enable = true;
|
||||
users.users.root.openssh.authorizedKeys.keys = [
|
||||
"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDN/2SAFm50kraB1fepAizox/QRXxB7WbqVbH+5OPalDT47VIJGNKOKhixQoqhABHxEoLxdf/C83wxlCVlPV9poLfDgVkA3Lyt5r3tSFQ6QjjOJAgchWamMsxxyGBedhKvhiEzcr/Lxytnoz3kjDG8fqQJwEpdqMmJoMUfyL2Rqp16u+FQ7d5aJtwO8EUqovhMaNO7rggjPpV/uMOg+tBxxmscliN7DLuP4EMTA/FwXVzcFNbOx3K9BdpMRAaSJt4SWcJO2cS2KHA5n/H+PQI7nz5KN3Yr/upJN5fROhi/SHvK39QOx12Pv7FCuWlc+oR68vLaoCKYhnkl3DnCfc7A7"
|
||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIRQuPqH5fdX3KEw7DXzWEdO3AlUn1oSmtJtHB71ICoH Generated By Termius"
|
||||
];
|
||||
|
||||
system.stateVersion = "22.05";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
sops.secrets.gitea-runner-token = {};
|
||||
|
||||
environment = {
|
||||
systemPackages = [
|
||||
pkgs.qemu
|
||||
pkgs.quickemu
|
||||
];
|
||||
};
|
||||
}
|
||||
@@ -1,110 +0,0 @@
|
||||
{ config, pkgs, ... }:
|
||||
let
|
||||
cids = import ../modules/staticids.nix;
|
||||
domain = "git.cloonar.com";
|
||||
|
||||
user = {
|
||||
isSystemUser = true;
|
||||
uid = cids.uids.gitea;
|
||||
group = "gitea";
|
||||
home = "/var/lib/gitea";
|
||||
createHome = true;
|
||||
};
|
||||
group = {
|
||||
gid = cids.gids.gitea;
|
||||
};
|
||||
in
|
||||
{
|
||||
users.users.gitea = user;
|
||||
users.groups.gitea = group;
|
||||
|
||||
security.acme.certs."${domain}" = {
|
||||
group = "nginx";
|
||||
};
|
||||
|
||||
containers.git = {
|
||||
autoStart = true;
|
||||
ephemeral = false; # because of ssh key
|
||||
privateNetwork = true;
|
||||
hostBridge = "server";
|
||||
hostAddress = "10.42.97.1";
|
||||
localAddress = "10.42.97.50/24";
|
||||
bindMounts = {
|
||||
"/var/lib/gitea" = {
|
||||
hostPath = "/var/lib/gitea/";
|
||||
isReadOnly = false;
|
||||
};
|
||||
"/var/lib/acme/gitea/" = {
|
||||
hostPath = "${config.security.acme.certs.${domain}.directory}";
|
||||
isReadOnly = true;
|
||||
};
|
||||
};
|
||||
config = { lib, config, pkgs, ... }: {
|
||||
imports = [
|
||||
../fleet.nix
|
||||
];
|
||||
|
||||
environment.systemPackages = with pkgs; [
|
||||
vim # my preferred editor
|
||||
];
|
||||
|
||||
networking = {
|
||||
hostName = "git";
|
||||
useHostResolvConf = false;
|
||||
defaultGateway = {
|
||||
address = "10.42.96.1";
|
||||
interface = "eth0";
|
||||
};
|
||||
firewall.enable = false;
|
||||
nameservers = [ "10.42.97.1" ];
|
||||
};
|
||||
|
||||
services.nginx.enable = true;
|
||||
services.nginx.virtualHosts."${domain}" = {
|
||||
sslCertificate = "/var/lib/acme/gitea/fullchain.pem";
|
||||
sslCertificateKey = "/var/lib/acme/gitea/key.pem";
|
||||
sslTrustedCertificate = "/var/lib/acme/gitea/chain.pem";
|
||||
forceSSL = true;
|
||||
locations."/" = {
|
||||
proxyPass = "http://localhost:3001/";
|
||||
};
|
||||
};
|
||||
|
||||
services.gitea = {
|
||||
enable = true;
|
||||
appName = "Cloonar Gitea server"; # Give the site a name
|
||||
settings = {
|
||||
server = {
|
||||
ROOT_URL = "https://${domain}/";
|
||||
HTTP_PORT = 3001;
|
||||
DOMAIN = domain;
|
||||
};
|
||||
openid = {
|
||||
ENABLE_OPENID_SIGNIN = false;
|
||||
ENABLE_OPENID_SIGNUP = true;
|
||||
WHITELISTED_URIS = "auth.cloonar.com";
|
||||
};
|
||||
service = {
|
||||
DISABLE_REGISTRATION = false;
|
||||
ALLOW_ONLY_EXTERNAL_REGISTRATION = true;
|
||||
SHOW_REGISTRATION_BUTTON = false;
|
||||
};
|
||||
actions.ENABLED=true;
|
||||
};
|
||||
};
|
||||
|
||||
services.openssh.enable = true;
|
||||
users.users.root.openssh.authorizedKeys.keys = [
|
||||
"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDN/2SAFm50kraB1fepAizox/QRXxB7WbqVbH+5OPalDT47VIJGNKOKhixQoqhABHxEoLxdf/C83wxlCVlPV9poLfDgVkA3Lyt5r3tSFQ6QjjOJAgchWamMsxxyGBedhKvhiEzcr/Lxytnoz3kjDG8fqQJwEpdqMmJoMUfyL2Rqp16u+FQ7d5aJtwO8EUqovhMaNO7rggjPpV/uMOg+tBxxmscliN7DLuP4EMTA/FwXVzcFNbOx3K9BdpMRAaSJt4SWcJO2cS2KHA5n/H+PQI7nz5KN3Yr/upJN5fROhi/SHvK39QOx12Pv7FCuWlc+oR68vLaoCKYhnkl3DnCfc7A7"
|
||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIRQuPqH5fdX3KEw7DXzWEdO3AlUn1oSmtJtHB71ICoH Generated By Termius"
|
||||
];
|
||||
|
||||
users.users.gitea = user;
|
||||
users.groups.gitea = group;
|
||||
|
||||
system.stateVersion = "23.05";
|
||||
};
|
||||
};
|
||||
|
||||
sops.secrets.gitea-runner = {};
|
||||
}
|
||||
@@ -1,60 +0,0 @@
|
||||
{ config, ... }: {
|
||||
services.home-assistant.config = {
|
||||
sensor = [
|
||||
{
|
||||
platform = "rest";
|
||||
name = "creality extruder";
|
||||
resource = "http://k1c-63e9.cloonar.smart:7125/printer/objects/query?extruder";
|
||||
value_template = "OK";
|
||||
json_attributes_path = "$.result.status.extruder";
|
||||
json_attributes = [
|
||||
"pressure_advance"
|
||||
"power"
|
||||
"target"
|
||||
"temperature"
|
||||
];
|
||||
}
|
||||
{
|
||||
platform = "rest";
|
||||
name = "creality print stats";
|
||||
resource = "http://k1c-63e9.cloonar.smart:7125/printer/objects/query?print_stats";
|
||||
value_template = "OK";
|
||||
json_attributes_path = "$.result.status.print_stats";
|
||||
json_attributes = [
|
||||
"filename"
|
||||
"total_duration"
|
||||
"print_duration"
|
||||
"filament_used"
|
||||
"state"
|
||||
"message"
|
||||
];
|
||||
}
|
||||
{
|
||||
platform = "template";
|
||||
sensors = {
|
||||
crality_hotend_actual = {
|
||||
friendly_name = "Hot End Actual";
|
||||
value_template = "{{ state_attr('sensor.creality_extruder', 'temperature') | float | round(1) }}";
|
||||
device_class = "temperature";
|
||||
unit_of_measurement = "°C";
|
||||
};
|
||||
};
|
||||
}
|
||||
];
|
||||
"automation 3d printer state" = {
|
||||
alias = "3d printer state change";
|
||||
trigger = [
|
||||
{
|
||||
platform = "template";
|
||||
value_template = "{{ state_attr('sensor.creality_print_stats','state') == 'standby' }}";
|
||||
}
|
||||
];
|
||||
action = {
|
||||
service = "notify.mobile_app_dominiks_iphone";
|
||||
data = {
|
||||
message = "Printer status changed to {{ state_attr('sensor.creality_print_stats','state') }}";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -1,120 +0,0 @@
|
||||
{
|
||||
|
||||
services.home-assistant.extraComponents = [
|
||||
"daikin"
|
||||
"enocean"
|
||||
];
|
||||
services.home-assistant.customComponents = [
|
||||
(import ./custom-components/scheduler.nix)
|
||||
];
|
||||
services.home-assistant.customLovelaceModules = [
|
||||
(import ./custom-components/lovelace-scheduler.nix)
|
||||
];
|
||||
|
||||
services.home-assistant.config = {
|
||||
sensor = [
|
||||
{
|
||||
name = "Living Room Window Handle 2";
|
||||
platform = "enocean";
|
||||
id = [ 129 0 227 53 ];
|
||||
device_class = "windowhandle";
|
||||
}
|
||||
{
|
||||
name = "Living Room Window Handle 1";
|
||||
platform = "enocean";
|
||||
id = [ 129 0 229 8 ];
|
||||
device_class = "windowhandle";
|
||||
}
|
||||
];
|
||||
"automation ac_livingroom" = {
|
||||
alias = "ac_livingroom";
|
||||
trigger = [
|
||||
{
|
||||
platform = "state";
|
||||
entity_id = "sensor.windowhandle_living_room_window_handle_1";
|
||||
to = [ "open" "tilt" ];
|
||||
}
|
||||
{
|
||||
platform = "state";
|
||||
entity_id = "sensor.windowhandle_living_room_window_handle_2";
|
||||
to = [ "open" "tilt" ];
|
||||
}
|
||||
];
|
||||
action = {
|
||||
service = "climate.set_hvac_mode";
|
||||
target = {
|
||||
entity_id = "climate.living_room";
|
||||
};
|
||||
data = {
|
||||
hvac_mode = "off";
|
||||
};
|
||||
};
|
||||
};
|
||||
"automation ac_eco" = {
|
||||
alias = "ac_eco";
|
||||
trigger = {
|
||||
platform = "state";
|
||||
entity_id = [
|
||||
"climate.living_room"
|
||||
"climate.bedroom"
|
||||
];
|
||||
to = [
|
||||
"heat"
|
||||
"cold"
|
||||
];
|
||||
};
|
||||
action = {
|
||||
service = "climate.set_preset_mode";
|
||||
target = {
|
||||
entity_id = "{{ trigger.entity_id }}";
|
||||
};
|
||||
data = {
|
||||
preset_mode = "eco";
|
||||
};
|
||||
};
|
||||
};
|
||||
"automation bedroom_ac_on" = {
|
||||
alias = "bedroom ac on";
|
||||
trigger = {
|
||||
platform = "time";
|
||||
at = "00:30:00";
|
||||
};
|
||||
action = {
|
||||
choose = [
|
||||
{
|
||||
conditions = [ "{{ states('sensor.bedroom_ac_inside_temperature') > 25 and states('sensor.bedroom_ac_outside_temperature') > 22 }}" ];
|
||||
sequence = [
|
||||
{
|
||||
service = "climate.set_hvac_mode";
|
||||
target = {
|
||||
entity_id = "climate.bedroom";
|
||||
};
|
||||
data = {
|
||||
hvac_mode = "cold";
|
||||
};
|
||||
}
|
||||
];
|
||||
}
|
||||
];
|
||||
};
|
||||
};
|
||||
"automation bedroom_ac_off" = {
|
||||
alias = "bedroom ac on";
|
||||
trigger = {
|
||||
platform = "template";
|
||||
value_template = ''
|
||||
{{ now().timestamp() | timestamp_custom('%H:%M') == (as_timestamp(strptime(states('sensor.bedtime_alarm'), "%H:%M")) - 1800) | timestamp_custom('%H:%M', false) }}
|
||||
'';
|
||||
};
|
||||
action = {
|
||||
service = "climate.set_hvac_mode";
|
||||
target = {
|
||||
entity_id = "climate.bedroom";
|
||||
};
|
||||
data = {
|
||||
hvac_mode = "off";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -1,91 +0,0 @@
|
||||
{
|
||||
services.home-assistant.config = {
|
||||
sensor = [
|
||||
{
|
||||
platform = "template";
|
||||
sensors = {
|
||||
sensors_lowest_battery_level = {
|
||||
friendly_name = "Lowest battery level (Sensors)";
|
||||
entity_id = "sun.sun";
|
||||
device_class = "battery";
|
||||
unit_of_measurement = "%";
|
||||
value_template = ''
|
||||
{% set domains = ['sensor', 'battery'] %}
|
||||
{% set ns = namespace(min_batt=100, entities=[]) %}
|
||||
{%- set exclude_sensors = ['sensor.sensors_lowest_battery_level','sensor.dominiks_iphone_battery_level'] -%}
|
||||
{% for domain in domains %}
|
||||
{% set ns.entities = states[domain] %}
|
||||
{% for sensor in exclude_sensors %}
|
||||
{% set ns.entities = ns.entities | rejectattr('entity_id', 'equalto', sensor) %}
|
||||
{% endfor %}
|
||||
{% set batt_sensors = ns.entities | selectattr('attributes.device_class','equalto','battery') | map(attribute='state') | reject('equalto', 'unknown') | reject('equalto', 'None') | map('int') | reject('equalto', 0) | list %}
|
||||
{% set batt_attrs = ns.entities | selectattr('attributes.battery_level','defined') | map(attribute='attributes.battery_level') | reject('equalto', 'unknown') | reject('equalto', 'None') | map('int') | reject('equalto', 0) | list %}
|
||||
{% set batt_lvls = batt_sensors + batt_attrs %}
|
||||
{% if batt_lvls|length > 0 %}
|
||||
{% set _min = batt_lvls|min %}
|
||||
{% if _min < ns.min_batt %}
|
||||
{% set ns.min_batt = _min %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{{ ns.min_batt }}
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
||||
];
|
||||
binary_sensor = [
|
||||
{
|
||||
platform = "template";
|
||||
sensors = {
|
||||
sensor_low_battery = {
|
||||
value_template = "{{ states('sensor.sensors_lowest_battery_level')|int <= 30 }}";
|
||||
friendly_name = "A sensor has low battery";
|
||||
device_class = "problem";
|
||||
};
|
||||
};
|
||||
}
|
||||
];
|
||||
alert = {
|
||||
sensor_low_battery = {
|
||||
name = "Sensor has low battery!";
|
||||
message = ''
|
||||
{% set domains = ['sensor', 'battery'] %}
|
||||
{% set threshold = 30 %}
|
||||
{%- set exclude_entities = ['sensor.sensors_lowest_battery_level','sensor.dominiks_iphone_battery_level','sensor.roborock_s8_pro_ultra_battery'] -%}
|
||||
Sensors are below 50% battery:
|
||||
{% for domain in domains %}
|
||||
{% for item in states[domain] %}
|
||||
{% if item.entity_id not in exclude_entities %}
|
||||
{% if item.attributes.battery_level is defined %}
|
||||
{% set level = item.attributes.battery_level|int %}
|
||||
{% if level > 0 and level < threshold %}
|
||||
- {{ item.attributes.friendly_name }} ({{ item.attributes['battery_level']|int}}%)
|
||||
{%- endif -%}
|
||||
{% endif %}
|
||||
{% if item.attributes.device_class is defined and item.attributes.device_class == 'battery' %}
|
||||
{% set level = item.state|int %}
|
||||
{% if level > 0 and level <= threshold %}
|
||||
- {{ item.attributes.friendly_name }} ({{ item.state|int }}%)
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
'';
|
||||
entity_id = "binary_sensor.sensor_low_battery";
|
||||
state = "on";
|
||||
repeat = [
|
||||
5
|
||||
60
|
||||
360
|
||||
];
|
||||
skip_first = true;
|
||||
can_acknowledge = true;
|
||||
notifiers = [
|
||||
"NotificationGroup"
|
||||
];
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -1,264 +0,0 @@
|
||||
{ config, pkgs, ... }:
|
||||
let
|
||||
domain = "home-assistant.cloonar.com";
|
||||
release2405 = import <nixos-24.05> { config = config.nixpkgs.config; };
|
||||
pkgs-with-home-assistant = import (builtins.fetchGit {
|
||||
name = "new-home-assistant";
|
||||
url = "https://github.com/nixos/nixpkgs/";
|
||||
rev = "268bb5090a3c6ac5e1615b38542a868b52ef8088";
|
||||
}) {};
|
||||
in
|
||||
{
|
||||
users.users.hass = {
|
||||
home = "/var/lib/hass";
|
||||
createHome = true;
|
||||
group = "hass";
|
||||
uid = config.ids.uids.hass;
|
||||
extraGroups = [ "dialout" ];
|
||||
};
|
||||
users.groups.hass.gid = config.ids.gids.hass;
|
||||
|
||||
security.acme.certs."${domain}" = {
|
||||
group = "nginx";
|
||||
};
|
||||
|
||||
sops.secrets."home-assistant-secrets.yaml" = {
|
||||
owner = "hass";
|
||||
restartUnits = [ "container@hass.service" ];
|
||||
};
|
||||
|
||||
sops.secrets."home-assistant-ldap" = {
|
||||
owner = "hass";
|
||||
};
|
||||
|
||||
containers.hass = {
|
||||
autoStart = true;
|
||||
ephemeral = false;
|
||||
privateNetwork = true;
|
||||
hostBridge = "server";
|
||||
hostAddress = "10.42.113.1";
|
||||
localAddress = "10.42.113.20/24";
|
||||
extraFlags = [
|
||||
"--capability=CAP_NET_ADMIN"
|
||||
"--capability=CAP_MKNOD"
|
||||
];
|
||||
# allowedDevices = [
|
||||
# {
|
||||
# modifier = "rwm";
|
||||
# node = "char-usb_device";
|
||||
# }
|
||||
# {
|
||||
# modifier = "rwm";
|
||||
# node = "char-ttyUSB";
|
||||
# }
|
||||
# {
|
||||
# modifier = "rwm";
|
||||
# node = "/dev/ttyUSB0";
|
||||
# }
|
||||
# ];
|
||||
bindMounts = {
|
||||
"/dev/ttyUSB0" = {
|
||||
hostPath = "/dev/ttyUSB0";
|
||||
isReadOnly = false;
|
||||
};
|
||||
"/etc/localtime" = {
|
||||
hostPath = "/etc/localtime";
|
||||
};
|
||||
"/var/lib/hass" = {
|
||||
hostPath = "/var/lib/hass/";
|
||||
isReadOnly = false;
|
||||
};
|
||||
"/var/lib/acme/hass/" = {
|
||||
hostPath = "${config.security.acme.certs.${domain}.directory}";
|
||||
};
|
||||
"/run/secrets/home-assistant-ldap" = {
|
||||
hostPath = config.sops.secrets."home-assistant-ldap".path;
|
||||
};
|
||||
"/var/lib/hass/secrets.yaml" = {
|
||||
hostPath = config.sops.secrets."home-assistant-secrets.yaml".path;
|
||||
};
|
||||
};
|
||||
config = { lib, config, pkgs, ... }: {
|
||||
imports = [
|
||||
./3dprinter.nix
|
||||
./ac.nix
|
||||
# ./aeg.nix
|
||||
./battery.nix
|
||||
./electricity.nix
|
||||
./enocean.nix
|
||||
./ldap.nix
|
||||
./light.nix
|
||||
./locks.nix
|
||||
./multimedia.nix
|
||||
./music.nix
|
||||
./notify.nix
|
||||
./pc.nix
|
||||
./pushover.nix
|
||||
./presense.nix
|
||||
./roborock.nix
|
||||
./scene-switch.nix
|
||||
./shelly.nix
|
||||
./sleep.nix
|
||||
./snapcast.nix
|
||||
];
|
||||
|
||||
networking = {
|
||||
hostName = "home-assistant";
|
||||
useHostResolvConf = false;
|
||||
defaultGateway = {
|
||||
address = "10.42.96.1";
|
||||
interface = "eth0";
|
||||
};
|
||||
firewall.enable = false;
|
||||
nameservers = [ "10.42.97.1" ];
|
||||
};
|
||||
|
||||
environment.systemPackages = [
|
||||
pkgs.wol
|
||||
pkgs.mariadb
|
||||
];
|
||||
|
||||
# Allow access to the USB device
|
||||
services.udev.extraRules = ''
|
||||
SUBSYSTEM=="usb", ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6001", MODE="0666"
|
||||
'';
|
||||
|
||||
services.nginx.enable = true;
|
||||
services.nginx.virtualHosts."${domain}" = {
|
||||
sslCertificate = "/var/lib/acme/hass/fullchain.pem";
|
||||
sslCertificateKey = "/var/lib/acme/hass/key.pem";
|
||||
sslTrustedCertificate = "/var/lib/acme/hass/chain.pem";
|
||||
forceSSL = true;
|
||||
extraConfig = ''
|
||||
proxy_buffering off;
|
||||
'';
|
||||
locations."/".extraConfig = ''
|
||||
proxy_pass http://127.0.0.1:8123;
|
||||
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;
|
||||
'';
|
||||
};
|
||||
|
||||
services.home-assistant = {
|
||||
package = pkgs-with-home-assistant.home-assistant;
|
||||
enable = true;
|
||||
};
|
||||
|
||||
services.home-assistant.extraComponents = [
|
||||
"mobile_app"
|
||||
"backup"
|
||||
"denonavr"
|
||||
"androidtv"
|
||||
"rainbird"
|
||||
"zha"
|
||||
"tplink_omada"
|
||||
];
|
||||
|
||||
services.mysql = {
|
||||
enable = true;
|
||||
package = pkgs.mariadb;
|
||||
ensureDatabases = [ "hass" ];
|
||||
};
|
||||
|
||||
services.mysqlBackup = {
|
||||
enable = true;
|
||||
databases = [ "hass" ];
|
||||
};
|
||||
|
||||
services.home-assistant.config =
|
||||
let
|
||||
hiddenEntities = [
|
||||
"sensor.last_boot"
|
||||
"sensor.date"
|
||||
];
|
||||
in
|
||||
{
|
||||
recorder = {
|
||||
db_url = "mysql://hass@localhost/hass?unix_socket=/var/run/mysqld/mysqld.sock";
|
||||
};
|
||||
homeassistant = {
|
||||
name = "Home";
|
||||
latitude = "!secret home_latitude";
|
||||
longitude = "!secret home_longitude";
|
||||
elevation = "!secret home_elevation";
|
||||
unit_system = "metric";
|
||||
currency = "EUR";
|
||||
country = "AT";
|
||||
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 = {
|
||||
use_x_forwarded_for = true;
|
||||
trusted_proxies = [
|
||||
"127.0.0.1"
|
||||
"::1"
|
||||
];
|
||||
};
|
||||
api = { };
|
||||
history.exclude = {
|
||||
entities = hiddenEntities;
|
||||
domains = [
|
||||
"automation"
|
||||
"updater"
|
||||
];
|
||||
};
|
||||
"map" = { };
|
||||
enocean = {
|
||||
device = "/dev/ttyUSB0";
|
||||
};
|
||||
# logbook.exclude.entities = "hiddenEntities";
|
||||
logger = {
|
||||
default = "info";
|
||||
};
|
||||
|
||||
#icloud = {
|
||||
# username = "!secret icloud_email";
|
||||
# password = "!secret icloud_password";
|
||||
# with_family = true;
|
||||
#};
|
||||
network = { };
|
||||
zeroconf = { };
|
||||
system_health = { };
|
||||
default_config = { };
|
||||
system_log = { };
|
||||
sensor = [
|
||||
{
|
||||
platform = "template";
|
||||
sensors.bedtime_alarm = {
|
||||
friendly_name = "Bedtime Alarm";
|
||||
value_template = "09:00";
|
||||
};
|
||||
}
|
||||
];
|
||||
};
|
||||
|
||||
services.mosquitto = {
|
||||
enable = true;
|
||||
listeners = [
|
||||
{
|
||||
acl = [ "pattern readwrite #" ];
|
||||
omitPasswordAuth = true;
|
||||
settings.allow_anonymous = true;
|
||||
}
|
||||
];
|
||||
};
|
||||
|
||||
users.users.hass.extraGroups = [ "dialout" "tty" ];
|
||||
system.stateVersion = "23.05";
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
{ config, ... }:
|
||||
let
|
||||
unstable = import
|
||||
(builtins.fetchTarball https://github.com/nixos/nixpkgs/tarball/nixpkgs-unstable)
|
||||
# reuse the current configuration
|
||||
{ config = config.nixpkgs.config; };
|
||||
in {
|
||||
services.home-assistant.customComponents = with unstable.home-assistant-custom-components; [
|
||||
epex_spot
|
||||
];
|
||||
|
||||
services.home-assistant.config = {
|
||||
sensor = [
|
||||
{
|
||||
platform = "template";
|
||||
sensors = {
|
||||
electricity_price = {
|
||||
friendly_name = "Current Price of electricity";
|
||||
unit_of_measurement = "EUR/kWh";
|
||||
value_template = ''
|
||||
{{ (((states('sensor.epex_spot_data_price') | int ) / 1000) + (0.0149 + 0.0053 + 0.00866)) | float }}
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
||||
];
|
||||
};
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
{
|
||||
services.home-assistant.config = {
|
||||
"binary_sensor pc_0" = [
|
||||
{
|
||||
platform = "enocean";
|
||||
id = [ 254 235 105 198 ];
|
||||
name = "enocean_switch_pc";
|
||||
}
|
||||
];
|
||||
sensor = [
|
||||
{
|
||||
name = "Bathroom HT";
|
||||
platform = "enocean";
|
||||
id = [ 5 41 146 251 ];
|
||||
device_class = "temperature";
|
||||
}
|
||||
];
|
||||
};
|
||||
}
|
||||
@@ -1,56 +0,0 @@
|
||||
{ pkgs
|
||||
, config
|
||||
, lib
|
||||
, ... }:
|
||||
let
|
||||
ldap-auth-sh = pkgs.stdenv.mkDerivation {
|
||||
name = "ldap-auth-sh";
|
||||
|
||||
src = pkgs.fetchFromGitHub {
|
||||
owner = "efficiosoft";
|
||||
repo = "ldap-auth-sh";
|
||||
rev = "93b2c00413942908139e37c7432a12bcb705ac87";
|
||||
sha256 = "1pymp6ki353aqkigr89g7hg5x1mny68m31c3inxf1zr26n5s2kz8";
|
||||
};
|
||||
|
||||
nativeBuildInputs = [ pkgs.makeWrapper ];
|
||||
installPhase = ''
|
||||
mkdir -p $out/etc
|
||||
cat > $out/etc/home-assistant.cfg << 'EOF'
|
||||
CLIENT="ldapsearch"
|
||||
SERVER="ldaps://ldap.cloonar.com:636"
|
||||
USERDN="cn=home-assistant,ou=system,ou=users,dc=cloonar,dc=com"
|
||||
PW="$(</run/secrets/home-assistant-ldap)"
|
||||
BASEDN="ou=users,dc=cloonar,dc=com"
|
||||
SCOPE="one"
|
||||
FILTER="(&(objectClass=cloonarUser)(memberOf=cn=HomeAssistant,ou=groups,dc=cloonar,dc=com)(mail=$(ldap_dn_escape "$username")))"
|
||||
USERNAME_PATTERN='^[a-z|A-Z|0-9|_|-|.|@]+$'
|
||||
on_auth_success() {
|
||||
# print the meta entries for use in HA
|
||||
if echo "$output" | grep -qE '^(dn|DN):: '; then
|
||||
# ldapsearch base64 encodes non-ascii
|
||||
output=$(echo "$output" | sed -n -e "s/^\(dn\|DN\)\s*::\s*\(.*\)$/\2/p" | base64 -d)
|
||||
else
|
||||
output=$(echo "$output" | sed -n -e "s/^\(dn\|DN\)\s*:\s*\(.*\)$/\2/p")
|
||||
fi
|
||||
name=$(echo "$output" | sed -nr 's/^cn=([^,]+).*/\1/Ip')
|
||||
[ -z "$name" ] || echo "name=$name"
|
||||
}
|
||||
EOF
|
||||
install -D -m755 ldap-auth.sh $out/bin/ldap-auth.sh
|
||||
wrapProgram $out/bin/ldap-auth.sh \
|
||||
--prefix PATH : ${lib.makeBinPath [pkgs.openldap pkgs.coreutils pkgs.gnused pkgs.gnugrep]} \
|
||||
--add-flags "$out/etc/home-assistant.cfg"
|
||||
'';
|
||||
};
|
||||
in
|
||||
{
|
||||
services.home-assistant.config.homeassistant.auth_providers = [
|
||||
{
|
||||
type = "command_line";
|
||||
command = "${ldap-auth-sh}/bin/ldap-auth.sh";
|
||||
meta = true;
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
@@ -1,417 +0,0 @@
|
||||
{
|
||||
services.home-assistant.extraComponents = [
|
||||
"deconz"
|
||||
"shelly"
|
||||
"sun"
|
||||
"nanoleaf"
|
||||
];
|
||||
|
||||
services.home-assistant.config = {
|
||||
homeassistant = {
|
||||
customize_domain = {
|
||||
light = {
|
||||
assumed_state = false;
|
||||
};
|
||||
};
|
||||
};
|
||||
"automation light_sunrise" = {
|
||||
alias = "light_sunrise";
|
||||
trigger = {
|
||||
platform = "sun";
|
||||
event = "sunrise";
|
||||
};
|
||||
action = {
|
||||
service = "light.turn_on";
|
||||
target = {
|
||||
entity_id = "{{ states.light | selectattr(\"state\",\"eq\",\"on\") | map(attribute=\"entity_id\") | list }}";
|
||||
};
|
||||
data = {
|
||||
brightness_pct = 254;
|
||||
color_temp = 250;
|
||||
};
|
||||
};
|
||||
};
|
||||
"automation light_sunset" = {
|
||||
alias = "light_sunset";
|
||||
trigger = {
|
||||
platform = "sun";
|
||||
event = "sunset";
|
||||
};
|
||||
action = {
|
||||
service = "light.turn_on";
|
||||
target = {
|
||||
entity_id = "{{ states.light | selectattr(\"state\",\"eq\",\"on\") | map(attribute=\"entity_id\") | list }}";
|
||||
};
|
||||
data = {
|
||||
brightness_pct = 30;
|
||||
color_temp = 450;
|
||||
};
|
||||
};
|
||||
};
|
||||
"automation light_on" = {
|
||||
alias = "light_on";
|
||||
trigger = {
|
||||
platform = "state";
|
||||
entity_id = [
|
||||
"light.bedroom_lights"
|
||||
"light.kitchen_lights"
|
||||
"light.livingroom_lights"
|
||||
"light.hallway_lights"
|
||||
"light.bathroom_lights"
|
||||
"light.toilet_lights"
|
||||
"light.storage_lights"
|
||||
];
|
||||
to = "on";
|
||||
};
|
||||
action = [
|
||||
{
|
||||
choose = [
|
||||
{
|
||||
conditions = [ "{{ state_attr('sun.sun', 'elevation') < 5 and trigger.entity_id == 'light.toilet_lights' }}" ];
|
||||
sequence = [
|
||||
{
|
||||
delay = 10;
|
||||
}
|
||||
{
|
||||
service = "light.turn_on";
|
||||
target = {
|
||||
entity_id = "{{ trigger.entity_id }}";
|
||||
};
|
||||
data = {
|
||||
brightness_pct = 20;
|
||||
color_temp = 450;
|
||||
};
|
||||
}
|
||||
];
|
||||
}
|
||||
{
|
||||
conditions = [ "{{ state_attr('sun.sun', 'elevation') < 5 and trigger.entity_id == 'light.hallway_lights' }}" ];
|
||||
sequence = [
|
||||
{
|
||||
delay = 10;
|
||||
}
|
||||
{
|
||||
service = "light.turn_on";
|
||||
target = {
|
||||
entity_id = "{{ trigger.entity_id }}";
|
||||
};
|
||||
data = {
|
||||
brightness_pct = 1;
|
||||
color_temp = 450;
|
||||
};
|
||||
}
|
||||
];
|
||||
}
|
||||
{
|
||||
conditions = [ "{{ state_attr('sun.sun', 'elevation') < 5 and trigger.entity_id == 'light.bathroom_lights' }}" ];
|
||||
sequence = [
|
||||
{
|
||||
delay = 10;
|
||||
}
|
||||
{
|
||||
service = "light.turn_on";
|
||||
target = {
|
||||
entity_id = "{{ trigger.entity_id }}";
|
||||
};
|
||||
data = {
|
||||
brightness_pct = 30;
|
||||
color_temp = 450;
|
||||
};
|
||||
}
|
||||
];
|
||||
}
|
||||
{
|
||||
conditions = [ "{{ state_attr('sun.sun', 'elevation') < 5 and trigger.entity_id == 'light.livingroom_lights' }}" ];
|
||||
sequence = [
|
||||
{
|
||||
delay = 10;
|
||||
}
|
||||
{
|
||||
service = "light.turn_on";
|
||||
target = {
|
||||
entity_id = "{{ trigger.entity_id }}";
|
||||
};
|
||||
data = {
|
||||
brightness_pct = 5;
|
||||
color_temp = 450;
|
||||
};
|
||||
}
|
||||
];
|
||||
}
|
||||
{
|
||||
conditions = [ "{{ state_attr('sun.sun', 'elevation') < 5 and trigger.entity_id == 'light.bedroom_lights' }}" ];
|
||||
sequence = [
|
||||
{
|
||||
delay = 10;
|
||||
}
|
||||
{
|
||||
service = "light.turn_on";
|
||||
target = {
|
||||
entity_id = "light.bedroom_lights";
|
||||
};
|
||||
data = {
|
||||
brightness_pct = 5;
|
||||
color_temp = 450;
|
||||
};
|
||||
}
|
||||
];
|
||||
}
|
||||
{
|
||||
conditions = [ "{{ state_attr('sun.sun', 'elevation') < 5 and trigger.entity_id == 'light.kitchen_lights' }}" ];
|
||||
sequence = [
|
||||
{
|
||||
delay = 10;
|
||||
}
|
||||
{
|
||||
service = "light.turn_on";
|
||||
target = {
|
||||
entity_id = "light.kitchen_lights";
|
||||
};
|
||||
data = {
|
||||
brightness_pct = 30;
|
||||
color_temp = 450;
|
||||
};
|
||||
}
|
||||
];
|
||||
}
|
||||
{
|
||||
conditions = [ "{{ state_attr('sun.sun', 'elevation') > 4 }}" ];
|
||||
sequence = [
|
||||
{
|
||||
delay = 10;
|
||||
}
|
||||
{
|
||||
service = "light.turn_on";
|
||||
target = {
|
||||
entity_id = "{{ trigger.entity_id }}";
|
||||
};
|
||||
data = {
|
||||
brightness_pct = 100;
|
||||
color_temp = 250;
|
||||
};
|
||||
}
|
||||
];
|
||||
}
|
||||
];
|
||||
}
|
||||
];
|
||||
};
|
||||
"automation bathroom light small" = {
|
||||
alias = "bathroom light small";
|
||||
mode = "restart";
|
||||
trigger = {
|
||||
platform = "state";
|
||||
entity_id = [
|
||||
"light.bathroom_switch_channel_1"
|
||||
];
|
||||
from = "on";
|
||||
to = "off";
|
||||
};
|
||||
action = [
|
||||
{
|
||||
service = "switch.turn_off";
|
||||
target = {
|
||||
entity_id = "switch.bathroom_small";
|
||||
};
|
||||
}
|
||||
];
|
||||
};
|
||||
"automation bathroom light" = {
|
||||
alias = "bathroom light";
|
||||
mode = "restart";
|
||||
trigger = {
|
||||
platform = "state";
|
||||
entity_id = [
|
||||
"light.bathroom_switch_channel_1"
|
||||
];
|
||||
from = "off";
|
||||
to = "on";
|
||||
};
|
||||
action = [
|
||||
{
|
||||
delay = 3600;
|
||||
}
|
||||
{
|
||||
service = "light.turn_off";
|
||||
target = {
|
||||
entity_id = "light.bathroom_switch_channel_1";
|
||||
};
|
||||
}
|
||||
];
|
||||
};
|
||||
"automation bed_led" = {
|
||||
alias = "bed_led";
|
||||
mode = "restart";
|
||||
trigger = {
|
||||
platform = "state";
|
||||
entity_id = [
|
||||
"light.bedroom_led"
|
||||
];
|
||||
from = "off";
|
||||
to = "on";
|
||||
};
|
||||
action = [
|
||||
{
|
||||
delay = 10800;
|
||||
}
|
||||
{
|
||||
service = "light.turn_off";
|
||||
target = {
|
||||
entity_id = "{{ trigger.entity_id }}";
|
||||
};
|
||||
}
|
||||
];
|
||||
};
|
||||
"automation hallway_motion" = {
|
||||
alias = "Hallway Motion";
|
||||
trigger = {
|
||||
platform = "state";
|
||||
entity_id = "binary_sensor.hallway_motion_motion";
|
||||
};
|
||||
action = {
|
||||
service_template = "light.turn_{{ trigger.to_state.state }}";
|
||||
target = {
|
||||
entity_id = "light.hallway_lights";
|
||||
};
|
||||
};
|
||||
};
|
||||
"automation bed_button_1" = {
|
||||
alias = "bed_button_1";
|
||||
trigger = {
|
||||
platform = "event";
|
||||
event_type = "shelly.click";
|
||||
event_data = {
|
||||
device = "shellybutton1-E8DB84AA196D";
|
||||
};
|
||||
};
|
||||
action = [
|
||||
{
|
||||
choose = [
|
||||
{
|
||||
conditions = [ "{{ trigger.event.data.click_type == \"single\" }}" ];
|
||||
sequence = [
|
||||
{
|
||||
service = "light.toggle";
|
||||
entity_id = "light.bed_reading_1";
|
||||
}
|
||||
];
|
||||
}
|
||||
{
|
||||
conditions = [ "{{ trigger.event.data.click_type == \"double\" }}" ];
|
||||
sequence = [
|
||||
{
|
||||
service = "light.toggle";
|
||||
entity_id = "light.bedroom_lights";
|
||||
}
|
||||
];
|
||||
}
|
||||
{
|
||||
conditions = [ "{{ trigger.event.data.click_type == \"triple\" }}" ];
|
||||
sequence = [
|
||||
{
|
||||
service = "light.toggle";
|
||||
entity_id = "light.bedroom_bed";
|
||||
}
|
||||
];
|
||||
}
|
||||
];
|
||||
}
|
||||
];
|
||||
};
|
||||
"automation bed_button_2" = {
|
||||
alias = "bed_button_2";
|
||||
trigger = {
|
||||
platform = "event";
|
||||
event_type = "shelly.click";
|
||||
event_data = {
|
||||
device = "shellybutton1-E8DB84AA136D";
|
||||
};
|
||||
};
|
||||
action = [
|
||||
{
|
||||
choose = [
|
||||
{
|
||||
conditions = [ "{{ trigger.event.data.click_type == \"single\" }}" ];
|
||||
sequence = [
|
||||
{
|
||||
service = "light.toggle";
|
||||
entity_id = "light.bed_reading_2";
|
||||
}
|
||||
];
|
||||
}
|
||||
{
|
||||
conditions = [ "{{ trigger.event.data.click_type == \"double\" }}" ];
|
||||
sequence = [
|
||||
{
|
||||
service = "light.toggle";
|
||||
entity_id = "light.bedroom_lights";
|
||||
}
|
||||
];
|
||||
}
|
||||
{
|
||||
conditions = [ "{{ trigger.event.data.click_type == \"triple\" }}" ];
|
||||
sequence = [
|
||||
{
|
||||
service = "light.toggle";
|
||||
entity_id = "light.bedroom_bed";
|
||||
}
|
||||
];
|
||||
}
|
||||
];
|
||||
}
|
||||
];
|
||||
};
|
||||
light = [
|
||||
{
|
||||
platform = "switch";
|
||||
name = "Livingroom Switch";
|
||||
entity_id = "switch.livingroom_switch";
|
||||
}
|
||||
{
|
||||
platform = "group";
|
||||
name = "Livingroom Lights";
|
||||
all = true;
|
||||
entities = [
|
||||
"light.livingroom_switch"
|
||||
"light.living_bulb_1"
|
||||
"light.living_bulb_2"
|
||||
"light.living_bulb_3"
|
||||
"light.living_bulb_4"
|
||||
"light.living_bulb_5"
|
||||
"light.living_bulb_6"
|
||||
];
|
||||
}
|
||||
{
|
||||
platform = "switch";
|
||||
name = "Bedroom Switch";
|
||||
entity_id = "switch.bedroom_switch";
|
||||
}
|
||||
{
|
||||
platform = "group";
|
||||
name = "Bedroom Lights";
|
||||
all = true;
|
||||
entities = [
|
||||
"light.bedroom_switch"
|
||||
"light.bedroom_bulb_1"
|
||||
"light.bedroom_bulb_2"
|
||||
"light.bedroom_bulb_3"
|
||||
"light.bedroom_bulb_4"
|
||||
];
|
||||
}
|
||||
{
|
||||
platform = "switch";
|
||||
name = "Toilet Switch";
|
||||
entity_id = "switch.toilet";
|
||||
}
|
||||
{
|
||||
platform = "group";
|
||||
name = "Toilet Lights";
|
||||
all = true;
|
||||
entities = [
|
||||
"light.toilet"
|
||||
"light.toilet_bulb"
|
||||
];
|
||||
}
|
||||
];
|
||||
};
|
||||
}
|
||||
@@ -1,170 +0,0 @@
|
||||
{
|
||||
services.home-assistant.extraComponents = [
|
||||
"nuki"
|
||||
];
|
||||
|
||||
services.home-assistant.config = {
|
||||
"automation house_door" = {
|
||||
alias = "house_door";
|
||||
mode = "restart";
|
||||
trigger = {
|
||||
platform = "state";
|
||||
entity_id = [
|
||||
"device_tracker.dominiks_iphone"
|
||||
];
|
||||
from = "not_home";
|
||||
to = "home";
|
||||
};
|
||||
action = [
|
||||
{
|
||||
service = "lock.unlock";
|
||||
target = {
|
||||
entity_id = "lock.house_door";
|
||||
};
|
||||
}
|
||||
{
|
||||
delay = "00:05:00";
|
||||
}
|
||||
{
|
||||
service = "lock.lock";
|
||||
target = {
|
||||
entity_id = "lock.house_door";
|
||||
};
|
||||
}
|
||||
];
|
||||
};
|
||||
"automation house_door_ring" = {
|
||||
alias = "house_door_ring";
|
||||
trigger = {
|
||||
platform = "event";
|
||||
event_type = "nuki_event";
|
||||
event_data = {
|
||||
type = "ring";
|
||||
};
|
||||
};
|
||||
action = [
|
||||
{
|
||||
choose = [
|
||||
{
|
||||
conditions = [ "{{ state.house_door == \"unlocked\" }}" ];
|
||||
sequence = [
|
||||
{
|
||||
service = "lock.lock";
|
||||
target = {
|
||||
entity_id = "lock.house_door";
|
||||
};
|
||||
}
|
||||
];
|
||||
}
|
||||
{
|
||||
conditions = [ "{{ state.house_door != \"unlocked\" }}" ];
|
||||
sequence = [
|
||||
{
|
||||
service = "notify.mobile_app_dominiks_iphone";
|
||||
data = {
|
||||
message = "Someone is at the door!";
|
||||
actions = [
|
||||
{
|
||||
action = "action_open";
|
||||
title = "Open house door";
|
||||
}
|
||||
{
|
||||
action = "action_ignore";
|
||||
title = "Ignore";
|
||||
}
|
||||
];
|
||||
};
|
||||
}
|
||||
{
|
||||
wait_for_trigger = [
|
||||
{
|
||||
platform = "event";
|
||||
event_type = "mobile_app_notification_action";
|
||||
event_data = {
|
||||
action = "{{ action_open }}";
|
||||
|
||||
};
|
||||
}
|
||||
{
|
||||
platform = "event";
|
||||
event_type = "mobile_app_notification_action";
|
||||
event_data = {
|
||||
action = "{{ action_ignore }}";
|
||||
};
|
||||
}
|
||||
|
||||
];
|
||||
}
|
||||
{
|
||||
choose = [
|
||||
{
|
||||
conditions = "{{ wait.trigger.event.data.action == action_open }}";
|
||||
sequence = [{
|
||||
service = "lock.open";
|
||||
target = {
|
||||
entity_id = "lock.house_door";
|
||||
};
|
||||
}];
|
||||
}
|
||||
];
|
||||
}
|
||||
];
|
||||
}
|
||||
];
|
||||
}
|
||||
];
|
||||
};
|
||||
binary_sensor = [
|
||||
{
|
||||
platform = "template";
|
||||
sensors = {
|
||||
lock_critical_battery = {
|
||||
value_template = ''
|
||||
{% set domains = ['lock'] %}
|
||||
{% set ns = namespace(crit=battery_critical, entities=[]) %}
|
||||
{% for domain in domains %}
|
||||
{% set batt_critical = states[domain] | selectattr('attributes.battery_critical','defined') | map(attribute='attributes.battery_critical') | reject('equalto', 'unknown') | reject('equalto', 'None') | map('int') | reject('equalto', 0) | list %}
|
||||
{% if batt_critical|length > 0 %}
|
||||
{% set ns.battery_critical = true %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{{ ns.battery_critical }}
|
||||
'';
|
||||
friendly_name = "A lock has critical battery";
|
||||
device_class = "problem";
|
||||
};
|
||||
};
|
||||
}
|
||||
];
|
||||
alert = {
|
||||
battery_critical = {
|
||||
name = "Lock has low battery!";
|
||||
message = ''
|
||||
{%- set domains = ['lock'] -%}
|
||||
Lock battery is critical:
|
||||
{%- for domain in domains -%}
|
||||
{%- for item in states[domain] -%}
|
||||
{%- if item.attributes.battery_critical is defined -%}
|
||||
{% if item.attributes.battery_critical %}
|
||||
- {{ item.attributes.friendly_name }}
|
||||
{%- endif -%}
|
||||
{%- endif -%}
|
||||
{%- endfor -%}
|
||||
{%- endfor -%}
|
||||
'';
|
||||
entity_id = "binary_sensor.lock_critical_battery";
|
||||
state = "on";
|
||||
repeat = [
|
||||
5
|
||||
60
|
||||
360
|
||||
];
|
||||
skip_first = true;
|
||||
can_acknowledge = true;
|
||||
notifiers = [
|
||||
"NotificationGroup"
|
||||
];
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -1,492 +0,0 @@
|
||||
{
|
||||
services.home-assistant.extraComponents = [
|
||||
"ping"
|
||||
"broadlink"
|
||||
"androidtv"
|
||||
"samsungtv"
|
||||
];
|
||||
services.home-assistant.config = {
|
||||
ios = {
|
||||
actions = [
|
||||
{
|
||||
name = "Home Cinema";
|
||||
label.text = "Home Cinema";
|
||||
icon = {
|
||||
icon = "theater";
|
||||
color = "#ffffff";
|
||||
};
|
||||
show_in_watch = true;
|
||||
}
|
||||
];
|
||||
};
|
||||
binary_sensor = [
|
||||
{
|
||||
name = "xbox";
|
||||
platform = "ping";
|
||||
host = "xbox.cloonar.multimedia";
|
||||
count = 2;
|
||||
scan_interval = 5;
|
||||
}
|
||||
{
|
||||
name = "ps5";
|
||||
platform = "ping";
|
||||
host = "ps5.cloonar.multimedia";
|
||||
count = 2;
|
||||
scan_interval = 5;
|
||||
}
|
||||
{
|
||||
name = "steamdeck";
|
||||
platform = "ping";
|
||||
host = "steamdeck.cloonar.com";
|
||||
count = 2;
|
||||
scan_interval = 5;
|
||||
}
|
||||
{
|
||||
platform = "template";
|
||||
sensors = {
|
||||
multimedia_device_on = {
|
||||
friendly_name = "Any multimedia device on";
|
||||
device_class = "connectivity";
|
||||
value_template = ''
|
||||
{% if is_state('binary_sensor.ps5', 'on') or is_state('binary_sensor.xbox', 'on') or (states('media_player.fire_tv_firetv_living_cloonar_multimedia') != 'off' and states('media_player.fire_tv_firetv_living_cloonar_multimedia') != 'unavailable') or (is_state('binary_sensor.steamdeck', 'on') and (states('sensor.steamdeck_power') | float > 5)) %}
|
||||
on
|
||||
{% else %}
|
||||
off
|
||||
{% endif %}
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
||||
];
|
||||
script = {
|
||||
turn_on_tv = {
|
||||
sequence = [
|
||||
{
|
||||
choose = [
|
||||
{
|
||||
conditions = [
|
||||
{
|
||||
condition = "state";
|
||||
entity_id = "switch.tv_switch";
|
||||
state = "off";
|
||||
}
|
||||
];
|
||||
sequence = [
|
||||
{
|
||||
service = "switch.turn_on";
|
||||
target = {
|
||||
entity_id = "switch.tv_switch";
|
||||
};
|
||||
}
|
||||
{
|
||||
delay = 10;
|
||||
}
|
||||
{
|
||||
service = "remote.send_command";
|
||||
target = {
|
||||
entity_id = "remote.rmproplus";
|
||||
};
|
||||
data = {
|
||||
num_repeats = 1;
|
||||
delay_secs = 0.4;
|
||||
hold_secs = 0;
|
||||
command = "b64:JgBOAJaSFREVNRU2FTUVERURFRAVERURFTUVNhU1FREVERUQFREVERUQFTYVNRURFREVEBURFTYVNRURFRAVNhU1FTYVNRUABfmWkhURFQANBQAAAAAAAAAAAAA=";
|
||||
};
|
||||
}
|
||||
];
|
||||
}
|
||||
{
|
||||
conditions = [
|
||||
{
|
||||
condition = "state";
|
||||
entity_id = "media_player.android_tv_metz_cloonar_multimedia";
|
||||
state = "unavailable";
|
||||
}
|
||||
];
|
||||
sequence = [
|
||||
{
|
||||
service = "remote.send_command";
|
||||
target = {
|
||||
entity_id = "remote.rmproplus";
|
||||
};
|
||||
data = {
|
||||
num_repeats = 1;
|
||||
delay_secs = 0.4;
|
||||
hold_secs = 0;
|
||||
command = "b64:JgBOAJaSFREVNRU2FTUVERURFRAVERURFTUVNhU1FREVERUQFREVERUQFTYVNRURFREVEBURFTYVNRURFRAVNhU1FTYVNRUABfmWkhURFQANBQAAAAAAAAAAAAA=";
|
||||
};
|
||||
}
|
||||
];
|
||||
}
|
||||
{
|
||||
conditions = [
|
||||
{
|
||||
condition = "state";
|
||||
entity_id = "media_player.android_tv_metz_cloonar_multimedia";
|
||||
state = "off";
|
||||
}
|
||||
];
|
||||
sequence = [
|
||||
{
|
||||
service = "media_player.turn_on";
|
||||
target = {
|
||||
entity_id = "media_player.android_tv_metz_cloonar_multimedia";
|
||||
};
|
||||
}
|
||||
];
|
||||
}
|
||||
];
|
||||
}
|
||||
];
|
||||
};
|
||||
};
|
||||
"automation steamdeck on" = {
|
||||
alias = "steamdeck on";
|
||||
trigger = {
|
||||
platform = "template";
|
||||
value_template = "{% if is_state('binary_sensor.steamdeck', 'on') and (states('sensor.steamdeck_power') | float > 5) %}true{% endif %}";
|
||||
};
|
||||
action = [
|
||||
{
|
||||
service = "denonavr.get_command";
|
||||
target = {
|
||||
entity_id = "media_player.marantz_sr6015";
|
||||
};
|
||||
data = {
|
||||
command = "/goform/formiPhoneAppDirect.xml?SIDVD";
|
||||
};
|
||||
}
|
||||
];
|
||||
};
|
||||
"automation xbox on" = {
|
||||
alias = "xbox on";
|
||||
trigger = {
|
||||
platform = "state";
|
||||
entity_id = "binary_sensor.xbox";
|
||||
to = "on";
|
||||
};
|
||||
action = [
|
||||
{
|
||||
service = "denonavr.get_command";
|
||||
target = {
|
||||
entity_id = "media_player.marantz_sr6015";
|
||||
};
|
||||
data = {
|
||||
command = "/goform/formiPhoneAppDirect.xml?SIGAME";
|
||||
};
|
||||
}
|
||||
];
|
||||
};
|
||||
"automation firetv on" = {
|
||||
alias = "firetv on";
|
||||
trigger = {
|
||||
platform = "state";
|
||||
entity_id = "media_player.fire_tv_firetv_living_cloonar_multimedia";
|
||||
from = "off";
|
||||
};
|
||||
action = [
|
||||
{
|
||||
service = "denonavr.get_command";
|
||||
target = {
|
||||
entity_id = "media_player.marantz_sr6015";
|
||||
};
|
||||
data = {
|
||||
command = "/goform/formiPhoneAppDirect.xml?SIMPLAY";
|
||||
};
|
||||
}
|
||||
];
|
||||
};
|
||||
"automation ps5 on" = {
|
||||
alias = "ps5 on";
|
||||
trigger = {
|
||||
platform = "state";
|
||||
entity_id = "binary_sensor.ps5";
|
||||
to = "on";
|
||||
};
|
||||
action = [
|
||||
{
|
||||
service = "denonavr.get_command";
|
||||
target = {
|
||||
entity_id = "media_player.marantz_sr6015";
|
||||
};
|
||||
data = {
|
||||
command = "/goform/formiPhoneAppDirect.xml?SIBD";
|
||||
};
|
||||
}
|
||||
];
|
||||
};
|
||||
"automation all multimedia off" = {
|
||||
alias = "all multimedia off";
|
||||
trigger = {
|
||||
platform = "state";
|
||||
entity_id = "binary_sensor.multimedia_device_on";
|
||||
to = "off";
|
||||
};
|
||||
action = [
|
||||
{
|
||||
service = "media_player.turn_off";
|
||||
target = {
|
||||
entity_id = "media_player.android_tv_metz_cloonar_multimedia";
|
||||
};
|
||||
}
|
||||
{
|
||||
service = "denonavr.get_command";
|
||||
target = {
|
||||
entity_id = "media_player.marantz_sr6015";
|
||||
};
|
||||
data = {
|
||||
command = "/goform/formiPhoneAppDirect.xml?PWSTANDBY";
|
||||
};
|
||||
}
|
||||
# silverscreen up
|
||||
{
|
||||
service = "remote.send_command";
|
||||
target = {
|
||||
entity_id = "remote.rmproplus";
|
||||
};
|
||||
data = {
|
||||
num_repeats = 2;
|
||||
delay_secs = 1;
|
||||
hold_secs = 0;
|
||||
command = "b64:sgBqAgkaBBoJCRsJHBoKGgoJGgQaCQkaBAgbGwoIHAgcGwkJGwgAARkbCRsJGwkJGgQaCgkaBAgbCRsbCQkbGwkJGgQIGxwJGwkJGxsJCRwIHBoKCBsECBsbCAQIGwkAARgbChoKGgoJGxsJCRoECBsJHBsJCRoEGgkJGwkcGgobCQkbGwkJGwkbGwoIHAkbGwkJGwkAARgbCRsJGwoIGxwJCRsJGwkbGwoIGxwIChoKGhwJGwkJHBsJCRsJGxsJCRsJHBsJCRsJAAEYGwkbCRsKCBscCQkbCRsJGxsJCRwbCQkbCRsbCRsJCRscCQgcCRocCQkbCRsbCQobCQABGBsJGwkbCQkbHAkJGwkbCRsbCQkbGwoJGwkbGwkbCQkbGwoIHAkbGwkJGgobGwkKGwkAARccCRsJGwkJHBsJCRsJGwkbGwkJGxsKCRsIHBsJGwkJGxsKCRoJGxwJCRsJGxsJChsIAAEZGwgcCRsJCRscCQkbCRsJGhwJCRscCQkaChsbCRsJCRscCQgcCRocCQkbCRsbCggcCQABGBsJGwkbCggcGwkJGwkbCRsbCggcGgoJGwkbGwkbCggcGwkJGwkbGwkJHAgcGwkJGwkAARgbChoKGgoJGhwJCRsJGwkcGgoJGxsJCRsJGxsJHAkJGxsJCRsJGhwJCRwJGhwJCRsJAAEYGwoaChsJCRsbCQkaChsJGxwJCRsbCQkbCRsbChsJCRsbCQkbCRsbCgkbCRsbCQkcCAABFwQaChsJGwkJGxsKCBwIHAgcGwkJGxsKCBwIGwQaCRsJCRwaCggcCBwbCQkbCRwaCggcCAAF3AAAAAAAAAAAAAAAAAAA";
|
||||
};
|
||||
}
|
||||
# turn off beamer
|
||||
{
|
||||
service = "remote.send_command";
|
||||
target = {
|
||||
entity_id = "remote.rmproplus";
|
||||
};
|
||||
data = {
|
||||
num_repeats = 2;
|
||||
delay_secs = 1;
|
||||
hold_secs = 0;
|
||||
command = "b64:JgDaAAABKZMUERMSExITEhMSExETEhMSExITEhMSExETNxQ2ExITEhMSEzcTNxM3ExITEhM3ExITNxMSEhITEhM3EzcTEhM3EwAFyAABKJQUERMSEhITEhMSExITEhMSEhITEhMSExITNxM3ExITEhMREzcTNxQ3EhITEhM3ExITNxMSExITEhM3EzcTEhM3EwAFyAABKJQUERMSExETEhMSExITEhMSExETEhMSExITNxM3ExITEhMREzcTOBI4ExETEhM3ExITNxMSExITEhM3EzcTEhM3E5IGAA0FAAAAAAAAAAAAAAAAAAA=";
|
||||
};
|
||||
}
|
||||
# turn off tv switch
|
||||
{
|
||||
service = "switch.turn_off";
|
||||
target = {
|
||||
entity_id = "switch.tv_switch";
|
||||
};
|
||||
}
|
||||
];
|
||||
};
|
||||
"automation all_multimedia_on" = {
|
||||
alias = "all multimedia on";
|
||||
trigger = {
|
||||
platform = "state";
|
||||
entity_id = "binary_sensor.multimedia_device_on";
|
||||
to = "on";
|
||||
};
|
||||
action = [
|
||||
{
|
||||
service = "script.turn_on";
|
||||
target = {
|
||||
entity_id = "script.turn_on_tv";
|
||||
};
|
||||
}
|
||||
{
|
||||
delay = 5;
|
||||
}
|
||||
{
|
||||
service = "androidtv.adb_command";
|
||||
target = {
|
||||
entity_id = "media_player.android_tv_metz_cloonar_multimedia";
|
||||
};
|
||||
data = {
|
||||
command = "adb shell am start -a android.intent.action.VIEW -d content://android.media.tv/passthrough/com.mediatek.tvinput%2F.hdmi.HDMIInputService%2FHDMI100004";
|
||||
};
|
||||
}
|
||||
];
|
||||
};
|
||||
"automation bedroom tv off" = {
|
||||
alias = "bedroom tv off";
|
||||
trigger = {
|
||||
platform = "state";
|
||||
entity_id = "media_player.fire_tv_firetv_bedroom_cloonar_multimedia";
|
||||
to = "off";
|
||||
};
|
||||
action = [
|
||||
{
|
||||
service = "media_player.turn_off";
|
||||
target = {
|
||||
entity_id = "media_player.samsung_7_series_55";
|
||||
};
|
||||
}
|
||||
];
|
||||
};
|
||||
"automation multimedia scene switch" = {
|
||||
alias = "multimedia scene switch";
|
||||
trigger = [
|
||||
{
|
||||
platform = "event";
|
||||
event_type = "button_pressed";
|
||||
event_data = {
|
||||
id = [ 254 235 105 198 ];
|
||||
onoff = 1;
|
||||
};
|
||||
}
|
||||
{
|
||||
platform = "event";
|
||||
event_type = "ios.action_fired";
|
||||
event_data = {
|
||||
actionID = "Home Cinema";
|
||||
};
|
||||
}
|
||||
];
|
||||
condition = {
|
||||
condition = "state";
|
||||
entity_id = "binary_sensor.multimedia_device_on";
|
||||
state = "on";
|
||||
};
|
||||
action = [
|
||||
{
|
||||
choose = [
|
||||
{
|
||||
conditions = [
|
||||
{
|
||||
condition = "state";
|
||||
entity_id = "switch.tv_switch";
|
||||
state = "off";
|
||||
}
|
||||
];
|
||||
sequence = [
|
||||
{
|
||||
service = "script.turn_on";
|
||||
target = {
|
||||
entity_id = "script.turn_on_tv";
|
||||
};
|
||||
}
|
||||
];
|
||||
}
|
||||
{
|
||||
conditions = [
|
||||
{
|
||||
condition = "or";
|
||||
conditions = [
|
||||
{
|
||||
condition = "state";
|
||||
entity_id = "media_player.android_tv_metz_cloonar_multimedia";
|
||||
state = "on";
|
||||
}
|
||||
{
|
||||
condition = "state";
|
||||
entity_id = "media_player.android_tv_metz_cloonar_multimedia";
|
||||
state = "idle";
|
||||
}
|
||||
];
|
||||
}
|
||||
];
|
||||
sequence = [
|
||||
# silver screen down
|
||||
{
|
||||
service = "remote.send_command";
|
||||
target = {
|
||||
entity_id = "remote.rmproplus";
|
||||
};
|
||||
data = {
|
||||
num_repeats = 2;
|
||||
delay_secs = 1;
|
||||
hold_secs = 0;
|
||||
command = "b64:sQs0AB0JCxsLGx0IHQgLGh0ICxoLGx0JCxodCQobCxoLAAEXHQgdCR0JCxodCQsbCxsLGx0JCxoAAAAA";
|
||||
};
|
||||
}
|
||||
# turn on beamer
|
||||
{
|
||||
service = "remote.send_command";
|
||||
target = {
|
||||
entity_id = "remote.rmproplus";
|
||||
};
|
||||
data = {
|
||||
num_repeats = 1;
|
||||
delay_secs = 0.4;
|
||||
hold_secs = 0;
|
||||
command = "b64:JgAgAQABKZMUERMSExETEhMSExITEhMSExETEhMSExITNxM3ExITERM3EzgSOBM3ExETEhM3ExITEhMSExITERM3EzcTEhM3EwAFyAABKZMTEhMRExITEhMSExITEhMRExITEhMSExITNxM3ExITERM3EzcTNxM3ExITEhM3ExITEhMSExETEhM3EzcTEhM3EwAFyAABKZMUERMRExITEhMSExITERMSExITEhMSExITNxM3ExISEhM3EzcTNxM3ExITEhM3ExITEhMSExETEhM3EzcTEhM3EwAFxwABKZQUERMRFBETEhMSExITEhISExITEhMSExITNxM3ExITERM3EzcTNxM3FBETEhM3ExITEhMSExITERM3EzcTEhM3EwANBQAAAAAAAAAA";
|
||||
};
|
||||
}
|
||||
{
|
||||
service = "media_player.turn_off";
|
||||
target = {
|
||||
entity_id = "media_player.android_tv_metz_cloonar_multimedia";
|
||||
};
|
||||
}
|
||||
{
|
||||
service = "media_player.turn_on";
|
||||
target = {
|
||||
entity_id = "media_player.marantz_sr6015";
|
||||
};
|
||||
}
|
||||
];
|
||||
}
|
||||
{
|
||||
conditions = [
|
||||
{
|
||||
condition = "or";
|
||||
conditions = [
|
||||
{
|
||||
condition = "state";
|
||||
entity_id = "media_player.android_tv_metz_cloonar_multimedia";
|
||||
state = "off";
|
||||
}
|
||||
{
|
||||
condition = "state";
|
||||
entity_id = "media_player.android_tv_metz_cloonar_multimedia";
|
||||
state = "unavailable";
|
||||
}
|
||||
];
|
||||
}
|
||||
];
|
||||
sequence = [
|
||||
{
|
||||
service = "remote.send_command";
|
||||
target = {
|
||||
entity_id = "remote.rmproplus";
|
||||
};
|
||||
data = {
|
||||
num_repeats = 2;
|
||||
delay_secs = 1;
|
||||
hold_secs = 0;
|
||||
command = "b64:sgBqAgkaBBoJCRsJHBoKGgoJGgQaCQkaBAgbGwoIHAgcGwkJGwgAARkbCRsJGwkJGgQaCgkaBAgbCRsbCQkbGwkJGgQIGxwJGwkJGxsJCRwIHBoKCBsECBsbCAQIGwkAARgbChoKGgoJGxsJCRoECBsJHBsJCRoEGgkJGwkcGgobCQkbGwkJGwkbGwoIHAkbGwkJGwkAARgbCRsJGwoIGxwJCRsJGwkbGwoIGxwIChoKGhwJGwkJHBsJCRsJGxsJCRsJHBsJCRsJAAEYGwkbCRsKCBscCQkbCRsJGxsJCRwbCQkbCRsbCRsJCRscCQgcCRocCQkbCRsbCQobCQABGBsJGwkbCQkbHAkJGwkbCRsbCQkbGwoJGwkbGwkbCQkbGwoIHAkbGwkJGgobGwkKGwkAARccCRsJGwkJHBsJCRsJGwkbGwkJGxsKCRsIHBsJGwkJGxsKCRoJGxwJCRsJGxsJChsIAAEZGwgcCRsJCRscCQkbCRsJGhwJCRscCQkaChsbCRsJCRscCQgcCRocCQkbCRsbCggcCQABGBsJGwkbCggcGwkJGwkbCRsbCggcGgoJGwkbGwkbCggcGwkJGwkbGwkJHAgcGwkJGwkAARgbChoKGgoJGhwJCRsJGwkcGgoJGxsJCRsJGxsJHAkJGxsJCRsJGhwJCRwJGhwJCRsJAAEYGwoaChsJCRsbCQkaChsJGxwJCRsbCQkbCRsbChsJCRsbCQkbCRsbCgkbCRsbCQkcCAABFwQaChsJGwkJGxsKCBwIHAgcGwkJGxsKCBwIGwQaCRsJCRwaCggcCBwbCQkbCRwaCggcCAAF3AAAAAAAAAAAAAAAAAAA";
|
||||
};
|
||||
}
|
||||
# turn off beamer
|
||||
{
|
||||
service = "remote.send_command";
|
||||
target = {
|
||||
entity_id = "remote.rmproplus";
|
||||
};
|
||||
data = {
|
||||
num_repeats = 2;
|
||||
delay_secs = 1;
|
||||
hold_secs = 0;
|
||||
command = "b64:JgDaAAABKZMUERMSExITEhMSExETEhMSExITEhMSExETNxQ2ExITEhMSEzcTNxM3ExITEhM3ExITNxMSEhITEhM3EzcTEhM3EwAFyAABKJQUERMSEhITEhMSExITEhMSEhITEhMSExITNxM3ExITEhMREzcTNxQ3EhITEhM3ExITNxMSExITEhM3EzcTEhM3EwAFyAABKJQUERMSExETEhMSExITEhMSExETEhMSExITNxM3ExITEhMREzcTOBI4ExETEhM3ExITNxMSExITEhM3EzcTEhM3E5IGAA0FAAAAAAAAAAAAAAAAAAA=";
|
||||
};
|
||||
}
|
||||
{
|
||||
service = "script.turn_on";
|
||||
target = {
|
||||
entity_id = "script.turn_on_tv";
|
||||
};
|
||||
}
|
||||
];
|
||||
}
|
||||
];
|
||||
}
|
||||
{
|
||||
delay = 5;
|
||||
}
|
||||
{
|
||||
service = "androidtv.adb_command";
|
||||
target = {
|
||||
entity_id = "media_player.android_tv_metz_cloonar_multimedia";
|
||||
};
|
||||
data = {
|
||||
command = "adb shell am start -a android.intent.action.VIEW -d content://android.media.tv/passthrough/com.mediatek.tvinput%2F.hdmi.HDMIInputService%2FHDMI100004";
|
||||
};
|
||||
}
|
||||
];
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
{
|
||||
services.home-assistant.config = {
|
||||
"automation toilet music" = {
|
||||
alias = "toilet music";
|
||||
trigger = {
|
||||
platform = "state";
|
||||
entity_id = "light.toilett_lights";
|
||||
};
|
||||
action = [
|
||||
{
|
||||
service = "media_player.volume_mute";
|
||||
target = {
|
||||
entity_id = "media_player.music_toilet_snapcast_client";
|
||||
};
|
||||
data = {
|
||||
is_volume_muted = "{{ trigger.to_state.state == 'off' }}";
|
||||
};
|
||||
}
|
||||
];
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
{
|
||||
services.home-assistant.config = {
|
||||
notify = [
|
||||
{
|
||||
name = "NotificationGroup";
|
||||
platform = "group";
|
||||
services = [
|
||||
{
|
||||
service = "pushover_dominik";
|
||||
}
|
||||
];
|
||||
}
|
||||
];
|
||||
};
|
||||
}
|
||||
@@ -1,71 +0,0 @@
|
||||
{
|
||||
services.home-assistant.extraComponents = [
|
||||
"wake_on_lan"
|
||||
];
|
||||
services.home-assistant.config = {
|
||||
ios = {
|
||||
actions = [
|
||||
{
|
||||
name = "Turn on PC";
|
||||
label.text = "Turn on PC";
|
||||
icon = {
|
||||
icon = "controller";
|
||||
color = "#ffffff";
|
||||
};
|
||||
show_in_watch = true;
|
||||
}
|
||||
];
|
||||
};
|
||||
wake_on_lan = {};
|
||||
"automation pc_switch" = {
|
||||
alias = "switch pc";
|
||||
trigger = {
|
||||
platform = "event";
|
||||
event_type = "button_pressed";
|
||||
event_data = {
|
||||
id = [ 254 235 105 198 ];
|
||||
onoff = 0;
|
||||
};
|
||||
};
|
||||
action = {
|
||||
service = "script.turn_on";
|
||||
target = {
|
||||
entity_id = "script.turn_on_pc";
|
||||
};
|
||||
};
|
||||
};
|
||||
script = {
|
||||
turn_on_pc = {
|
||||
sequence = [
|
||||
{
|
||||
service = "wake_on_lan.send_magic_packet";
|
||||
data = {
|
||||
mac = "04:7c:16:d5:63:5e";
|
||||
broadcast_address = "10.42.96.5";
|
||||
broadcast_port = 9;
|
||||
};
|
||||
}
|
||||
];
|
||||
};
|
||||
};
|
||||
"automation turn on pc" = {
|
||||
trigger = [
|
||||
{
|
||||
platform = "event";
|
||||
event_type = "ios.action_fired";
|
||||
event_data = {
|
||||
actionID = "Turn on PC";
|
||||
};
|
||||
}
|
||||
];
|
||||
action = [
|
||||
{
|
||||
service = "script.turn_on";
|
||||
target = {
|
||||
entity_id = "script.turn_on_pc";
|
||||
};
|
||||
}
|
||||
];
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -1,138 +0,0 @@
|
||||
{
|
||||
services.home-assistant.extraComponents = [
|
||||
"daikin"
|
||||
"enocean"
|
||||
];
|
||||
|
||||
services.home-assistant.config = {
|
||||
"automation presense kitchen" = {
|
||||
alias = "presense kitchen";
|
||||
mode = "restart";
|
||||
trigger = {
|
||||
platform = "state";
|
||||
entity_id = [
|
||||
"sensor.presense_kitchen"
|
||||
];
|
||||
};
|
||||
action = [
|
||||
{
|
||||
choose = [
|
||||
{
|
||||
conditions = [ "{{ trigger.to_state.state == \"\" }}" ];
|
||||
sequence = [
|
||||
];
|
||||
}
|
||||
{
|
||||
conditions = [ "{{ trigger.to_state.state != \"\" }}" ];
|
||||
sequence = [
|
||||
{
|
||||
service = "light.turn_on";
|
||||
entity_id = "light.kitchen_lights";
|
||||
}
|
||||
];
|
||||
}
|
||||
];
|
||||
}
|
||||
];
|
||||
};
|
||||
sensor = [
|
||||
{
|
||||
platform = "mqtt_room";
|
||||
device_id = "dominiksiphone";
|
||||
name = "Dominiks iPhone";
|
||||
state_topic = "espresense/devices/dominiksiphone";
|
||||
timeout = 10;
|
||||
away_timeout = 120;
|
||||
}
|
||||
{
|
||||
platform = "template";
|
||||
sensors = {
|
||||
presense_devices = {
|
||||
friendly_name = "Presense Devices";
|
||||
value_template = "dominiks_iphone";
|
||||
};
|
||||
};
|
||||
}
|
||||
{
|
||||
platform = "template";
|
||||
sensors = {
|
||||
presense_livingroom = {
|
||||
friendly_name = "Presense Livingroom";
|
||||
value_template = ''
|
||||
{% set room = "livingroom" %}
|
||||
{% set presense = namespace(list=[]) %}
|
||||
{% set presense_list = [] %}
|
||||
{% set device_list = states('sensor.presense_devices').split(',') %}
|
||||
{% for device in device_list %}
|
||||
{% if is_state('sensor.' + device, room) %}
|
||||
{% set presense.list = presense.list + [device] %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{{ presense.list | join("") }}
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
||||
{
|
||||
platform = "template";
|
||||
sensors = {
|
||||
presense_kitchen = {
|
||||
friendly_name = "Presense Kitchen";
|
||||
value_template = ''
|
||||
{% set room = "kitchen" %}
|
||||
{% set presense = namespace(list=[]) %}
|
||||
{% set presense_list = [] %}
|
||||
{% set device_list = states('sensor.presense_devices').split(',') %}
|
||||
{% for device in device_list %}
|
||||
{% if is_state('sensor.' + device, room) %}
|
||||
{% set presense.list = presense.list + [device] %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{{ presense.list | join("") }}
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
||||
{
|
||||
platform = "template";
|
||||
sensors = {
|
||||
presense_hallway = {
|
||||
friendly_name = "Presense Hallway";
|
||||
value_template = ''
|
||||
{% set room = "hallway" %}
|
||||
{% set presense = namespace(list=[]) %}
|
||||
{% set presense_list = [] %}
|
||||
{% set device_list = states('sensor.presense_devices').split(',') %}
|
||||
{% for device in device_list %}
|
||||
{% if is_state('sensor.' + device, room) %}
|
||||
{% set presense.list = presense.list + [device] %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{{ presense.list | join("") }}
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
||||
{
|
||||
platform = "template";
|
||||
sensors = {
|
||||
presense_bedroom = {
|
||||
friendly_name = "Presense Bedroom";
|
||||
value_template = ''
|
||||
{% set room = "bedroom" %}
|
||||
{% set presense = namespace(list=[]) %}
|
||||
{% set presense_list = [] %}
|
||||
{% set device_list = states('sensor.presense_devices').split(',') %}
|
||||
{% for device in device_list %}
|
||||
{% if is_state('sensor.' + device, room) %}
|
||||
{% set presense.list = presense.list + [device] %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{{ presense.list | join("") }}
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
||||
];
|
||||
};
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
{
|
||||
services.home-assistant.extraComponents = [
|
||||
"pushover"
|
||||
];
|
||||
|
||||
# services.home-assistant.config = {
|
||||
# notify = [
|
||||
# {
|
||||
# name = "pushover_dominik";
|
||||
# platform = "pushover";
|
||||
# api_key = "!secret pushover_dominik_api_key";
|
||||
# user_key = "!secret pushover_dominik_user_key";
|
||||
# }
|
||||
# ];
|
||||
# };
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
{
|
||||
services.home-assistant.extraComponents = [
|
||||
"roborock"
|
||||
];
|
||||
|
||||
services.home-assistant.config = {
|
||||
"automation roborock" = {
|
||||
alias = "roborock";
|
||||
trigger = {
|
||||
platform = "state";
|
||||
entity_id = [
|
||||
"person.dominik"
|
||||
];
|
||||
from = "home";
|
||||
to = "not_home";
|
||||
};
|
||||
action = [
|
||||
{
|
||||
service = "vacuum.start";
|
||||
target = {
|
||||
device_id = "136c307ff46cd968d08e9f9d20886755";
|
||||
};
|
||||
}
|
||||
];
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
{
|
||||
services.home-assistant.config = {
|
||||
"automation scene_switch" = {
|
||||
alias = "switch scene";
|
||||
trigger = {
|
||||
platform = "event";
|
||||
event_type = "button_pressed";
|
||||
event_data = {
|
||||
id = [ 254 242 234 134 ];
|
||||
};
|
||||
};
|
||||
action = {
|
||||
service_template = "switch.turn_on";
|
||||
data_template = {
|
||||
entity_id = "switch.computer";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -1,114 +0,0 @@
|
||||
{ lib, ... }:
|
||||
let
|
||||
colorbulbs = [
|
||||
{ name = "Living Bulb 1"; id = "34945479BC57"; }
|
||||
{ name = "Living Bulb 2"; id = "485519D9A1B2"; }
|
||||
{ name = "Living Bulb 3"; id = "485519D9AE95"; }
|
||||
{ name = "Living Bulb 4"; id = "485519D94A28"; }
|
||||
{ name = "Living Bulb 5"; id = "485519DA6B6A"; }
|
||||
{ name = "Living Bulb 6"; id = "485519D9E018"; }
|
||||
{ name = "Bedroom Bulb 1"; id = "485519FBDF20"; }
|
||||
{ name = "Bedroom Bulb 2"; id = "485519FBE171"; }
|
||||
{ name = "Bedroom Bulb 3"; id = "485519FBE377"; }
|
||||
{ name = "Bedroom Bulb 4"; id = "485519FC05C5"; }
|
||||
];
|
||||
|
||||
switches = [];
|
||||
|
||||
proswitches = [
|
||||
{ name = "Livingroom Switch"; id = "shellyplus2pm-e86beae5d5d8"; relay = "0"; }
|
||||
{ name = "Kitchen Switch"; id = "shellyplus2pm-e86beae5d5d8"; relay = "1"; }
|
||||
{ name = "Bedroom Switch"; id = "shelly1pmminig3-34b7da933fe0"; relay = "0"; }
|
||||
{ name = "Hallway Circuit"; id = "shellypro3-c8f09e894448"; relay = "0"; }
|
||||
{ name = "Bathroom Circuit"; id = "shellypro3-c8f09e894448"; relay = "1"; }
|
||||
{ name = "Kitchen Circuit"; id = "shellypro3-c8f09e894448"; relay = "2"; }
|
||||
{ name = "TV Switch"; id = "shelly1pmminig3-34b7da8b64c8"; relay = "0"; }
|
||||
];
|
||||
in {
|
||||
services.home-assistant.extraComponents = [
|
||||
"shelly"
|
||||
];
|
||||
|
||||
services.home-assistant.config = {
|
||||
mqtt = {
|
||||
switch = builtins.concatLists [
|
||||
(builtins.map (switch:
|
||||
let
|
||||
unique_id = builtins.replaceStrings [" "] ["_"] switch.name;
|
||||
in {
|
||||
name = switch.name;
|
||||
unique_id = unique_id;
|
||||
state_topic = "shellies/shellyswitch25-${switch.id}/relay/${switch.relay}";
|
||||
command_topic = "shellies/shellyswitch25-${switch.id}/relay/${switch.relay}/command";
|
||||
payload_on = "on";
|
||||
payload_off = "off";
|
||||
}
|
||||
) switches)
|
||||
(builtins.map (switch:
|
||||
let
|
||||
unique_id = builtins.replaceStrings [" "] ["_"] switch.name;
|
||||
in {
|
||||
name = switch.name;
|
||||
unique_id = unique_id;
|
||||
state_topic = "shellies/${switch.id}/status/switch:${switch.relay}";
|
||||
value_template = "{{ value_json.output }}";
|
||||
state_on = true;
|
||||
state_off = false;
|
||||
command_topic = "shellies/${switch.id}/rpc";
|
||||
payload_on = "{\"id\":${switch.relay}, \"src\":\"homeassistant\", \"method\":\"Switch.Set\", \"params\":{\"id\":${switch.relay}, \"on\":true}}";
|
||||
payload_off = "{\"id\":${switch.relay}, \"src\":\"homeassistant\", \"method\":\"Switch.Set\", \"params\":{\"id\":${switch.relay}, \"on\":false}}";
|
||||
availability_topic = "shellies/${switch.id}/online";
|
||||
payload_available = "true";
|
||||
payload_not_available = "false";
|
||||
}
|
||||
) proswitches)
|
||||
];
|
||||
light = builtins.map (bulb:
|
||||
let
|
||||
unique_id = builtins.replaceStrings [" "] ["_"] bulb.name;
|
||||
in {
|
||||
name = bulb.name;
|
||||
unique_id = "${unique_id}";
|
||||
schema = "template";
|
||||
state_topic = "shellies/shellycolorbulb-${bulb.id}/color/0/status";
|
||||
state_template = "{% if value_json.ison %}on{% else %}off{% endif %}";
|
||||
command_topic = "shellies/shellycolorbulb-${bulb.id}/color/0/set";
|
||||
command_on_template = ''
|
||||
{
|
||||
"turn": "on",
|
||||
"effect": 0,
|
||||
|
||||
{%- if red is defined and green is defined and blue is defined -%}
|
||||
"mode": "color",
|
||||
"red": {{ red }},
|
||||
"green": {{ green }},
|
||||
"blue": {{ blue }},
|
||||
{%- endif -%}
|
||||
|
||||
{%- if brightness is defined -%}
|
||||
"gain": {{brightness | float | multiply(0.3922) | round(0)}},
|
||||
"brightness": {{brightness | float | multiply(0.3922) | round(0)}},
|
||||
{%- endif -%}
|
||||
|
||||
{% if color_temp is defined %}
|
||||
"mode": "white",
|
||||
"temp":{{ (1/(color_temp | float)) | multiply(1000000) | round(0) }},
|
||||
{% endif %}
|
||||
}
|
||||
'';
|
||||
command_off_template = ''
|
||||
{
|
||||
"turn": "off"
|
||||
}
|
||||
'';
|
||||
brightness_template = "{{ value_json.brightness | float | multiply(2.55) | round(0) }}";
|
||||
color_temp_template = "{{ 1000000 | multiply(1/(value_json.temp | float)) | round(0) }}";
|
||||
red_template = "{{ value_json.red }}";
|
||||
green_template = "{{ value_json.green }}";
|
||||
blue_template = "{{ value_json.blue }}";
|
||||
max_mireds = 333;
|
||||
min_mireds = 154;
|
||||
}) colorbulbs;
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -1,74 +0,0 @@
|
||||
{
|
||||
services.home-assistant.config = {
|
||||
"automation wakeup" = {
|
||||
alias = "wakeup";
|
||||
trigger = {
|
||||
platform = "time";
|
||||
at = "input_datetime.wakeup";
|
||||
};
|
||||
action = [
|
||||
{
|
||||
service = "switch.turn_on";
|
||||
entity_id = "switch.coffee";
|
||||
}
|
||||
{
|
||||
delay = 1700;
|
||||
}
|
||||
{
|
||||
service = "switch.turn_on";
|
||||
entity_id = "switch.78_8c_b5_fe_41_62_port_2_poe"; # livingroom
|
||||
}
|
||||
{
|
||||
service = "switch.turn_on";
|
||||
entity_id = "switch.78_8c_b5_fe_41_62_port_3_poe"; # garden
|
||||
}
|
||||
];
|
||||
};
|
||||
"automation sleep" = {
|
||||
alias = "sleep";
|
||||
trigger = [
|
||||
{
|
||||
platform = "event";
|
||||
event_type = "shelly.click";
|
||||
event_data = {
|
||||
device = "shellybutton1-E8DB84AA196D";
|
||||
};
|
||||
}
|
||||
{
|
||||
platform = "event";
|
||||
event_type = "shelly.click";
|
||||
event_data = {
|
||||
device = "shellybutton1-E8DB84AA136D";
|
||||
};
|
||||
}
|
||||
];
|
||||
action = [
|
||||
{
|
||||
choose = [
|
||||
{
|
||||
conditions = [ "{{ trigger.event.data.click_type == \"long\" }}" ];
|
||||
sequence = [
|
||||
{
|
||||
service = "light.turn_off";
|
||||
entity_id = "all";
|
||||
}
|
||||
{
|
||||
service = "switch.turn_off";
|
||||
entity_id = "switch.coffee";
|
||||
}
|
||||
{
|
||||
service = "switch.turn_off";
|
||||
entity_id = "switch.78_8c_b5_fe_41_62_port_2_poe";
|
||||
}
|
||||
{
|
||||
service = "switch.turn_off";
|
||||
entity_id = "switch.78_8c_b5_fe_41_62_port_3_poe";
|
||||
}
|
||||
];
|
||||
}
|
||||
];
|
||||
}
|
||||
];
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
{
|
||||
services.home-assistant = {
|
||||
extraComponents = [ "snapcast" ];
|
||||
config = {
|
||||
"automation piano" = {
|
||||
alias = "piano";
|
||||
trigger = {
|
||||
platform = "state";
|
||||
entity_id = "media_player.music_piano_snapcast_client";
|
||||
attribute = "is_volume_muted";
|
||||
};
|
||||
condition = [
|
||||
{
|
||||
condition = "template";
|
||||
value_template = "{{ trigger.from_state.state != 'unavailable' }}";
|
||||
}
|
||||
{
|
||||
condition = "template";
|
||||
value_template = "{{ state_attr('media_player.music_piano_snapcast_client', 'is_volume_muted') == true or state_attr('media_player.music_piano_snapcast_client', 'is_volume_muted') == false }}";
|
||||
}
|
||||
];
|
||||
action = {
|
||||
service = "switch.turn_on";
|
||||
target = {
|
||||
entity_id = "switch.piano_switch_power";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
{ nixpkgs, ...}:
|
||||
{
|
||||
imports = [ (builtins.fetchGit {
|
||||
url = "https://github.com/astro/microvm.nix";
|
||||
} + "/nixos-modules/host") ];
|
||||
|
||||
systemd.network.networks."31-server".matchConfig.Name = [ "vm-*" ];
|
||||
}
|
||||
@@ -1,59 +0,0 @@
|
||||
{ pkgs, lib, ... }:
|
||||
let
|
||||
mopidy-autoplay = pkgs.python3Packages.buildPythonApplication rec {
|
||||
pname = "Mopidy-Autoplay";
|
||||
version = "0.2.3";
|
||||
|
||||
src = pkgs.python3Packages.fetchPypi {
|
||||
inherit pname version;
|
||||
sha256 = "sha256-E2Q+Cn2LWSbfoT/gFzUfChwl67Mv17uKmX2woFz/3YM=";
|
||||
};
|
||||
|
||||
propagatedBuildInputs = [
|
||||
pkgs.mopidy
|
||||
] ++ (with pkgs.python3Packages; [
|
||||
configobj
|
||||
]);
|
||||
|
||||
# no tests implemented
|
||||
doCheck = false;
|
||||
|
||||
meta = with lib; {
|
||||
homepage = "https://codeberg.org/sph/mopidy-autoplay";
|
||||
};
|
||||
};
|
||||
in
|
||||
{
|
||||
services.mopidy = {
|
||||
enable = true;
|
||||
extensionPackages = [ pkgs.mopidy-iris pkgs.mopidy-tunein mopidy-autoplay ];
|
||||
configuration = ''
|
||||
[audio]
|
||||
output = audioresample ! audioconvert ! audio/x-raw,rate=48000,channels=2,format=S16LE ! wavenc ! filesink location=/run/snapserver/mopidy
|
||||
|
||||
[file]
|
||||
enabled = false
|
||||
|
||||
[autoplay]
|
||||
enabled = true
|
||||
'';
|
||||
};
|
||||
|
||||
services.nginx.virtualHosts."mopidy.cloonar.com" = {
|
||||
forceSSL = true;
|
||||
enableACME = true;
|
||||
acmeRoot = null;
|
||||
extraConfig = ''
|
||||
proxy_buffering off;
|
||||
'';
|
||||
locations."/".extraConfig = ''
|
||||
proxy_pass http://127.0.0.1:6680;
|
||||
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;
|
||||
'';
|
||||
};
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
{ config, pkgs, ... }:
|
||||
|
||||
{
|
||||
services.mosquitto = {
|
||||
enable = true;
|
||||
|
||||
listeners = [
|
||||
{
|
||||
users."espresense" = {
|
||||
password = "insecure-password";
|
||||
acl = [ "readwrite espresense/#" ];
|
||||
};
|
||||
users."home-assistant" = {
|
||||
hashedPassword = "$7$101$7uaagoQWQ3ICJ/wg$5cWZs4ae4DjToe44bOzpDopPv1kRaaVD+zF6BE64yDJH2/MBqXfD6f2/o9M/65ArhV92DAK+txXRYsEcZLl45A==";
|
||||
acl = [ "readwrite #" ];
|
||||
};
|
||||
users."ps5-mqtt" = {
|
||||
password = "insecure-password";
|
||||
acl = [ "readwrite #" ];
|
||||
};
|
||||
users."shairport-mqtt" = {
|
||||
password = "insecure-password";
|
||||
acl = [ "readwrite #" ];
|
||||
};
|
||||
users."shelly" = {
|
||||
password = "password";
|
||||
acl = [ "readwrite shellies/#" ];
|
||||
};
|
||||
}
|
||||
];
|
||||
};
|
||||
|
||||
# networking.firewall = {
|
||||
# allowedTCPPorts = [ 1883 ];
|
||||
# };
|
||||
}
|
||||
@@ -1,110 +0,0 @@
|
||||
{ ... }: {
|
||||
boot.kernel.sysctl = {
|
||||
# if you use ipv4, this is all you need
|
||||
"net.ipv4.conf.all.forwarding" = true;
|
||||
# If you want to use it for ipv6
|
||||
"net.ipv6.conf.all.forwarding" = false;
|
||||
};
|
||||
|
||||
systemd.network = {
|
||||
enable = true;
|
||||
wait-online.anyInterface = true;
|
||||
links = {
|
||||
"10-wan" = {
|
||||
matchConfig.PermanentMACAddress = "c0:74:2b:fd:9a:7f";
|
||||
linkConfig.Name = "wan";
|
||||
};
|
||||
};
|
||||
netdevs = {
|
||||
"30-server".netdevConfig = {
|
||||
Kind = "bridge";
|
||||
Name = "server";
|
||||
};
|
||||
};
|
||||
networks = {
|
||||
"31-server" = {
|
||||
matchConfig.Name = [ "vserver" ];
|
||||
# Attach to the bridge that was configured above
|
||||
networkConfig.Bridge = "server";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
networking = {
|
||||
useDHCP = false;
|
||||
# Define VLANS
|
||||
nameservers = [ "10.42.97.1" ];
|
||||
# resolvconf.enable = false;
|
||||
vlans = {
|
||||
lan = {
|
||||
id = 95;
|
||||
interface = "enP3p49s0";
|
||||
};
|
||||
vserver = {
|
||||
id = 97;
|
||||
interface = "enP3p49s0";
|
||||
};
|
||||
multimedia = {
|
||||
id = 98;
|
||||
interface = "enP3p49s0";
|
||||
};
|
||||
smart = {
|
||||
id = 99;
|
||||
interface = "enP3p49s0";
|
||||
};
|
||||
infrastructure = {
|
||||
id = 100;
|
||||
interface = "enP3p49s0";
|
||||
};
|
||||
guest = {
|
||||
id = 111;
|
||||
interface = "enP3p49s0";
|
||||
};
|
||||
};
|
||||
|
||||
interfaces = {
|
||||
# Don't request DHCP on the physical interfaces
|
||||
lan.useDHCP = false;
|
||||
enP3p49s0.useDHCP = false;
|
||||
|
||||
# Handle the VLANs
|
||||
wan.useDHCP = true;
|
||||
lan = {
|
||||
ipv4.addresses = [{
|
||||
address = "10.42.95.1";
|
||||
prefixLength = 24;
|
||||
}];
|
||||
};
|
||||
server = {
|
||||
ipv4.addresses = [{
|
||||
address = "10.42.97.1";
|
||||
prefixLength = 24;
|
||||
}];
|
||||
};
|
||||
multimedia = {
|
||||
ipv4.addresses = [{
|
||||
address = "10.42.98.1";
|
||||
prefixLength = 24;
|
||||
}];
|
||||
};
|
||||
smart = {
|
||||
ipv4.addresses = [{
|
||||
address = "10.42.99.1";
|
||||
prefixLength = 24;
|
||||
}];
|
||||
};
|
||||
infrastructure = {
|
||||
ipv4.addresses = [{
|
||||
address = "10.42.100.1";
|
||||
prefixLength = 24;
|
||||
}];
|
||||
};
|
||||
guest = {
|
||||
ipv4.addresses = [{
|
||||
address = "10.42.111.1";
|
||||
prefixLength = 24;
|
||||
}];
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
{ config, pkgs, ... }: {
|
||||
users.users.omada = {
|
||||
isSystemUser = true;
|
||||
group = "omada";
|
||||
home = "/var/lib/omada";
|
||||
createHome = true;
|
||||
};
|
||||
users.groups.omada = { };
|
||||
users.groups.docker.members = [ "omada" ];
|
||||
|
||||
# TODO: check if we can run docker service as other user than root
|
||||
virtualisation = {
|
||||
oci-containers.containers = {
|
||||
omada = {
|
||||
autoStart = false;
|
||||
image = "mbentley/omada-controller:5.14.26.1";
|
||||
volumes = [
|
||||
"/var/lib/omada/data:/opt/tplink/EAPController/data"
|
||||
"/var/lib/omada/logs:/opt/tplink/EAPController/logs"
|
||||
];
|
||||
extraOptions = [
|
||||
"--network=server"
|
||||
"--mac-address=1a:c4:04:6e:29:bd"
|
||||
"--ip=10.42.97.2"
|
||||
];
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
{ config, pkgs, stdenv, ... }:
|
||||
let
|
||||
vpnc = pkgs.writeShellScript "vpnc" ''
|
||||
export INTERNAL_IP4_DNS=
|
||||
. ${pkgs.vpnc-scripts}/bin/vpnc-script
|
||||
'';
|
||||
in
|
||||
{
|
||||
sops.secrets.wrwks_vpn_key = {};
|
||||
|
||||
networking.openconnect.interfaces = {
|
||||
wrwks = {
|
||||
gateway = "vpn.wrwks.at";
|
||||
passwordFile = config.sops.secrets.wrwks_vpn_key.path;
|
||||
protocol = "anyconnect";
|
||||
user = "exdpolakovics@wrwks.local";
|
||||
extraOptions = {
|
||||
authgroup = "WRWKS-SSL-VPN-Service";
|
||||
script = "${vpnc}";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
systemd.services.openconnect-wrwks-keepalive = {
|
||||
serviceConfig.Type = "oneshot";
|
||||
path = with pkgs; [ bash inetutils ];
|
||||
script = ''
|
||||
ping -c 2 stage.wsw.at
|
||||
'';
|
||||
};
|
||||
|
||||
systemd.timers.openconnect-wrwks-keepalive = {
|
||||
wantedBy = [ "timers.target" ];
|
||||
partOf = [ "openconnect-wrwks-keepalive.service" ];
|
||||
timerConfig = {
|
||||
OnCalendar = "*:0/1";
|
||||
Unit = "openconnect-wrwks-keepalive.service";
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
{ config, pkgs, ... }:
|
||||
|
||||
{
|
||||
virtualisation.oci-containers.backend = "podman";
|
||||
virtualisation.oci-containers.containers = {
|
||||
palworld = {
|
||||
image = "thijsvanloef/palworld-server-docker:latest";
|
||||
autoStart = false;
|
||||
ports = [
|
||||
"8211:8211/udp"
|
||||
"27015:27015/udp"
|
||||
];
|
||||
environmentFiles = [
|
||||
config.sops.secrets.palworld.path
|
||||
];
|
||||
volumes = [
|
||||
"/var/lib/palworld/:/palworld/"
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
systemd.timers."restart-palworld" = {
|
||||
wantedBy = [ "timers.target" ];
|
||||
timerConfig = {
|
||||
OnCalendar = "*-*-* 3:00:00";
|
||||
Unit = "restart-palworld.service";
|
||||
};
|
||||
};
|
||||
|
||||
systemd.services."restart-palworld" = {
|
||||
script = ''
|
||||
set -eu
|
||||
if ${pkgs.systemd}/bin/systemctl is-active --quiet podman-palworld.service; then
|
||||
${pkgs.systemd}/bin/systemctl restart podman-palworld.service
|
||||
fi
|
||||
'';
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
User = "root";
|
||||
};
|
||||
};
|
||||
|
||||
sops.secrets.palworld = {};
|
||||
}
|
||||
@@ -1,77 +0,0 @@
|
||||
{ pkgs, ... }:
|
||||
let
|
||||
cids = import ../modules/staticids.nix;
|
||||
json = pkgs.formats.json { };
|
||||
|
||||
update-containers = pkgs.writeShellScriptBin "update-containers" ''
|
||||
SUDO=""
|
||||
if [[ $(id -u) -ne 0 ]]; then
|
||||
SUDO="sudo"
|
||||
fi
|
||||
|
||||
images=$($SUDO ${pkgs.podman}/bin/podman ps -a --format="{{.Image}}" | sort -u)
|
||||
|
||||
for image in $images
|
||||
do
|
||||
$SUDO ${pkgs.podman}/bin/podman pull $image
|
||||
done
|
||||
'';
|
||||
in {
|
||||
users.groups.podman.gid = cids.gids.podman;
|
||||
virtualisation = {
|
||||
# containers.containersConf.settings = {
|
||||
# containers.dns_servers = [ "10.42.97.1" ];
|
||||
# };
|
||||
podman = {
|
||||
enable = true;
|
||||
dockerCompat = true;
|
||||
# defaultNetwork.settings = {
|
||||
# dns_enabled = true; # Enable DNS resolution in the podman network.
|
||||
# };
|
||||
};
|
||||
};
|
||||
|
||||
environment.etc."containers/networks/server.json" = {
|
||||
source = json.generate "server.json" ({
|
||||
name = "server";
|
||||
id = "d3a55d6bcc28571c124b4e65cdf1831339045d296858f79e7130fa70da9c0904";
|
||||
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 = "host-local";
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
systemd.timers = {
|
||||
# ...
|
||||
updatecontainers = {
|
||||
timerConfig = {
|
||||
Unit = "updatecontainers.service";
|
||||
OnCalendar = "02:00";
|
||||
};
|
||||
wantedBy = [ "timers.target" ];
|
||||
};
|
||||
# ...
|
||||
};
|
||||
|
||||
systemd.services = {
|
||||
# ...
|
||||
updatecontainers = {
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
ExecStart = "${update-containers}/bin/update-containers";
|
||||
};
|
||||
};
|
||||
# ...
|
||||
};
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
{ config, pkgs, ... }:
|
||||
|
||||
{
|
||||
services.postgresql = {
|
||||
enable = true;
|
||||
ensureDatabases = [ "mydatabase" ];
|
||||
|
||||
identMap = ''
|
||||
# ArbitraryMapName systemUser DBUser
|
||||
superuser_map root postgres
|
||||
superuser_map postgres postgres
|
||||
# Let other names login as themselves
|
||||
superuser_map /^(.*)$ \1
|
||||
'';
|
||||
authentication = pkgs.lib.mkOverride 10 ''
|
||||
#type database DBuser auth-method optional_ident_map
|
||||
local sameuser all peer map=superuser_map
|
||||
'';
|
||||
};
|
||||
};
|
||||
@@ -1,133 +0,0 @@
|
||||
{ pkgs, config, python3Packages, ... }:
|
||||
let
|
||||
domain = "snapcast.cloonar.com";
|
||||
|
||||
snapweb = pkgs.stdenv.mkDerivation {
|
||||
pname = "snapweb";
|
||||
version = "0.8";
|
||||
|
||||
src = pkgs.fetchzip {
|
||||
url = "https://github.com/badaix/snapweb/releases/download/v0.8.0/snapweb.zip";
|
||||
sha256 = "sha256-IpT1pcuzcM8kqWJUX3xxpRQHlfPNsrwhemLmY0PyzjI=";
|
||||
stripRoot = false;
|
||||
};
|
||||
|
||||
installPhase = ''
|
||||
mkdir -p $out
|
||||
cp -r $src/* $out/
|
||||
'';
|
||||
};
|
||||
in
|
||||
{
|
||||
security.acme.certs."${domain}" = {
|
||||
group = "nginx";
|
||||
};
|
||||
|
||||
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;
|
||||
};
|
||||
};
|
||||
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.enable = true;
|
||||
http.docRoot = "${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.enable = 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";
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
{
|
||||
uids = {
|
||||
unbound = 10001;
|
||||
gitea = 10002;
|
||||
gitea-runner = 10003;
|
||||
podman = 10004;
|
||||
};
|
||||
gids = {
|
||||
unbound = 10001;
|
||||
gitea = 10002;
|
||||
gitea-runner = 10003;
|
||||
podman = 10004;
|
||||
};
|
||||
}
|
||||
@@ -1,58 +0,0 @@
|
||||
{ pkgs, ... }:
|
||||
{
|
||||
systemd.services.sysbox = {
|
||||
description = "Sysbox container runtime";
|
||||
documentation = [ "https://github.com/nestybox/sysbox" ];
|
||||
bindsTo = [ "sysbox-mgr.service" "sysbox-fs.service" ];
|
||||
after = [ "sysbox-mgr.service" "sysbox-fs.service" ];
|
||||
before = [ "docker.service" "containerd.service" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
serviceConfig = {
|
||||
Type = "exec";
|
||||
ExecStart = ''
|
||||
/bin/sh -c "${pkgs.sysbox}/bin/sysbox-runc --version && ${pkgs.sysbox}/bin/sysbox-mgr --version && ${pkgs.sysbox}/bin/sysbox-fs --version && ${pkgs.coreutils-full}/bin/sleep infinity"
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
systemd.services.sysbox-fs = {
|
||||
description = "sysbox-fs (part of the Sysbox container runtime)";
|
||||
partOf = [ "sysbox.service" ];
|
||||
after = [ "sysbox-mgr.service" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
serviceConfig = {
|
||||
Type = "notify";
|
||||
ExecStart = "${pkgs.sysbox}/bin/sysbox-fs";
|
||||
TimeoutStartSec = 10;
|
||||
TimeoutStopSec = 10;
|
||||
StartLimitInterval = 0;
|
||||
NotifyAccess = "main";
|
||||
OOMScoreAdjust = -500;
|
||||
# The number of files opened by sysbox-fs is a function of the number of
|
||||
# containers and the workloads within them. Thus we set the limit to
|
||||
# infinite so to prevent "too many open files" errors.
|
||||
LimitNOFILE = "infinity";
|
||||
LimitNPROC = "infinity";
|
||||
};
|
||||
};
|
||||
|
||||
systemd.services.sysbox-mgr = {
|
||||
description = "sysbox-mgr (part of the Sysbox container runtime)";
|
||||
partOf = [ "sysbox.service" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
serviceConfig = {
|
||||
Type = "notify";
|
||||
ExecStart = "${pkgs.sysbox}/bin/sysbox-mgr";
|
||||
TimeoutStartSec = 45;
|
||||
TimeoutStopSec = 90;
|
||||
StartLimitInterval = 0;
|
||||
NotifyAccess = "main";
|
||||
OOMScoreAdjust = -500;
|
||||
# The number of files opened by sysbox-fs is a function of the number of
|
||||
# containers and the workloads within them. Thus we set the limit to
|
||||
# infinite so to prevent "too many open files" errors.
|
||||
LimitNOFILE = "infinity";
|
||||
LimitNPROC = "infinity";
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -1,329 +0,0 @@
|
||||
{ config, pkgs, ... }:
|
||||
let
|
||||
cids = import ../modules/staticids.nix;
|
||||
domain = "ns.cloonar.com";
|
||||
|
||||
adblockLocalZones = pkgs.stdenv.mkDerivation {
|
||||
name = "unbound-zones-adblock";
|
||||
|
||||
src = (pkgs.fetchFromGitHub {
|
||||
owner = "StevenBlack";
|
||||
repo = "hosts";
|
||||
rev = "3.0.0";
|
||||
sha256 = "01g6pc9s1ah2w1cbf6bvi424762hkbpbgja9585a0w99cq0n6bxv";
|
||||
} + "/hosts");
|
||||
|
||||
phases = [ "installPhase" ];
|
||||
|
||||
installPhase = ''
|
||||
${pkgs.gawk}/bin/awk '{sub(/\r$/,"")} {sub(/^127\.0\.0\.1/,"0.0.0.0")} BEGIN { OFS = "" } NF == 2 && $1 == "0.0.0.0" { print "local-zone: \"", $2, "\" static"}' $src | tr '[:upper:]' '[:lower:]' | sort -u > $out
|
||||
'';
|
||||
|
||||
};
|
||||
cfg = {
|
||||
remote-control.control-enable = true;
|
||||
server = {
|
||||
include = [
|
||||
"\"${adblockLocalZones}\""
|
||||
];
|
||||
interface = [ "0.0.0.0" "::0" ];
|
||||
interface-automatic = "yes";
|
||||
access-control = [
|
||||
"127.0.0.0/8 allow"
|
||||
"10.42.96.0/24 allow"
|
||||
"10.42.97.0/24 allow"
|
||||
"10.42.98.0/24 allow"
|
||||
"10.42.99.0/24 allow"
|
||||
"10.42.101.0/24 allow"
|
||||
"0.0.0.0/0 allow"
|
||||
];
|
||||
tls-cert-bundle = "/etc/ssl/certs/ca-certificates.crt";
|
||||
local-zone = "\"cloonar.com\" transparent";
|
||||
local-data = [
|
||||
"\"localhost A 127.0.0.1\""
|
||||
"\"localhost.cloonar.com A 127.0.0.1\""
|
||||
"\"localhost AAAA ::1\""
|
||||
"\"localhost.cloonar.com AAAA ::1\""
|
||||
"\"fw.cloonar.com A 10.42.97.1\""
|
||||
"\"fw A 10.42.97.1\""
|
||||
|
||||
"\"pc.cloonar.com IN A 10.42.96.5\""
|
||||
"\"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.21\""
|
||||
"\"deconz.cloonar.com IN A 10.42.97.22\""
|
||||
"\"brn30055c566237.cloonar.com IN A 10.42.96.100\""
|
||||
"\"snapcast.cloonar.com IN A 10.42.97.21\""
|
||||
"\"home-assistant.cloonar.com IN A 10.42.97.20\""
|
||||
"\"web-02.cloonar.com IN A 10.42.97.5\""
|
||||
"\"support.cloonar.com IN A 10.42.97.5\""
|
||||
"\"git.cloonar.com IN A 10.42.97.50\""
|
||||
"\"sync.cloonar.com IN A 10.42.97.51\""
|
||||
|
||||
"\"feeds.cloonar.com IN A 188.34.191.144\""
|
||||
# "\"paraclub.cloonar.dev IN A 49.12.244.139\""
|
||||
# "\"api.paraclub.cloonar.dev IN A 49.12.244.139\""
|
||||
# "\"module.paraclub.cloonar.dev IN A 49.12.244.139\""
|
||||
# "\"tandem.paraclub.cloonar.dev IN A 49.12.244.139\""
|
||||
|
||||
"\"stage.wsw.at IN A 10.254.235.22\""
|
||||
"\"prod.wsw.at IN A 10.254.217.23\""
|
||||
"\"piwik.wohnservice-wien.at IN A 10.254.240.109\""
|
||||
"\"wohnservice-wien.at IN A 10.254.240.109\""
|
||||
"\"mieterhilfe.at IN A 10.254.240.109\""
|
||||
"\"wohnpartner-wien.at IN A 10.254.240.109\""
|
||||
"\"new.wohnberatung-wien.at IN A 10.254.240.109\""
|
||||
"\"wohnberatung-wien.at IN A 10.254.240.109\""
|
||||
"\"wienbautvor.at IN A 10.254.240.109\""
|
||||
"\"wienwohntbesser.at IN A 10.254.240.109\""
|
||||
"\"b.wohnservice-wien.at IN A 10.254.240.109\""
|
||||
"\"b.mieterhilfe.at IN A 10.254.240.109\""
|
||||
"\"b.wohnpartner-wien.at IN A 10.254.240.109\""
|
||||
"\"b.wohnberatung-wien.at IN A 10.254.240.109\""
|
||||
"\"b.wienbautvor.at IN A 10.254.240.109\""
|
||||
"\"b.wienwohntbesser.at IN A 10.254.240.109\""
|
||||
"\"a.wohnservice-wien.at IN A 10.254.240.109\""
|
||||
"\"a.wohnpartner-wien.at IN A 10.254.240.109\""
|
||||
"\"a.stage.wohnservice-wien.at IN A 10.254.240.110\""
|
||||
"\"a.stage.mieterhilfe.at IN A 10.254.240.110\""
|
||||
"\"a.stage.wohnpartner-wien.at IN A 10.254.240.110\""
|
||||
"\"a.stage.wohnberatung-wien.at IN A 10.254.240.110\""
|
||||
"\"a.stage.wienbautvor.at IN A 10.254.240.110\""
|
||||
"\"a.stage.wienwohntbesser.at IN A 10.254.240.110\""
|
||||
"\"b.stage.wohnservice-wien.at IN A 10.254.240.110\""
|
||||
"\"b.stage.mieterhilfe.at IN A 10.254.240.110\""
|
||||
"\"b.stage.wohnpartner-wien.at IN A 10.254.240.110\""
|
||||
"\"b.stage.new.wohnberatung-wien.at IN A 10.254.240.110\""
|
||||
"\"b.stage.wohnberatung-wien.at IN A 10.254.240.110\""
|
||||
"\"b.stage.wienbautvor.at IN A 10.254.240.110\""
|
||||
"\"b.stage.wienwohntbesser.at IN A 10.254.240.110\""
|
||||
"\"upgrade-staging.wohnservice-wien.at IN A 10.254.240.110\""
|
||||
"\"upgrade-staging.mieterhilfe.at IN A 10.254.240.110\""
|
||||
"\"upgrade-staging.wohnpartner-wien.at IN A 10.254.240.110\""
|
||||
"\"upgrade-staging.wohnberatung-wien.at IN A 10.254.240.110\""
|
||||
"\"upgrade-staging.wienbautvor.at IN A 10.254.240.110\""
|
||||
"\"upgrade-staging.wienwohntbesser.at IN A 10.254.240.110\""
|
||||
"\"conf.wrwks.at IN A 10.254.240.105\""
|
||||
|
||||
"\"web.hilgenberg-gmbh.de IN A 91.107.197.169\""
|
||||
|
||||
"\"deconz.cloonar.multimedia IN A 10.42.97.22\""
|
||||
"\"metz.cloonar.multimedia IN A 10.42.99.10\""
|
||||
# "\"ps5.cloonar.multimedia IN A 10.42.99.12\""
|
||||
"\"xbox.cloonar.multimedia IN A 10.42.99.13\""
|
||||
# "\"switch.cloonar.multimedia IN A 10.42.99.14\""
|
||||
#living room
|
||||
"\"shellyuni-livingroom-1.cloonar.smart IN A 10.42.100.8\""
|
||||
"\"shellyswitch25-livingroom-1.cloonar.smart IN A 10.42.100.9\""
|
||||
"\"shellyplug-s-living-1.cloonar.smart IN A 10.42.100.10\""
|
||||
"\"shellyplug-s-living-2.cloonar.smart IN A 10.42.100.11\""
|
||||
# kitchen
|
||||
"\"shellyplug-s-kitchen-1.cloonar.smart IN A 10.42.100.17\""
|
||||
"\"shellyrgbw2-kitchen-1.cloonar.smart IN A 10.42.100.18\""
|
||||
#bedroom
|
||||
"\"shelly1-bedroom-1.cloonar.smart IN A 10.42.100.33\""
|
||||
"\"shellybutton1-bedroom-1.cloonar.smart IN A 10.42.100.34\""
|
||||
"\"shellybutton1-bedroom-2.cloonar.smart IN A 10.42.100.35\"" # todo
|
||||
"\"shellyrgbw2-bedroom-1.cloonar.smart IN A 10.42.100.36\""
|
||||
"\"shellyrgbw2-bedroom-2.cloonar.smart IN A 10.42.100.37\""
|
||||
"\"shellyrgbw2-bedroom-3.cloonar.smart IN A 10.42.100.38\""
|
||||
# bath
|
||||
"\"shellyswitch25-bath-1.cloonar.smart IN A 10.42.100.49\""
|
||||
"\"shellybulbduo-bath-1.cloonar.smart IN A 10.42.100.50\""
|
||||
"\"shellybulbduo-bath-2.cloonar.smart IN A 10.42.100.51\""
|
||||
"\"shelly1pm-bath-1.cloonar.smart IN A 10.42.100.52\""
|
||||
"\"shellyht-bath-1.cloonar.smart IN A 10.42.100.53\"" # todo
|
||||
# hallway
|
||||
"\"shelly1-hallway-1.cloonar.smart IN A 10.42.100.65\""
|
||||
"\"shellycolorbulb-hallway-1.cloonar.smart IN A 10.42.100.66\""
|
||||
"\"shellycolorbulb-hallway-2.cloonar.smart IN A 10.42.100.67\""
|
||||
"\"shellycolorbulb-hallway-3.cloonar.smart IN A 10.42.100.68\""
|
||||
"\"shellycolorbulb-hallway-4.cloonar.smart IN A 10.42.100.69\""
|
||||
"\"shellyem3.cloonar.smart IN A 10.42.100.70\""
|
||||
"\"shellypro-1.cloonar.smart IN A 10.42.100.71\""
|
||||
"\"shellypro-2.cloonar.smart IN A 10.42.100.72\""
|
||||
# toilet
|
||||
"\"shelly1-toilet-1.cloonar.smart IN A 10.42.100.81\""
|
||||
"\"shellybulbduo-toilet-1.cloonar.smart IN A 10.42.100.82\""
|
||||
# storage
|
||||
"\"shelly1-storage-1.cloonar.smart IN A 10.42.100.97\""
|
||||
"\"shellyplug-storage-1.cloonar.smart IN A 10.42.100.98\""
|
||||
"\"brn30055c566237.cloonar.multimedia IN A 10.42.99.100\""
|
||||
|
||||
"\"ddl-warez.to IN A 172.67.184.30\""
|
||||
"\"cdnjs.cloudflare.com IN A 104.17.24.14\""
|
||||
];
|
||||
local-data-ptr = [
|
||||
"\"127.0.0.1 localhost\""
|
||||
"\"::1 localhost\""
|
||||
"\"10.42.97.1 fw.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\""
|
||||
"\"10.254.240.109 wohnservice-wien.at\""
|
||||
"\"10.254.240.110 a.stage.wohnservice-wien.at\""
|
||||
|
||||
"\"172.67.184.30 ddl-warez.to\""
|
||||
"\"104.17.24.14 cdnjs.cloudflare.com\""
|
||||
];
|
||||
# ssl-upstream = "yes";
|
||||
};
|
||||
forward-zone = [
|
||||
{
|
||||
name = "local.ghetto.at.";
|
||||
forward-tls-upstream = "no";
|
||||
forward-addr = [
|
||||
"10.43.97.1"
|
||||
];
|
||||
}
|
||||
{
|
||||
name = "ghetto.at.local.";
|
||||
forward-tls-upstream = "no";
|
||||
forward-addr = [
|
||||
"10.43.97.1"
|
||||
];
|
||||
}
|
||||
{
|
||||
name = "epicenter.works.";
|
||||
forward-tls-upstream = "no";
|
||||
forward-addr = [
|
||||
"10.50.60.1"
|
||||
];
|
||||
}
|
||||
{
|
||||
name = "akvorrat.at.";
|
||||
forward-tls-upstream = "no";
|
||||
forward-addr = [
|
||||
"10.50.60.1"
|
||||
];
|
||||
}
|
||||
{
|
||||
name = "epicenter.intra.";
|
||||
forward-tls-upstream = "no";
|
||||
forward-addr = [
|
||||
"10.14.1.1"
|
||||
];
|
||||
}
|
||||
{
|
||||
name = "intra.epicenter.works.";
|
||||
forward-tls-upstream = "no";
|
||||
forward-addr = [
|
||||
"10.14.1.1"
|
||||
];
|
||||
}
|
||||
{
|
||||
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;
|
||||
uid = cids.uids.unbound;
|
||||
};
|
||||
users.groups.unbound = {
|
||||
gid = cids.gids.unbound;
|
||||
};
|
||||
|
||||
security.acme.certs."${domain}" = {
|
||||
group = "unbound";
|
||||
};
|
||||
security.acme.certs."fw.cloonar.com" = {
|
||||
group = "unbound";
|
||||
};
|
||||
|
||||
services.resolved.enable = false;
|
||||
|
||||
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 echo "''\${1}" | grep -Eq '.*\.(cloonar.com|cloonar.multimedia|cloonar.smart)'; 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
|
||||
# else
|
||||
# if [[ "''\$2" == "A" ]] ; then
|
||||
# echo ''\${address} | while IFS=. read -r ip0 ip1 ip2 ip3
|
||||
# do
|
||||
# if [[ "''\${hostname}" != "" ]]; then
|
||||
# domain=cloonar.com
|
||||
# if [[ "''\${ip2}" == 99 ]]; then
|
||||
# domain=cloonar.multimedia
|
||||
# fi
|
||||
# if [[ "''\${ip2}" == 100 ]]; then
|
||||
# domain=cloonar.smart
|
||||
# fi
|
||||
# if [[ "''\${hostname}" != *. ]]; then
|
||||
# unbound-control local_data ''\${hostname}.''\${domain} ''\$2 ''\${address}
|
||||
# else
|
||||
# unbound-control local_data ''\${hostname}''\${domain} ''\$2 ''\${address}
|
||||
# fi
|
||||
#
|
||||
# fi
|
||||
# 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" ];
|
||||
# };
|
||||
|
||||
networking.firewall.allowedUDPPorts = [ 53 5353 ];
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
{ config, pkgs, ... }:
|
||||
let
|
||||
update-containers = pkgs.writeShellScriptBin "update-containers" ''
|
||||
SUDO=""
|
||||
if [[ $(id -u) -ne 0 ]]; then
|
||||
SUDO="sudo"
|
||||
fi
|
||||
|
||||
images=$($SUDO ${pkgs.podman}/bin/podman ps -a --format="{{.Image}}" | sort -u)
|
||||
|
||||
for image in $images
|
||||
do
|
||||
$SUDO ${pkgs.podman}/bin/podman pull $image
|
||||
done
|
||||
'';
|
||||
in {
|
||||
systemd.timers = {
|
||||
# ...
|
||||
updatecontainers = {
|
||||
timerConfig = {
|
||||
Unit = "updatecontainers.service";
|
||||
OnCalendar = "02:00";
|
||||
};
|
||||
wantedBy = [ "timers.target" ];
|
||||
};
|
||||
# ...
|
||||
};
|
||||
|
||||
systemd.services = {
|
||||
# ...
|
||||
updatecontainers = {
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
ExecStart = "update-containers";
|
||||
};
|
||||
};
|
||||
# ...
|
||||
};
|
||||
}
|
||||
@@ -1,113 +0,0 @@
|
||||
{ lib, nixpkgs, pkgs, ... }: let
|
||||
hostname = "web-02";
|
||||
json = pkgs.formats.json { };
|
||||
impermanence = builtins.fetchTarball "https://github.com/nix-community/impermanence/archive/master.tar.gz";
|
||||
in {
|
||||
microvm.vms = {
|
||||
web = {
|
||||
config = {
|
||||
microvm = {
|
||||
mem = 4096;
|
||||
# hypervisor = "cloud-hypervisor";
|
||||
shares = [
|
||||
{
|
||||
source = "/nix/store";
|
||||
mountPoint = "/nix/.ro-store";
|
||||
tag = "ro-store";
|
||||
proto = "virtiofs";
|
||||
}
|
||||
{
|
||||
source = "/var/lib/microvms/persist/web-02";
|
||||
mountPoint = "/persist";
|
||||
tag = "persist";
|
||||
proto = "virtiofs";
|
||||
}
|
||||
];
|
||||
volumes = [
|
||||
{
|
||||
image = "rootfs.img";
|
||||
mountPoint = "/";
|
||||
size = 102400;
|
||||
}
|
||||
];
|
||||
interfaces = [
|
||||
{
|
||||
type = "tap";
|
||||
id = "vm-${hostname}";
|
||||
mac = "02:00:00:00:00:03";
|
||||
}
|
||||
];
|
||||
};
|
||||
|
||||
imports = [
|
||||
"${impermanence}/nixos.nix"
|
||||
../../utils/modules/sops.nix
|
||||
../../utils/modules/lego/lego.nix
|
||||
# ../../utils/modules/borgbackup.nix
|
||||
|
||||
# ./zammad.nix
|
||||
./proxies.nix
|
||||
];
|
||||
|
||||
time.timeZone = "Europe/Vienna";
|
||||
|
||||
systemd.network.networks."10-lan" = {
|
||||
matchConfig.PermanentMACAddress = "02:00:00:00:00:03";
|
||||
address = [ "10.42.97.5/24" ];
|
||||
gateway = [ "10.42.97.1" ];
|
||||
dns = [ "10.42.97.1" ];
|
||||
};
|
||||
|
||||
fileSystems."/persist".neededForBoot = lib.mkForce true;
|
||||
environment.persistence."/persist-local" = {
|
||||
directories = [
|
||||
"/var/lib/zammad"
|
||||
"/var/lib/postgresql"
|
||||
"/var/log"
|
||||
"/var/lib/systemd/coredump"
|
||||
];
|
||||
};
|
||||
|
||||
environment.systemPackages = with pkgs; [
|
||||
vim # my preferred editor
|
||||
];
|
||||
|
||||
networking.hostName = hostname;
|
||||
|
||||
services.openssh = {
|
||||
enable = true;
|
||||
hostKeys = [
|
||||
{
|
||||
path = "/persist/etc/ssh/ssh_host_ed25519_key";
|
||||
type = "ed25519";
|
||||
}
|
||||
{
|
||||
path = "/persist/etc/ssh/ssh_host_rsa_key";
|
||||
type = "rsa";
|
||||
bits = 4096;
|
||||
}
|
||||
];
|
||||
};
|
||||
users.users.root.openssh.authorizedKeys.keys = [
|
||||
"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDN/2SAFm50kraB1fepAizox/QRXxB7WbqVbH+5OPalDT47VIJGNKOKhixQoqhABHxEoLxdf/C83wxlCVlPV9poLfDgVkA3Lyt5r3tSFQ6QjjOJAgchWamMsxxyGBedhKvhiEzcr/Lxytnoz3kjDG8fqQJwEpdqMmJoMUfyL2Rqp16u+FQ7d5aJtwO8EUqovhMaNO7rggjPpV/uMOg+tBxxmscliN7DLuP4EMTA/FwXVzcFNbOx3K9BdpMRAaSJt4SWcJO2cS2KHA5n/H+PQI7nz5KN3Yr/upJN5fROhi/SHvK39QOx12Pv7FCuWlc+oR68vLaoCKYhnkl3DnCfc7A7"
|
||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIRQuPqH5fdX3KEw7DXzWEdO3AlUn1oSmtJtHB71ICoH Generated By Termius"
|
||||
];
|
||||
|
||||
# backups
|
||||
# borgbackup.repo = "u149513-sub2@u149513-sub2.your-backup.de:borg";
|
||||
|
||||
|
||||
sops.age.sshKeyPaths = [ "/persist/etc/ssh/ssh_host_ed25519_key" ];
|
||||
sops.defaultSopsFile = ./secrets.yaml;
|
||||
|
||||
networking.firewall = {
|
||||
enable = true;
|
||||
allowedTCPPorts = [ 22 80 443 ];
|
||||
};
|
||||
|
||||
|
||||
system.stateVersion = "22.05";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
{ ... }: {
|
||||
services.nginx.virtualHosts."git.cloonar.com" = {
|
||||
forceSSL = true;
|
||||
enableACME = true;
|
||||
acmeRoot = null;
|
||||
locations."/" = {
|
||||
proxyPass = "https://git.cloonar.com/";
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
borg-passphrase: ENC[AES256_GCM,data:2WjoqMRmXvW9EGMmpMYhrC0Qt0Dk7QWlbEncZPdK2SxVljEoFibjVEr6jeYdAx6UkaXdjk9pD3PBbls2tWt0TiNQdh8=,iv:bHzASNjqqfPsQ/1w/oM7x0FubAzzRkn+iWrZlenU9rs=,tag:ektqi0rqEywg9YGybPQesw==,type:str]
|
||||
borg-ssh-key: ENC[AES256_GCM,data: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,iv:U3+fjacm8+gZAjPQNz2mjFYTUbLyltTaPiSKb3lvCmk=,tag:ZR6zI1UijDayIvH3v35Hqg==,type:str]
|
||||
zammad-key-base: ENC[AES256_GCM,data:HO9MuwcwjryuXr5No8sCPfso5bpLtQCoczrC/R214ecVIFwwH1uhMeNO8Tlh6EjRLPo7aVTSz87Vx5yaNVezvHCs55G6TT9mcNS/v/V7sbFz9dNIgbFblY3gFIAa4cViioYc71wdb7d4Tta7qhse5zQ41KhAqCWuGDgFErQA4Oc=,iv:b1wY8fW0psircSlNXwDjPzNWK8NyAMNqegitNcqV6U4=,tag:oQ7nyO9TKOOu6IF7ODzpPA==,type:str]
|
||||
sops:
|
||||
kms: []
|
||||
gcp_kms: []
|
||||
azure_kv: []
|
||||
hc_vault: []
|
||||
age:
|
||||
- recipient: age16veg3fmvpfm7a89a9fc8dvvsxmsthlm70nfxqspr6t8vnf9wkcwsvdq38d
|
||||
enc: |
|
||||
-----BEGIN AGE ENCRYPTED FILE-----
|
||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBoUWdTYlRjWDJvemF5Q2sr
|
||||
VCtrS2dTTGRwUlNIWHd0WkVCRkRMcGhuTzE0ClNic1FmQ05UNWQwbGc4TUFMNGlI
|
||||
K0RhK2pqUGY3UElmK1pNUEkxV2xGUTQKLS0tIFRORE9JTDRZK0MwZUJoc2xlcHFH
|
||||
bmp3ZW14TVdCMHhkSi84NE5neDdrY3cKYfgu7aqvG6wQmEFhmzieXFGoQpyffPXj
|
||||
jiHrAPjBBFy21wdYf0nQXNMzekqOMJwOj0oNA2b5omprPxjB9uns4Q==
|
||||
-----END AGE ENCRYPTED FILE-----
|
||||
- recipient: age1gjm4c3swt8u88e36gf2qlg3syxfc0ly94u64c42f2tsf24npw4csa6e4fw
|
||||
enc: |
|
||||
-----BEGIN AGE ENCRYPTED FILE-----
|
||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBUUjQxWnBMQXo3QmF1STUw
|
||||
bHh1NDhvQXZIQ2RiOUx5OU5Wc3BVSEJDUEZVCmVzeFk5SWpMbVV4VUdsRmhiaWwz
|
||||
bTJDY1pJRXJvNUdCSXJqQ3Byd3lWN2sKLS0tIHRKdXRNc1BYcURBRVNlenk1OEl3
|
||||
Q05BN0VnQ0haeHBobWhRV0EzL3dLSEkKWlALiX5mvG8y0WUc8yFWMbcpSRrSGoQx
|
||||
SHaOlDCjYvViZ7GPRLqnSwDGZ1clC6JsTbwKXrMsWdZBKvSO/VIWQw==
|
||||
-----END AGE ENCRYPTED FILE-----
|
||||
lastmodified: "2024-08-16T11:12:23Z"
|
||||
mac: ENC[AES256_GCM,data:nMLxD/WP3LxLTECQ/wQjiDW3F2Lx8yeMTkNIg97eipebVZwTLiVGg4t+sVzen+X3t4tPixO2a72mWMtIVQKs8d2MzkydLh+LjYItUBP+uw/rnCjB0zfxiPN883+FO6q4+BoT0JJc4LUHbgQQWEDnKaqld4/ICE1xJbPZVEJWo40=,iv:JenHaRqB8ZVDRV5rUOgMURflqQzfOrt9pHege2oiT7g=,tag:xv0p2oW1P0FPqcrRoQ/6tw==,type:str]
|
||||
pgp: []
|
||||
unencrypted_suffix: _unencrypted
|
||||
version: 3.8.1
|
||||
@@ -1,120 +0,0 @@
|
||||
{ config, pkgs, ... }:
|
||||
|
||||
{
|
||||
services.zammad = {
|
||||
enable = true;
|
||||
port = 3010;
|
||||
secretKeyBaseFile = config.sops.secrets.zammad-key-base.path;
|
||||
database = {
|
||||
createLocally = true;
|
||||
};
|
||||
};
|
||||
|
||||
services.nginx.enable = true;
|
||||
services.nginx.virtualHosts."support.cloonar.com" = {
|
||||
forceSSL = true;
|
||||
enableACME = true;
|
||||
acmeRoot = null;
|
||||
|
||||
extraConfig = ''
|
||||
# Virtual endpoint created by nginx to forward auth requests.
|
||||
location /authelia {
|
||||
internal;
|
||||
set $upstream_authelia https://auth.cloonar.com/api/verify;
|
||||
proxy_pass_request_body off;
|
||||
proxy_pass $upstream_authelia;
|
||||
proxy_set_header Content-Length "";
|
||||
|
||||
# Timeout if the real server is dead
|
||||
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503;
|
||||
|
||||
# [REQUIRED] Needed by Authelia to check authorizations of the resource.
|
||||
# Provide either X-Original-URL and X-Forwarded-Proto or
|
||||
# X-Forwarded-Proto, X-Forwarded-Host and X-Forwarded-Uri or both.
|
||||
# Those headers will be used by Authelia to deduce the target url of the user.
|
||||
# Basic Proxy Config
|
||||
client_body_buffer_size 128k;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Original-URL $scheme://$http_host$request_uri;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $remote_addr;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_set_header X-Forwarded-Host $http_host;
|
||||
proxy_set_header X-Forwarded-Uri $request_uri;
|
||||
proxy_set_header X-Forwarded-Ssl on;
|
||||
proxy_redirect http:// $scheme://;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Connection "";
|
||||
proxy_cache_bypass $cookie_session;
|
||||
proxy_no_cache $cookie_session;
|
||||
proxy_buffers 4 32k;
|
||||
|
||||
# Advanced Proxy Config
|
||||
send_timeout 5m;
|
||||
proxy_read_timeout 240;
|
||||
proxy_send_timeout 240;
|
||||
proxy_connect_timeout 240;
|
||||
}
|
||||
'';
|
||||
|
||||
locations."/" = {
|
||||
proxyPass = "http://127.0.0.1:3010";
|
||||
proxyWebsockets = true;
|
||||
extraConfig =
|
||||
"proxy_set_header X-Forwarded-Proto 'https';" +
|
||||
"proxy_set_header X-Forwarded-Ssl on;" +
|
||||
"proxy_connect_timeout 300;" +
|
||||
"proxy_send_timeout 300;" +
|
||||
"proxy_read_timeout 300;" +
|
||||
"send_timeout 300;"
|
||||
;
|
||||
};
|
||||
locations."/auth/sso" = {
|
||||
proxyPass = "http://127.0.0.1:3010";
|
||||
proxyWebsockets = true;
|
||||
|
||||
extraConfig = ''
|
||||
# Basic Authelia Config
|
||||
# Send a subsequent request to Authelia to verify if the user is authenticated
|
||||
# and has the right permissions to access the resource.
|
||||
auth_request /authelia;
|
||||
# Set the `target_url` variable based on the request. It will be used to build the portal
|
||||
# URL with the correct redirection parameter.
|
||||
auth_request_set $target_url $scheme://$http_host$request_uri;
|
||||
# Set the X-Forwarded-User and X-Forwarded-Groups with the headers
|
||||
# returned by Authelia for the backends which can consume them.
|
||||
# This is not safe, as the backend must make sure that they come from the
|
||||
# proxy. In the future, it's gonna be safe to just use OAuth.
|
||||
auth_request_set $user $upstream_http_remote_user;
|
||||
auth_request_set $groups $upstream_http_remote_groups;
|
||||
auth_request_set $name $upstream_http_remote_name;
|
||||
auth_request_set $email $upstream_http_remote_email;
|
||||
proxy_set_header Remote-User $user;
|
||||
proxy_set_header Remote-Groups $groups;
|
||||
proxy_set_header Remote-Name $name;
|
||||
proxy_set_header Remote-Email $email;
|
||||
# If Authelia returns 401, then nginx redirects the user to the login portal.
|
||||
# If it returns 200, then the request pass through to the backend.
|
||||
# For other type of errors, nginx will handle them as usual.
|
||||
error_page 401 =302 https://auth.cloonar.com/?rd=$target_url;
|
||||
'';
|
||||
};
|
||||
locations."/ws" = {
|
||||
proxyPass = "http://127.0.0.1:6042";
|
||||
proxyWebsockets = true;
|
||||
extraConfig =
|
||||
"proxy_set_header X-Forwarded-Proto 'https';" +
|
||||
"proxy_set_header X-Forwarded-Ssl on;" +
|
||||
"proxy_read_timeout 86400;" +
|
||||
"send_timeout 300;"
|
||||
;
|
||||
};
|
||||
};
|
||||
|
||||
sops.secrets = {
|
||||
zammad-key-base.owner = "zammad";
|
||||
};
|
||||
|
||||
services.postgresqlBackup.enable = true;
|
||||
services.postgresqlBackup.databases = [ "zammad" ];
|
||||
}
|
||||
@@ -1,53 +0,0 @@
|
||||
{ config, ... }: {
|
||||
sops.secrets.wg_cloonar_key = {};
|
||||
sops.secrets.wg_epicenter_works_key = {};
|
||||
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.114.1/24" ];
|
||||
listenPort = 51820;
|
||||
# publicKey: TKQVDmBnf9av46kQxLQSBDhAeaK8r1zh8zpU64zuc1Q=
|
||||
privateKeyFile = config.sops.secrets.wg_cloonar_key.path;
|
||||
peers = [
|
||||
{ # Notebook
|
||||
publicKey = "YdlRGsjh4hS3OMJI+t6SZ2eGXKbs0wZBXWudHW4NyS8=";
|
||||
allowedIPs = [ "10.42.114.201/32" ];
|
||||
}
|
||||
{ # iPhone
|
||||
publicKey = "nkm10abmwt2G8gJXnpqel6QW5T8aSaxiqqGjE8va/A0=";
|
||||
allowedIPs = [ "10.42.114.202/32" ];
|
||||
}
|
||||
];
|
||||
};
|
||||
wg_epicenter = {
|
||||
ips = [ "10.50.60.6/32" ];
|
||||
privateKeyFile = config.sops.secrets.wg_epicenter_works_key.path;
|
||||
peers = [
|
||||
{
|
||||
endpoint = "5.9.131.17:51821";
|
||||
publicKey = "T7jPGSapSudtKyWwi2nu+2hjjse96I4U3lccRHZWd2s=";
|
||||
presharedKeyFile = config.sops.secrets.wg_epicenter_works_psk.path;
|
||||
allowedIPs = [ "10.14.1.0/24" "10.14.2.0/24" "10.14.11.0/24" "10.14.40.0/24" "10.25.0.0/24" "10.50.60.0/24" ];
|
||||
}
|
||||
];
|
||||
};
|
||||
wg_ghetto_at = {
|
||||
ips = [ "10.43.98.2/32" ];
|
||||
# publicKey: o0FsoHL7ymwuDYmWA5N1mngbGT1sZJnhK6zhJkuEtzE=
|
||||
privateKeyFile = config.sops.secrets.wg_ghetto_at_key.path;
|
||||
peers = [
|
||||
{
|
||||
endpoint = "vpn.ghetto.at:51820";
|
||||
publicKey = "v4pr6tzS0Xpwh/mWTohxxvCRaAj2B4bqtJnNOu9v2Xs=";
|
||||
allowedIPs = [ "10.43.0.0/16" ];
|
||||
}
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
networking.firewall.allowedUDPPorts = [ 51820 ];
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
{ pkgs, ... }:
|
||||
let
|
||||
wolScript = pkgs.writeScriptBin "wol-script" ''
|
||||
case $1 in
|
||||
"gaming")
|
||||
${pkgs.wol}/bin/wol -i 10.42.96.255 78:8c:b5:fe:41:62
|
||||
};
|
||||
"") echo "Usage: $0 <hostname>"; exit 1;;
|
||||
esac
|
||||
'';
|
||||
in
|
||||
{
|
||||
environment.systemPackages = [
|
||||
wolScript
|
||||
];
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,51 +0,0 @@
|
||||
# args of buildLinux:
|
||||
# https://github.com/NixOS/nixpkgs/blob/nixos-unstable/pkgs/os-specific/linux/kernel/generic.nix
|
||||
# Note that this method will use the deconfig in source tree,
|
||||
# commbined the common configuration defined in pkgs/os-specific/linux/kernel/common-config.nix, which is suitable for a NixOS system.
|
||||
# but it't not suitable for embedded systems, so we comment it out.
|
||||
# ================================================================
|
||||
# If you already have a generated configuration file, you can build a kernel that uses it with pkgs.linuxManualConfig
|
||||
# The difference between deconfig and the generated configuration file is that the generated configuration file is more complete,
|
||||
#
|
||||
{
|
||||
fetchFromGitHub,
|
||||
linuxManualConfig,
|
||||
ubootTools,
|
||||
...
|
||||
}:
|
||||
(linuxManualConfig rec {
|
||||
modDirVersion = "6.1.43";
|
||||
# modDirVersion = "5.10.65";
|
||||
version = "${modDirVersion}-xunlong-rk3588";
|
||||
extraMeta.branch = "6.1";
|
||||
# extraMeta.branch = "5.10";
|
||||
|
||||
# https://github.com/orangepi-xunlong/linux-orangepi/tree/orange-pi-6.1-rk35xx
|
||||
src = fetchFromGitHub {
|
||||
owner = "orangepi-xunlong";
|
||||
repo = "linux-orangepi";
|
||||
# rev = "122b41d84d018af909a766e48f3f90cbea9868e0";
|
||||
# hash = "sha256-kOhxDP1hbrrIriOXizgZoB0I+3/JWOPcOCdNeXcPJV0=";
|
||||
# rev = "eb1c681e5184e51d8ce1f351559d149d17f48b57";
|
||||
# hash = "sha256-kOhxDP1hbrrIriOXizgZoB0I+3/JWOPcOCdNeXcPJV0=";
|
||||
rev = "752c0d0a12fdce201da45852287b48382caa8c0f";
|
||||
hash = "sha256-tVu/3SF/+s+Z6ytKvuY+ZwqsXUlm40yOZ/O5kfNfUYc=";
|
||||
};
|
||||
|
||||
|
||||
|
||||
# Steps to the generated kernel config file
|
||||
# 1. git clone --depth 1 https://github.com/armbian/linux-rockchip.git -b rk-6.1-rkr1
|
||||
# 2. put https://github.com/armbian/build/blob/main/config/kernel/linux-rk35xx-vendor.config to linux-rockchip/arch/arm64/configs/rk35xx_vendor_defconfig
|
||||
# 3. run `nix develop .#fhsEnv` in this project to enter the fhs test environment defined here.
|
||||
# 4. `cd linux-rockchip` and `make rk35xx_vendor_defconfig` to configure the kernel.
|
||||
# 5. Then use `make menuconfig` in kernel's root directory to view and customize the kernel(like enable/disable rknpu, rkflash, ACPI(for UEFI) etc).
|
||||
# 6. copy the generated .config to ./pkgs/kernel/rk35xx_vendor_config and commit it.
|
||||
#
|
||||
configfile = ./rk35xx_vendor_config;
|
||||
allowImportFromDerivation = true;
|
||||
})
|
||||
.overrideAttrs (old: {
|
||||
name = "k"; # dodge uboot length limits
|
||||
# nativeBuildInputs = old.nativeBuildInputs ++ [ubootTools];
|
||||
})
|
||||
@@ -1,17 +0,0 @@
|
||||
{
|
||||
stdenv,
|
||||
fetchurl,
|
||||
}:
|
||||
stdenv.mkDerivation {
|
||||
pname = "mali-g610-firmware";
|
||||
version = "g21p0-01eac0";
|
||||
|
||||
src = fetchurl {
|
||||
url = "https://github.com/JeffyCN/mirrors/raw/e08ced3e0235b25a7ba2a3aeefd0e2fcbd434b68/firmware/g610/mali_csffw.bin";
|
||||
hash = "sha256-jnyCGlXKHDRcx59hJDYW3SX8NbgfCQlG8wKIbWdxLfU=";
|
||||
};
|
||||
|
||||
buildCommand = ''
|
||||
install -Dm444 $src $out/lib/firmware/mali_csffw.bin
|
||||
'';
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
{ fetchFromGitHub, stdenvNoCC, ... }: stdenvNoCC.mkDerivation {
|
||||
pname = "orangepi-firmware";
|
||||
version = "2024.01.24";
|
||||
dontBuild = true;
|
||||
dontFixup = true;
|
||||
compressFirmware = false;
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "orangepi-xunlong";
|
||||
repo = "firmware";
|
||||
rev = "76ead17a1770459560042a9a7c43fe615bbce5e7";
|
||||
hash = "sha256-mltaup92LTGbuCXeGTMdoFloX3vZRbaUFVbh6lwveFs=";
|
||||
};
|
||||
|
||||
installPhase = ''
|
||||
runHook preInstall
|
||||
|
||||
mkdir -p $out/lib/firmware
|
||||
cp -a * $out/lib/firmware/
|
||||
|
||||
runHook postInstall
|
||||
'';
|
||||
}
|
||||
@@ -1,63 +0,0 @@
|
||||
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]
|
||||
wg_epicenter_works_psk: ENC[AES256_GCM,data:Den3NDWdP013Or6/2Vll1igUahuRSNW4hu+nDa5vkr93bbveQTaWFT4TD4U=,iv:r3UsD3+3lUIP2X3Grti7wpXTQBXtu1/MdrycEmpZfsI=,tag:ghbAcxmjGVOe9jCZsmFzjA==,type:str]
|
||||
wg_ghetto_at_key: ENC[AES256_GCM,data:OIHmoy3SpIi9aefZnZ1PzpyHbEso18ceoTULf2eQkx1rJbaxC6PD1lma7eQ=,iv:u0eFjHHOBzPTmBvBEQsYY5flcBayiAQKd6e7RyiPwJI=,tag:731C9wvv8bA5fuuQq+weVQ==,type:str]
|
||||
gitea-runner: ENC[AES256_GCM,data:IRx9QzbLJrkF/DYvpVf2012BiSBnHZJe10opkRO2kJuegdb0denW3mvmnU4isoj7jO/0QyN6HZHlHb5ihC7fFl4LavPDVjAAhZPynkpDw9IHFeqZDUSPzxQsq7FibKmfEpEmWEz+Npe8JI1kl694XYV/kqErKa3JrZS7Jm8zFcv7DSY/V5bdy4Is8ZSRtHiP/aVzFdsvjwtissCDnCl7zRZjXUcN0FssvPHBZHxLuc68EoagIw1aVSzkvSVBXer4rFdlefjskFelRnUr3pvm188=,iv:VnvPFDFGz/QyfQmZxQFB3J2ReqaHdRaypb2Vnq7Dthw=,tag:19rx0nlmXLj/6yPRAFGigA==,type:str]
|
||||
gitea-runner-token: ENC[AES256_GCM,data:Nd0vsnuJficsdZaqeBZXa9vD7PLMdDtV9sMX0TxUSEMNU7Reu3HLCWuvP0easPU=,iv:4mrfQc1tobg/QiExUuWST6iU9TdNwiS1BMmOnQqCFZU=,tag:85aRoD3IkRq3mcoPdLKaBQ==,type:str]
|
||||
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:rdqChPt4gSJHS1D60+HJ+4m5mg35JbC+pOmevK21Y95QyAIeyBLVGhRYlOaUcqdZM2e4atyTTSf6z4nHsm539ddCbW7J2DCdF5PQkrAGDmmdTVq+jyJAT8gTrbXXCglT1wvFYY5dbf2NKA4ASJIA8bdVNuwRZU0CtFiishzLuc9m8ZcGCNwQ/+xkMZgkUAHYRlEJAZyMpXR6KkFftiR05JRAFczD4N7GXPPe+vyvgXg7QBGtf20Qd4SGBUw0zI/SNTRmifHUuc4Z6+Fe9JHgvTc3uFcTMVnty0fEuL+a29liaVdAFq8BnqJfc5CNV401ZSUeMbG41lCn1cegP/WChs9J6HXNrhWDgiXa6ln++NoKcfOHIfZVbYOCoOxFR6+YWeBU2+sHmdwI9j5XQf5Ly2hmg12j0Ds2Cn8k4PG5aQP+HT2bedqyxwSt6fi97A0Osnh4ig7+DzYAjSNLewbYLzVdK39VdvB9hqLto+yFS3gAaeYOHwPwtqa+COI85c55lHiyKHlSwPhBqYaaiDu00lQTUzq9R5vz6F/l+T3bUjuna5RryUu8yhnk5DyK834KycTOg4ETcZTqro6prfiEBxc+Utsc9JvEtZgwFv6fsVLOu7nHxuiYuvseZ4YA8LlYdwPJboMPO2XsuhwWtT1uz/rh2orH7/vsXvzA/kF8NFemWBEMVLYA8byC5ze8doiGDYp4T5AAf10nJB1ceQ==,iv:gs78fxhvo9KlTaR5nzs12/LdgPChSFPHD2k4VQp3ARo=,tag:lpWBOi9xh2cWkS+71KD/UQ==,type:str]
|
||||
ark: ENC[AES256_GCM,data:YYGyzoVIKI9Ac1zGOr0BEpd3fgBsvp1hSwAvfO07/EQdg8ufMWUkNvqNHDKN62ZK5A1NnY3JTA1p4gyZ4ryQeAOsbwqU1GSk2YKHFyPeEnpLz/Ml82KMsv7XPGXuKRXZ4v3UcLu0R8k1Q0gQsMWo4FjCs3FF5mVtJG/YWxxbCYHoBLJ/di5p0DgjuFgJBQknYBpuLzr+yIoeqEyN7XcGYAJO53trEJuOOxLILULifkqISHjZ66i5F1fHW0iUdRbmeWV4aOAeOrsQqXYv,iv:gJwV5ip84zHqpU0l0uESfWWOtcgihMvEEdLaeI+twcU=,tag:sy8udVQsKxV/jOqwhJmWAg==,type:str]
|
||||
firefox-sync: ENC[AES256_GCM,data:uAJAdyKAuXRuqCFl8742vIejU5RnAPpUxUFCC0s0QeXZR5oH2YOrDh+3vKUmckW4V1cIhSHoe+4+I4HuU5E73DDrJThfIzBEw+spo4HXwZf5KBtu3ujgX6/fSTlPWV7pEsDDsZ0y6ziKPADBDym8yEk0bU9nRedvTBUhVryo3aolzF/c+gJvdeDvKUYa8+8=,iv:yuvE4KG7z7Rp9ZNlLiJ2rh0keed3DuvrELzsfJu4+bs=,tag:HFo1A53Eva31NJ8fRE7TlA==,type:str]
|
||||
sops:
|
||||
kms: []
|
||||
gcp_kms: []
|
||||
azure_kv: []
|
||||
hc_vault: []
|
||||
age:
|
||||
- recipient: age14grjcxaq4h55yfnjxvnqhtswxhj9sfdcvyas4lwvpa8py27pjy2sv3g6v7
|
||||
enc: |
|
||||
-----BEGIN AGE ENCRYPTED FILE-----
|
||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB6aEpEZklTYi9oakF6WTg4
|
||||
RDlNV1FrWlN6Skd1V1BmRU93SGJ1RTNGc2xRCmlzRk56NnRrbkthcWhpTjNlb0VV
|
||||
cE9GaU5TRjAxaGFYTlkzbGtQY092eUkKLS0tIGdncHpVdTd5ZDN0NzllVmFuN2pR
|
||||
WDJzNzZKdGxzOTRBZ1BPRUgxSE5DQ1EK3t2074FilJxZDQYZew8ckEbaBnQrDOsW
|
||||
f+G4AnR83inhGsJwebmwwyI5dORVuBldA0CNjvihAmhlvf7G4TZ/Vw==
|
||||
-----END AGE ENCRYPTED FILE-----
|
||||
- recipient: age16veg3fmvpfm7a89a9fc8dvvsxmsthlm70nfxqspr6t8vnf9wkcwsvdq38d
|
||||
enc: |
|
||||
-----BEGIN AGE ENCRYPTED FILE-----
|
||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB6MVNyWE0zd1FScmpOcVNs
|
||||
R2FsWGxyZ0ZiZzkrNjEyNkVybjlVbFh6WFVFCmtoWFd2bTRFUU8zL3J1Ry9uak56
|
||||
ZUxKMVdha1h1ajBnb1grbTNPcjkrc3cKLS0tIHZXL25UU2Fqd2VVL0ZhNE1vVUVJ
|
||||
TWtVdzIwNU1McDNtM3VMdjhZNmhENGsK1x5pbkUdFuZtxLPLHQonmJEwSlWYBwjv
|
||||
50v5i8fK4CTSjKO3VLh6iCkFUq2RYwerCpK2PdrujH33ymSUOzlXWw==
|
||||
-----END AGE ENCRYPTED FILE-----
|
||||
- recipient: age1v6p8dan2t3w9h94fz4flldl32082j3s9x6zqq7u5j66keth9aphsd6pvch
|
||||
enc: |
|
||||
-----BEGIN AGE ENCRYPTED FILE-----
|
||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB1R3V0Z3ZxQSt4dnkyNS96
|
||||
VGRqWUV6WllLenY2TWF2OTVWbEdUY2NDbFNvCmpwV3dwS2hwbk8zV0ZsMDYycHky
|
||||
bU8zRjY1aFF2T0l3YzBaQ0l1UDFRYjAKLS0tIEgwbzF3TytRNHduYkErSTI3WXJF
|
||||
STZ2NnlKaDdLeCt3RS9IRnc5dUkzZmsK5VwTv1CASmuvEvVLd67YIFx2fouXONtA
|
||||
vtuVW1MCG4Z/btsQ5smRUsKWVdL+G2Cy1dk8SWZcy1tK3bDOLZ/VNg==
|
||||
-----END AGE ENCRYPTED FILE-----
|
||||
- recipient: age12msc2c6drsaw0yk2hjlaw0q0lyq0emjx5e8rq7qc7ql689k593kqfmhss2
|
||||
enc: |
|
||||
-----BEGIN AGE ENCRYPTED FILE-----
|
||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBLRXBDdXhYL01jaDRkbXZP
|
||||
R2hFOXpBT25CRXNvTjhoNU1JWDRpa2RlcW1zCjlBMlZabFZhMTI1U1FxalI5SlBS
|
||||
SkVMVXBldHF1aUdBREFyckpYVVBzaE0KLS0tIGowV3oxU0FYRjNoTDB3SWFMZWVF
|
||||
bVBNM0o0KzJRUndkSlZzeUQ2UU91N28KFfW9ID6X0IPeCnRBc6v7EGJAZ7my70Ih
|
||||
wHMDCrsnvs1XUFlHCFq4a7fzbqMcBoZ3Gkq5gBeuL2Cmuqoh92slzA==
|
||||
-----END AGE ENCRYPTED FILE-----
|
||||
lastmodified: "2024-08-02T22:57:14Z"
|
||||
mac: ENC[AES256_GCM,data:U9/pKXdqXMvjQgyTIGz0JG+88aBXVgp29Fmm0OE66KMArkX8ungcEtdnGYKhD0gFJKLrKZZY5V8oyAXEq95D+Bh8ZnfmQibYw04cPldc6kTZstsrpbzrWVfn6sqG/ih12oXdsLws+H6IeN+O2qGZHDIVjvPufAdJ3A2X+Yakahg=,iv:mG+dGv3l/PNhggvlujLxDGU5z47qVA9sOTUbU2b2dPo=,tag:Rz2av33iwa9aYR7c0cviEg==,type:str]
|
||||
pgp: []
|
||||
unencrypted_suffix: _unencrypted
|
||||
version: 3.8.1
|
||||
@@ -1 +0,0 @@
|
||||
../../utils
|
||||
@@ -1 +0,0 @@
|
||||
https://channels.nixos.org/nixos-24.05
|
||||
@@ -1,50 +0,0 @@
|
||||
{ config, pkgs, ... }:
|
||||
{
|
||||
imports = [
|
||||
./utils/bento.nix
|
||||
./utils/modules/sops.nix
|
||||
./utils/modules/lego/lego.nix
|
||||
./utils/modules/nginx.nix
|
||||
|
||||
# ./modules/self-service-password.nix
|
||||
./modules/rspamd.nix
|
||||
./modules/openldap.nix
|
||||
./modules/dovecot.nix
|
||||
./modules/postfix.nix
|
||||
./modules/autoconfig.nix
|
||||
|
||||
./utils/modules/borgbackup.nix
|
||||
# ./utils/modules/promtail
|
||||
# ./utils/modules/victoriametrics
|
||||
|
||||
./hardware-configuration.nix
|
||||
];
|
||||
|
||||
|
||||
sops.defaultSopsFile = ./secrets.yaml;
|
||||
sops.age.sshKeyPaths = [ "/etc/ssh/ssh_host_ed25519_key" ];
|
||||
|
||||
networking.hostName = "mail";
|
||||
networking.domain = "social-grow.tech";
|
||||
|
||||
services.openssh.enable = true;
|
||||
users.users.root.openssh.authorizedKeys.keys = [
|
||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHC9YODKEKu5bOC61qkpPd8QeZxbNPCQKgfh8xUFMdV0" # dominik
|
||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIRQuPqH5fdX3KEw7DXzWEdO3AlUn1oSmtJtHB71ICoH Generated By Termius"
|
||||
];
|
||||
|
||||
# backups
|
||||
borgbackup.repo = "u428777-sub1@u428777.your-storagebox.de:borg";
|
||||
|
||||
networking.firewall = {
|
||||
enable = true;
|
||||
allowedTCPPorts = [ 22 80 443 ];
|
||||
};
|
||||
|
||||
nix.gc = {
|
||||
automatic = true;
|
||||
options = "--delete-older-than 60d";
|
||||
};
|
||||
|
||||
system.stateVersion = "22.11";
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
{ modulesPath, ... }:
|
||||
{
|
||||
imports = [ (modulesPath + "/profiles/qemu-guest.nix") ];
|
||||
boot.loader.grub = {
|
||||
efiSupport = true;
|
||||
efiInstallAsRemovable = true;
|
||||
device = "nodev";
|
||||
configurationLimit = 5;
|
||||
};
|
||||
fileSystems."/boot" = { device = "/dev/sda15"; fsType = "vfat"; };
|
||||
boot.initrd.availableKernelModules = [ "ata_piix" "uhci_hcd" "xen_blkfront" ];
|
||||
boot.initrd.kernelModules = [ "nvme" ];
|
||||
fileSystems."/" = { device = "/dev/sda1"; fsType = "ext4"; };
|
||||
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
{ pkgs, lib, config, ... }:
|
||||
let
|
||||
domain = config.networking.domain;
|
||||
in
|
||||
{
|
||||
services.nginx.virtualHosts."autoconfig.${domain}" = {
|
||||
forceSSL = true;
|
||||
enableACME = true;
|
||||
acmeRoot = null;
|
||||
locations."/" = {
|
||||
proxyPass = "http://localhost:1323/";
|
||||
};
|
||||
};
|
||||
|
||||
services.go-autoconfig = {
|
||||
enable = true;
|
||||
settings = {
|
||||
service_addr = ":1323";
|
||||
domain = domain;
|
||||
imap = {
|
||||
server = "imap.${domain}";
|
||||
port = 993;
|
||||
};
|
||||
smtp = {
|
||||
server = "mail.${domain}";
|
||||
port = 587;
|
||||
starttls = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -1,253 +0,0 @@
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
domain = config.networking.domain;
|
||||
components = lib.strings.splitString "." domain;
|
||||
dcComponents = map (x: "dc=" + x) components;
|
||||
ldapPath = builtins.concatStringsSep "," dcComponents;
|
||||
|
||||
ldapConfig = pkgs.writeText "dovecot-ldap.conf" ''
|
||||
hosts = ldap.${domain}
|
||||
tls = yes
|
||||
dn = "cn=vmail,ou=system,ou=users,${ldapPath}"
|
||||
dnpass = "@ldap-password@"
|
||||
auth_bind = no
|
||||
ldap_version = 3
|
||||
base = ou=users,dc=%Dd
|
||||
user_filter = (&(objectClass=mailAccount)(mail=%u))
|
||||
user_attrs = \
|
||||
quota=quota_rule=*:bytes=%$, \
|
||||
=home=/var/vmail/%d/%n/, \
|
||||
=mail=maildir:/var/vmail/%d/%n/Maildir
|
||||
pass_attrs = mail=user,userPassword=password
|
||||
pass_filter = (&(objectClass=mailAccount)(mail=%u))
|
||||
iterate_attrs = =user=%{ldap:mail}
|
||||
iterate_filter = (objectClass=mailAccount)
|
||||
scope = subtree
|
||||
default_pass_scheme = CRYPT
|
||||
'';
|
||||
|
||||
doveSync = pkgs.writeShellScriptBin "dove-sync.sh" ''
|
||||
#!/usr/bin/env bash
|
||||
SERVER=''${1}
|
||||
|
||||
if [ -z "$SERVER" ]; then
|
||||
echo "use as dove-sync.sh host.example.com"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
doveadm user *@${domain} | while read user; do
|
||||
doveadm -v sync -u $user $SERVER
|
||||
done
|
||||
|
||||
doveadm user *@ekouniversity.com | while read user; do
|
||||
doveadm -v sync -u $user $SERVER
|
||||
done
|
||||
'';
|
||||
|
||||
quotaWarning = pkgs.writeShellScriptBin "quota-warning.sh" ''
|
||||
#!/usr/bin/env bash
|
||||
PERCENT=''${1}
|
||||
USER=''${2}
|
||||
|
||||
cat << EOF | /usr/lib/dovecot/deliver -d ''${USER} -o "plugin/quota=dict:User quota::noenforcing:proxy::quotadict"
|
||||
From: no-reply@$(hostname -f)
|
||||
Subject: Warning: Your mailbox is now ''${PERCENT}% full.
|
||||
|
||||
Your mailbox is now ''${PERCENT}% full, please clean up some mails for further incoming mails.
|
||||
EOF
|
||||
|
||||
if [ ''${PERCENT} -ge 95 ]; then
|
||||
DOMAIN="$(echo ''${USER} | awk -F'@' '{print $2}')"
|
||||
cat << EOF | /usr/lib/dovecot/deliver -d postmaster@''${DOMAIN} -o "plugin/quota=dict:User quota::noenforcing:proxy::quotadict"
|
||||
From: no-reply@$(hostname -f)
|
||||
Subject: Mailbox Quota Warning: ''${PERCENT}% full, ''${USER}
|
||||
|
||||
Mailbox (''${USER}) is now ''${PERCENT}% full, please clean up some mails for
|
||||
further incoming mails.
|
||||
EOF
|
||||
fi
|
||||
'';
|
||||
in
|
||||
{
|
||||
environment.systemPackages = with pkgs; [
|
||||
doveSync
|
||||
];
|
||||
|
||||
services.dovecot2 = {
|
||||
enable = true;
|
||||
enableImap = true;
|
||||
enableLmtp = true;
|
||||
enablePAM = false;
|
||||
mailLocation = "maildir:/var/vmail/%d/%n/Maildir";
|
||||
mailUser = "vmail";
|
||||
mailGroup = "vmail";
|
||||
extraConfig = ''
|
||||
ssl = yes
|
||||
ssl_cert = </var/lib/acme/imap.${domain}/fullchain.pem
|
||||
ssl_key = </var/lib/acme/imap.${domain}/key.pem
|
||||
ssl_min_protocol = TLSv1.2
|
||||
ssl_cipher_list = EECDH+AESGCM:EDH+AESGCM
|
||||
ssl_prefer_server_ciphers = yes
|
||||
ssl_dh=<${config.security.dhparams.params.dovecot2.path}
|
||||
|
||||
mail_plugins = virtual fts fts_lucene quota acl
|
||||
|
||||
service lmtp {
|
||||
user = vmail
|
||||
unix_listener /var/lib/postfix/queue/private/dovecot-lmtp {
|
||||
group = postfix
|
||||
mode = 0600
|
||||
user = postfix
|
||||
}
|
||||
}
|
||||
|
||||
service doveadm {
|
||||
inet_listener {
|
||||
port = 4170
|
||||
ssl = yes
|
||||
}
|
||||
}
|
||||
protocol imap {
|
||||
mail_plugins = $mail_plugins imap_quota imap_acl
|
||||
}
|
||||
protocol lmtp {
|
||||
postmaster_address=postmaster@${domain}
|
||||
hostname=mail.${domain}
|
||||
mail_plugins = $mail_plugins sieve
|
||||
}
|
||||
service auth {
|
||||
unix_listener auth-userdb {
|
||||
mode = 0640
|
||||
user = vmail
|
||||
group = vmail
|
||||
}
|
||||
# Postfix smtp-auth
|
||||
unix_listener /var/lib/postfix/queue/private/auth {
|
||||
mode = 0666
|
||||
user = postfix
|
||||
group = postfix
|
||||
}
|
||||
}
|
||||
userdb {
|
||||
args = /run/dovecot2/ldap.conf
|
||||
driver = ldap
|
||||
}
|
||||
passdb {
|
||||
args = /run/dovecot2/ldap.conf
|
||||
driver = ldap
|
||||
}
|
||||
|
||||
service imap-login {
|
||||
client_limit = 1000
|
||||
service_count = 0
|
||||
inet_listener imaps {
|
||||
port = 993
|
||||
}
|
||||
}
|
||||
|
||||
service managesieve-login {
|
||||
inet_listener sieve {
|
||||
port = 4190
|
||||
}
|
||||
}
|
||||
service quota-warning {
|
||||
executable = script ${quotaWarning}/bin/quota-warning.sh
|
||||
unix_listener quota-warning {
|
||||
user = vmail
|
||||
group = vmail
|
||||
mode = 0660
|
||||
}
|
||||
}
|
||||
service quota-status {
|
||||
# '-p <protocol>'. Currently only 'postfix' protocol is supported.
|
||||
executable = quota-status -p postfix
|
||||
client_limit = 1
|
||||
inet_listener {
|
||||
address = 127.0.0.1
|
||||
port = 12340
|
||||
}
|
||||
}
|
||||
|
||||
protocol sieve {
|
||||
managesieve_logout_format = bytes ( in=%i : out=%o )
|
||||
}
|
||||
|
||||
plugin {
|
||||
sieve_dir = /var/vmail/%d/%n/sieve/scripts/
|
||||
sieve = /var/vmail/%d/%n/sieve/active-script.sieve
|
||||
sieve_extensions = +vacation-seconds +editheader
|
||||
sieve_vacation_min_period = 1min
|
||||
|
||||
fts = lucene
|
||||
fts_lucene = whitespace_chars=@.
|
||||
|
||||
quota_warning = storage=100%% quota-warning 100 %u
|
||||
quota_warning2 = storage=95%% quota-warning 95 %u
|
||||
quota_warning3 = storage=90%% quota-warning 90 %u
|
||||
quota_warning4 = storage=85%% quota-warning 85 %u
|
||||
|
||||
quota_grace = 10%%
|
||||
|
||||
quota_status_success = DUNNO
|
||||
quota_status_nouser = DUNNO
|
||||
quota_status_overquota = "552 5.2.2 Mailbox is full"
|
||||
}
|
||||
|
||||
# If you have Dovecot v2.2.8+ you may get a significant performance improvement with fetch-headers:
|
||||
imapc_features = $imapc_features fetch-headers
|
||||
# Read multiple mails in parallel, improves performance
|
||||
mail_prefetch_count = 20
|
||||
'';
|
||||
modules = [
|
||||
pkgs.dovecot_pigeonhole
|
||||
];
|
||||
protocols = [
|
||||
"sieve"
|
||||
];
|
||||
};
|
||||
|
||||
users.users.vmail = {
|
||||
home = "/var/vmail";
|
||||
createHome = true;
|
||||
isSystemUser = true;
|
||||
uid = 1000;
|
||||
shell = "/run/current-system/sw/bin/nologin";
|
||||
};
|
||||
|
||||
security.dhparams = {
|
||||
enable = true;
|
||||
params.dovecot2 = { };
|
||||
};
|
||||
|
||||
sops.secrets.dovecot-ldap-password = { };
|
||||
|
||||
systemd.services.dovecot2.preStart = ''
|
||||
sed -e "s/@ldap-password@/$(cat ${config.sops.secrets.dovecot-ldap-password.path})/" ${ldapConfig} > /run/dovecot2/ldap.conf
|
||||
'';
|
||||
|
||||
systemd.services.dovecot2 = {
|
||||
wants = [ "acme-imap.${domain}.service" ];
|
||||
after = [ "acme-imap.${domain}.service" ];
|
||||
};
|
||||
|
||||
users.groups.acme.members = [ "openldap" ];
|
||||
|
||||
/* trigger the actual certificate generation for your hostname */
|
||||
security.acme.certs."imap.${domain}" = {
|
||||
extraDomainNames = [
|
||||
"imap-test.${domain}"
|
||||
];
|
||||
postRun = "systemctl restart dovecot2.service";
|
||||
};
|
||||
|
||||
networking.firewall.allowedTCPPorts = [
|
||||
143 # imap
|
||||
993 # imaps
|
||||
4190 # sieve
|
||||
];
|
||||
}
|
||||
@@ -1,311 +0,0 @@
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
domain = config.networking.domain;
|
||||
components = lib.strings.splitString "." domain;
|
||||
dcComponents = map (x: "dc=" + x) components;
|
||||
ldapPath = builtins.concatStringsSep "," dcComponents;
|
||||
in {
|
||||
services.openldap = {
|
||||
enable = true;
|
||||
|
||||
urlList = [ "ldap:///" "ldaps:///" ];
|
||||
|
||||
settings.attrs = {
|
||||
olcLogLevel = "-1";
|
||||
|
||||
olcTLSCACertificateFile = "/var/lib/acme/ldap.${domain}/full.pem";
|
||||
olcTLSCertificateFile = "/var/lib/acme/ldap.${domain}/cert.pem";
|
||||
olcTLSCertificateKeyFile = "/var/lib/acme/ldap.${domain}/key.pem";
|
||||
# olcTLSCipherSuite = "HIGH:MEDIUM:+3DES:+RC4:+aNULL";
|
||||
olcTLSCipherSuite = "HIGH:!aNULL:!kRSA:!PSK:!SRP:!MD5:!RC4";
|
||||
olcTLSCRLCheck = "none";
|
||||
olcTLSVerifyClient = "never";
|
||||
olcTLSProtocolMin = "3.3";
|
||||
olcSecurity = "tls=1";
|
||||
};
|
||||
|
||||
settings.children = {
|
||||
"cn=schema".includes = [
|
||||
"${pkgs.openldap}/etc/schema/core.ldif"
|
||||
"${pkgs.openldap}/etc/schema/cosine.ldif"
|
||||
"${pkgs.openldap}/etc/schema/inetorgperson.ldif"
|
||||
"${pkgs.openldap}/etc/schema/nis.ldif"
|
||||
];
|
||||
|
||||
"olcDatabase={1}mdb".attrs = {
|
||||
objectClass = ["olcDatabaseConfig" "olcMdbConfig"];
|
||||
|
||||
olcDatabase = "{1}mdb";
|
||||
olcDbDirectory = "/var/lib/openldap/data";
|
||||
|
||||
olcSuffix = "${ldapPath}";
|
||||
|
||||
olcRootDN = "cn=admin,${ldapPath}";
|
||||
olcRootPW.path = config.sops.secrets.openldap-rootpw.path;
|
||||
|
||||
|
||||
olcAccess = [
|
||||
''
|
||||
{0}to attrs=userPassword
|
||||
by self write
|
||||
by anonymous auth
|
||||
by dn="cn=owncloud,ou=system,ou=users,${ldapPath}" write
|
||||
by dn.subtree="ou=system,ou=users,${ldapPath}" read
|
||||
by group.exact="cn=Administrators,ou=groups,${ldapPath}" write
|
||||
by * none
|
||||
''
|
||||
''
|
||||
{1}to attrs=loginShell
|
||||
by self write
|
||||
by dn.subtree="ou=system,ou=users,${ldapPath}" read
|
||||
by group.exact="cn=Administrators,ou=groups,${ldapPath}" write
|
||||
by * none
|
||||
''
|
||||
''
|
||||
{2}to dn.subtree="ou=system,ou=users,${ldapPath}"
|
||||
by dn.subtree="ou=system,ou=users,${ldapPath}" read
|
||||
by group.exact="cn=Administrators,ou=groups,${ldapPath}" write
|
||||
by * none
|
||||
''
|
||||
''
|
||||
{3}to *
|
||||
by dn.subtree="ou=system,ou=users,${ldapPath}" read
|
||||
by dn="cn=admin,${ldapPath}" write
|
||||
by group.exact="cn=Administrators,ou=groups,${ldapPath}" write
|
||||
by * none
|
||||
''
|
||||
];
|
||||
};
|
||||
"olcOverlay=memberof,olcDatabase={1}mdb".attrs = {
|
||||
objectClass = [ "olcOverlayConfig" "olcMemberOf" ];
|
||||
olcOverlay = "memberof";
|
||||
olcMemberOfRefint = "TRUE";
|
||||
};
|
||||
"olcOverlay=ppolicy,olcDatabase={1}mdb".attrs = {
|
||||
objectClass = [ "olcOverlayConfig" "olcPPolicyConfig" ];
|
||||
olcOverlay = "ppolicy";
|
||||
olcPPolicyHashCleartext = "TRUE";
|
||||
};
|
||||
# "olcOverlay=syncprov,olcDatabase={1}mdb".attrs = {
|
||||
# objectClass = ["olcOverlayConfig" "olcSyncProvConfig"];
|
||||
# olcOverlay = "syncprov";
|
||||
# olcSpSessionLog = "100";
|
||||
# };
|
||||
"olcDatabase={2}monitor".attrs = {
|
||||
olcDatabase = "{2}monitor";
|
||||
objectClass = ["olcDatabaseConfig" "olcMonitorConfig"];
|
||||
olcAccess = [
|
||||
''
|
||||
{0}to *
|
||||
by dn.exact="cn=netdata,ou=system,ou=users,${ldapPath}" read
|
||||
by * none
|
||||
''
|
||||
];
|
||||
};
|
||||
|
||||
"olcDatabase={3}mdb".attrs = {
|
||||
objectClass = ["olcDatabaseConfig" "olcMdbConfig"];
|
||||
|
||||
olcDatabase = "{3}mdb";
|
||||
olcDbDirectory = "/var/lib/openldap/data";
|
||||
|
||||
olcSuffix = "dc=ekouniversity,dc=com";
|
||||
|
||||
olcAccess = [
|
||||
''
|
||||
{0}to attrs=userPassword
|
||||
by self write
|
||||
by anonymous auth
|
||||
by dn="cn=admin,${ldapPath}" write
|
||||
by dn="cn=owncloud,ou=system,ou=users,${ldapPath}" write
|
||||
by dn="cn=authelia,ou=system,ou=users,${ldapPath}" write
|
||||
by dn.subtree="ou=system,ou=users,${ldapPath}" read
|
||||
by group.exact="cn=Administrators,ou=groups,${ldapPath}" write
|
||||
by * none
|
||||
''
|
||||
''
|
||||
{1}to *
|
||||
by dn.subtree="ou=system,ou=users,${ldapPath}" read
|
||||
by dn="cn=admin,${ldapPath}" write
|
||||
by group.exact="cn=Administrators,ou=groups,${ldapPath}" write
|
||||
by * read
|
||||
''
|
||||
];
|
||||
};
|
||||
"olcOverlay=memberof,olcDatabase={3}mdb".attrs = {
|
||||
objectClass = [ "olcOverlayConfig" "olcMemberOf" ];
|
||||
olcOverlay = "memberof";
|
||||
olcMemberOfRefint = "TRUE";
|
||||
};
|
||||
"olcOverlay=ppolicy,olcDatabase={3}mdb".attrs = {
|
||||
objectClass = [ "olcOverlayConfig" "olcPPolicyConfig" ];
|
||||
olcOverlay = "ppolicy";
|
||||
olcPPolicyHashCleartext = "TRUE";
|
||||
};
|
||||
|
||||
"cn={3}cloonar,cn=schema" = {
|
||||
attrs = {
|
||||
cn = "{1}cloonar";
|
||||
objectClass = "olcSchemaConfig";
|
||||
olcObjectClasses = [
|
||||
''
|
||||
(1.3.6.1.4.1.28298.1.2.4 NAME 'cloonarUser'
|
||||
SUP (mailAccount) AUXILIARY
|
||||
DESC 'Cloonar Account'
|
||||
MAY (sshPublicKey $ ownCloudQuota $ quota))
|
||||
''
|
||||
];
|
||||
};
|
||||
};
|
||||
"cn={2}postfix,cn=schema".attrs = {
|
||||
cn = "{2}postfix";
|
||||
objectClass = "olcSchemaConfig";
|
||||
olcAttributeTypes = [
|
||||
''
|
||||
(1.3.6.1.4.1.12461.1.1.1 NAME 'postfixTransport'
|
||||
DESC 'A string directing postfix which transport to use'
|
||||
EQUALITY caseExactIA5Match
|
||||
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{20} SINGLE-VALUE)''
|
||||
''
|
||||
(1.3.6.1.4.1.12461.1.1.5 NAME 'mailbox'
|
||||
DESC 'The absolute path to the mailbox for a mail account in a non-default location'
|
||||
EQUALITY caseExactIA5Match
|
||||
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
|
||||
''
|
||||
''
|
||||
(1.3.6.1.4.1.12461.1.1.6 NAME 'quota'
|
||||
DESC 'A string that represents the quota on a mailbox'
|
||||
EQUALITY caseExactIA5Match
|
||||
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE)
|
||||
''
|
||||
''
|
||||
(1.3.6.1.4.1.12461.1.1.8 NAME 'maildrop'
|
||||
DESC 'RFC822 Mailbox - mail alias'
|
||||
EQUALITY caseIgnoreIA5Match
|
||||
SUBSTR caseIgnoreIA5SubstringsMatch
|
||||
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256})
|
||||
''
|
||||
];
|
||||
olcObjectClasses = [
|
||||
''
|
||||
(1.3.6.1.4.1.12461.1.2.1 NAME 'mailAccount'
|
||||
SUP top AUXILIARY
|
||||
DESC 'Mail account objects'
|
||||
MUST ( mail $ userPassword )
|
||||
MAY ( cn $ description $ quota))
|
||||
''
|
||||
''
|
||||
(1.3.6.1.4.1.12461.1.2.2 NAME 'mailAlias'
|
||||
SUP top STRUCTURAL
|
||||
DESC 'Mail aliasing/forwarding entry'
|
||||
MUST ( mail $ maildrop )
|
||||
MAY ( cn $ description ))
|
||||
''
|
||||
''
|
||||
(1.3.6.1.4.1.12461.1.2.3 NAME 'mailDomain'
|
||||
SUP domain STRUCTURAL
|
||||
DESC 'Virtual Domain entry to be used with postfix transport maps'
|
||||
MUST ( dc )
|
||||
MAY ( postfixTransport $ description ))
|
||||
''
|
||||
''
|
||||
(1.3.6.1.4.1.12461.1.2.4 NAME 'mailPostmaster'
|
||||
SUP top AUXILIARY
|
||||
DESC 'Added to a mailAlias to create a postmaster entry'
|
||||
MUST roleOccupant)
|
||||
''
|
||||
];
|
||||
};
|
||||
"cn={1}openssh,cn=schema".attrs = {
|
||||
cn = "{1}openssh";
|
||||
objectClass = "olcSchemaConfig";
|
||||
olcAttributeTypes = [
|
||||
''
|
||||
(1.3.6.1.4.1.24552.500.1.1.1.13
|
||||
NAME 'sshPublicKey'
|
||||
DESC 'MANDATORY: OpenSSH Public key'
|
||||
EQUALITY octetStringMatch
|
||||
SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )
|
||||
''
|
||||
];
|
||||
olcObjectClasses = [
|
||||
''
|
||||
(1.3.6.1.4.1.24552.500.1.1.2.0
|
||||
NAME 'ldapPublicKey'
|
||||
SUP top AUXILIARY
|
||||
DESC 'MANDATORY: OpenSSH LPK objectclass'
|
||||
MUST ( sshPublicKey $ uid ))
|
||||
''
|
||||
];
|
||||
};
|
||||
"cn={1}nextcloud,cn=schema".attrs = {
|
||||
cn = "{1}nextcloud";
|
||||
objectClass = "olcSchemaConfig";
|
||||
olcAttributeTypes = [
|
||||
''
|
||||
(1.3.6.1.4.1.39430.1.1.1
|
||||
NAME 'ownCloudQuota'
|
||||
DESC 'User Quota (e.g. 15 GB)'
|
||||
SYNTAX '1.3.6.1.4.1.1466.115.121.1.15')
|
||||
''
|
||||
];
|
||||
olcObjectClasses = [
|
||||
''
|
||||
(1.3.6.1.4.1.39430.1.2.1
|
||||
NAME 'ownCloud'
|
||||
DESC 'ownCloud LDAP Schema'
|
||||
AUXILIARY
|
||||
MUST ( mail $ userPassword )
|
||||
MAY ( ownCloudQuota ))
|
||||
''
|
||||
];
|
||||
};
|
||||
"cn={1}gogs,cn=schema".attrs = {
|
||||
cn = "{1}gogs";
|
||||
objectClass = "olcSchemaConfig";
|
||||
olcObjectClasses = [
|
||||
''
|
||||
( 1.3.6.1.4.1.28293.1.2.4 NAME 'gitlab'
|
||||
SUP uidObject AUXILIARY
|
||||
DESC 'Added to an account to allow gitlab access'
|
||||
MUST (mail))
|
||||
''
|
||||
];
|
||||
};
|
||||
"cn={1}homeAssistant,cn=schema".attrs = {
|
||||
cn = "{1}homeAssistant";
|
||||
objectClass = "olcSchemaConfig";
|
||||
olcObjectClasses = [
|
||||
''
|
||||
(1.3.6.1.4.1.28297.1.2.4 NAME 'homeAssistant'
|
||||
SUP uidObject AUXILIARY
|
||||
DESC 'Added to an account to allow home-assistant access'
|
||||
MUST (mail) )
|
||||
''
|
||||
];
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
/* ensure openldap is launched after certificates are created */
|
||||
systemd.services.openldap = {
|
||||
wants = [ "acme-${domain}.service" ];
|
||||
after = [ "acme-${domain}.service" ];
|
||||
};
|
||||
|
||||
users.groups.acme.members = [ "openldap" ];
|
||||
|
||||
/* trigger the actual certificate generation for your hostname */
|
||||
security.acme.certs."ldap.${domain}" = {
|
||||
postRun = "systemctl restart openldap.service";
|
||||
};
|
||||
|
||||
sops.secrets.openldap-rootpw.owner = "openldap";
|
||||
|
||||
networking.firewall.allowedTCPPorts = [ 389 636 ];
|
||||
}
|
||||
@@ -1,248 +0,0 @@
|
||||
{ pkgs
|
||||
, lib
|
||||
, config
|
||||
, ...
|
||||
}:
|
||||
let
|
||||
domain = config.networking.domain;
|
||||
components = lib.strings.splitString "." domain;
|
||||
dcComponents = map (x: "dc=" + x) components;
|
||||
ldapPath = builtins.concatStringsSep "," dcComponents;
|
||||
ldapServer = "ldap.${domain}";
|
||||
|
||||
domains = pkgs.writeText "domains.cf" ''
|
||||
server_host = ldap://${ldapServer}
|
||||
search_base = ou=domains,${ldapPath}
|
||||
version = 3
|
||||
bind = yes
|
||||
start_tls = yes
|
||||
bind_dn = cn=vmail,ou=system,ou=users,${ldapPath}
|
||||
bind_pw = @ldap-password@
|
||||
scope = one
|
||||
query_filter = (&(dc=%s)(objectClass=mailDomain))
|
||||
result_attribute = postfixTransport
|
||||
debuglevel = 0
|
||||
'';
|
||||
|
||||
mailboxes = pkgs.writeText "mailboxes.cf" ''
|
||||
server_host = ldap://${ldapServer}
|
||||
search_base = ou=users,dc=%2,dc=%1
|
||||
version = 3
|
||||
bind = yes
|
||||
start_tls = yes
|
||||
bind_dn = cn=vmail,ou=system,ou=users,${ldapPath}
|
||||
bind_pw = @ldap-password@
|
||||
scope = sub
|
||||
query_filter = (&(uid=%u)(objectClass=mailAccount))
|
||||
result_attribute = mail
|
||||
debuglevel = 0
|
||||
'';
|
||||
|
||||
senderLoginMaps = pkgs.writeText "sender_login_maps.cf" ''
|
||||
server_host = ldap://${ldapServer}
|
||||
search_base = dc=%2,dc=%1
|
||||
version = 3
|
||||
bind = yes
|
||||
start_tls = yes
|
||||
bind_dn = cn=vmail,ou=system,ou=users,${ldapPath}
|
||||
bind_pw = @ldap-password@
|
||||
scope = sub
|
||||
query_filter = (|(&(objectClass=mailAccount)(uid=%u))(&(objectClass=mailAlias)(mail=%s)))
|
||||
result_attribute = maildrop, mail
|
||||
debuglevel = 0
|
||||
'';
|
||||
|
||||
accountsmap = pkgs.writeText "accountsmap.cf" ''
|
||||
server_host = ldap://${ldapServer}
|
||||
search_base = ou=users,dc=%2,dc=%1
|
||||
version = 3
|
||||
bind = yes
|
||||
start_tls = yes
|
||||
bind_dn = cn=vmail,ou=system,ou=users,${ldapPath}
|
||||
bind_pw = @ldap-password@
|
||||
scope = sub
|
||||
query_filter = (&(objectClass=mailAccount)(uid=%u))
|
||||
result_attribute = mail
|
||||
debuglevel = 0
|
||||
'';
|
||||
|
||||
aliases = pkgs.writeText "aliases.cf" ''
|
||||
server_host = ldap://${ldapServer}
|
||||
search_base = ou=aliases,dc=%2,dc=%1
|
||||
version = 3
|
||||
bind = yes
|
||||
start_tls = yes
|
||||
bind_dn = cn=vmail,ou=system,ou=users,${ldapPath}
|
||||
bind_pw = @ldap-password@
|
||||
scope = one
|
||||
query_filter = (&(objectClass=mailAlias)(mail=%s))
|
||||
result_attribute = maildrop
|
||||
debuglevel = 0
|
||||
'';
|
||||
|
||||
helo_access = pkgs.writeText "helo_access" ''
|
||||
/^([0-9\.]+)$/ REJECT ACCESS DENIED. Your email was rejected because the sending mail server sent non RFC compliant HELO identity (''${1})
|
||||
${domain} REJECT ACCESS DENIED. Your email was rejected because the sending mail server sent non RFC compliant HELO identity (''${1})
|
||||
ghetto.at REJECT ACCESS DENIED. Your email was rejected because the sending mail server sent non RFC compliant HELO identity (''${1})
|
||||
'';
|
||||
in
|
||||
{
|
||||
services.postfix = {
|
||||
enable = true;
|
||||
enableSubmission = true;
|
||||
hostname = "mail.${domain}";
|
||||
domain = domain;
|
||||
|
||||
masterConfig."465" = {
|
||||
type = "inet";
|
||||
private = false;
|
||||
command = "smtpd";
|
||||
args = [
|
||||
"-o smtpd_client_restrictions=permit_sasl_authenticated,reject"
|
||||
"-o syslog_name=postfix/smtps"
|
||||
"-o smtpd_tls_wrappermode=yes"
|
||||
"-o smtpd_sasl_auth_enable=yes"
|
||||
"-o smtpd_tls_security_level=none"
|
||||
"-o smtpd_reject_unlisted_recipient=no"
|
||||
"-o smtpd_recipient_restrictions="
|
||||
"-o smtpd_relay_restrictions=permit_sasl_authenticated,reject"
|
||||
"-o milter_macro_daemon_name=ORIGINATING"
|
||||
];
|
||||
};
|
||||
|
||||
mapFiles."helo_access" = helo_access;
|
||||
|
||||
config = {
|
||||
# debug_peer_list = "10.42.96.190";
|
||||
# smtp_bind_address = config.networking.eve.ipv4.address;
|
||||
# smtp_bind_address6 = "2a01:4f9:2b:1605::1";
|
||||
mailbox_transport = "lmtp:unix:private/dovecot-lmtp";
|
||||
virtual_mailbox_domains = "ldap:/run/postfix/domains.cf";
|
||||
virtual_mailbox_maps = "ldap:/run/postfix/mailboxes.cf";
|
||||
virtual_alias_maps = "ldap:/run/postfix/accountsmap.cf,ldap:/run/postfix/aliases.cf";
|
||||
virtual_transport = "lmtp:unix:private/dovecot-lmtp";
|
||||
smtpd_sender_login_maps = "ldap:/run/postfix/sender_login_maps.cf";
|
||||
|
||||
# Do not display the name of the recipient table in the "User unknown" responses.
|
||||
# The extra detail makes trouble shooting easier but also reveals information
|
||||
# that is nobody elses business.
|
||||
show_user_unknown_table_name = "no";
|
||||
compatibility_level = "2";
|
||||
|
||||
# bigger attachement size
|
||||
mailbox_size_limit = "202400000";
|
||||
message_size_limit = "51200000";
|
||||
smtpd_helo_required = "yes";
|
||||
smtpd_delay_reject = "yes";
|
||||
strict_rfc821_envelopes = "yes";
|
||||
|
||||
# send Limit
|
||||
smtpd_error_sleep_time = "1s";
|
||||
smtpd_soft_error_limit = "10";
|
||||
smtpd_hard_error_limit = "20";
|
||||
|
||||
smtpd_use_tls = "yes";
|
||||
smtp_tls_note_starttls_offer = "yes";
|
||||
smtpd_tls_security_level = "may";
|
||||
smtpd_tls_auth_only = "yes";
|
||||
|
||||
smtp_dns_support_level = "dnssec";
|
||||
smtp_tls_security_level = "dane";
|
||||
|
||||
smtpd_tls_cert_file = "/var/lib/acme/mail.${domain}/full.pem";
|
||||
smtpd_tls_key_file = "/var/lib/acme/mail.${domain}/key.pem";
|
||||
smtpd_tls_CAfile = "/var/lib/acme/mail.${domain}/fullchain.pem";
|
||||
|
||||
smtpd_tls_dh512_param_file = config.security.dhparams.params.postfix512.path;
|
||||
smtpd_tls_dh1024_param_file = config.security.dhparams.params.postfix2048.path;
|
||||
|
||||
smtpd_tls_session_cache_database = ''btree:''${data_directory}/smtpd_scache'';
|
||||
smtpd_tls_mandatory_protocols = "!SSLv2,!SSLv3,!TLSv1,!TLSv1.1";
|
||||
smtpd_tls_protocols = "!SSLv2,!SSLv3,!TLSv1,!TLSv1.1";
|
||||
smtpd_tls_mandatory_ciphers = "medium";
|
||||
tls_medium_cipherlist = "AES128+EECDH:AES128+EDH";
|
||||
|
||||
# authentication
|
||||
smtpd_sasl_auth_enable = "yes";
|
||||
smtpd_sasl_local_domain = "$mydomain";
|
||||
smtpd_sasl_security_options = "noanonymous";
|
||||
smtpd_sasl_tls_security_options = "$smtpd_sasl_security_options";
|
||||
smtpd_sasl_type = "dovecot";
|
||||
smtpd_sasl_path = "/var/lib/postfix/queue/private/auth";
|
||||
smtpd_relay_restrictions = "
|
||||
permit_mynetworks,
|
||||
permit_sasl_authenticated,
|
||||
defer_unauth_destination";
|
||||
smtpd_client_restrictions = "
|
||||
permit_mynetworks,
|
||||
permit_sasl_authenticated,
|
||||
reject_invalid_hostname,
|
||||
reject_unknown_client,
|
||||
permit";
|
||||
smtpd_helo_restrictions = "
|
||||
permit_mynetworks,
|
||||
permit_sasl_authenticated,
|
||||
reject_unauth_pipelining,
|
||||
reject_non_fqdn_hostname,
|
||||
reject_invalid_hostname,
|
||||
warn_if_reject reject_unknown_hostname,
|
||||
permit";
|
||||
smtpd_recipient_restrictions = "
|
||||
permit_mynetworks,
|
||||
permit_sasl_authenticated,
|
||||
reject_non_fqdn_sender,
|
||||
reject_non_fqdn_recipient,
|
||||
reject_non_fqdn_hostname,
|
||||
reject_invalid_hostname,
|
||||
reject_unknown_sender_domain,
|
||||
reject_unknown_recipient_domain,
|
||||
reject_unknown_client_hostname,
|
||||
reject_unauth_pipelining,
|
||||
reject_unknown_client,
|
||||
permit";
|
||||
smtpd_sender_restrictions = "
|
||||
reject_non_fqdn_sender,
|
||||
reject_unlisted_sender,
|
||||
reject_authenticated_sender_login_mismatch,
|
||||
permit_mynetworks,
|
||||
permit_sasl_authenticated,
|
||||
reject_unknown_sender_domain,
|
||||
reject_unknown_client_hostname,
|
||||
reject_unknown_address";
|
||||
|
||||
smtpd_etrn_restrictions = "permit_mynetworks, reject";
|
||||
smtpd_data_restrictions = "reject_unauth_pipelining, reject_multi_recipient_bounce, permit";
|
||||
};
|
||||
};
|
||||
|
||||
systemd.tmpfiles.rules = [ "d /run/postfix 0750 postfix postfix -" ];
|
||||
|
||||
systemd.services.postfix.preStart = ''
|
||||
sed -e "s/@ldap-password@/$(cat ${config.sops.secrets.dovecot-ldap-password.path})/" ${domains} > /run/postfix/domains.cf
|
||||
sed -e "s/@ldap-password@/$(cat ${config.sops.secrets.dovecot-ldap-password.path})/" ${mailboxes} > /run/postfix/mailboxes.cf
|
||||
sed -e "s/@ldap-password@/$(cat ${config.sops.secrets.dovecot-ldap-password.path})/" ${accountsmap} > /run/postfix/accountsmap.cf
|
||||
sed -e "s/@ldap-password@/$(cat ${config.sops.secrets.dovecot-ldap-password.path})/" ${aliases} > /run/postfix/aliases.cf
|
||||
sed -e "s/@ldap-password@/$(cat ${config.sops.secrets.dovecot-ldap-password.path})/" ${senderLoginMaps} > /run/postfix/sender_login_maps.cf
|
||||
'';
|
||||
|
||||
security.dhparams = {
|
||||
enable = true;
|
||||
params.postfix512.bits = 512;
|
||||
params.postfix2048.bits = 1024;
|
||||
};
|
||||
|
||||
security.acme.certs."mail.${domain}" = {
|
||||
extraDomainNames = [
|
||||
"mail-test.${domain}"
|
||||
"mail-02.${domain}"
|
||||
];
|
||||
postRun = "systemctl restart postfix.service";
|
||||
group = "postfix";
|
||||
};
|
||||
|
||||
networking.firewall.allowedTCPPorts = [
|
||||
25 # smtp
|
||||
465 # smtps
|
||||
587 # submission
|
||||
];
|
||||
}
|
||||
@@ -1,131 +0,0 @@
|
||||
{ pkgs
|
||||
, config
|
||||
, ...
|
||||
}:
|
||||
let
|
||||
domain = config.networking.domain;
|
||||
|
||||
localConfig = pkgs.writeText "local.conf" ''
|
||||
logging {
|
||||
level = "notice";
|
||||
}
|
||||
classifier "bayes" {
|
||||
autolearn = true;
|
||||
}
|
||||
dkim_signing {
|
||||
path = "/var/lib/rspamd/dkim/$domain.$selector.key";
|
||||
selector = "default";
|
||||
allow_username_mismatch = true;
|
||||
}
|
||||
arc {
|
||||
path = "/var/lib/rspamd/dkim/$domain.$selector.key";
|
||||
selector = "default";
|
||||
allow_username_mismatch = true;
|
||||
}
|
||||
milter_headers {
|
||||
use = ["authentication-results", "x-spam-status"];
|
||||
authenticated_headers = ["authentication-results"];
|
||||
}
|
||||
replies {
|
||||
action = "no action";
|
||||
}
|
||||
url_reputation {
|
||||
enabled = true;
|
||||
}
|
||||
phishing {
|
||||
openphish_enabled = true;
|
||||
# too much memory
|
||||
#phishtank_enabled = true;
|
||||
}
|
||||
neural {
|
||||
enabled = true;
|
||||
}
|
||||
neural_group {
|
||||
symbols = {
|
||||
"NEURAL_SPAM" {
|
||||
weight = 3.0; # sample weight
|
||||
description = "Neural network spam";
|
||||
}
|
||||
"NEURAL_HAM" {
|
||||
weight = -3.0; # sample weight
|
||||
description = "Neural network ham";
|
||||
}
|
||||
}
|
||||
}
|
||||
'';
|
||||
|
||||
sieve-spam-filter = pkgs.callPackage ../pkgs/sieve-spam-filter { };
|
||||
in
|
||||
{
|
||||
services.rspamd = {
|
||||
enable = true;
|
||||
extraConfig = ''
|
||||
.include(priority=1,duplicate=merge) "${localConfig}"
|
||||
'';
|
||||
|
||||
postfix.enable = true;
|
||||
workers.controller = {
|
||||
extraConfig = ''
|
||||
count = 1;
|
||||
static_dir = "''${WWWDIR}";
|
||||
password = "$2$7rb4gnnw8qbcy3x3m7au8c4mezecfjim$da4ahtt3gnjtbj7ni6bt1q8jwgqtzxp5ck6941m6prjxsz3udfgb";
|
||||
enable_password = "$2$xo1qdd1zgozwto8yazr1o35zbarbzcgp$u8mx6hcsb1qdscejb4zadcb3iucmm4mw6btgmim9h6e5d8cpy5ib";
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
services.dovecot2 = {
|
||||
mailboxes.Spam = {
|
||||
auto = "subscribe";
|
||||
specialUse = "Junk";
|
||||
};
|
||||
extraConfig = ''
|
||||
protocol imap {
|
||||
mail_plugins = $mail_plugins imap_sieve
|
||||
}
|
||||
|
||||
plugin {
|
||||
sieve_plugins = sieve_imapsieve sieve_extprograms
|
||||
|
||||
# From elsewhere to Spam folder
|
||||
imapsieve_mailbox1_name = Spam
|
||||
imapsieve_mailbox1_causes = COPY
|
||||
imapsieve_mailbox1_before = file:/var/lib/dovecot/sieve/report-spam.sieve
|
||||
|
||||
# From Spam folder to elsewhere
|
||||
imapsieve_mailbox2_name = *
|
||||
imapsieve_mailbox2_from = Spam
|
||||
imapsieve_mailbox2_causes = COPY
|
||||
imapsieve_mailbox2_before = file:/var/lib/dovecot/sieve/report-ham.sieve
|
||||
|
||||
# Move Spam emails to Spam folder
|
||||
sieve_before = /var/lib/dovecot/sieve/move-to-spam.sieve
|
||||
|
||||
sieve_pipe_bin_dir = ${sieve-spam-filter}/bin
|
||||
sieve_global_extensions = +vnd.dovecot.pipe +vnd.dovecot.environment
|
||||
}
|
||||
'';
|
||||
};
|
||||
|
||||
services.nginx.enable = true;
|
||||
services.nginx.virtualHosts."rspamd.${domain}" = {
|
||||
forceSSL = true;
|
||||
enableACME = true;
|
||||
acmeRoot = null;
|
||||
locations."/".extraConfig = ''
|
||||
proxy_pass http://localhost:11334;
|
||||
'';
|
||||
};
|
||||
|
||||
# systemd.services.rspamd.serviceConfig.SupplementaryGroups = [ "redis-rspamd" ];
|
||||
|
||||
systemd.services.dovecot2.preStart = ''
|
||||
mkdir -p /var/lib/dovecot/sieve/
|
||||
for i in ${sieve-spam-filter}/share/sieve-rspamd-filter/*.sieve; do
|
||||
dest="/var/lib/dovecot/sieve/$(basename $i)"
|
||||
cp "$i" "$dest"
|
||||
${pkgs.dovecot_pigeonhole}/bin/sievec "$dest"
|
||||
done
|
||||
chown -R "${config.services.dovecot2.mailUser}:${config.services.dovecot2.mailGroup}" /var/lib/dovecot/sieve
|
||||
'';
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
{ stdenv
|
||||
, makeWrapper
|
||||
, rspamd
|
||||
,
|
||||
}:
|
||||
stdenv.mkDerivation {
|
||||
name = "sieve-rspamd-filter";
|
||||
nativeBuildInputs = [ makeWrapper ];
|
||||
src = ./src;
|
||||
|
||||
installPhase = ''
|
||||
for sieve in $src/*.sieve; do
|
||||
install -D "$sieve" "$out/share/sieve-rspamd-filter/$(basename $sieve)"
|
||||
done
|
||||
|
||||
mkdir $out/bin
|
||||
cat > $out/bin/learn-spam.sh <<'EOF'
|
||||
#!/bin/sh
|
||||
exec ${rspamd}/bin/rspamc -h /run/rspamd.sock learn_spam
|
||||
EOF
|
||||
cat > $out/bin/learn-ham.sh <<'EOF'
|
||||
#!/bin/sh
|
||||
exec ${rspamd}/bin/rspamc -h /run/rspamd.sock learn_ham
|
||||
EOF
|
||||
chmod +x $out/bin/*.sh
|
||||
'';
|
||||
}
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
require ["fileinto"];
|
||||
|
||||
if header :is "X-Spam" "Yes" {
|
||||
fileinto "Spam";
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
require ["vnd.dovecot.pipe", "copy", "imapsieve", "environment", "variables"];
|
||||
|
||||
if environment :matches "imap.mailbox" "*" {
|
||||
set "mailbox" "${1}";
|
||||
}
|
||||
|
||||
if string "${mailbox}" "Trash" {
|
||||
stop;
|
||||
}
|
||||
|
||||
if environment :matches "imap.user" "*" {
|
||||
set "username" "${1}";
|
||||
}
|
||||
|
||||
pipe :copy "learn-ham.sh" [ "${username}" ];
|
||||
@@ -1,7 +0,0 @@
|
||||
require ["vnd.dovecot.pipe", "copy", "imapsieve", "environment", "variables"];
|
||||
|
||||
if environment :matches "imap.user" "*" {
|
||||
set "username" "${1}";
|
||||
}
|
||||
|
||||
pipe :copy "learn-spam.sh" [ "${username}" ];
|
||||
@@ -1,51 +0,0 @@
|
||||
borg-passphrase: ENC[AES256_GCM,data:JtQ0LlFgo5xO09T4YqQtlVEBHRQFPw97qkRnDJYjz1b8PQ64cF32vpRav6YuyPHUqltN3elaaw7WyalLNLaJAg==,iv:ylgC0G7F00m9Xru+v4Q3gB3OohFX5XuSsMefRP19Llw=,tag:OAsYZSx59/pnfYrkzvQP5Q==,type:str]
|
||||
borg-ssh-key: ENC[AES256_GCM,data:nY3fL73+bNhp/h//AADzrhHKmPC7zkp7FoLxW+MrYLO5uLdjIOemGyX9V0IIpV4LimrEI0tB6rfqwdW47P7zA+YGZZK9g+PAd9yGEy1I8VGuel5ZOVvBrv8BC2ysKUzziXNv33KKw4mrU5BvBYoyQClGsNkXvKlJ1XH0T8TnA4EmIKoujcMjI3K1yT8w3nn9TZ11VG9bnv9F7mXttUyXH053rz6TuENjxNdVjSsJkROpL/j5i7/RxiOwnxyIFyZmCK8/joGQhfEKuPKkZv3xAYypEg9DudKZTmcN92ooykjHUaGJ/X1vkpv2dR9vjaGHxnJtBKM4qpjS3AH+iXg4qwBOOPIIcwoYkj4v4xzAdteda7wDwchM69yrGjGA5j88trvJ/UOIJ108htSzij4+SPpa3A8zyt2zV4enNWpC0CAf2PkJyp+VbdDhP4as7NGqc7saMzZdRFOYnfmyAd47wUf4VsjZ2svxHQH+8l1Lb7kpZObhMBzuzbAKSKNwTPfhlZ78TnhUpfwO07gdK8mS,iv:06rmPl3ER3DcJvJISxnbuMzbGb/3JbNpIxNeOUCals8=,tag:ejagsOwoBWRF20q2rFpWbA==,type:str]
|
||||
openldap-rootpw: ENC[AES256_GCM,data:uO5SVlPCxz+jACwdXuPowdlP5NjVu/KZ/uhAbPsBrnKQnW7eeZD+yqK189VNsQTqhq61AUZ1r5nzgMAHTclniQ==,iv:C3unIpOZh1x48RGqycqyoDFO0K41WwFkdtvlAmSEZy8=,tag:4N4tph2qvHbWSzDdTmh+VQ==,type:str]
|
||||
dovecot-ldap-password: ENC[AES256_GCM,data:mygVtdK5lwsZ0YluyvJGss6Gf2Hb9zM7BtIBknJAgQBb0MT5d2U47HCoANVHQJYCidyjvqTDku6pSI11rGmRIw==,iv:HrEgWGuARYeb42g+/4bHByJOVMDc2GroKVrlixHCc1w=,tag:+vm5kMZPne0UToAMl62IWA==,type:str]
|
||||
sops:
|
||||
kms: []
|
||||
gcp_kms: []
|
||||
azure_kv: []
|
||||
hc_vault: []
|
||||
age:
|
||||
- recipient: age14grjcxaq4h55yfnjxvnqhtswxhj9sfdcvyas4lwvpa8py27pjy2sv3g6v7
|
||||
enc: |
|
||||
-----BEGIN AGE ENCRYPTED FILE-----
|
||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB5SURFbHFMQVVyN0laSkR6
|
||||
U1JQRXgvK1grTFdyTjhUY1JsSW9sVHROZ0ZJCjYzOGRXODZZZWxCd2xPcThOWVpo
|
||||
L1RpZlZxZTZQQnozcUZ5SnIrYnJ2OEkKLS0tIFBVZHJJUzEydVd0U0lBdGdvYjlk
|
||||
Wjl5aUpZbUk4ZUxwS0NLTHE1KzhaVk0Ky8nBCAUamOuwqW3Qio25jr4ye98J7Y6O
|
||||
9gmNmsCyxkaZg9gKrH8LCTfjh+NwH2qVpmFSQEXcj5qW0na5xwENJA==
|
||||
-----END AGE ENCRYPTED FILE-----
|
||||
- recipient: age16veg3fmvpfm7a89a9fc8dvvsxmsthlm70nfxqspr6t8vnf9wkcwsvdq38d
|
||||
enc: |
|
||||
-----BEGIN AGE ENCRYPTED FILE-----
|
||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBRZU9FZ0I2WkpSUjBoYktK
|
||||
WHlsZWovQlVEZ1lFajgwKzFJcGgvL1lUOFJrCnVNNU5LOWIza2lMVGtOcmFhQnUz
|
||||
cDlGOU9ySjRMaWx6TlMvQStnNFZvNkUKLS0tIENGYXZhSWwvZmUvQTlKU2pFb1ND
|
||||
WkJWMElRc3h3SmZkR2YyclVNVGhYT1kK49wmyQ/S0qQkDac+Z3UvBGWPgia6FdBZ
|
||||
Rm/isGOIe0ips25Vdhl2a5jZt99u1Dlgv094Fxopxs8494xIunDeFg==
|
||||
-----END AGE ENCRYPTED FILE-----
|
||||
- recipient: age1v6p8dan2t3w9h94fz4flldl32082j3s9x6zqq7u5j66keth9aphsd6pvch
|
||||
enc: |
|
||||
-----BEGIN AGE ENCRYPTED FILE-----
|
||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBhWk1xeXhjaEpIM2pBZlJp
|
||||
UXBmcDlUQVN0S0RDbW5TaEladEFRR1l2cDNFCjRoYkdwakE2U0U1SE1RK1ZjTGZu
|
||||
L29SMGltM1poMU54YzF2emVxNTZINUUKLS0tIEJJcVpsK0hkc1YzaXZDV1oxVTZi
|
||||
QXYwQmJYd2dtY2ZqSE5YcTk5RndvalkKDCKp+k0QYuDdUfhm/fenv/kdnPcO93Iz
|
||||
b0GGoqnveCDcXX47s3DDZ/Kuu1EK4Cd71wvWyVu0sXWtt3c6l933qQ==
|
||||
-----END AGE ENCRYPTED FILE-----
|
||||
- recipient: age1gtulvdj4aclpfhk3mmzvpz9xysccxhvu99x6ayaqlj8m44ehffgq6zuc5u
|
||||
enc: |
|
||||
-----BEGIN AGE ENCRYPTED FILE-----
|
||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBSTUUrMUp0RXJHNjl0dWts
|
||||
UXhnMU1kNW5lSGQ1N202WlZ2U1psUnFlMlNZCjdQVzRkTC9CcGRlVVMyQWxMOFRy
|
||||
b0Ezdnc0RnpKekhUcUJlc1pWQ2VjKzAKLS0tIFdRM2Zab1pRT1VnbzlGbExmaEUy
|
||||
RzVyNEdHVzZUdENlVEh4c3l3V0h1TzgKlDTvDMe67hfDd3yEepLeIhuVym3wekoy
|
||||
Fk86lgIY7VIGW0Oncyj/mOg10MYQuzoTqgMKfwDN9bnV4aeSS24rKw==
|
||||
-----END AGE ENCRYPTED FILE-----
|
||||
lastmodified: "2024-10-18T13:21:23Z"
|
||||
mac: ENC[AES256_GCM,data:uv3uz45U6dxfFkKonwCv+tfWD3g9zBGudCuXXAHgav5XY+z62Z7KEV5PUGMI74k1cRg8etIyUo17Ur/KVIrTDSt67R+70WaSOXnRtEX2F/kJWb8NLC8pfQYPVFtaaCSx0kFPZeu7vSUD5GkTJ9UzwbKUZ32N823sIXosia24x2o=,iv:7/Z6XCE/iY5TBTOdjmKwjgue2tzAB6F9HHZYjk/qrok=,tag:WhyEqM8nBID1PGaTXvz8kQ==,type:str]
|
||||
pgp: []
|
||||
unencrypted_suffix: _unencrypted
|
||||
version: 3.8.1
|
||||
@@ -1 +0,0 @@
|
||||
../../utils
|
||||
@@ -1 +0,0 @@
|
||||
https://channels.nixos.org/nixos-24.05
|
||||
@@ -1,62 +0,0 @@
|
||||
{ lib, pkgs, ... }: {
|
||||
imports = [
|
||||
./utils/bento.nix
|
||||
./utils/modules/sops.nix
|
||||
./utils/modules/lego/lego.nix
|
||||
|
||||
|
||||
./modules/mysql.nix
|
||||
./utils/modules/nginx.nix
|
||||
./modules/authelia
|
||||
./modules/collabora.nix
|
||||
./modules/nextcloud
|
||||
|
||||
./utils/modules/autoupgrade.nix
|
||||
./utils/modules/borgbackup.nix
|
||||
|
||||
./hardware-configuration.nix
|
||||
|
||||
./modules/web/stack.nix
|
||||
];
|
||||
|
||||
environment.systemPackages = with pkgs; [
|
||||
vim
|
||||
davfs2
|
||||
screen
|
||||
ucommon
|
||||
php
|
||||
php83
|
||||
];
|
||||
|
||||
time.timeZone = "Europe/Vienna";
|
||||
|
||||
services.logind.extraConfig = "RuntimeDirectorySize=2G";
|
||||
|
||||
sops.age.sshKeyPaths = [ "/etc/ssh/ssh_host_ed25519_key" ];
|
||||
sops.defaultSopsFile = ./secrets.yaml;
|
||||
|
||||
nix.gc = {
|
||||
automatic = true;
|
||||
options = "--delete-older-than 60d";
|
||||
};
|
||||
|
||||
boot.tmp.cleanOnBoot = true;
|
||||
zramSwap.enable = true;
|
||||
networking.hostName = "web";
|
||||
networking.domain = "social-grow.tech";
|
||||
services.openssh.enable = true;
|
||||
users.users.root.openssh.authorizedKeys.keys = [
|
||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHC9YODKEKu5bOC61qkpPd8QeZxbNPCQKgfh8xUFMdV0" # dominik
|
||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIRQuPqH5fdX3KEw7DXzWEdO3AlUn1oSmtJtHB71ICoH Generated By Termius"
|
||||
];
|
||||
|
||||
# backups
|
||||
borgbackup.repo = "u428777-sub3@u428777.your-storagebox.de:borg";
|
||||
|
||||
networking.firewall = {
|
||||
enable = true;
|
||||
allowedTCPPorts = [ 22 80 443 ];
|
||||
};
|
||||
|
||||
system.stateVersion = "22.05";
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
../../fleet.nix
|
||||
@@ -1,14 +0,0 @@
|
||||
{ modulesPath, ... }:
|
||||
{
|
||||
imports = [ (modulesPath + "/profiles/qemu-guest.nix") ];
|
||||
boot.loader.grub = {
|
||||
efiSupport = true;
|
||||
efiInstallAsRemovable = true;
|
||||
device = "nodev";
|
||||
configurationLimit = 5;
|
||||
};
|
||||
fileSystems."/boot" = { device = "/dev/sda15"; fsType = "vfat"; };
|
||||
boot.initrd.availableKernelModules = [ "ata_piix" "uhci_hcd" "xen_blkfront" ];
|
||||
boot.initrd.kernelModules = [ "nvme" ];
|
||||
fileSystems."/" = { device = "/dev/sda1"; fsType = "ext4"; };
|
||||
}
|
||||
@@ -1,251 +0,0 @@
|
||||
{ config, lib, ... }:
|
||||
let
|
||||
domain = config.networking.domain;
|
||||
components = lib.strings.splitString "." domain;
|
||||
dcComponents = map (x: "dc=" + x) components;
|
||||
ldapPath = builtins.concatStringsSep "," dcComponents;
|
||||
in {
|
||||
sops.secrets.authelia-jwt-secret = {
|
||||
owner = "authelia-main";
|
||||
};
|
||||
sops.secrets.authelia-backend-ldap-password = {
|
||||
owner = "authelia-main";
|
||||
};
|
||||
sops.secrets.authelia-storage-encryption-key = {
|
||||
owner = "authelia-main";
|
||||
};
|
||||
sops.secrets.authelia-session-secret = {
|
||||
owner = "authelia-main";
|
||||
};
|
||||
sops.secrets.authelia-identity-providers-oidc-hmac-secret = {
|
||||
owner = "authelia-main";
|
||||
};
|
||||
sops.secrets.authelia-identity-providers-oidc-issuer-certificate-chain = {
|
||||
owner = "authelia-main";
|
||||
};
|
||||
sops.secrets.authelia-identity-providers-oidc-issuer-private-key = {
|
||||
owner = "authelia-main";
|
||||
};
|
||||
|
||||
services.authelia.instances.main = {
|
||||
enable = true;
|
||||
secrets = {
|
||||
jwtSecretFile = config.sops.secrets.authelia-jwt-secret.path;
|
||||
storageEncryptionKeyFile = config.sops.secrets.authelia-storage-encryption-key.path;
|
||||
sessionSecretFile = config.sops.secrets.authelia-session-secret.path;
|
||||
oidcHmacSecretFile = config.sops.secrets.authelia-identity-providers-oidc-hmac-secret.path;
|
||||
oidcIssuerPrivateKeyFile = config.sops.secrets.authelia-identity-providers-oidc-issuer-private-key.path;
|
||||
};
|
||||
environmentVariables = {
|
||||
"AUTHELIA_AUTHENTICATION_BACKEND_LDAP_PASSWORD_FILE" = config.sops.secrets.authelia-backend-ldap-password.path;
|
||||
"AUTHELIA_NOTIFIER_SMTP_PASSWORD_FILE" = config.sops.secrets.authelia-backend-ldap-password.path;
|
||||
};
|
||||
settings = {
|
||||
theme = "dark";
|
||||
default_redirection_url = "https://${domain}";
|
||||
|
||||
server = {
|
||||
host = "127.0.0.1";
|
||||
port = 9091;
|
||||
};
|
||||
|
||||
# log = {
|
||||
# level = "debug";
|
||||
# format = "text";
|
||||
# };
|
||||
|
||||
authentication_backend = {
|
||||
ldap = {
|
||||
url = "ldaps://ldap.${domain}";
|
||||
base_dn = ldapPath;
|
||||
additional_users_dn = "OU=users";
|
||||
users_filter = "(&({username_attribute}={input})(objectClass=person))";
|
||||
username_attribute = "mail";
|
||||
mail_attribute = "mail";
|
||||
display_name_attribute = "cn";
|
||||
additional_groups_dn = "OU=groups";
|
||||
groups_filter = "(&(member={dn})(objectClass=groupOfNames))";
|
||||
group_name_attribute = "cn";
|
||||
permit_referrals = false;
|
||||
permit_unauthenticated_bind = false;
|
||||
user = "cn=authelia,ou=system,ou=users,${ldapPath}";
|
||||
};
|
||||
};
|
||||
|
||||
webauthn = {
|
||||
disable = false;
|
||||
display_name = "Authelia";
|
||||
attestation_conveyance_preference = "indirect";
|
||||
user_verification = "preferred";
|
||||
timeout = "60s";
|
||||
};
|
||||
|
||||
totp = {
|
||||
disable = false;
|
||||
issuer = "auth.${domain}";
|
||||
algorithm = "sha1";
|
||||
digits = 6;
|
||||
period = 30;
|
||||
skew = 1;
|
||||
secret_size = 32;
|
||||
};
|
||||
|
||||
access_control = {
|
||||
default_policy = "deny";
|
||||
rules = [
|
||||
{
|
||||
domain = ["auth.${domain}"];
|
||||
policy = "bypass";
|
||||
}
|
||||
{
|
||||
domain = ["*.${domain}"];
|
||||
policy = "two_factor";
|
||||
}
|
||||
];
|
||||
};
|
||||
|
||||
session = {
|
||||
name = "authelia_session";
|
||||
expiration = "12h";
|
||||
inactivity = "45m";
|
||||
remember_me_duration = "1M";
|
||||
domain = domain;
|
||||
# todo: enable with 4.38
|
||||
# cookies = [
|
||||
# {
|
||||
# domain = "${domain}";
|
||||
# }
|
||||
# ];
|
||||
};
|
||||
|
||||
regulation = {
|
||||
max_retries = 3;
|
||||
find_time = "5m";
|
||||
ban_time = "15m";
|
||||
};
|
||||
|
||||
storage = {
|
||||
# mysql = {
|
||||
# host = "/run/mysqld/mysqld.sock'";
|
||||
# port = 3306;
|
||||
# database = "authelia_main";
|
||||
# username = "authelia_main";
|
||||
# password = "socket_auth";
|
||||
# timeout = "5s";
|
||||
# };
|
||||
local = {
|
||||
path = "/var/lib/authelia-main/db.sqlite3";
|
||||
};
|
||||
};
|
||||
|
||||
notifier = {
|
||||
disable_startup_check = false;
|
||||
smtp = {
|
||||
host = "mail.${domain}";
|
||||
port = 25;
|
||||
username = "authelia@${domain}";
|
||||
sender = "Authelia <authelia@${domain}>";
|
||||
};
|
||||
};
|
||||
identity_providers = {
|
||||
oidc = {
|
||||
## The other portions of the mandatory OpenID Connect 1.0 configuration go here.
|
||||
## See: https://www.authelia.com/c/oidc
|
||||
# authorization_policies = {
|
||||
# support = {
|
||||
# default_policy = "deny";
|
||||
# rules = [
|
||||
# {
|
||||
# policy = "two_factor";
|
||||
# subject = "group:support"; # Deny access to users of services group
|
||||
# }
|
||||
# {
|
||||
# policy = "two_factor";
|
||||
# subject = "group:admin"; # Deny access to users of services group
|
||||
# }
|
||||
# ];
|
||||
# };
|
||||
# };
|
||||
clients = [
|
||||
{
|
||||
id = "nextcloud";
|
||||
description = "Nextcloud";
|
||||
secret = "$pbkdf2-sha512$310000$P/kCFCL7FPwrZORA7KLIcg$HfC4qdmCJclSICHBjCltyT2Q1B4hiq.h75U1V1pfM4UbUu9kqll100I4/tdxjCBcPDePPXq8OFTQedNLsp.feA";
|
||||
public = false;
|
||||
authorization_policy = "one_factor";
|
||||
redirect_uris = [
|
||||
"https://cloud.${domain}/apps/oidc_login/oidc"
|
||||
];
|
||||
pre_configured_consent_duration = "1y";
|
||||
scopes = [
|
||||
"openid"
|
||||
"profile"
|
||||
"email"
|
||||
"groups"
|
||||
];
|
||||
userinfo_signing_algorithm = "none";
|
||||
}
|
||||
];
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
services.nginx.virtualHosts."auth.${domain}" = {
|
||||
enableACME = true;
|
||||
forceSSL = true;
|
||||
acmeRoot = null;
|
||||
|
||||
locations."/api/verify" = {
|
||||
proxyPass = "http://127.0.0.1:9091";
|
||||
proxyWebsockets = true;
|
||||
|
||||
extraConfig = ''
|
||||
allow 127.0.0.1;
|
||||
allow 49.12.244.139;
|
||||
allow 77.119.230.30;
|
||||
deny all;
|
||||
'';
|
||||
};
|
||||
|
||||
locations."/" = {
|
||||
proxyPass = "http://127.0.0.1:9091";
|
||||
proxyWebsockets = true;
|
||||
|
||||
extraConfig = ''
|
||||
client_body_buffer_size 128k;
|
||||
|
||||
#Timeout if the real server is dead
|
||||
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503;
|
||||
|
||||
# Advanced Proxy Config
|
||||
send_timeout 5m;
|
||||
proxy_read_timeout 360;
|
||||
proxy_send_timeout 360;
|
||||
proxy_connect_timeout 360;
|
||||
|
||||
# Basic Proxy Config
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Original-URL $scheme://$http_host$request_uri;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_set_header X-Forwarded-Host $http_host;
|
||||
proxy_set_header X-Forwarded-Uri $request_uri;
|
||||
proxy_set_header X-Forwarded-Ssl on;
|
||||
proxy_redirect http:// $scheme://;
|
||||
proxy_set_header Connection "";
|
||||
proxy_cache_bypass $cookie_session;
|
||||
proxy_no_cache $cookie_session;
|
||||
proxy_buffers 64 256k;
|
||||
|
||||
# If behind reverse proxy, forwards the correct IP
|
||||
set_real_ip_from 10.0.0.0/8;
|
||||
set_real_ip_from 172.0.0.0/8;
|
||||
set_real_ip_from 192.168.0.0/16;
|
||||
set_real_ip_from fc00::/7;
|
||||
real_ip_header X-Forwarded-For;
|
||||
real_ip_recursive on;
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
authelia-jwt-secret: ENC[AES256_GCM,data:+4mCRAbPYeuxZwPxIWdzym9M0soVRJGZOHpBLFp1dsienOes6PcF6DhkzLwx1g/2KYQBrWq5QtNyysLkl32mNg==,iv:3354Ww7D1fQAVZh8xlJo3W9VaLTC6sUxXpNzwFYGZPg=,tag:NjPuHi4R+I3CJ09ZbV1Cbw==,type:str]
|
||||
authelia-backend-ldap-password: ENC[AES256_GCM,data:AJ5/lQxxQ0PjPpja4Lm7Qbn4rrZ/fapFeTO9nXsXpYC7cSgPDmGL4LG6QTFrgHpJU4FGEyFhWUYf/BZvHFLA2A==,iv:/w3SlYC74vSV/hkOdp2wb50beSTaokQC9C1ogs82nxo=,tag:b5M78WOUgHcydoJTKiAAOQ==,type:str]
|
||||
authelia-storage-encryption-key: ENC[AES256_GCM,data:I3ek+p0faJUUjS3ULeeLzsrsl03MKlHwrC+R3IqrJ2P9AbJmMBvvXnqLx2H2THkjGiqN3kLgrhnmInn+BnCgYg==,iv:EiZpXbkyC3tbdzcp20hV6ctAJdB9tlgxT3gI7wiqSZc=,tag:qqG02RJAizr2jlGV0JnStA==,type:str]
|
||||
authelia-session-secret: ENC[AES256_GCM,data:+hljRSv4nABWg+vEOhYM27h9Gu1FCqcWWa51VqlN1r8AE79S78Uq2txWL7bZKql/fxmaguTLwk18xkHIAvIEsA==,iv:RoytV5jWIUDq6olp8rWAc0NRC4f1FLL43EpTzcXZ3eg=,tag:vIvDVRSqlVt/W/52vuDDZA==,type:str]
|
||||
authelia-identity-providers-oidc-hmac-secret: ENC[AES256_GCM,data:yyqauvp+/8ufhCaZ1o0DWn4Nx1rdTW8C1HRVAtyCRuBaQA/yFVmZkwFVbnIDC3TrmuEMc2MXzVCREbdDsEqkGm6LJAB4Eq31NyhhbAtKufeqKHhMgEF4d41K71V//FJn2/ZBY6CaR1Ke0rX3p/Rpwk0rwddikkUmdJ7i7w9ayP8=,iv:ONBU0uWEUeQxQCGmHtGOySuLmTnJlAx//lQcK32i1Gs=,tag:Tk2BbYZSqbJRc/2cj8yxHQ==,type:str]
|
||||
authelia-identity-providers-oidc-issuer-certificate-chain: ENC[AES256_GCM,data:oQwBKE0VjTIKYWOGKFtLwkOkjTh16gf5lJvMEEVs3Sy/+gmyGGmnDHm+xv9aT7Mmq9wSM7SVBe39yT5K9bUd0vGXO2Ze5V55B+B+9bAPKUL4rPNQAeSy3QCJPh6EoG3urDD/HUklV8QCprgTlokdgVgY3fv3be2Y1oOdiZDvbacol6OlcRXSi8ZqMro+f15e44j8NGhzsSahhzOLtmiRGLr5zWnzk8b221HZWtjSdG4rLrtcCZ1UjvvUX5pf8J5PI/9X4S6J7pglG+IlI0WGSHvQ9BXGQqWgmWky/3+hnC/B3ZPm3bz5CqMHzsdx/QmiCtQQf08GOoan/3rgp3pAu5J5TPDldnzEQkWPjciOMp4ewlu4nC1AViat7DH8wFtV9IpixEZm3fMidpPBpkTTRZMCy6AstNlPMvvvRDN/6nJypN++gvkBw3OJac2xBdtbdF5uC9nIrZqWENLnOn4623/C8yJJ8a2l1W1FF95hHiZDQKua+kB4CfFJSFxhtcWj3vcCzv7QIGHZPTIVn+aCozb4CdOegLswCuY9g5ncHfOnqIhSCY3Bc2xbd5GO7kVRvqT79abwHsAdArdDJAE4Fq3mNJG9/fy0N31GW4qKMTb3W5EgEt/2OtfsUn8MwHJV9BGPMeZhpn9hdzkXo9vmakVMKNoK4SEgZmFiKCj/uwhwdvJfYMRvl/n1DSpy8mxzKWt1IO9FD5HRUhkKeas6spOSyzbi4FTJJmJb9NQ5gzAcfTXs8C49S/DSocRwUHvQMvRIRZzBejxFKdnwGxwIJiVDY/04FWAjMR4HgxkCBvo9x+CxajnCw/S9g02uY85vxW1ZURi9wUK9Q9nbEyMu1IGWadhVO6fKvqWr9rVZ6tqqJ7FP81LKca80nkY+6Elec6l6u01Lzb4pLA6MFLyJbCE97+Vmoh056N73RNapWP6G3Txs2CvtzqWdup0J4xpwAxoEqVlnkBQ61abucZH9veMoq4gvxM90S+bBX7c6A+FYRha/PXovRL/SZWEfuKlVDeLQyb2IwQ==,iv:jhnNkcLXN3pHx6S8g78+R6X+ckhOF35QK615zcH2gqI=,tag:JSHDo9nbBbhpiQFSrLuDdg==,type:str]
|
||||
authelia-identity-providers-oidc-issuer-private-key: ENC[AES256_GCM,data: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,iv:PWdVLhu0BPx7sXMzow9wl+cqDXD2Y5J5lfVSX3tNCMg=,tag:P4vHogedMdAUeIh4XHlmdw==,type:str]
|
||||
sops:
|
||||
kms: []
|
||||
gcp_kms: []
|
||||
azure_kv: []
|
||||
hc_vault: []
|
||||
age:
|
||||
- recipient: age16veg3fmvpfm7a89a9fc8dvvsxmsthlm70nfxqspr6t8vnf9wkcwsvdq38d
|
||||
enc: |
|
||||
-----BEGIN AGE ENCRYPTED FILE-----
|
||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBHWkRuWXdaQ1RUbkF1d2p0
|
||||
elZkbnFVSW9tVjdqSHFvbjFiL202cW1tWjJ3ClpDUEFIMDFteFA1QTdTVmtVWHI0
|
||||
OFRuU1Fockh4aTBwa3l3ZjdiMFFYSm8KLS0tIGdCZjZNVXNVZWV3ZlJzY3ZyZXhr
|
||||
WFp1eVZna1VWUUZuTVY4Q2h2c0Y2ZDAKcglSV3UBoZ65+SsM+zRFJmjIH61jXbT0
|
||||
rpeJ8/0i4THmVpbZY+NOIh2zECmzBkAA06jv0jMoftL40h2wsdgncg==
|
||||
-----END AGE ENCRYPTED FILE-----
|
||||
- recipient: age1v6p8dan2t3w9h94fz4flldl32082j3s9x6zqq7u5j66keth9aphsd6pvch
|
||||
enc: |
|
||||
-----BEGIN AGE ENCRYPTED FILE-----
|
||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBna282T2hYcDl4UWFISDVL
|
||||
eE42MjVxZndUVEU5bjJwUzdHU2xHNXVNRW13CmZwUmdCWDFNVmdDbktwOXBIbzNZ
|
||||
eGgrZHQwMEdRSG11aWpoSllrcjBBY2cKLS0tIFBZRUdYVUhsbFZYV0w5T3RYc0Ez
|
||||
RDJZcjA4VFNadEZCUmpOVWRBdGNKMzQKhhQCbeRxDvhFVsF3G+OoXo4i+koqqgrV
|
||||
o/esYoxA1ZNsS9mhFbfMw1C2YO43iPtaWChAO5zUABDALD6dJ1Rf1A==
|
||||
-----END AGE ENCRYPTED FILE-----
|
||||
- recipient: age1y6lvl5jkwc47p5ae9yz9j9kuwhy7rtttua5xhygrgmr7ehd49svsszyt42
|
||||
enc: |
|
||||
-----BEGIN AGE ENCRYPTED FILE-----
|
||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB5ZUJuMnNwTGpSdVA4UXV5
|
||||
bkdGTWJsRjliMGJWcXBKekc3WDZiN0FWV0MwCmZIVld4M0xaWWhmUDVqSGcwbGpz
|
||||
S0kzQy9scDRObS82WkMzYUw2dVBaWXMKLS0tIGpkeFZqdXIrY0lFdUgwekNJeDN4
|
||||
eFhnWGdoTzdyZmtjZDJBc3FveTRaN0EKBj2hSr6qDxwW+k5hox47P5uyoHQAzCjH
|
||||
+TplhMUd5p8/ud3U4lixLezGu1qftVSKtz/4SAXrSC5DYZJF1w7tDQ==
|
||||
-----END AGE ENCRYPTED FILE-----
|
||||
lastmodified: "2023-08-17T01:43:14Z"
|
||||
mac: ENC[AES256_GCM,data:zcCKk+VAddbb4vZltdC6hKPAnoo4rvcLcmIsKATQekbVo9OUk5Q5JnxglgAxXyj/YMZ7tIY/IXoWdSW4Kw673vthVnWpGLnuHtXJFGslkQ+GEkIt0z/oepr33gXErsEolZ3rIx02CVsIK5tb38ol0DhAe+6dUihsi23HruMJNog=,iv:2RVGRBTgqR9YLrRpoxuN72NOcXvRlZVTaPNiU7l75w0=,tag:lr4/sBBE9F27II289OWUNQ==,type:str]
|
||||
pgp: []
|
||||
unencrypted_suffix: _unencrypted
|
||||
version: 3.7.3
|
||||
@@ -1,68 +0,0 @@
|
||||
{ config, ... }:
|
||||
let
|
||||
domain = config.networking.domain;
|
||||
in {
|
||||
#Collabora Containers
|
||||
virtualisation.oci-containers.containers.collabora = {
|
||||
image = "docker.io/collabora/code:latest";
|
||||
ports = [ "9980:9980/tcp" ];
|
||||
environment = {
|
||||
server_name = "code.${domain}";
|
||||
aliasgroup1 = "https://cloud.${domain}:443";
|
||||
dictionaries = "en_US";
|
||||
extra_params = "--o:ssl.enable=false --o:ssl.termination=true";
|
||||
};
|
||||
extraOptions = [
|
||||
"--pull=newer"
|
||||
];
|
||||
};
|
||||
|
||||
services.nginx.virtualHosts.${config.virtualisation.oci-containers.containers.collabora.environment.server_name} = {
|
||||
enableACME = true;
|
||||
forceSSL = true;
|
||||
|
||||
extraConfig = ''
|
||||
# static files
|
||||
location ^~ /browser {
|
||||
proxy_pass http://127.0.0.1:9980;
|
||||
proxy_set_header Host $host;
|
||||
}
|
||||
|
||||
# WOPI discovery URL
|
||||
location ^~ /hosting/discovery {
|
||||
proxy_pass http://127.0.0.1:9980;
|
||||
proxy_set_header Host $host;
|
||||
}
|
||||
|
||||
# Capabilities
|
||||
location ^~ /hosting/capabilities {
|
||||
proxy_pass http://127.0.0.1:9980;
|
||||
proxy_set_header Host $host;
|
||||
}
|
||||
|
||||
# main websocket
|
||||
location ~ ^/cool/(.*)/ws$ {
|
||||
proxy_pass http://127.0.0.1:9980;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "Upgrade";
|
||||
proxy_set_header Host $host;
|
||||
proxy_read_timeout 36000s;
|
||||
}
|
||||
|
||||
# download, presentation and image upload
|
||||
location ~ ^/(c|l)ool {
|
||||
proxy_pass http://127.0.0.1:9980;
|
||||
proxy_set_header Host $host;
|
||||
}
|
||||
|
||||
# Admin Console websocket
|
||||
location ^~ /cool/adminws {
|
||||
proxy_pass http://127.0.0.1:9980;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "Upgrade";
|
||||
proxy_set_header Host $host;
|
||||
proxy_read_timeout 36000s;
|
||||
}
|
||||
'';
|
||||
};
|
||||
}
|
||||
@@ -1,80 +0,0 @@
|
||||
{ pkgs, ... }:
|
||||
|
||||
let
|
||||
mysqlCreateDatabase = pkgs.writeShellScriptBin "mysql-create-database" ''
|
||||
#!/usr/bin/env bash
|
||||
if [ $# -lt 2 ]
|
||||
then
|
||||
echo "Usage: $0 <database> <host>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! [ $EUID -eq 0 ]
|
||||
then
|
||||
echo "Must be root!" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
DB="$1"
|
||||
HOST="$2"
|
||||
PASSWORD="$(tr -dc A-Za-z0-9 < /dev/urandom | head -c 64 | xargs)"
|
||||
|
||||
cat <<EOF | mysql --host localhost --user root
|
||||
create database $DB;
|
||||
grant usage on $DB.* to '$DB'@'$HOST' identified by '$PASSWORD';
|
||||
grant all privileges on $DB.* to '$DB'@'$HOST';
|
||||
EOF
|
||||
|
||||
echo
|
||||
echo "Password for user $DB is:"
|
||||
echo
|
||||
echo $PASSWORD
|
||||
echo
|
||||
'';
|
||||
mysqlDeleteDatabase = pkgs.writeShellScriptBin "mysql-delete-database" ''
|
||||
#!/usr/bin/env bash
|
||||
if [ $# -lt 1 ]
|
||||
then
|
||||
echo "Usage: $0 <database>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! [ $EUID -eq 0 ]
|
||||
then
|
||||
echo "Must be root!" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
DB="$1"
|
||||
PASSWORD="$(tr -dc A-Za-z0-9 < /dev/urandom | head -c 64 | xargs)"
|
||||
|
||||
cat <<EOF | mysql --host localhost --user root
|
||||
drop database $DB;
|
||||
drop user '$DB';
|
||||
EOF
|
||||
|
||||
echo
|
||||
echo "Dropped database $DB!"
|
||||
echo
|
||||
'';
|
||||
in {
|
||||
environment.systemPackages = [
|
||||
mysqlCreateDatabase
|
||||
mysqlDeleteDatabase
|
||||
];
|
||||
|
||||
services.mysql = {
|
||||
enable = true;
|
||||
package = pkgs.mariadb;
|
||||
settings = {
|
||||
mysqld = {
|
||||
max_allowed_packet = "64M";
|
||||
transaction_isolation = "READ-COMMITTED";
|
||||
binlog_format = "ROW";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
services.mysqlBackup.enable = true;
|
||||
services.mysqlBackup.databases = [ "mysql" ];
|
||||
}
|
||||
@@ -1,108 +0,0 @@
|
||||
{ pkgs, config, ... }:
|
||||
let
|
||||
domain = config.networking.domain;
|
||||
in {
|
||||
imports = [
|
||||
./ldap.nix
|
||||
];
|
||||
sops.secrets.nextcloud-smb-credentials = {};
|
||||
sops.secrets.nextcloud-adminpass.owner = "nextcloud";
|
||||
sops.secrets.nextcloud-secrets.owner = "nextcloud";
|
||||
|
||||
services.nextcloud = {
|
||||
enable = true;
|
||||
hostName = "cloud.${domain}";
|
||||
https = true;
|
||||
package = pkgs.nextcloud29;
|
||||
# Instead of using pkgs.nextcloud27Packages.apps,
|
||||
# we'll reference the package version specified above
|
||||
extraApps = {
|
||||
inherit (config.services.nextcloud.package.packages.apps) calendar contacts deck forms groupfolders richdocuments;
|
||||
oidc_login = pkgs.fetchNextcloudApp rec {
|
||||
url = "https://github.com/pulsejet/nextcloud-oidc-login/releases/download/v3.1.1/oidc_login.tar.gz";
|
||||
sha256 = "sha256-EVHDDFtz92lZviuTqr+St7agfBWok83HpfuL6DFCoTE=";
|
||||
license = "gpl3";
|
||||
};
|
||||
guests = pkgs.fetchNextcloudApp rec {
|
||||
url = "https://github.com/nextcloud-releases/guests/releases/download/v4.0.0/guests-v4.0.0.tar.gz";
|
||||
sha256 = "sha256-dM2BmckOGZpcFDVs2oYVDqPafyBtLFB3ZCcsnOflteM=";
|
||||
license = "gpl3";
|
||||
};
|
||||
files_accesscontrol = pkgs.fetchNextcloudApp rec {
|
||||
url = "https://github.com/nextcloud/files_accesscontrol/archive/refs/tags/v1.20.1.tar.gz";
|
||||
sha256 = "sha256-3vcnXiLsmUnt3GiF8H9Mw8jOwAmIn1cqr13SBgvdm+g=";
|
||||
license = "gpl3";
|
||||
};
|
||||
appointments = pkgs.fetchNextcloudApp rec {
|
||||
url = "https://github.com/SergeyMosin/Appointments/raw/refs/tags/v2.1.12/build/artifacts/appstore/appointments.tar.gz";
|
||||
sha256 = "sha256-hMLimaBz5RBRzkEwpWJ9ZUrNY0oRTbPeYFCvH8hl1YE=";
|
||||
license = "gpl3";
|
||||
};
|
||||
};
|
||||
autoUpdateApps.enable = true;
|
||||
extraAppsEnable = true;
|
||||
database.createLocally = true;
|
||||
|
||||
caching.apcu = true;
|
||||
configureRedis = true;
|
||||
phpOptions."opcache.interned_strings_buffer" = "23";
|
||||
config = {
|
||||
adminpassFile = config.sops.secrets.nextcloud-adminpass.path;
|
||||
dbtype = "mysql";
|
||||
};
|
||||
|
||||
secretFile = config.sops.secrets.nextcloud-secrets.path;
|
||||
|
||||
settings = {
|
||||
log_type = "file";
|
||||
log_level = 0;
|
||||
allow_user_to_change_display_name = false;
|
||||
maintenance_window_start = 1;
|
||||
lost_password_link = "disabled";
|
||||
sharing.enable_share_mail = true;
|
||||
oidc_login_provider_url = "https://auth.${domain}";
|
||||
oidc_login_client_id = "nextcloud";
|
||||
oidc_login_button_text = "Log in with Authelia";
|
||||
oidc_login_auto_redirect = false;
|
||||
oidc_login_proxy_ldap = true;
|
||||
oidc_login_attributes = {
|
||||
id = "preferred_username";
|
||||
name = "name";
|
||||
mail = "email";
|
||||
groups = "groups";
|
||||
ldap_uid = "email";
|
||||
};
|
||||
oidc_login_scope = "openid profile email groups";
|
||||
default_phone_region = "AT";
|
||||
};
|
||||
};
|
||||
|
||||
environment.systemPackages = [ pkgs.cifs-utils ];
|
||||
fileSystems."/var/lib/nextcloud/data" = {
|
||||
device = "//u428777.your-storagebox.de/u428777-sub2/";
|
||||
fsType = "cifs";
|
||||
options = let
|
||||
automount_opts = "x-systemd.automount,noauto,x-systemd.idle-timeout=60,x-systemd.device-timeout=5s,x-systemd.mount-timeout=5s,user,users,file_mode=0770,dir_mode=0770";
|
||||
in ["${automount_opts},credentials=${config.sops.secrets.nextcloud-smb-credentials.path},uid=992,gid=992"];
|
||||
};
|
||||
|
||||
services.nginx.virtualHosts.${config.services.nextcloud.hostName} = {
|
||||
forceSSL = true;
|
||||
enableACME = true;
|
||||
acmeRoot = null;
|
||||
};
|
||||
|
||||
services.mysql = {
|
||||
ensureUsers = [
|
||||
{
|
||||
name = "nextcloud";
|
||||
ensurePermissions = {
|
||||
"nextcloud.*" = "ALL PRIVILEGES";
|
||||
};
|
||||
}
|
||||
];
|
||||
ensureDatabases = [ "nextcloud" ];
|
||||
};
|
||||
|
||||
services.mysqlBackup.databases = [ "nextcloud" ];
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
{ config, pkgs, ... }:
|
||||
let
|
||||
updateLdapSettings = pkgs.writeText "nextcloud-update-ldap-settings.sql" (builtins.readFile ./update-ldap-settings.sql);
|
||||
in {
|
||||
|
||||
sops.secrets.nextcloud-ldap-password.owner = "nextcloud";
|
||||
|
||||
systemd.services."nextcloud-update-ldap-settings" = {
|
||||
enable = true;
|
||||
description = "My custom service";
|
||||
after = [ "nextcloud-setup.service" ];
|
||||
script = let
|
||||
updateLdapSettings = pkgs.writeText "nextcloud-update-ldap-settings.sql" (builtins.readFile ./update-ldap-settings.sql);
|
||||
in ''
|
||||
ldappass=$(base64 -w 0 ${config.sops.secrets.nextcloud-ldap-password.path})
|
||||
${pkgs.mysql}/bin/mysql -u nextcloud -e "INSERT INTO oc_appconfig (appid, configkey, configvalue, type, lazy) VALUES ('user_ldap', 's01ldap_agent_password', '$ldappass', 2, 0) ON DUPLICATE KEY UPDATE configvalue = '$ldappass';" nextcloud
|
||||
${pkgs.mysql}/bin/mysql -u nextcloud nextcloud < ${updateLdapSettings}
|
||||
'';
|
||||
serviceConfig = {
|
||||
Type = "exec";
|
||||
User = "nextcloud";
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
nextcloud-adminpass: ENC[AES256_GCM,data:WJA7+5XqLK2eYefCviHqvHwqYPy9yfN+/3j5RTF0edrw41oB/wC5JWYejK2FzMkjkXZM0BUQ6waE3PCal3Ebqvzt/ZyC8Pwm8Z+PuMuXFx/6fQLJDxHALXH03GWAzNhUZpcZUYoNtu+uwaROg/4ZVNRu3IXxw+b2DWN65EaMO48=,iv:arkUgibmZQuaiCwYg6NBrMHZXUCLY2y/XiuVjB450ag=,tag:RH6r8nJPU24qq/EUC3jQ/A==,type:str]
|
||||
sops:
|
||||
kms: []
|
||||
gcp_kms: []
|
||||
azure_kv: []
|
||||
hc_vault: []
|
||||
age:
|
||||
- recipient: age16veg3fmvpfm7a89a9fc8dvvsxmsthlm70nfxqspr6t8vnf9wkcwsvdq38d
|
||||
enc: |
|
||||
-----BEGIN AGE ENCRYPTED FILE-----
|
||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB0VmR4THNkUGpvVHB6WWtw
|
||||
WkQ1dlc3R0FWaXpVZ29Sd2g1ZWJzYUFQWHdFCndkUWxqZEdIQlBnSDluN2NEWmZG
|
||||
VndCbXlqV3p0ZnYwcFhjeGZVa09xcW8KLS0tIHVnc2RPWTF1b2NvWVp3OEFwVDZk
|
||||
V0FWOXhSbXQyd0JmVEVpdG9IeXlsQ1UKFxGluq+uOgkA7UUa6/4ZErEPRgQQ5cXS
|
||||
PdB5Et5f02RWBRAUtGEE0UrLiINlIFvFAIr3PKctNVc8/Ovf/jGojg==
|
||||
-----END AGE ENCRYPTED FILE-----
|
||||
- recipient: age1v6p8dan2t3w9h94fz4flldl32082j3s9x6zqq7u5j66keth9aphsd6pvch
|
||||
enc: |
|
||||
-----BEGIN AGE ENCRYPTED FILE-----
|
||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB0RnRPK0Y4ekRiYS9xdGs0
|
||||
ZE5oT1FIWmlySERMbDAyQXlHNDJnQ2Q2dkVvCjNQSGlyQXlzUXAzV0wrNHppUFY4
|
||||
a3k4Y2VtQ1Z4UjVqcnQ4MXhjSzJoM0UKLS0tIHBORnVoSHlJVnpjcmdZVTA1NHhF
|
||||
dHVTWnpXTnNNc0l1M3J6enFBdUwwNWcK80nKzyIrrKaEa0naFsnuie+732hMZQUg
|
||||
IAU9V7/bZiDItTUVdATDjjNBiXnMgDB73SqHhuyIDD+VhDkVUBhjWw==
|
||||
-----END AGE ENCRYPTED FILE-----
|
||||
- recipient: age1y6lvl5jkwc47p5ae9yz9j9kuwhy7rtttua5xhygrgmr7ehd49svsszyt42
|
||||
enc: |
|
||||
-----BEGIN AGE ENCRYPTED FILE-----
|
||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBVdDduRUZOS2VEUldmRFRS
|
||||
QUVxeUVWRERSQ2ZkdnV1ekw4SVVFSzZvUFN3CkQrRnBQQzlnL2xtcFpVd0xiQmda
|
||||
NFZnQmhxcm1xUnVZY3l2eHp6Sjl4a0UKLS0tIG1maDNiRW44VmJDSlk2eWRQcHB2
|
||||
ZHpwQURoNGhuOWJPUkFpc0RSaHFBM0UKW4lMlcxC5+Hpm6DO3wwco41kJsfuWP33
|
||||
+2qhmnwt8mXWxAVxNreQQ0YQDliBnQR3uUny7hWyfrIkeQzOBLBrOw==
|
||||
-----END AGE ENCRYPTED FILE-----
|
||||
lastmodified: "2023-08-18T17:47:34Z"
|
||||
mac: ENC[AES256_GCM,data:bm/lHsobqvZSzk9crPmf8vc2idN3h/HOpQab7n7N6vtEY0QpMTv+6K7YERBD7T9oIxSNtcLNOcw6Rr2w9Cd1cq+W0azPA2dxd6/crq6rbhAgld/MipemP+YfdENxRrdyastk7P3FWyHZzhKlhem/ft0lpeiJg5NWRjA8IkLSDZc=,iv:W4cYC/e1CO5nsLx5yOaH0vGJ7fAx5bAH9acJShciHcI=,tag:whYqwogQMPPklHqoyhuL8g==,type:str]
|
||||
pgp: []
|
||||
unencrypted_suffix: _unencrypted
|
||||
version: 3.7.3
|
||||
@@ -1,83 +0,0 @@
|
||||
INSERT IGNORE INTO oc_appconfig (appid, configkey, configvalue, type, lazy)
|
||||
VALUES
|
||||
("user_ldap", "background_sync_interval", "43200", 2, 0),
|
||||
("user_ldap", "background_sync_offset", "0", 2, 0),
|
||||
("user_ldap", "background_sync_prefix", "s01", 2, 0),
|
||||
("user_ldap", "cleanUpJobOffset", "0", 2, 0),
|
||||
("user_ldap", "enabled", "yes", 2, 0),
|
||||
("user_ldap", "installed_version", "1.20.0", 2, 0),
|
||||
("user_ldap", "types", "authentication", 2, 0),
|
||||
("user_ldap", "s01_lastChange", "1729585245", 2, 0),
|
||||
("user_ldap", "s01has_memberof_filter_support", "1", 2, 0),
|
||||
("user_ldap", "s01home_folder_naming_rule", "", 2, 0),
|
||||
("user_ldap", "s01last_jpegPhoto_lookup", "0", 2, 0),
|
||||
("user_ldap", "s01ldap_admin_group", "admin_2", 2, 0),
|
||||
("user_ldap", "s01ldap_attr_address", "", 2, 0),
|
||||
("user_ldap", "s01ldap_attr_biography", "", 2, 0),
|
||||
("user_ldap", "s01ldap_attr_fediverse", "", 2, 0),
|
||||
("user_ldap", "s01ldap_attr_headline", "", 2, 0),
|
||||
("user_ldap", "s01ldap_attr_organisation", "", 2, 0),
|
||||
("user_ldap", "s01ldap_attr_phone", "", 2, 0),
|
||||
("user_ldap", "s01ldap_attr_role", "", 2, 0),
|
||||
("user_ldap", "s01ldap_attr_twitter", "", 2, 0),
|
||||
("user_ldap", "s01ldap_attr_website", "", 2, 0),
|
||||
("user_ldap", "s01ldap_attributes_for_group_search", "", 2, 0),
|
||||
("user_ldap", "s01ldap_attributes_for_user_search", "", 2, 0),
|
||||
("user_ldap", "s01ldap_background_host", "", 2, 0),
|
||||
("user_ldap", "s01ldap_background_port", "", 2, 0),
|
||||
("user_ldap", "s01ldap_backup_host", "", 2, 0),
|
||||
("user_ldap", "s01ldap_backup_port", "636", 2, 0),
|
||||
("user_ldap", "s01ldap_base", "dc=social-grow,dc=tech", 2, 0),
|
||||
("user_ldap", "s01ldap_base_groups", "cn=cloud,ou=groups,dc=social-grow,dc=tech", 2, 0),
|
||||
("user_ldap", "s01ldap_base_users", "ou=users,dc=social-grow,dc=tech", 2, 0),
|
||||
("user_ldap", "s01ldap_cache_ttl", "600", 2, 0),
|
||||
("user_ldap", "s01ldap_configuration_active", "1", 2, 0),
|
||||
("user_ldap", "s01ldap_connection_timeout", "15", 2, 0),
|
||||
("user_ldap", "s01ldap_default_ppolicy_dn", "", 2, 0),
|
||||
("user_ldap", "s01ldap_display_name", "cn", 2, 0),
|
||||
("user_ldap", "s01ldap_dn", "cn=cloud,ou=system,ou=users,dc=social-grow,dc=tech", 2, 0),
|
||||
("user_ldap", "s01ldap_dynamic_group_member_url", "", 2, 0),
|
||||
("user_ldap", "s01ldap_email_attr", "mail", 2, 0),
|
||||
("user_ldap", "s01ldap_experienced_admin", "0", 2, 0),
|
||||
("user_ldap", "s01ldap_expert_username_attr", "mail", 2, 0),
|
||||
("user_ldap", "s01ldap_expert_uuid_group_attr", "", 2, 0),
|
||||
("user_ldap", "s01ldap_expert_uuid_user_attr", "mail", 2, 0),
|
||||
("user_ldap", "s01ldap_ext_storage_home_attribute", "", 2, 0),
|
||||
("user_ldap", "s01ldap_gid_number", "gidNumber", 2, 0),
|
||||
("user_ldap", "s01ldap_group_display_name", "cn", 2, 0),
|
||||
("user_ldap", "s01ldap_group_filter", "(objectClass=groupOfNames)", 2, 0),
|
||||
("user_ldap", "s01ldap_group_filter_mode", "1", 2, 0),
|
||||
("user_ldap", "s01ldap_group_member_assoc_attribute", "member", 2, 0),
|
||||
("user_ldap", "s01ldap_groupfilter_groups", "", 2, 0),
|
||||
("user_ldap", "s01ldap_groupfilter_objectclass", "", 2, 0),
|
||||
("user_ldap", "s01ldap_host", "ldaps://ldap.social-grow.tech", 2, 0),
|
||||
("user_ldap", "s01ldap_login_filter", "(&(objectclass=inetOrgPerson)(owncloudQuota=*)(mail=%uid))", 2, 0),
|
||||
("user_ldap", "s01ldap_login_filter_mode", "1", 2, 0),
|
||||
("user_ldap", "s01ldap_loginfilter_attributes", "", 2, 0),
|
||||
("user_ldap", "s01ldap_loginfilter_email", "0", 2, 0),
|
||||
("user_ldap", "s01ldap_loginfilter_username", "1", 2, 0),
|
||||
("user_ldap", "s01ldap_mark_remnants_as_disabled", "0", 2, 0),
|
||||
("user_ldap", "s01ldap_matching_rule_in_chain_state", "unknown", 2, 0),
|
||||
("user_ldap", "s01ldap_nested_groups", "0", 2, 0),
|
||||
("user_ldap", "s01ldap_override_main_server", "", 2, 0),
|
||||
("user_ldap", "s01ldap_paging_size", "500", 2, 0),
|
||||
("user_ldap", "s01ldap_port", "636", 2, 0),
|
||||
("user_ldap", "s01ldap_quota_attr", "owncloudQuota", 2, 0),
|
||||
("user_ldap", "s01ldap_quota_def", "1GB", 2, 0),
|
||||
("user_ldap", "s01ldap_tls", "0", 2, 0),
|
||||
("user_ldap", "s01ldap_turn_off_cert_check", "0", 2, 0),
|
||||
("user_ldap", "s01ldap_turn_on_pwd_change", "0", 2, 0),
|
||||
("user_ldap", "s01ldap_user_avatar_rule", "default", 2, 0),
|
||||
("user_ldap", "s01ldap_user_display_name_2", "", 2, 0),
|
||||
("user_ldap", "s01ldap_user_filter_mode", "1", 2, 0),
|
||||
("user_ldap", "s01ldap_userfilter_groups", "", 2, 0),
|
||||
("user_ldap", "s01ldap_userfilter_objectclass", "person", 2, 0),
|
||||
("user_ldap", "s01ldap_userlist_filter", "(&(objectclass=inetOrgPerson)(owncloudQuota=*))", 2, 0),
|
||||
("user_ldap", "s01use_memberof_to_detect_membership", "1", 2, 0)
|
||||
ON DUPLICATE KEY UPDATE
|
||||
appid = VALUES(appid),
|
||||
configkey = VALUES(configkey),
|
||||
configvalue = VALUES(configvalue),
|
||||
type = VALUES(type),
|
||||
lazy = VALUES(lazy);
|
||||
|
||||
@@ -1,320 +0,0 @@
|
||||
{ config, ... }:
|
||||
{
|
||||
sops.secrets.alertmanager = { };
|
||||
sops.secrets.hass-token.owner = "prometheus";
|
||||
|
||||
# imports = [
|
||||
# ./matrix-alertmanager.nix
|
||||
# ./irc-alertmanager.nix
|
||||
# ./rules.nix
|
||||
# ];
|
||||
|
||||
services.prometheus = {
|
||||
webExternalUrl = "https://prometheus.cloonar.com";
|
||||
alertmanagers = [
|
||||
{
|
||||
static_configs = [
|
||||
{
|
||||
targets = [ "localhost:9093" ];
|
||||
}
|
||||
];
|
||||
}
|
||||
];
|
||||
rules = [
|
||||
''
|
||||
ALERT node_down
|
||||
IF up == 0
|
||||
FOR 5m
|
||||
LABELS {
|
||||
severity="page"
|
||||
}
|
||||
ANNOTATIONS {
|
||||
summary = "{{$labels.alias}}: Node is down.",
|
||||
description = "{{$labels.alias}} has been down for more than 5 minutes."
|
||||
}
|
||||
ALERT node_systemd_service_failed
|
||||
IF node_systemd_unit_state{state="failed"} == 1
|
||||
FOR 4m
|
||||
LABELS {
|
||||
severity="page"
|
||||
}
|
||||
ANNOTATIONS {
|
||||
summary = "{{$labels.alias}}: Service {{$labels.name}} failed to start.",
|
||||
description = "{{$labels.alias}} failed to (re)start service {{$labels.name}}."
|
||||
}
|
||||
ALERT node_filesystem_full_90percent
|
||||
IF sort(node_filesystem_free{device!="ramfs"} < node_filesystem_size{device!="ramfs"} * 0.1) / 1024^3
|
||||
FOR 5m
|
||||
LABELS {
|
||||
severity="page"
|
||||
}
|
||||
ANNOTATIONS {
|
||||
summary = "{{$labels.alias}}: Filesystem is running out of space soon.",
|
||||
description = "{{$labels.alias}} device {{$labels.device}} on {{$labels.mountpoint}} got less than 10% space left on its filesystem."
|
||||
}
|
||||
ALERT node_filesystem_full_in_4h
|
||||
IF predict_linear(node_filesystem_free{device!="ramfs"}[1h], 4*3600) <= 0
|
||||
FOR 5m
|
||||
LABELS {
|
||||
severity="page"
|
||||
}
|
||||
ANNOTATIONS {
|
||||
summary = "{{$labels.alias}}: Filesystem is running out of space in 4 hours.",
|
||||
description = "{{$labels.alias}} device {{$labels.device}} on {{$labels.mountpoint}} is running out of space of in approx. 4 hours"
|
||||
}
|
||||
ALERT node_filedescriptors_full_in_3h
|
||||
IF predict_linear(node_filefd_allocated[1h], 3*3600) >= node_filefd_maximum
|
||||
FOR 20m
|
||||
LABELS {
|
||||
severity="page"
|
||||
}
|
||||
ANNOTATIONS {
|
||||
summary = "{{$labels.alias}} is running out of available file descriptors in 3 hours.",
|
||||
description = "{{$labels.alias}} is running out of available file descriptors in approx. 3 hours"
|
||||
}
|
||||
ALERT node_load1_90percent
|
||||
IF node_load1 / on(alias) count(node_cpu{mode="system"}) by (alias) >= 0.9
|
||||
FOR 1h
|
||||
LABELS {
|
||||
severity="page"
|
||||
}
|
||||
ANNOTATIONS {
|
||||
summary = "{{$labels.alias}}: Running on high load.",
|
||||
description = "{{$labels.alias}} is running with > 90% total load for at least 1h."
|
||||
}
|
||||
ALERT node_cpu_util_90percent
|
||||
IF 100 - (avg by (alias) (irate(node_cpu{mode="idle"}[5m])) * 100) >= 90
|
||||
FOR 1h
|
||||
LABELS {
|
||||
severity="page"
|
||||
}
|
||||
ANNOTATIONS {
|
||||
summary = "{{$labels.alias}}: High CPU utilization.",
|
||||
description = "{{$labels.alias}} has total CPU utilization over 90% for at least 1h."
|
||||
}
|
||||
ALERT node_ram_using_90percent
|
||||
IF node_memory_MemFree + node_memory_Buffers + node_memory_Cached < node_memory_MemTotal * 0.1
|
||||
FOR 30m
|
||||
LABELS {
|
||||
severity="page"
|
||||
}
|
||||
ANNOTATIONS {
|
||||
summary="{{$labels.alias}}: Using lots of RAM.",
|
||||
description="{{$labels.alias}} is using at least 90% of its RAM for at least 30 minutes now.",
|
||||
}
|
||||
ALERT node_swap_using_80percent
|
||||
IF node_memory_SwapTotal - (node_memory_SwapFree + node_memory_SwapCached) > node_memory_SwapTotal * 0.8
|
||||
FOR 10m
|
||||
LABELS {
|
||||
severity="page"
|
||||
}
|
||||
ANNOTATIONS {
|
||||
summary="{{$labels.alias}}: Running out of swap soon.",
|
||||
description="{{$labels.alias}} is using 80% of its swap space for at least 10 minutes now."
|
||||
}
|
||||
ALERT homeassistant = {
|
||||
IF homeassistant_entity_available{domain="persistent_notification", entity!~"persistent_notification.http_login|persistent_notification.recorder_database_migration"} >= 0
|
||||
ANNOTATIONS {
|
||||
description="homeassistant notification {{$labels.entity}} ({{$labels.friendly_name}}): {{$value}}"
|
||||
}
|
||||
|
||||
ALERT gitea
|
||||
IF rate(promhttp_metric_handler_requests_total{job="gitea", code="500"}[5m]) > 3
|
||||
ANNOTATIONS {
|
||||
description="{{$labels.instance}}: gitea instances error rate went up: {{$value}} errors in 5 minutes"
|
||||
}
|
||||
''
|
||||
];
|
||||
scrapeConfigs = [
|
||||
{
|
||||
job_name = "telegraf";
|
||||
scrape_interval = "60s";
|
||||
metrics_path = "/metrics";
|
||||
static_configs = [
|
||||
{
|
||||
targets = [
|
||||
"web-01.cloonar.com:9273"
|
||||
];
|
||||
labels.host = "web-01.cloonar.com";
|
||||
}
|
||||
{
|
||||
targets = [
|
||||
"web-arm.cloonar.com:9273"
|
||||
];
|
||||
labels.host = "web-arm.cloonar.com";
|
||||
}
|
||||
{
|
||||
targets = [
|
||||
"fw.cloonar.com:9273"
|
||||
];
|
||||
labels.host = "fw.cloonar.com";
|
||||
}
|
||||
{
|
||||
targets = [
|
||||
"mail.cloonar.com:9273"
|
||||
];
|
||||
labels.host = "mail.cloonar.com";
|
||||
}
|
||||
{
|
||||
targets = [
|
||||
"git.cloonar.com:9273"
|
||||
];
|
||||
labels.host = "git.cloonar.com";
|
||||
}
|
||||
{
|
||||
targets = [
|
||||
"home-assistant.cloonar.com:9273"
|
||||
];
|
||||
labels.host = "home-assistant.cloonar.com";
|
||||
}
|
||||
{
|
||||
targets = map (host: "${host}.cloonar.com:9273") [
|
||||
"web-01"
|
||||
"web-arm"
|
||||
"fw"
|
||||
"mail"
|
||||
"git"
|
||||
"home-assistant"
|
||||
];
|
||||
|
||||
labels.org = "cloonar";
|
||||
}
|
||||
];
|
||||
}
|
||||
{
|
||||
job_name = "homeassistant";
|
||||
scrape_interval = "60s";
|
||||
metrics_path = "/api/prometheus";
|
||||
|
||||
authorization.credentials_file = config.sops.secrets.hass-token.path;
|
||||
|
||||
scheme = "https";
|
||||
static_configs = [
|
||||
{
|
||||
targets = [
|
||||
"home-assistant.cloonar.com:443"
|
||||
];
|
||||
}
|
||||
];
|
||||
}
|
||||
{
|
||||
job_name = "gitea";
|
||||
scrape_interval = "60s";
|
||||
metrics_path = "/metrics";
|
||||
|
||||
scheme = "https";
|
||||
static_configs = [
|
||||
{
|
||||
targets = [
|
||||
"git.cloonar.com:443"
|
||||
];
|
||||
}
|
||||
];
|
||||
}
|
||||
];
|
||||
};
|
||||
# services.prometheus.alertmanager = {
|
||||
# enable = true;
|
||||
# environmentFile = config.sops.secrets.alertmanager.path;
|
||||
# webExternalUrl = "https://alertmanager.cloonar.com";
|
||||
# listenAddress = "[::1]";
|
||||
# configuration = {
|
||||
# global = {
|
||||
# # The smarthost and SMTP sender used for mail notifications.
|
||||
# smtp_smarthost = "mail.cloonar.com:587";
|
||||
# smtp_from = "alertmanager@cloonar.com";
|
||||
# smtp_auth_username = "alertmanager@cloonar.com";
|
||||
# smtp_auth_password = "$SMTP_PASSWORD";
|
||||
# };
|
||||
# route = {
|
||||
# receiver = "default";
|
||||
# routes = [
|
||||
# {
|
||||
# group_by = [ "host" ];
|
||||
# match_re.org = "krebs";
|
||||
# group_wait = "5m";
|
||||
# group_interval = "5m";
|
||||
# repeat_interval = "4h";
|
||||
# receiver = "krebs";
|
||||
# }
|
||||
# {
|
||||
# group_by = [ "host" ];
|
||||
# match_re.org = "nix-community";
|
||||
# group_wait = "5m";
|
||||
# group_interval = "5m";
|
||||
# repeat_interval = "4h";
|
||||
# receiver = "nix-community";
|
||||
# }
|
||||
# {
|
||||
# group_by = [ "host" ];
|
||||
# match_re.org = "clan-lol";
|
||||
# group_wait = "5m";
|
||||
# group_interval = "5m";
|
||||
# repeat_interval = "4h";
|
||||
# receiver = "clan-lol";
|
||||
# }
|
||||
# {
|
||||
# group_by = [ "host" ];
|
||||
# group_wait = "30s";
|
||||
# group_interval = "2m";
|
||||
# repeat_interval = "2h";
|
||||
# receiver = "all";
|
||||
# }
|
||||
# ];
|
||||
# };
|
||||
# receivers = [
|
||||
# {
|
||||
# name = "krebs";
|
||||
# webhook_configs = [
|
||||
# {
|
||||
# url = "http://127.0.0.1:9223/";
|
||||
# max_alerts = 5;
|
||||
# }
|
||||
# ];
|
||||
# }
|
||||
# #{
|
||||
# # name = "numtide";
|
||||
# # slack_configs = [
|
||||
# # {
|
||||
# # token = "$SLACK_TOKEN";
|
||||
# # api_url = "https://";
|
||||
# # }
|
||||
# # ];
|
||||
# #}
|
||||
# {
|
||||
# name = "nix-community";
|
||||
# webhook_configs = [
|
||||
# {
|
||||
# url = "http://localhost:9088/alert";
|
||||
# max_alerts = 5;
|
||||
# }
|
||||
# ];
|
||||
# }
|
||||
# {
|
||||
# name = "clan-lol";
|
||||
# webhook_configs = [
|
||||
# # TODO
|
||||
# #{
|
||||
# # url = "http://localhost:4050/services/hooks/YWxlcnRtYW5hZ2VyX3NlcnZpY2U";
|
||||
# # max_alerts = 5;
|
||||
# #}
|
||||
# ];
|
||||
# }
|
||||
# {
|
||||
# name = "all";
|
||||
# pushover_configs = [
|
||||
# {
|
||||
# user_key = "$PUSHOVER_USER_KEY";
|
||||
# token = "$PUSHOVER_TOKEN";
|
||||
# priority = "0";
|
||||
# }
|
||||
# ];
|
||||
# }
|
||||
# {
|
||||
# name = "default";
|
||||
# }
|
||||
# ];
|
||||
# };
|
||||
# };
|
||||
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
{ config, pkgs, ... }:
|
||||
|
||||
{
|
||||
virtualisation = {
|
||||
podman.enable = true;
|
||||
oci-containers.containers = {
|
||||
rustdesk-server = {
|
||||
image = "rustdesk/rustdesk-server-s6:1";
|
||||
volumes = [ "/var/lib/rustdesk-server:/data" ];
|
||||
environment = {
|
||||
RELAY = "rustdesk.cloonar.com:21117";
|
||||
};
|
||||
ports = [
|
||||
"21115:21115"
|
||||
"21116:21116"
|
||||
"21116:21116/udp"
|
||||
"21118:21118"
|
||||
"21117:21117"
|
||||
"21119:21119"
|
||||
];
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
users.users.rustdesk-server = {
|
||||
isSystemUser = true;
|
||||
group = "rustdesk-server";
|
||||
home = "/var/lib/rustdesk-server";
|
||||
createHome = true;
|
||||
};
|
||||
users.groups.rustdesk-server = { };
|
||||
users.groups.docker.members = [ "rustdesk-server" ];
|
||||
|
||||
networking.firewall = {
|
||||
enable = true;
|
||||
allowedTCPPorts = [ 5000 21115 21116 21117 21118 21119 ];
|
||||
allowedUDPPorts = [ 21116 ];
|
||||
};
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
{ config, ... }:
|
||||
let
|
||||
configure_prom = builtins.toFile "prometheus.yml" ''
|
||||
scrape_configs:
|
||||
- job_name: 'server'
|
||||
stream_parse: true
|
||||
static_configs:
|
||||
- targets:
|
||||
- ${config.networking.hostName}:9100
|
||||
'';
|
||||
in {
|
||||
services.prometheus.exporters.node.enable = true;
|
||||
|
||||
sops.secrets.victoria-nginx-password.owner = "nginx";
|
||||
|
||||
services.victoriametrics = {
|
||||
enable = true;
|
||||
extraOptions = [
|
||||
"-promscrape.config=${configure_prom}"
|
||||
];
|
||||
};
|
||||
|
||||
services.nginx.virtualHosts."victoria-server.cloonar.com" = {
|
||||
forceSSL = true;
|
||||
enableACME = true;
|
||||
acmeRoot = null;
|
||||
locations."/" = {
|
||||
proxyWebsockets = true;
|
||||
extraConfig = ''
|
||||
auth_basic "Victoria password";
|
||||
auth_basic_user_file ${config.sops.secrets.victoria-nginx-password.path};
|
||||
|
||||
proxy_read_timeout 1800s;
|
||||
proxy_redirect off;
|
||||
proxy_connect_timeout 1600s;
|
||||
|
||||
access_log off;
|
||||
proxy_pass http://127.0.0.1:8428;
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,328 +0,0 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.webstack;
|
||||
|
||||
instanceOpts = { name, ... }:
|
||||
{
|
||||
options = {
|
||||
user = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
description = lib.mdDoc ''
|
||||
User of the typo3 instance. Defaults to attribute name in instances.
|
||||
'';
|
||||
example = "example.org";
|
||||
};
|
||||
|
||||
domain = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
description = lib.mdDoc ''
|
||||
Domain of the typo3 instance. Defaults to attribute name in instances.
|
||||
'';
|
||||
example = "example.org";
|
||||
};
|
||||
|
||||
domainAliases = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [];
|
||||
example = [ "www.example.org" "example.org" ];
|
||||
description = lib.mdDoc ''
|
||||
Additional domains served by this typo3 instance.
|
||||
'';
|
||||
};
|
||||
|
||||
phpPackage = mkOption {
|
||||
type = types.package;
|
||||
example = literalExpression "pkgs.php";
|
||||
description = lib.mdDoc ''
|
||||
Which PHP package to use in this typo3 instance.
|
||||
'';
|
||||
};
|
||||
|
||||
phpOptions = mkOption {
|
||||
type = types.lines;
|
||||
default = "";
|
||||
description = ''
|
||||
"Options appended to the PHP configuration file {file}`php.ini` used for this PHP-FPM pool."
|
||||
'';
|
||||
};
|
||||
|
||||
enableMysql = mkEnableOption (lib.mdDoc "MySQL Database");
|
||||
enableDefaultLocations = mkEnableOption (lib.mdDoc "Create default nginx location directives") // { default = true; };
|
||||
|
||||
authorizedKeys = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = null;
|
||||
description = lib.mdDoc ''
|
||||
Authorized keys for the typo3 instance ssh user.
|
||||
'';
|
||||
};
|
||||
|
||||
extraConfig = mkOption {
|
||||
type = types.lines;
|
||||
default = ''
|
||||
if (!-e $request_filename) {
|
||||
rewrite ^/(.+)\.(\d+)\.(php|js|css|png|jpg|gif|gzip)$ /$1.$3 last;
|
||||
}
|
||||
'';
|
||||
description = lib.mdDoc ''
|
||||
These lines go to the end of the vhost verbatim.
|
||||
'';
|
||||
};
|
||||
|
||||
locations = mkOption {
|
||||
type = types.attrsOf (types.submodule (import <nixpkgs/nixos/modules/services/web-servers/nginx/location-options.nix> {
|
||||
inherit lib config;
|
||||
}));
|
||||
default = {};
|
||||
example = literalExpression ''
|
||||
{
|
||||
"/" = {
|
||||
proxyPass = "http://localhost:3000";
|
||||
};
|
||||
};
|
||||
'';
|
||||
description = lib.mdDoc "Declarative location config";
|
||||
};
|
||||
|
||||
};
|
||||
};
|
||||
in
|
||||
|
||||
{
|
||||
options.services.webstack = {
|
||||
dataDir = mkOption {
|
||||
type = types.path;
|
||||
default = "/var/www";
|
||||
description = lib.mdDoc ''
|
||||
The data directory for MySQL.
|
||||
|
||||
::: {.note}
|
||||
If left as the default value of `/var/www` this directory will automatically be created before the web
|
||||
server starts, otherwise you are responsible for ensuring the directory exists with appropriate ownership and permissions.
|
||||
:::
|
||||
'';
|
||||
};
|
||||
|
||||
instances = mkOption {
|
||||
type = types.attrsOf (types.submodule instanceOpts);
|
||||
default = {};
|
||||
description = lib.mdDoc "Create vhosts for typo3";
|
||||
example = literalExpression ''
|
||||
{
|
||||
"typo3.example.com" = {
|
||||
domain = "example.com";
|
||||
domainAliases = [ "www.example.com" ];
|
||||
phpPackage = pkgs.php81;
|
||||
authorizedKeys = [
|
||||
"ssh-rsa AZA=="
|
||||
];
|
||||
};
|
||||
};
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
config = {
|
||||
systemd.services = mapAttrs' (instance: instanceOpts:
|
||||
let
|
||||
domain = if instanceOpts.domain != null then instanceOpts.domain else instance;
|
||||
in
|
||||
nameValuePair "phpfpm-${domain}" {
|
||||
serviceConfig = {
|
||||
ProtectHome = lib.mkForce "tmpfs";
|
||||
BindPaths = "BindPaths=/var/www/${domain}:/var/www/${domain}";
|
||||
};
|
||||
}
|
||||
) cfg.instances;
|
||||
|
||||
services.phpfpm.pools = mapAttrs' (instance: instanceOpts:
|
||||
let
|
||||
domain = if instanceOpts.domain != null then instanceOpts.domain else instance;
|
||||
user = if instanceOpts.user != null
|
||||
then instanceOps.user
|
||||
else builtins.replaceStrings ["." "-"] ["_" "_"] domain;
|
||||
in
|
||||
nameValuePair domain {
|
||||
user = user;
|
||||
settings = {
|
||||
"listen.owner" = config.services.nginx.user;
|
||||
"pm" = "dynamic";
|
||||
"pm.max_children" = 32;
|
||||
"pm.max_requests" = 500;
|
||||
"pm.start_servers" = 2;
|
||||
"pm.min_spare_servers" = 2;
|
||||
"pm.max_spare_servers" = 5;
|
||||
"php_admin_value[error_log]" = "syslog";
|
||||
"php_admin_value[max_execution_time]" = 240;
|
||||
"php_admin_value[max_input_vars]" = 1500;
|
||||
"access.log" = "/var/log/$pool.access.log";
|
||||
};
|
||||
phpOptions = instanceOpts.phpOptions;
|
||||
phpPackage = instanceOpts.phpPackage;
|
||||
phpEnv."PATH" = pkgs.lib.makeBinPath [ instanceOpts.phpPackage ];
|
||||
}
|
||||
) cfg.instances;
|
||||
|
||||
};
|
||||
|
||||
|
||||
config.services.nginx.virtualHosts = mapAttrs' (instance: instanceOpts:
|
||||
let
|
||||
domain = if instanceOpts.domain != null then instanceOpts.domain else instance;
|
||||
user = if instanceOpts.user != null
|
||||
then instanceOps.user
|
||||
else builtins.replaceStrings ["." "-"] ["_" "_"] domain;
|
||||
in
|
||||
nameValuePair domain {
|
||||
forceSSL = true;
|
||||
enableACME = true;
|
||||
acmeRoot = null;
|
||||
root = cfg.dataDir + "/" + domain + "/public";
|
||||
|
||||
locations = lib.mkMerge [
|
||||
instanceOpts.locations
|
||||
(mkIf instanceOpts.enableDefaultLocations {
|
||||
"/favicon.ico".extraConfig = ''
|
||||
log_not_found off;
|
||||
access_log off;
|
||||
'';
|
||||
|
||||
# Cache.appcache, your document html and data
|
||||
"~* \\.(?:manifest|appcache|html?|xml|json)$".extraConfig = ''
|
||||
expires -1;
|
||||
# access_log logs/static.log; # I don't usually include a static log
|
||||
'';
|
||||
|
||||
"~* \\.(jpe?g|png)$".extraConfig = ''
|
||||
set $red Z;
|
||||
|
||||
if ($http_accept ~* "webp") {
|
||||
set $red A;
|
||||
}
|
||||
|
||||
if (-f $document_root/webp/$request_uri.webp) {
|
||||
set $red "''${red}B";
|
||||
}
|
||||
|
||||
if ($red = "AB") {
|
||||
add_header Vary Accept;
|
||||
rewrite ^ /webp/$request_uri.webp;
|
||||
}
|
||||
'';
|
||||
|
||||
# Cache Media: images, icons, video, audio, HTC
|
||||
"~* \\.(?:jpg|jpeg|gif|png|webp|ico|cur|gz|svg|svgz|mp4|ogg|ogv|webm|htc|woff2)$".extraConfig = ''
|
||||
expires 1y;
|
||||
access_log off;
|
||||
add_header Cache-Control "public";
|
||||
'';
|
||||
|
||||
# Feed
|
||||
"~* \\.(?:rss|atom)$".extraConfig = ''
|
||||
expires 1h;
|
||||
add_header Cache-Control "public";
|
||||
'';
|
||||
|
||||
# Cache CSS, Javascript, Images, Icons, Video, Audio, HTC, Fonts
|
||||
"~* \\.(?:css|js|jpg|jpeg|gif|png|ico|cur|gz|svg|svgz|mp4|ogg|ogv|webm|htc|woff2)$".extraConfig = ''
|
||||
expires 1y;
|
||||
access_log off;
|
||||
add_header Cache-Control "public";
|
||||
'';
|
||||
|
||||
"/".extraConfig = ''
|
||||
index index.php index.html;
|
||||
try_files $uri $uri/ /index.php$is_args$args;
|
||||
'';
|
||||
})
|
||||
{
|
||||
"~ [^/]\\.php(/|$)".extraConfig = ''
|
||||
fastcgi_split_path_info ^(.+?\.php)(/.*)$;
|
||||
if (!-f $document_root$fastcgi_script_name) {
|
||||
return 404;
|
||||
}
|
||||
include ${pkgs.nginx}/conf/fastcgi_params;
|
||||
include ${pkgs.nginx}/conf/fastcgi.conf;
|
||||
fastcgi_buffer_size 32k;
|
||||
fastcgi_buffers 8 16k;
|
||||
fastcgi_connect_timeout 240s;
|
||||
fastcgi_read_timeout 240s;
|
||||
fastcgi_send_timeout 240s;
|
||||
fastcgi_pass unix:${config.services.phpfpm.pools."${domain}".socket};
|
||||
fastcgi_index index.php;
|
||||
'';
|
||||
}
|
||||
];
|
||||
|
||||
extraConfig = instanceOpts.extraConfig;
|
||||
|
||||
|
||||
# locations = mapAttrs' (location: locationOpts:
|
||||
# nameValuePair location locationOpts) instanceOpts.locations;
|
||||
|
||||
}
|
||||
) cfg.instances;
|
||||
|
||||
config.users.users = mapAttrs' (instance: instanceOpts:
|
||||
let
|
||||
domain = if instanceOpts.domain != null then instanceOpts.domain else instance;
|
||||
user = if instanceOpts.user != null
|
||||
then instanceOps.user
|
||||
else builtins.replaceStrings ["." "-"] ["_" "_"] domain;
|
||||
in
|
||||
nameValuePair user {
|
||||
isNormalUser = true;
|
||||
createHome = true;
|
||||
home = "/var/www/" + domain;
|
||||
homeMode= "770";
|
||||
group = config.services.nginx.group;
|
||||
openssh.authorizedKeys.keys = instanceOpts.authorizedKeys;
|
||||
}
|
||||
) cfg.instances;
|
||||
config.users.groups = mapAttrs' (instance: instanceOpts:
|
||||
let
|
||||
domain = if instanceOpts.domain != null then instanceOpts.domain else instance;
|
||||
user = if instanceOpts.user != null
|
||||
then instanceOps.user
|
||||
else builtins.replaceStrings ["." "-"] ["_" "_"] domain;
|
||||
in nameValuePair user {}) cfg.instances;
|
||||
|
||||
config.services.mysql.ensureUsers = mapAttrsToList (instance: instanceOpts:
|
||||
let
|
||||
domain = if instanceOpts.domain != null then instanceOpts.domain else instance;
|
||||
user = if instanceOpts.user != null
|
||||
then instanceOps.user
|
||||
else builtins.replaceStrings ["." "-"] ["_" "_"] domain;
|
||||
in
|
||||
mkIf instanceOpts.enableMysql {
|
||||
name = user;
|
||||
ensurePermissions = {
|
||||
"${user}.*" = "ALL PRIVILEGES";
|
||||
};
|
||||
}) cfg.instances;
|
||||
|
||||
config.services.mysql.ensureDatabases = mapAttrsToList (instance: instanceOpts:
|
||||
let
|
||||
domain = if instanceOpts.domain != null then instanceOpts.domain else instance;
|
||||
user = if instanceOpts.user != null
|
||||
then instanceOps.user
|
||||
else builtins.replaceStrings ["." "-"] ["_" "_"] domain;
|
||||
in
|
||||
mkIf instanceOpts.enableMysql user
|
||||
) cfg.instances;
|
||||
config.services.mysqlBackup.databases = mapAttrsToList (instance: instanceOpts:
|
||||
let
|
||||
domain = if instanceOpts.domain != null then instanceOpts.domain else instance;
|
||||
user = if instanceOpts.user != null
|
||||
then instanceOps.user
|
||||
else builtins.replaceStrings ["." "-"] ["_" "_"] domain;
|
||||
in
|
||||
mkIf instanceOpts.enableMysql user
|
||||
) cfg.instances;
|
||||
}
|
||||
|
||||
@@ -1,60 +0,0 @@
|
||||
borg-passphrase: ENC[AES256_GCM,data:CnaF4M/fSHNrNUJ7LwZRVp+RpUWpE2Pr1t9edCvkQ8c+ParvFgAcGQOGTpLtAbunUaPZCH2I32qhwgoABVr5TQ==,iv:ZII4SoivJEVHBD5iEHom7MbjeSDqgFUnNNr2T2UGL74=,tag:+O2B+pYl369y+MExxLL20Q==,type:str]
|
||||
borg-ssh-key: ENC[AES256_GCM,data:vhcDNj5m3Ly9YxB7m1m1TFlFegND1K9cPgPFtIGBCHYJnsoYMNYaVoZMekZIyXZkP9UR4aps6pbcQEXcggYiRbUwucdKClJRoRnbYHaS5UVRN1wKhih7iwCaos+OOtnYEP7TxkNwczOyoq2C7iakBUD0tLTkLlyAkBSR/s+BQiq8ad/P09zM9vTK/LDHZPY+TAYLuSmOJyZM+pwzxgvhs15gcAwrio8t3nuZoDXsAsjFKVNfGE4s3cQTPzWIkJ4MJkIkRD3S/avXiXWfUExNggPGigQpa9TJ6OMEeCglu2f4CW+FnlZKP6qfVKR0FOcRuNJkwsZRpDmNHcrEd+l30UbLxbtmVRo+LQIXL8LqPZRyyyTFa0yvQ76jGHtzlGqSHUG8z5oclW4+j+QIjh6SmeBhXGGLanghTRJpi0SOkvp9OAH+gikMDiLU84Aw5udMAMvRiYj0LyfOnPGEotJsbD3c7DZeBy1QtEqbuGNq51mrKF91RjPccdh1b4lo6ScKHQELyc6C8OVvjfVMEo7f,iv:PHVop1XIKvPrhlAt2Kk+NrhQWw0qmkF2wDydwyu6s88=,tag:7vm+Fzf/FyZODCccEgfgXg==,type:str]
|
||||
authelia-jwt-secret: ENC[AES256_GCM,data:txm7218ZPwx14WHvULbT0Wwb/41Zu/uEM7NyNlZPBrp6ahn7cW4DRhV2i3NAQ8pw796mMCsfpDHH2na9uOBmSQ==,iv:f0XCDp+qnS9oU8LiILScVUmUpyj8wDIZYh8ZphtsmqY=,tag:4rHEiAiMurd5yKvnCXnWbA==,type:str]
|
||||
authelia-backend-ldap-password: ENC[AES256_GCM,data:HmPF/BgTH36H0tMry0E0q5YNevsmQc4GnAaHj+D4wScVtoR/6Y/j0XavaLy5VYsVLoNtMX3dJ6UZQ8ECmEkVGQ==,iv:w0p22wo7hgXXpqIV+UqM1+8S4v34Wf2aBPLA68MMrVQ=,tag:QXUbz7kqdL4XhOMfq+6xUw==,type:str]
|
||||
authelia-storage-encryption-key: ENC[AES256_GCM,data:pYhnvNK8yzX97zLQ9sbNMDsICjOZYmunYwb4zIKv+mgMMqZwMtPEnzz42xZEYo0xxoSrXwrr3eqG1dB7isgP+vP7rQF9pbjnVIDOw+vwlDyvnkB2S9+/oeCf7g0FOtLolwV3febdo+0dO2nHIdD4oBAUrhUq64vsft8P3QCkAWc=,iv:Eu28tFG1i/Qj/GtW7EXzqeFPwawxthrc74xqSvpkGHw=,tag:ZK8zbTdyakHddHqorcZ4nQ==,type:str]
|
||||
authelia-session-secret: ENC[AES256_GCM,data:6AhdM13jdD3eEOTdztm8TLBpgqfl4b9R9fvz52wkgIONHRNswuXxRRATlgWS0IFbkWO9O/RC/+dhMUd36R78bNRIdyx33Rsj7g9JOkdLldJe3ofLtn4IL2bsNwHc+9cF5J4VCYSqo4q33FSkqGOpVyf8sQxuWKC6gC5UUqkG7P4=,iv:GqZhovL5eAVYDM/nM2eKcRBamw/E60nIHnT4muJQ1b4=,tag:OZQjy8GGzgkTMR2aqJZlyw==,type:str]
|
||||
authelia-identity-providers-oidc-hmac-secret: ENC[AES256_GCM,data:ljswWCWEemDzFugrt2wZikqmSE7+tTbGiMzfN8rufd0ec/AsZq3CoHNuCcLpBT99/PlUts32XPY0GLvbq4i7vA==,iv:h2RZs4AyrHCnxybe/MNZHRGXHmLvrTFy8J15CUdjpXE=,tag:JbPSKt5YNfnRgd2NKm1rWA==,type:str]
|
||||
authelia-identity-providers-oidc-issuer-certificate-chain: ENC[AES256_GCM,data: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,iv:n0ybHvyZCIDufdJ6VDT+0txXqFKEJg8BX3LvoBvkpmU=,tag:Pdy+Gl2177yVkXNwoLCmzw==,type:str]
|
||||
authelia-identity-providers-oidc-issuer-private-key: ENC[AES256_GCM,data:SWVTYvjgU3SCXfonEkzU4/38AIWferd2/0pDssScj4mJCCBZv5+ZAsc4KtWLZHcv8PlacGn4+mt8BeQLS/QC2Olxt7SPfR0xsJPA9OJWy+Vl3Xdf/RPZzOdQBB2HqH2IPXl7r2n9e3IO60nP6n38FpHQ3JvvitAMVF6nbf3B1tlCKEofqU7efnCOuU1iWWepof2xGnIut6As6EXE0v0aV2fwrZSz7c6vFTs/MtNwfNcsgkUXPOSqDXtotLjblKyTmARMHyP6YDinm+4s2TnHjsrxcXhXEX0VQkzNpLzMivXSKExooymeG/c6zW802hoxjrD9mDJoptlzqT8VkxrWrUtwgznZHcZXyueFyfscBY+3J8s/33WOhnaQ9OEL+ID40dxMDTisVOK3TvTObb2hMFikW3HqcTJQ7eAd+5bZzoFwe+k2SfV5cUSdSAJb6p9LKT4dYT6kKCAABeGEFOxetSt+eyU82kHcYpXwFzuXSrzzLlG260lb8orjOPMRpjq/joblPoBXcw3kUxhkIWKeEmtc7NBnCfdN/Ut0p3EZRinjO6Ms4+4blXhuQPZvHGgdDpPun6EkmrozHGgcIkWDegBOKyMnlV5elXZKW0lJqSc5TpLEIBRN8YcRZOfG3xH+pxrRXqt60OCjLoU27Kd6XqrruTGjnXtr7lEvkBQBgw+jQhCkQ/FFzcNOdKvU4RE5UxhSA0ZnDmn3c5g7r8kqN33+H33EMvU69kA/OQVUle2ttwKfRm3vShVq5V8/gJBFviHaCti3ZyFC6UNragKsR3cWptWvWul905khhn9pVDcey1Y0ycUdmK1voyyrwoD2bjswhq554gbffsHrn4LrccQC33Ei1IUoqVhnNtbpA1Q15qK0AHcWsCdkZz3kFsGVHKqW2xjFBdju59UqbObNU0aAlTSd++jPf5xfSqeMBHuV7/qTBXLkkQsZrrqGYMlb6OpfC/2fXgkwpjGQ3Zp/qh0VYnbspRJvyvX6TbhHNhDKDjrFeOU39NudqqwCl58NXST92WavDeD1nTXXP2S78XrCjZjEZkUaO5r0lztv7eMcrUQca3DQ9ucBRXIc/idX+dFrFnK9+ChT/kvSncK+/Tz4EbwkRNz7OJDjDN6yTxFkvbelUlifE0pj5q1Qd9XsJvoi6tB5j8An2ABZJZluv2Gy8gxo3eY7wmCdia3a0Preizx0U10TMHZY5NEj4FjRSwKkndsXchHOw+VuBcJynEpzu60gEanNDJFCWdctFhJUu0yas4rwRrzeMn5gXGmO4luLiCzXHeFCAmSA8CQQKQ0SMaZ8e8bptj89RFaiaE91YvEw/cpWwYevdvi40hVhOhIqGd4bjOl7tw13nkuPAqUAqCv+wZ8UAUfZEOH+/c5eXspgTd/Y4MAo2JgVQogSiUTZrbkG3mBPq/QLTywMHXBjVVRdI10bHtgN38ljkC1SGw+dbHuZZytMHC2tXa7RiFKX0ko1DG0Jn0U0QyrMoqwUW5wld6QNMIVV9GpqGj7PMHQA4GVfKDgiGfAuEwf9/2cq1cM1dXOTbszYFGuHDuv0GNyQL6vv9A8mqrQF3VaJPM9ipyl3gXlfCN2qrDUi0BatS3qeOcllXHXPpE7xkYNoChtj+xxUKqhbPvoIT8M0Jxgy7D1VQjUBcX/hCbuICkDfWF4vEIX04DOP+BzNvm3Z6zU+6GuhkU/gCZhvoiYZc+mK45YHvKcxQcftiOPwJUAt99OjXbZXBospM14dFnCGi+b9Vh4zj9XlNj46afQc60aCG/dm9l0I/2PnaQikIQdFEnwOgY2lQ7Z1M2VH8AE5AwNn7BYTF6qoCMrMpM5F56KfmysY0yF3E7pjZDkrbLDWhvkafbSdYjyqG/K0eO32X57NVNNro75J/YtacbnaSrnZrHmEAZYRxy2YWdqVhtJ47gc0sg4EebGR5nlU2hBAW9PavlHuCyxl0TMwHB4rrOBpWGt31eQzV6MBFvX1KKFIy1JlCF986+W4v6tN9oUqS132rYp+B9IjAvGkNbreGi1GTJ06tyXdX8ZNAOyRrxo5uDdBey6XrEArJIoXD/jpC6NoQ25EKdfhomw8JnobXk+thyQNGJeQ3W4LQQDeaTGKGhlNzuI0tzAHS0T8nC9abKtuEXyLSRmXhTt1ALgSX6/bgeVH+mXUr2Z3NcCOIRsBkRO7ejlvuh7uPRJbQBvnS+Wz5GSoY1QOxhZvL0/2zYLpejsMkb4Sq0pv9YAFDWDZGS3GZ15e9jIZo3k37YvrUzjbFaNeICBu0R9mr9oNAgM0WAR2JdOeH1UsDEbaUiRjqhUZAvYQJvwcm5fdIRbndkV1OXcLGaIIJAHYla0m8eQGFX09ye5rVwICXOlDIwIMC6fn3mFovXwizOgGG38rmSPKkckzrYcLAdJC4822hRoohzpdDbQNMnX9Mbe64yaR1HV+Ds4Ni+aOXxtotwmMlb6UIQ4gFzkkrHTyvpE4yxp7JiskuvmSgHFOU4IbaohKaqFUZHcrP8Q70ih/cNYRbCMEn4HjFPT0Vl+Fpjnnn0Asq3gHRPCDUU+m9apjFjPSheBAOsz/OFlVVulvtOYRHH9lTyqeoBNb6pxhi3S3+tM8zuJTs85U6gaI2vI9Ih/9BMdpa9HsXM+/UOPwk8mjE57FgiDqcYQNPEXuk5fAK1wvGq38kUlf1BN0e6mJESxgG8j1Oox5+hzGoOemnpbCOBI9Wsbmb8bLQ7zye5NYAMldet/uuD4Jxq7YdlOni0S+V7iEQKpqDRme2kwC8ZjXDLKlRYalVGyz5JpCj7dv+BGDdae1LeD9XHca/NwE+N/t3UAcYGAYBafrVO3q9la4hvvAQtoaQra9yVgJ2C3+lsdWoUepoOuQISXZ12gZl423EWF946UAtr/Pixyb563j4YOLLOAgRBjTJPbUYWqfiMUXHP6FPgWs2rcxqdWY4SRCgqXWP3y82cm4mXMH8K8IEL9edp5Ty6piZuOiC7YWfycvHtzzoki7Zr7tzVHjxFCcSn0SmRYl6vo1nAzg4V8GOO3rzeT9PUPBHmVQDGyAE9igIv6zadAZkk5i64co32XO7OPwDThFgBvOrEB02YRMfSOQ5PfJ7hXLolmnGr+mqGk5yg0+FVT4E7ypT0hFqN6KS/8L8acbrqsivOTimPN/wTMyWK0e6xYYc8I/0LfNZySPCbA1gqNOa+mPx98UtQDlFi93h+rtlBMrmiFYMpR7qJFTlBOesTFisUlpYE0yrrmeDOTuz7eetZ0u7PS3iL6iLEKyYRW9COY3bOKtDZPuhANwV5lXVIK76XQe37/lVKgKuBbx96AzKIKBgi1QjZhQLntKRf/RW9lAHFRGNpgoV+PO3Ydt59Olzl8WNUTgAWszI7AL9FZikoIQKrtUi1c1uvEt6oKgeM+X6nVLAyhlS+5HbEBEVHLNOi1t98i0cV+sNWsOqE4Y9LPqJCHIWX71/PEFFfaYpOL2kI1NdyXksKfuiDr6P9ZTkA/pMO9rjsBaei0IKqSmV9z4UE28U7NIzYW7Il4aZlIXdt9O3h+u8aMwRhU1RkcFnaX+EZGSXxWMz69iwbdRYAJhLBNfkz0RZKnMkTpJL1/w2wWRGt15kmOrOnuSqmHECpOfX9Jxs8TRGdgMo+De/c6P8XW7TgyeGm778c5+CempFX/hRY1jie6G7A9pNm6IYBLiEI8l5ldR/HXydCg8ZGEm0cLyqEosDjs30h77+OMBmqMDvUflZ765UPp4bH064/KrmHLibXXh0pbVrU4JDcGZQUBkXsN/RaRwwMq/JUgjUmq/UQsWXvwmGvHTVEHtMlozl8A8QR156XvhCbS121f2Z7JAdSxlU/XePlNiIkTsV4kd6n7VI+doWjDeUa8KVA1Mcm0yWtul0cafJ4Q/scfBYY6mZ+G7X3qTZ8k79o/+YtOGOvAOM1ensSY/B0JOdsED6Rzeb9hNmqRrNXV0xYPO5MORwjzcz50QFy1ijP60WzAubSusPQWV3OVJiJysX2qWzcCagCgkt+EHkC6qriFsWBcC2kqWox4tyc4q+t0vrN9tGjAyoEodyc72u8YyicBPaNx8rYu0VrUTquZHcmDdu8tbzvVVdddzkbw1IxNZ6bAkQq75bMFjRi+tA+GA9NM+ANU5LeInWIu9KdMK8L2rRDm/3VTK65D1glI4kQU1HzQf54Le3k4FAguve13VgimsEuYEh+c5toKBJDMXR1lpQ9ppX5+IR2jJj9c22fnvqTGcnJolq3/UYa9i9R6CPpprSXa081AVSfzpYqLqBK7QiAwJDIuvLZasCrndO/oSVisQiJfrHaw8xJumfisAYajs7HeOTU/k0bH/Qr6CeAiwbS0Pz58L6At/8Bw=,iv:ybaZfw0o4MYwUn+QZCydeJtrEgwCC5/hKm/MTqJ1ny4=,tag:bNxCYKTtrBTxb/REaCwZJg==,type:str]
|
||||
nextcloud-ldap-password: ENC[AES256_GCM,data:PTURzI/Nu23LZo/ICxFRNURPD4oZwT0150CYs98KQ4GAAVzycboIocUXr8WRiu3O8/+kZkHO/7QV9Pa//i2ipw==,iv:4rW/SDZ+4LkTa2auVGvXHGQXPqHJmUStZoLlI+yFUdk=,tag:TQSDoxzvD036M6z91w9YDw==,type:str]
|
||||
nextcloud-adminpass: ENC[AES256_GCM,data:4j80ZLynFjJDy9egCPZUbusPhlsi1iTCpN6+EeBoA8ph3wQRaRzolqRnrgrvpsr2HEAfLEf6ErmLlMdT8jQGiQ==,iv:oQjyxf0EDwzLhgIujpnxbQ2vnXZFJgT99YdMo8w1jpM=,tag:f4AOoZZp8v1JL3vycU9dxg==,type:str]
|
||||
nextcloud-secrets: ENC[AES256_GCM,data:iyLYZWUnMcejvO4iXf6dyJfAiYtCoIrCjafRJzycRqVVxwpHK2o0xetkkymFvWCiWQKFZUpV7v8u4L1pnD/Zwmbvwlvyasstfvj10NztpZ9tFFGLUqgcs+AOSw5rqhWqo3pewHpRUpskyuZPCg==,iv:Z+AATaNqI4LpCkFPD5+skL2fUeM9Oz/krVPW31vMl1s=,tag:OKpnYN/IXP7e/m620XzHAg==,type:str]
|
||||
nextcloud-smb-credentials: ENC[AES256_GCM,data:jmFV1dVq6dThe2BlSb28YAKwGayBn10f98tc2jjibpAa5oAVzD04NpAtpcTQThtY,iv:SJADE393kJH5VgPd919ZH2UKS0GBCaelo+/Xyb9kFAY=,tag:n/UApNtPS8esGfkx5dIwzw==,type:str]
|
||||
sops:
|
||||
kms: []
|
||||
gcp_kms: []
|
||||
azure_kv: []
|
||||
hc_vault: []
|
||||
age:
|
||||
- recipient: age14grjcxaq4h55yfnjxvnqhtswxhj9sfdcvyas4lwvpa8py27pjy2sv3g6v7
|
||||
enc: |
|
||||
-----BEGIN AGE ENCRYPTED FILE-----
|
||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBFUFR5UzNXWDlCU3Y5bWQ4
|
||||
VUl2akE1Ym1jWlFaU3BTb2FDYW15aEJRZ1JJClRhOWNDUTZTZzhwVmN1TG9PTUNs
|
||||
SHN5b0pQMGhyNmtDdGwvVUlNU29RVGMKLS0tIEJpNnE4KzM4bkxuNlhhR1FRbTZ4
|
||||
ekZUdjlSSG5OQXoySkZ2WEZ1dWFIQkkKB1lM2FdslIg+JzllHyilnMH3EqvHRImD
|
||||
Qi3M64gKr3s6ulIU0k0HjCetILONUdX6VRXIMozDaGZCz7f+yXHkwQ==
|
||||
-----END AGE ENCRYPTED FILE-----
|
||||
- recipient: age16veg3fmvpfm7a89a9fc8dvvsxmsthlm70nfxqspr6t8vnf9wkcwsvdq38d
|
||||
enc: |
|
||||
-----BEGIN AGE ENCRYPTED FILE-----
|
||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBpQ3A3SkovZUtpS20vcVVH
|
||||
SUJKMnU3Z21oN2tqZ05nTUhFTEZZK3JLeFFVCkZadVAyUEhFaGVRalJUOTJ5N1JV
|
||||
Qi85dStiajErSndtV3BFVXBRS0w1N2cKLS0tIHRIbGlZMmtYdDRMQm5WRXFBWUpF
|
||||
VjlVaDh2K1FGdmVwSWVqYmNES2hLYTQKTpO9nN+gD/EohH9Yo1+bkM4hncWrpfIG
|
||||
Vyv7Rfval0QWGHU52VO6xlTieOse4NzrYQ9NQ3m/UROBpSmdiBWiBg==
|
||||
-----END AGE ENCRYPTED FILE-----
|
||||
- recipient: age1v6p8dan2t3w9h94fz4flldl32082j3s9x6zqq7u5j66keth9aphsd6pvch
|
||||
enc: |
|
||||
-----BEGIN AGE ENCRYPTED FILE-----
|
||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBuUXNXM1Y3eTljcm9OUGpY
|
||||
c0hTa0F0THhiZHNQSWNoUDgxNmMzbks1amlVCmFsUGtuQzNKeDVxZ1hMYytEZnlP
|
||||
bUd0bTZnM0xPMTl2ajB4K0F5cWF0eWMKLS0tIE1jNnRXRG9UaUU1TXBWdVdpaUlx
|
||||
RE1xeHFpNFF2QkRKYzl5YUxiZjJtU2cKou/P1Aw9h2by7FoyQF4fyXu3IwxqVEHq
|
||||
c97KVXI+MoHm6sq1OTJ94XsKB/h+VjiUk8KEl3kmnC0twzd56qsb4A==
|
||||
-----END AGE ENCRYPTED FILE-----
|
||||
- recipient: age1md4kkdf08zmagqv0yzza8h75f80c9j8np2p6eqea6fpa94szd5lsltz9va
|
||||
enc: |
|
||||
-----BEGIN AGE ENCRYPTED FILE-----
|
||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBraWFHUTI1Q2hMa1RaM2Fz
|
||||
M0djcUIzendUUnlaY2N1SnJVM3JuMDZSZ0hzCndNbHJoN3o0ODl5SGhDVzJpS0c3
|
||||
Q1dxMEFSOEJwUGRBQlhOUkRBV3hBTkUKLS0tIFhOSWphVVV4QS9jaDFza3VOdVps
|
||||
T09oTGJjaU1kUlM4TTV4NmRjMHFyNEkKRdunkGCAOXtfhAxp/baX1GH6JI09jSRf
|
||||
jK4gPmuNTcxQRSRoKigX04LdKr1YjYvyfeejIzNZEDd22EYj1ISS/w==
|
||||
-----END AGE ENCRYPTED FILE-----
|
||||
lastmodified: "2024-10-23T21:04:42Z"
|
||||
mac: ENC[AES256_GCM,data:D+FJiH4CLfiYcsFHpW1Lf6V7Ej9AFzVhTpM97mkd0rsDIVCFb+4PQmwQ8aF3SQvpuVmo49G7MmHhgC4WJPMyCVGs87E1J5QgNzaj/uBvEze42YRkC0rsePsoq/CyG+3DPFPE7DoPtijNqT+vTQk0Ku2245vTejk6oF2JdbzQ3u8=,iv:3tWsnBgmceqqhb01fGfBBqLD5F3bD8J9M4NIcdxNzgY=,tag:caeRk/lvI1ymHv91N85c4g==,type:str]
|
||||
pgp: []
|
||||
unencrypted_suffix: _unencrypted
|
||||
version: 3.8.1
|
||||
@@ -1 +0,0 @@
|
||||
../../utils
|
||||
Reference in New Issue
Block a user