Compare commits
6 Commits
da669efee2
...
a2d482e16d
| Author | SHA1 | Date | |
|---|---|---|---|
| a2d482e16d | |||
| 12ef36af33 | |||
| 6ae6c5e0e5 | |||
| 44b47ce18c | |||
| c96c24f864 | |||
| df50e70f3e |
10
.chatgpt_config.yaml
Normal file
10
.chatgpt_config.yaml
Normal file
@@ -0,0 +1,10 @@
|
||||
project_name: "cloonar-nixos"
|
||||
default_prompt_blocks:
|
||||
- "basic-prompt"
|
||||
- "secure-coding"
|
||||
initial_prompt: |
|
||||
You are a NixOS expert.
|
||||
You are tasked with maintaining the configuration for the infrastructure of a company.
|
||||
Keep best practices in mind and make sure the configuration is secure.
|
||||
directories:
|
||||
- "hosts/nb"
|
||||
78
.sops.yaml
78
.sops.yaml
@@ -7,19 +7,13 @@ keys:
|
||||
- &dominik age16veg3fmvpfm7a89a9fc8dvvsxmsthlm70nfxqspr6t8vnf9wkcwsvdq38d
|
||||
- &dominik2 age1v6p8dan2t3w9h94fz4flldl32082j3s9x6zqq7u5j66keth9aphsd6pvch
|
||||
- &git-server age106n5n3rrrss45eqqzz8pq90la3kqdtnw63uw0sfa2mahk5xpe30sxs5x58
|
||||
- &web-01-server age1y6lvl5jkwc47p5ae9yz9j9kuwhy7rtttua5xhygrgmr7ehd49svsszyt42
|
||||
- &web-02 age1gjm4c3swt8u88e36gf2qlg3syxfc0ly94u64c42f2tsf24npw4csa6e4fw
|
||||
- &web-arm age1ylrpaytkm0k5kcecsxvyv5xd9ts4md0uap48g6wsmj9pwm4lf5esffu0gw
|
||||
- &home-assistant-server age1ezq2j34qngky22enhnslx6hzh4ekwk8dtmn6c9us0uqxqpn7hgpsspjz58
|
||||
- &ldap-server-test age1azmxsw5llmp2nnsv3yc2l8paelmq9rfepxd8jvmswgsmax0qyyxqdnsc7t
|
||||
- &testmodules age1zkzpnfeakyvg3fqtyay32sushjx2hqe28y6hs6ss7plemzqjqa5s6s5yu3
|
||||
- &ldap-server-arm age1jyeppc8yl2twnv8fwcewutd5gjewnxl59lmhev6ygds9qel8zf8syt7zz4
|
||||
- &fw age1wq82xjyj80htz33x7agxddjfumr3wkwh3r24tasagepxw7ka893sau68df
|
||||
- &fw-new age12msc2c6drsaw0yk2hjlaw0q0lyq0emjx5e8rq7qc7ql689k593kqfmhss2
|
||||
- &netboot age14uarclad0ty5supc8ep09793xrnwkv8a4h9j0fq8d8lc92n2dadqkf64vw
|
||||
|
||||
- &mail-social-grow-tech age1gtulvdj4aclpfhk3mmzvpz9xysccxhvu99x6ayaqlj8m44ehffgq6zuc5u
|
||||
- &web-social-grow-tech age1md4kkdf08zmagqv0yzza8h75f80c9j8np2p6eqea6fpa94szd5lsltz9va
|
||||
creation_rules:
|
||||
- path_regex: ^[^/]+\.yaml$
|
||||
key_groups:
|
||||
@@ -27,19 +21,13 @@ creation_rules:
|
||||
- *bitwarden
|
||||
- *dominik
|
||||
- *dominik2
|
||||
- path_regex: hosts/nb-01.cloonar.com/[^/]+\.yaml$
|
||||
- path_regex: hosts/nb/[^/]+\.yaml$
|
||||
key_groups:
|
||||
- age:
|
||||
- *bitwarden
|
||||
- *dominik
|
||||
- *dominik2
|
||||
- path_regex: hosts/nb-new.cloonar.com/[^/]+\.yaml$
|
||||
key_groups:
|
||||
- age:
|
||||
- *bitwarden
|
||||
- *dominik
|
||||
- *dominik2
|
||||
- path_regex: hosts/fw.cloonar.com/[^/]+\.yaml$
|
||||
- path_regex: hosts/fw/[^/]+\.yaml$
|
||||
key_groups:
|
||||
- age:
|
||||
- *bitwarden
|
||||
@@ -52,20 +40,8 @@ creation_rules:
|
||||
- *bitwarden
|
||||
- *dominik
|
||||
- *dominik2
|
||||
- *fw
|
||||
- *fw-new
|
||||
- path_regex: hosts/fw.cloonar.com/modules/web/[^/]+\.yaml$
|
||||
key_groups:
|
||||
- age:
|
||||
- *bitwarden
|
||||
- *dominik
|
||||
- *web-02
|
||||
- path_regex: hosts/web-01.cloonar.com/[^/]+\.yaml$
|
||||
key_groups:
|
||||
- age:
|
||||
- *bitwarden
|
||||
- *dominik
|
||||
- *dominik2
|
||||
- *web-01-server
|
||||
- path_regex: hosts/web-arm/[^/]+\.yaml$
|
||||
key_groups:
|
||||
- age:
|
||||
@@ -73,28 +49,13 @@ creation_rules:
|
||||
- *dominik
|
||||
- *dominik2
|
||||
- *web-arm
|
||||
- path_regex: hosts/mail.cloonar.com/[^/]+\.yaml$
|
||||
- path_regex: hosts/mail/[^/]+\.yaml$
|
||||
key_groups:
|
||||
- age:
|
||||
- *bitwarden
|
||||
- *dominik
|
||||
- *dominik2
|
||||
- *ldap-server-arm
|
||||
- *ldap-server-test
|
||||
- path_regex: hosts/mail.social-grow.tech/[^/]+\.yaml$
|
||||
key_groups:
|
||||
- age:
|
||||
- *bitwarden
|
||||
- *dominik
|
||||
- *dominik2
|
||||
- *mail-social-grow-tech
|
||||
- path_regex: hosts/web.social-grow.tech/[^/]+\.yaml$
|
||||
key_groups:
|
||||
- age:
|
||||
- *bitwarden
|
||||
- *dominik
|
||||
- *dominik2
|
||||
- *web-social-grow-tech
|
||||
- path_regex: utils/modules/lego/[^/]+\.yaml$
|
||||
key_groups:
|
||||
- age:
|
||||
@@ -102,52 +63,26 @@ creation_rules:
|
||||
- *dominik
|
||||
- *dominik2
|
||||
- *git-server
|
||||
- *web-01-server
|
||||
- *web-02
|
||||
- *web-arm
|
||||
- *home-assistant-server
|
||||
- *ldap-server-arm
|
||||
- *ldap-server-test
|
||||
- *testmodules
|
||||
- *netboot
|
||||
- *fw
|
||||
- *fw-new
|
||||
- *mail-social-grow-tech
|
||||
- *web-social-grow-tech
|
||||
- path_regex: hosts/web-01.cloonar.com/modules/bitwarden/[^/]+\.yaml$
|
||||
key_groups:
|
||||
- age:
|
||||
- *bitwarden
|
||||
- *dominik
|
||||
- *dominik2
|
||||
- *web-01-server
|
||||
- path_regex: hosts/web-01.cloonar.com/modules/zammad/[^/]+\.yaml$
|
||||
key_groups:
|
||||
- age:
|
||||
- *bitwarden
|
||||
- *dominik
|
||||
- *dominik2
|
||||
- *web-01-server
|
||||
- path_regex: utils/modules/plausible/[^/]+\.yaml$
|
||||
key_groups:
|
||||
- age:
|
||||
- *bitwarden
|
||||
- *dominik
|
||||
- *dominik2
|
||||
- *web-01-server
|
||||
- path_regex: utils/modules/promtail/[^/]+\.yaml$
|
||||
key_groups:
|
||||
- age:
|
||||
- *bitwarden
|
||||
- *dominik
|
||||
- *dominik2
|
||||
- *git-server
|
||||
- *web-01-server
|
||||
- *web-arm
|
||||
- *home-assistant-server
|
||||
- *ldap-server-arm
|
||||
- *ldap-server-test
|
||||
- *testmodules
|
||||
- *netboot
|
||||
- *fw
|
||||
- *fw-new
|
||||
@@ -157,13 +92,8 @@ creation_rules:
|
||||
- *bitwarden
|
||||
- *dominik
|
||||
- *dominik2
|
||||
- *git-server
|
||||
- *web-01-server
|
||||
- *web-arm
|
||||
- *home-assistant-server
|
||||
- *ldap-server-arm
|
||||
- *ldap-server-test
|
||||
- *testmodules
|
||||
- *netboot
|
||||
- *fw
|
||||
- *fw-new
|
||||
|
||||
2
buchhaltung.md
Normal file
2
buchhaltung.md
Normal file
@@ -0,0 +1,2 @@
|
||||
Bei EU Rechnungen das Hakerl machen bei "Nicht im Inland steuerbare Leistung (außerhalb EU, z.B. Schweiz)"
|
||||
VXEhGveIHdSj7JKq6zof48vLhKaCo0RJea6DhVqopA8=
|
||||
@@ -38,6 +38,8 @@ interval:
|
||||
# Enable Home Assistant API
|
||||
api:
|
||||
|
||||
logger:
|
||||
|
||||
ota:
|
||||
platform: esphome
|
||||
|
||||
|
||||
@@ -38,6 +38,8 @@ interval:
|
||||
# Enable Home Assistant API
|
||||
api:
|
||||
|
||||
logger:
|
||||
|
||||
ota:
|
||||
platform: esphome
|
||||
|
||||
|
||||
@@ -38,6 +38,8 @@ interval:
|
||||
# Enable Home Assistant API
|
||||
api:
|
||||
|
||||
logger:
|
||||
|
||||
ota:
|
||||
platform: esphome
|
||||
|
||||
|
||||
@@ -38,6 +38,8 @@ interval:
|
||||
# Enable Home Assistant API
|
||||
api:
|
||||
|
||||
logger:
|
||||
|
||||
ota:
|
||||
platform: esphome
|
||||
|
||||
|
||||
@@ -38,6 +38,8 @@ interval:
|
||||
# Enable Home Assistant API
|
||||
api:
|
||||
|
||||
logger:
|
||||
|
||||
ota:
|
||||
platform: esphome
|
||||
|
||||
|
||||
@@ -38,6 +38,8 @@ interval:
|
||||
# Enable Home Assistant API
|
||||
api:
|
||||
|
||||
logger:
|
||||
|
||||
ota:
|
||||
platform: esphome
|
||||
|
||||
|
||||
23
fleet.nix
23
fleet.nix
@@ -19,43 +19,26 @@
|
||||
};
|
||||
|
||||
users = [
|
||||
{
|
||||
username = "web-01.cloonar.com";
|
||||
key = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCl7cvUGMmtpVfJ3PB4Rco7V8z83nivst77SgBn+Z3cHgcDJDu9l3L4Q6rv9b6thmEX+Xf0ri6UwDI8UuJro4F9qpCXsTkHres3f/pDZokgfO7bvU2l7ujq6NnAx0qJWdB6oku36x3t2wBnvkDijXLtGPeQbd6c33hECEwA7QszvoBbGi0yFiGsqR5W7o0kiju/LMzCkExeaspFV6DBtEW0qZVMYx+lBIK5Hi/g3vBjbhFdWGz8T2AITcAnGI9n6f+dg3dlMPEHXnF9KRod1EVDnYMxbEp49i98m65F1xAFwOo35WSg48LlV1PK1VusboE3pHgE2VEFmW1J+PVQZ+z0JAaRBv/wSVN0YzuCLfLtUr10K1W23YbT1UVm7FusKpT1KElZ9adfbk6SXVhXnru40VcwqgYfw7naQJzT8aDI9Tnci+z4xCCxrdUF/psDBPD5sfjMPbjdPbt6Jnx1H9ZodiC/sQUtbn6MMbenMSf/AmuUC9xzpXlqCtPmN1dSC+8= root@web-01";
|
||||
}
|
||||
{
|
||||
username = "web-arm";
|
||||
key = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGzJRWe8hsqAVnGSjPrcheloteWMzORoQ5Gj4IfhCROF";
|
||||
}
|
||||
{
|
||||
username = "mail.cloonar.com";
|
||||
username = "mail";
|
||||
key = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCfEuRazRv8zKWJSq+T3SssgOrkBFu6y/t6uoMNrD3P9WHowRDejo2rBsWFgPszhfgxLpWHiuSZFMG8z+07k5fVTdmbUwx0vXI1lmQ7AxB/CPwBef2Vpb7b8Rq6geejvP8X6UjQWP0rsCMtoX2SeBDTG8bDlyq1U3vYxVY4hery6a9Wu57OI5VbSIHhqQvExo7euz8V7ORsLyT8gi9x3r8gNaKJmvssB6QXXZ7U2sJaAUjhV/BmrZJD5qR9EwqwiMPJ2+SkZ0Vz6CFG6GLyB/ngXPEfclLKK7AzookJy7WepqojjFTzmOBMH903oR+MIpjDECKxgaFtW4xY0A/tj8ZDCBPtP8AKjediOASkAi7eUMPseQKDE0BNLSidC0hlQUe0aPaMeA8b1U86PblzpgF8ntkUPbxhO0AgHKq9fPN+f58f75fryNbhgPRRkeLet1q3hxguEMg2MIg/EqIw862YPWPtGRk0wJHwQU7jx+9BbjdptAVTJo/Cj9vM7mpZphE= root@mail";
|
||||
}
|
||||
{
|
||||
username = "nb-01.cloonar.com";
|
||||
key = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDN/2SAFm50kraB1fepAizox/QRXxB7WbqVbH+5OPalDT47VIJGNKOKhixQoqhABHxEoLxdf/C83wxlCVlPV9poLfDgVkA3Lyt5r3tSFQ6QjjOJAgchWamMsxxyGBedhKvhiEzcr/Lxytnoz3kjDG8fqQJwEpdqMmJoMUfyL2Rqp16u+FQ7d5aJtwO8EUqovhMaNO7rggjPpV/uMOg+tBxxmscliN7DLuP4EMTA/FwXVzcFNbOx3K9BdpMRAaSJt4SWcJO2cS2KHA5n/H+PQI7nz5KN3Yr/upJN5fROhi/SHvK39QOx12Pv7FCuWlc+oR68vLaoCKYhnkl3DnCfc7A7";
|
||||
}
|
||||
{
|
||||
username = "nb-new.cloonar.com";
|
||||
username = "nb";
|
||||
key = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIC1dDoAJUY58I+4SSfDAkO5kInsMcJT/r/mW+MYXLQVR";
|
||||
}
|
||||
{
|
||||
username = "fw.cloonar.com";
|
||||
username = "fw";
|
||||
key = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDtxpJAFohRtBaET9e7EE4I6UmeUT/h1ZTD1zeOHFiWB/AT71ooDT4/QukJOA3LqklDjtDQHH+qjGY50Wa8/oGTA/X3aBDPg5GAHN+U+kYO2UTC69VVjh4TTS35ijg+AdgegtMI4c0VIUMZB24tthV9KEbD20w6XnTzy2Q6PjbBrwsOeHYr9pkygJZDU65ZeKmLyR6yLaadHzXX1I7V2SwiakPEebhQaGipm540d+tAbirKCHcmiORkpd++e3dfwi25hC9bCQ7b3bdaFPAmuhhFEid4jpCt79X+l0qqpClgRLziBjYykNJDFKAljFBJA11/3ofPCuaBCDUuJVhAH044gtT3sbvJq1prd8ElZy6L1yc5YbfFgDMwi71Y2hef780NmDs5Opk9xUCKqdl1YfLyUDgdiiaZ8uhUMd2Ai9BAxJAXtcz/V41ngt3YkUVyGTZdTAODIKk44blGIkgs7JO4yam4UB1curbD0faIZnWLyS5pdFQ+FI05YVjoHXJdme8=";
|
||||
}
|
||||
{
|
||||
username = "fw-new";
|
||||
key = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILnb9todh2b+c3iCmEz72smRwL37aZf3Xs3voT7+PLTP";
|
||||
}
|
||||
|
||||
{
|
||||
username = "mail.social-grow.tech";
|
||||
key = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH1K4mhBji1kMGnO55OOFaDknBf2Q6wgm7DaMYKip+S5";
|
||||
}
|
||||
{
|
||||
username = "web.social-grow.tech";
|
||||
key = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIw4lHUd/+rHIWP2WBAj9smo2CkeHEOHhTqZzacmxMcC";
|
||||
}
|
||||
];
|
||||
in {
|
||||
imports = builtins.map create_users users;
|
||||
|
||||
1
hosts/fw-new/channel
Normal file
1
hosts/fw-new/channel
Normal file
@@ -0,0 +1 @@
|
||||
https://channels.nixos.org/nixos-unstable
|
||||
141
hosts/fw-new/configuration.nix
Normal file
141
hosts/fw-new/configuration.nix
Normal file
@@ -0,0 +1,141 @@
|
||||
{ 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
|
||||
./modules/foundry-vtt.nix
|
||||
|
||||
# setup network
|
||||
# ./modules/setupnetwork.nix
|
||||
|
||||
|
||||
./hardware-configuration.nix
|
||||
];
|
||||
|
||||
nixpkgs.overlays = [
|
||||
(import ./utils/overlays/packages.nix)
|
||||
];
|
||||
|
||||
nixpkgs.config.permittedInsecurePackages = [
|
||||
"openssl-1.1.1w"
|
||||
];
|
||||
|
||||
nixpkgs.config.allowUnfreePredicate = pkg: builtins.elem (lib.getName pkg) [
|
||||
"mongodb"
|
||||
];
|
||||
|
||||
time.timeZone = "Europe/Vienna";
|
||||
|
||||
services.logind.extraConfig = "RuntimeDirectorySize=2G";
|
||||
|
||||
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 = {
|
||||
settings.auto-optimise-store = true;
|
||||
gc = {
|
||||
automatic = true;
|
||||
dates = "weekly";
|
||||
options = "--delete-older-than 60d";
|
||||
};
|
||||
# Free up to 1GiB whenever there is less than 100MiB left.
|
||||
extraOptions = ''
|
||||
min-free = ${toString (100 * 1024 * 1024)}
|
||||
max-free = ${toString (1024 * 1024 * 1024)}
|
||||
'';
|
||||
};
|
||||
|
||||
# services.tlp = {
|
||||
# enable = true;
|
||||
# settings = {
|
||||
# CPU_SCALING_GOVERNOR_ON_AC = "powersave"; # powersave or performance
|
||||
# CPU_ENERGY_PERF_POLICY_ON_AC = "power"; # power or performance
|
||||
# # CPU_MIN_PERF_ON_AC = 0;
|
||||
# # CPU_MAX_PERF_ON_AC = 100; # max 100
|
||||
# };
|
||||
# };
|
||||
|
||||
# systemd.services = {
|
||||
# powertop = {
|
||||
# wantedBy = [ "multi-user.target" ];
|
||||
# after = [ "multi-user.target" ];
|
||||
# description = "Powertop tunings";
|
||||
# path = [ pkgs.kmod ];
|
||||
# serviceConfig = {
|
||||
# Type = "oneshot";
|
||||
# RemainAfterExit = "yes";
|
||||
# ExecStart = "${pkgs.powertop}/bin/powertop --auto-tune && for dev in /sys/class/net/*; do echo on > \"$dev/device/power/control\"; done'";
|
||||
# };
|
||||
# };
|
||||
# };
|
||||
|
||||
boot.tmp.cleanOnBoot = true;
|
||||
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"
|
||||
];
|
||||
|
||||
# backups
|
||||
borgbackup.repo = "u149513-sub2@u149513-sub2.your-backup.de:borg";
|
||||
|
||||
system.stateVersion = "22.05";
|
||||
}
|
||||
86
hosts/fw-new/hardware-configuration.nix
Normal file
86
hosts/fw-new/hardware-configuration.nix
Normal file
@@ -0,0 +1,86 @@
|
||||
# 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, ... }:
|
||||
let
|
||||
# needs to get pinned because otherwise kernel will fail to build because of gcc
|
||||
kernelpkgs = import (builtins.fetchGit {
|
||||
name = "kernelpkgs";
|
||||
url = "https://github.com/nixos/nixpkgs/";
|
||||
rev = "4c2fcb090b1f3e5b47eaa7bd33913b574a11e0a0";
|
||||
}) {};
|
||||
in
|
||||
{
|
||||
powerManagement.cpuFreqGovernor = lib.mkDefault "ondemand";
|
||||
|
||||
|
||||
boot = {
|
||||
loader.systemd-boot.enable = true;
|
||||
loader.efi.canTouchEfiVariables = true;
|
||||
|
||||
kernelPackages = pkgs.linuxPackagesFor (kernelpkgs.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 {})
|
||||
];
|
||||
};
|
||||
|
||||
|
||||
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";
|
||||
}
|
||||
110
hosts/fw-new/modules/networking.nix
Normal file
110
hosts/fw-new/modules/networking.nix
Normal file
@@ -0,0 +1,110 @@
|
||||
{ ... }: {
|
||||
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 = 96;
|
||||
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.96.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;
|
||||
}];
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
9591
hosts/fw-new/pkgs/kernel/rk35xx_vendor_config
Normal file
9591
hosts/fw-new/pkgs/kernel/rk35xx_vendor_config
Normal file
File diff suppressed because it is too large
Load Diff
4780
hosts/fw-new/pkgs/kernel/rk35xx_vendor_config.nix
Normal file
4780
hosts/fw-new/pkgs/kernel/rk35xx_vendor_config.nix
Normal file
File diff suppressed because it is too large
Load Diff
61
hosts/fw-new/pkgs/kernel/vendor.nix
Normal file
61
hosts/fw-new/pkgs/kernel/vendor.nix
Normal file
@@ -0,0 +1,61 @@
|
||||
# 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
|
||||
, fetchurl
|
||||
, ...
|
||||
}:
|
||||
let
|
||||
modDirVersion = "6.1.75";
|
||||
|
||||
panthor-base = "aa54fa4e0712616d44f2c2f312ecc35c0827833d";
|
||||
panthor-head = "c81ebd8e12b64a42a6efd68cc0ed018b57d14e91";
|
||||
in
|
||||
(linuxManualConfig {
|
||||
inherit modDirVersion;
|
||||
version = "${modDirVersion}-jr-noble";
|
||||
extraMeta.branch = "6.1";
|
||||
|
||||
# https://github.com/Joshua-Riek/linux-rockchip/tree/noble
|
||||
src = fetchFromGitHub {
|
||||
owner = "Joshua-Riek";
|
||||
repo = "linux-rockchip";
|
||||
rev = "5c43412639fd134f0ba690de2108eaa7ea349e2a";
|
||||
hash = "sha256-aKm/RQTRTzLr8+ACdG6QW1LWn+ZOjQtlvU2KkZmYicg=";
|
||||
};
|
||||
|
||||
# https://github.com/hbiyik/linux/tree/rk-6.1-rkr3-panthor
|
||||
# allows usage of mainline mesa
|
||||
kernelPatches = [{
|
||||
name = "hbiyik-panthor.patch";
|
||||
# NOTE: This needs to be `fetchurl` instead of `fetchpatch`, because `fetchpatch`
|
||||
# reorders the patches, and the order matters since they're generated from commits.
|
||||
patch = fetchurl {
|
||||
url = "https://github.com/hbiyik/linux/compare/${panthor-base}...${panthor-head}.patch";
|
||||
hash = "sha256-nSfmgem0CElUHL1wXSL+9aVixeaRjcxMyey4YaNdHfc=";
|
||||
};
|
||||
extraConfig = { };
|
||||
}];
|
||||
|
||||
# Steps to the generated kernel config file
|
||||
# 1. git clone --depth 1 https://github.com/hbiyik/linux.git -b rk-6.1-rkr3-panthor
|
||||
# 2. put https://github.com/hbiyik/linux/blob/rk-6.1-rkr3-panthor/debian.rockchip/config/config.common.ubuntu to arch/arm64/configs/rk35xx_vendor_defconfig
|
||||
# 3. run `nix develop .#fhsEnv` in this project to enter the fhs test environment defined here.
|
||||
# 4. `make rk35xx_vendor_defconfig` in the kernel root directory 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 (also be sure to update the corresponding `.nix` file accordingly) and commit it.
|
||||
#
|
||||
configfile = ./rk35xx_vendor_config;
|
||||
config = import ./rk35xx_vendor_config.nix;
|
||||
}).overrideAttrs (old: {
|
||||
name = "k"; # dodge uboot length limits
|
||||
nativeBuildInputs = old.nativeBuildInputs ++ [ ubootTools ];
|
||||
})
|
||||
17
hosts/fw-new/pkgs/mali-firmware/default.nix
Normal file
17
hosts/fw-new/pkgs/mali-firmware/default.nix
Normal file
@@ -0,0 +1,17 @@
|
||||
{
|
||||
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
|
||||
'';
|
||||
}
|
||||
23
hosts/fw-new/pkgs/orangepi-firmware/default.nix
Normal file
23
hosts/fw-new/pkgs/orangepi-firmware/default.nix
Normal file
@@ -0,0 +1,23 @@
|
||||
{ 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
|
||||
'';
|
||||
}
|
||||
73
hosts/fw-new/secrets.yaml
Normal file
73
hosts/fw-new/secrets.yaml
Normal file
@@ -0,0 +1,73 @@
|
||||
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-mailer-password: ENC[AES256_GCM,data:M4qCWNt1oQVJzxThIjocm2frwuVMyx+69TBpke25RwxJxEQnvHL1CM579OVroTm7+gGE/oOJqAwDIepfiDtyM1xm,iv:jayFZMbu3uDimS/rIKZSeoU0MsYwWp880iEMs1oQE4k=,tag:qGDncRkyuCWaELhcxUrqtQ==,type:str]
|
||||
gitea-runner: ENC[AES256_GCM,data:NYG3qRLiMjmfA+oHYBXBbxpuX2ZjB/VgvLaS7yr5kJeDN/NukB/B3OZcEfsUWgbBS5IsLENESngWTFmK4W3htN4lSqdg/g4UsUr20beNov+pbyPN05rkBYmSCZZFwZ1L9POEE4GF4LuuoNpDlWIw0mrA8oV8MoI4W5QS2IGranBTIQQaYXU5TEGYa4XMVo4oC75iuH6DIq1KD6OgFAfMhm/wlbP8CP/Iaw2K8CNPxktk93pm3OSmggf22Z4JPEnvV25sc9iBkxLkDk9FXYFys0g=,iv:UzL5ncVOC/loJwcFSG1QJHnzLp3il4Hf3qDwLWxrIlo=,tag:w0Zn/E+02KyAsPXZdOLrew==,type:str]
|
||||
gitea-runner-token: ENC[AES256_GCM,data:HpBjLS10w78ihbnAUrlCRGvwrXLBYKH5v/P7XggoUSWLoAazSVQArABxaK7PJas=,iv:q3Y6jV0gmug06O0EYqGVyIJ4AvMGr2ydwY17YKxo0Qw=,tag:Ws5HLbdaeYGGXzDZW/FX4w==,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]
|
||||
matrix-shared-secret: ENC[AES256_GCM,data:67imd3m6WBeGP/5Msmjy8B6sP983jMyWzRIzWgNVV5jZslX+GBJyEYzm3OTDs1iTZf4ScvuYheTH0QFPfw==,iv:7ElCpESWumbIHmmFaedcpkFm5M58ZT3vW9wb9e1Sbh4=,tag:wr4FIymtJBtCerVqae+Xlw==,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+IFgyNTUxOSB2dUdkQ2MrUTRtV3RIWHo1
|
||||
T0F2cEh2czgrNVB0ZVlTa1hEVllJZUlkNGljCms3R1c1U0F6cnRaWk54M1FJeWwz
|
||||
cGltRDN2ZHRrWnBWY1o3MHNnK2dkM00KLS0tIG0zL0svWEtweW14Q1V1WXlWMEVS
|
||||
cy9IdTNTeDIrVUl1WWk2dnplcVZaZFkKAXoWKjSryB9jpoSf/KSUsmSfDb3IJjY3
|
||||
3BDOyoQq52zimP27iy8jhEPUwcLfL093FrRYFraOTOzL19uKDr1Kaw==
|
||||
-----END AGE ENCRYPTED FILE-----
|
||||
- recipient: age16veg3fmvpfm7a89a9fc8dvvsxmsthlm70nfxqspr6t8vnf9wkcwsvdq38d
|
||||
enc: |
|
||||
-----BEGIN AGE ENCRYPTED FILE-----
|
||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBzL1JLNzhNa0JZV1lxS295
|
||||
VExnbEhTeVZLMDRPUHJtTVRsa29QamNseFZFCkdnNEZ0ZHYxNFBTVC9MUVhZN1ZX
|
||||
bHpsRkMvWlFBZkwxTG9DZEFwRTdSbWsKLS0tIC9QS3ZRZnZiNXl5VDJ4OWhrT1U5
|
||||
di9kS05JMENYRHNYSHBQbmJZaHZKZ2cKcQBBKuqR748ReULbmOWxLV+4l/kI6WC5
|
||||
PDPTLzeVPzlFXKGXq/OwkNbgzN0Pq9HdOqNImheb6Qdi8X5CLHVT1Q==
|
||||
-----END AGE ENCRYPTED FILE-----
|
||||
- recipient: age1v6p8dan2t3w9h94fz4flldl32082j3s9x6zqq7u5j66keth9aphsd6pvch
|
||||
enc: |
|
||||
-----BEGIN AGE ENCRYPTED FILE-----
|
||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBqc1dRT3h4RDlzdi9UWHEr
|
||||
KzJmck9Edk50YmxJOUFZQ1F2aEZ0aEdNL3drCkFyaDBQVzg4UlYvd0hWL0dUNXlz
|
||||
eVpFUUJXY2sxNHBqbFZjUlZJbVV6ZDQKLS0tIDR4TUF1N2VYMnVXMUZiMHFhQ202
|
||||
VkhkRWF6MWZwbmVzRFBhS01pSnNoaEkKjrXaqL1OoiuWvMIRek6ozICxK4bzNLHc
|
||||
bP0G3q86VR0uV+oQFjmSx0OGphAEjv1KDPpCIdJ5P8o3JUs/crHUEQ==
|
||||
-----END AGE ENCRYPTED FILE-----
|
||||
- recipient: age1wq82xjyj80htz33x7agxddjfumr3wkwh3r24tasagepxw7ka893sau68df
|
||||
enc: |
|
||||
-----BEGIN AGE ENCRYPTED FILE-----
|
||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBTZmVKVTAxUVE2dmRoSzdh
|
||||
QkZGOW9CNUpobEVIY25acmdaUDVYbWY3TURZCjZ4a3RsajBCajdiTkh5NGNhZi8y
|
||||
RC9VRGJYOTJzWjA3cld1Skw5TXUzbzAKLS0tIDE2RlZLZlNrb1F2VjJPK3R3di80
|
||||
ci8wRmV1clZlaHp2cDRXZSs3VzdBUnMKfnvxSasz18LrF7ZZOQjAOVAVsWGcF7Ax
|
||||
rYe9dM46Mbb2measOgXlwqKVqINcvhVxKdgOiJJ0ZdGtNeNsmyBRgA==
|
||||
-----END AGE ENCRYPTED FILE-----
|
||||
- recipient: age12msc2c6drsaw0yk2hjlaw0q0lyq0emjx5e8rq7qc7ql689k593kqfmhss2
|
||||
enc: |
|
||||
-----BEGIN AGE ENCRYPTED FILE-----
|
||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBWK25sZGh0TVdGM0lUU1Fj
|
||||
T1g3cXByYTVzTTFUeFBYMEJjelRLVXFaUVN3CnQyUG5CSG1FWVJoYnNYaWFOYjBU
|
||||
dGh6V29Bb01iTXk5YmRvQ0V6SUtSVGMKLS0tIEhVeVRQbVUzcWtFMWpDNjdWeTAv
|
||||
VDIzd0RIUlAya1lscTJ6bUJqMFRtS00K0TJ4ji3UU5G14xNC9Qru9bH9MdEbIJd7
|
||||
rzVp5S1HS+pdpprzOTmqAPFBe87Y6oX2yPauo/3GFTDZtjuVfYCvLA==
|
||||
-----END AGE ENCRYPTED FILE-----
|
||||
lastmodified: "2024-11-20T21:39:00Z"
|
||||
mac: ENC[AES256_GCM,data:JCFvFwSqnAQCOB76n5pfQsdsaod8bBiVZ2VY+WWBDWi84gQByhqy808E2ZZJSJ1/amUi8dNBeOPNWZIGdieuWJyatrqjWziAl7gXx5u35i77sS6hAD+G/Fc/elgRbjc0VIbplZ7UxBmwo3vkVpI4RqQiQv63MvKHI+TkoY8vFUM=,iv:uy50x8FqqDW7hCLZeHfhFB/dxa3N6kM2Vj9waAZJngg=,tag:Wt1FG0kW4VFZ2fvvAC0T4A==,type:str]
|
||||
pgp: []
|
||||
unencrypted_suffix: _unencrypted
|
||||
version: 3.8.1
|
||||
@@ -4,7 +4,6 @@
|
||||
./utils/bento.nix
|
||||
./utils/modules/sops.nix
|
||||
./utils/modules/lego/lego.nix
|
||||
|
||||
./utils/modules/nginx.nix
|
||||
|
||||
./utils/modules/autoupgrade.nix
|
||||
@@ -13,7 +12,9 @@
|
||||
# ./utils/modules/netdata.nix
|
||||
|
||||
# fw
|
||||
./modules/network-prefix.nix
|
||||
./modules/networking.nix
|
||||
./modules/setupnetwork.nix
|
||||
./modules/firewall.nix
|
||||
./modules/dhcp4.nix
|
||||
./modules/unbound.nix
|
||||
@@ -57,6 +58,8 @@
|
||||
./hardware-configuration.nix
|
||||
];
|
||||
|
||||
networkPrefix = "10.42";
|
||||
|
||||
nixpkgs.overlays = [
|
||||
(import ./utils/overlays/packages.nix)
|
||||
];
|
||||
24
hosts/fw/modules/ark-survival-evolved.nix
Normal file
24
hosts/fw/modules/ark-survival-evolved.nix
Normal file
@@ -0,0 +1,24 @@
|
||||
{ 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=${config.networkPrefix}.97.201"
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
sops.secrets.ark = {};
|
||||
}
|
||||
16
hosts/fw/modules/avahi.nix
Normal file
16
hosts/fw/modules/avahi.nix
Normal file
@@ -0,0 +1,16 @@
|
||||
{ pkgs, ... }: {
|
||||
services.avahi = {
|
||||
enable = true;
|
||||
reflector = true;
|
||||
allowInterfaces = [
|
||||
"multimedia"
|
||||
"server"
|
||||
"lan"
|
||||
"smart"
|
||||
];
|
||||
};
|
||||
|
||||
environment.systemPackages = with pkgs; [
|
||||
nssmdns
|
||||
];
|
||||
}
|
||||
24
hosts/fw/modules/ddclient.nix
Normal file
24
hosts/fw/modules/ddclient.nix
Normal file
@@ -0,0 +1,24 @@
|
||||
{ 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"
|
||||
"element.cloonar.com"
|
||||
];
|
||||
};
|
||||
|
||||
sops.secrets.ddclient = {
|
||||
# owner = config.systemd.services.ddclient.serviceConfig.User;
|
||||
};
|
||||
}
|
||||
24
hosts/fw/modules/deconz.nix
Normal file
24
hosts/fw/modules/deconz.nix
Normal file
@@ -0,0 +1,24 @@
|
||||
{ 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=${config.networkPrefix}.97.22"
|
||||
"--device=/dev/ttyACM0"
|
||||
"--hostname=deconz"
|
||||
];
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
283
hosts/fw/modules/dhcp4.nix
Normal file
283
hosts/fw/modules/dhcp4.nix
Normal file
@@ -0,0 +1,283 @@
|
||||
{ config, ... }:
|
||||
{
|
||||
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 = "${config.networkPrefix}.96.100 - ${config.networkPrefix}.96.240";
|
||||
}
|
||||
];
|
||||
subnet = "${config.networkPrefix}.96.0/24";
|
||||
interface = "lan";
|
||||
option-data = [
|
||||
{
|
||||
name = "routers";
|
||||
data = "${config.networkPrefix}.96.1";
|
||||
}
|
||||
{
|
||||
name = "domain-name";
|
||||
data = "cloonar.com";
|
||||
}
|
||||
{
|
||||
name = "domain-search";
|
||||
data = "cloonar.com";
|
||||
}
|
||||
{
|
||||
name = "domain-name-servers";
|
||||
data = "${config.networkPrefix}.96.1";
|
||||
}
|
||||
];
|
||||
reservations = [
|
||||
{
|
||||
hw-address = "04:7c:16:d5:63:5e";
|
||||
ip-address = "${config.networkPrefix}.96.5";
|
||||
server-hostname = "omada.cloonar.com";
|
||||
}
|
||||
{
|
||||
hw-address = "30:05:5c:56:62:37";
|
||||
ip-address = "${config.networkPrefix}.96.100";
|
||||
server-hostname = "brn30055c566237.cloonar.com";
|
||||
}
|
||||
{
|
||||
hw-address = "24:df:a7:b1:1b:74";
|
||||
ip-address = "${config.networkPrefix}.96.101";
|
||||
server-hostname = "rmproplus-b1-1b-74.cloonar.com";
|
||||
}
|
||||
];
|
||||
|
||||
}
|
||||
{
|
||||
pools = [
|
||||
{
|
||||
pool = "${config.networkPrefix}.97.100 - ${config.networkPrefix}.97.240";
|
||||
}
|
||||
];
|
||||
subnet = "${config.networkPrefix}.97.0/24";
|
||||
interface = "server";
|
||||
option-data = [
|
||||
{
|
||||
name = "routers";
|
||||
data = "${config.networkPrefix}.97.1";
|
||||
}
|
||||
{
|
||||
name = "domain-name";
|
||||
data = "cloonar.com";
|
||||
}
|
||||
{
|
||||
name = "domain-name-servers";
|
||||
data = "${config.networkPrefix}.97.1";
|
||||
}
|
||||
];
|
||||
reservations = [
|
||||
{
|
||||
hw-address = "1a:c4:04:6e:29:bd";
|
||||
ip-address = "${config.networkPrefix}.97.2";
|
||||
server-hostname = "omada.cloonar.com";
|
||||
}
|
||||
{
|
||||
hw-address = "02:00:00:00:00:03";
|
||||
ip-address = "${config.networkPrefix}.97.5";
|
||||
server-hostname = "web-02.cloonar.com";
|
||||
}
|
||||
{
|
||||
hw-address = "02:00:00:00:00:04";
|
||||
ip-address = "${config.networkPrefix}.97.6";
|
||||
server-hostname = "matrix.cloonar.com";
|
||||
}
|
||||
{
|
||||
hw-address = "ea:db:d4:c1:18:ba";
|
||||
ip-address = "${config.networkPrefix}.97.50";
|
||||
server-hostname = "git.cloonar.com";
|
||||
}
|
||||
{
|
||||
hw-address = "c2:4f:64:dd:13:0c";
|
||||
ip-address = "${config.networkPrefix}.97.20";
|
||||
server-hostname = "home-assistant.cloonar.com";
|
||||
}
|
||||
{
|
||||
hw-address = "1a:c4:04:6e:29:02";
|
||||
ip-address = "${config.networkPrefix}.97.25";
|
||||
server-hostname = "deconz.cloonar.com";
|
||||
}
|
||||
];
|
||||
}
|
||||
{
|
||||
pools = [
|
||||
{
|
||||
pool = "${config.networkPrefix}.101.100 - ${config.networkPrefix}.101.240";
|
||||
}
|
||||
];
|
||||
subnet = "${config.networkPrefix}.101.0/24";
|
||||
interface = "infrastructure";
|
||||
option-data = [
|
||||
{
|
||||
name = "routers";
|
||||
data = "${config.networkPrefix}.101.1";
|
||||
}
|
||||
{
|
||||
name = "domain-name";
|
||||
data = "cloonar.com";
|
||||
}
|
||||
{
|
||||
name = "domain-name-servers";
|
||||
data = "${config.networkPrefix}.101.1";
|
||||
}
|
||||
{
|
||||
name = "capwap-ac-v4";
|
||||
code = 138;
|
||||
data = "${config.networkPrefix}.97.2";
|
||||
}
|
||||
];
|
||||
reservations = [
|
||||
];
|
||||
}
|
||||
{
|
||||
pools = [
|
||||
{
|
||||
pool = "${config.networkPrefix}.99.100 - ${config.networkPrefix}.99.240";
|
||||
}
|
||||
];
|
||||
subnet = "${config.networkPrefix}.99.0/24";
|
||||
interface = "multimedia";
|
||||
option-data = [
|
||||
{
|
||||
name = "routers";
|
||||
data = "${config.networkPrefix}.99.1";
|
||||
}
|
||||
{
|
||||
name = "domain-name";
|
||||
data = "cloonar.multimedia";
|
||||
}
|
||||
{
|
||||
name = "domain-name-servers";
|
||||
data = "${config.networkPrefix}.99.1";
|
||||
}
|
||||
];
|
||||
reservations = [
|
||||
{
|
||||
hw-address = "c4:a7:2b:c7:ea:30";
|
||||
ip-address = "${config.networkPrefix}.99.10";
|
||||
hostname = "metz.cloonar.multimedia";
|
||||
}
|
||||
{
|
||||
hw-address = "f0:2f:9e:d4:3b:21";
|
||||
ip-address = "${config.networkPrefix}.99.11";
|
||||
hostname = "firetv-living";
|
||||
}
|
||||
{
|
||||
hw-address = "bc:33:29:ed:24:f0";
|
||||
ip-address = "${config.networkPrefix}.99.12";
|
||||
hostname = "ps5";
|
||||
}
|
||||
{
|
||||
hw-address = "e4:2a:ac:32:3f:79";
|
||||
ip-address = "${config.networkPrefix}.99.13";
|
||||
hostname = "xbox";
|
||||
}
|
||||
{
|
||||
hw-address = "98:b6:e9:b6:ef:f4";
|
||||
ip-address = "${config.networkPrefix}.99.14";
|
||||
hostname = "switch";
|
||||
}
|
||||
{
|
||||
hw-address = "f0:2f:9e:c1:74:72";
|
||||
ip-address = "${config.networkPrefix}.99.21";
|
||||
hostname = "firetv-bedroom";
|
||||
}
|
||||
{
|
||||
hw-address = "30:05:5c:56:62:37";
|
||||
ip-address = "${config.networkPrefix}.99.100";
|
||||
server-hostname = "brn30055c566237";
|
||||
}
|
||||
];
|
||||
}
|
||||
{
|
||||
pools = [
|
||||
{
|
||||
pool = "${config.networkPrefix}.254.10 - ${config.networkPrefix}.254.254";
|
||||
}
|
||||
];
|
||||
subnet = "${config.networkPrefix}.254.0/24";
|
||||
interface = "guest";
|
||||
option-data = [
|
||||
{
|
||||
name = "routers";
|
||||
data = "${config.networkPrefix}.254.1";
|
||||
}
|
||||
{
|
||||
name = "domain-name-servers";
|
||||
data = "9.9.9.9";
|
||||
}
|
||||
];
|
||||
}
|
||||
{
|
||||
pools = [
|
||||
{
|
||||
pool = "${config.networkPrefix}.100.100 - ${config.networkPrefix}.100.240";
|
||||
}
|
||||
];
|
||||
subnet = "${config.networkPrefix}.100.0/24";
|
||||
interface = "smart";
|
||||
option-data = [
|
||||
{
|
||||
name = "routers";
|
||||
data = "${config.networkPrefix}.100.1";
|
||||
}
|
||||
{
|
||||
name = "domain-name";
|
||||
data = "cloonar.smart";
|
||||
}
|
||||
{
|
||||
name = "domain-name-servers";
|
||||
data = "${config.networkPrefix}.100.1";
|
||||
}
|
||||
];
|
||||
reservations = [
|
||||
{
|
||||
hw-address = "fc:ee:28:03:63:e9";
|
||||
ip-address = "${config.networkPrefix}.100.148";
|
||||
server-hostname = "k1c";
|
||||
}
|
||||
{
|
||||
hw-address = "cc:50:e3:bc:27:64";
|
||||
ip-address = "${config.networkPrefix}.100.112";
|
||||
server-hostname = "Nuki_Bridge_1A753F72";
|
||||
}
|
||||
|
||||
{
|
||||
hw-address = "34:6f:24:f3:af:ad";
|
||||
ip-address = "${config.networkPrefix}.100.137";
|
||||
server-hostname = "daikin86604";
|
||||
}
|
||||
{
|
||||
hw-address = "34:6f:24:c1:f8:54";
|
||||
ip-address = "${config.networkPrefix}.100.139";
|
||||
server-hostname = "daikin53800";
|
||||
}
|
||||
];
|
||||
}
|
||||
];
|
||||
valid-lifetime = 4000;
|
||||
};
|
||||
};
|
||||
}
|
||||
83
hosts/fw/modules/firefox-sync.nix
Normal file
83
hosts/fw/modules/firefox-sync.nix
Normal file
@@ -0,0 +1,83 @@
|
||||
{ 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 = "${config.networkPrefix}.97.1";
|
||||
localAddress = "${config.networkPrefix}.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 = "${config.networkPrefix}.97.1";
|
||||
interface = "eth0";
|
||||
};
|
||||
firewall.enable = false;
|
||||
nameservers = [ "${config.networkPrefix}.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";
|
||||
};
|
||||
};
|
||||
}
|
||||
161
hosts/fw/modules/firewall.nix
Normal file
161
hosts/fw/modules/firewall.nix
Normal file
@@ -0,0 +1,161 @@
|
||||
{ config, 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 { "server", "vserver", "vm-*", "lan", "wg_cloonar" } counter accept comment "allow trusted to router"
|
||||
iifname { "multimedia", "smart", "infrastructure", "podman0", "setup" } 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 ${config.networkPrefix}.97.20/32 tcp dport { llmnr } counter accept
|
||||
iifname "server" ip saddr ${config.networkPrefix}.97.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 ${config.networkPrefix}.97.20/32 oifname { "lan" } counter accept
|
||||
|
||||
# smart home coap
|
||||
iifname "smart" oifname "server" ip daddr ${config.networkPrefix}.97.20/32 udp dport { 5683 } counter accept
|
||||
iifname "smart" oifname "server" ip daddr ${config.networkPrefix}.97.20/32 tcp dport { 1883 } counter accept
|
||||
|
||||
# Forward to git server
|
||||
oifname "server" ip daddr ${config.networkPrefix}.97.50 tcp dport { 22 } counter accept
|
||||
oifname "server" ip daddr ${config.networkPrefix}.97.5 tcp dport { 80, 443 } counter accept
|
||||
|
||||
# lan and vpn to any
|
||||
iifname { "lan", "server", "vserver", "wg_cloonar" } oifname { "lan", "vb-*", "vm-*", "server", "vserver", "infrastructure", "multimedia", "smart", "wg_cloonar", "guest", "setup" } counter accept
|
||||
iifname { "lan", "server", "wg_cloonar" } oifname { "wrwks", "wg_epicenter", "wg_ghetto_at" } counter accept
|
||||
iifname { "infrastructure", "setup" } 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 ${config.networkPrefix}.97.201 tcp dport { 27020 } counter accept comment "ark survival evolved"
|
||||
oifname "server" ip daddr ${config.networkPrefix}.97.201 udp dport { 7777, 7778, 27015 } counter accept comment "ark survival evolved"
|
||||
|
||||
# firefox-sync
|
||||
oifname "server" ip daddr ${config.networkPrefix}.97.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",
|
||||
"setup",
|
||||
"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 ${config.networkPrefix}.96.255 udp dport { 9 } dnat to ${config.networkPrefix}.96.255
|
||||
iifname "wan" tcp dport { 22 } dnat to ${config.networkPrefix}.97.50
|
||||
iifname "wan" tcp dport { 80, 443 } dnat to ${config.networkPrefix}.97.5
|
||||
iifname "wan" tcp dport { 5000 } dnat to ${config.networkPrefix}.97.51
|
||||
iifname { "wan", "lan" } udp dport { 7777, 7778, 27015 } dnat to ${config.networkPrefix}.97.201
|
||||
iifname { "wan", "lan" } tcp dport { 27020 } dnat to ${config.networkPrefix}.97.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 { "lan", "wg_cloonar" } ip daddr ${config.networkPrefix}.110.101 masquerade
|
||||
iifname { "wan", "wg_cloonar" } ip daddr ${config.networkPrefix}.97.50 masquerade
|
||||
iifname { "wan", "wg_cloonar" } ip daddr ${config.networkPrefix}.97.51 masquerade
|
||||
iifname { "wan", "wg_cloonar" } ip daddr ${config.networkPrefix}.97.201 masquerade
|
||||
}
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
78
hosts/fw/modules/foundry-vtt.nix
Normal file
78
hosts/fw/modules/foundry-vtt.nix
Normal file
@@ -0,0 +1,78 @@
|
||||
{ config, pkgs, ... }:
|
||||
let
|
||||
foundry-vtt = pkgs.callPackage ../pkgs/foundry-vtt {};
|
||||
cids = import ../modules/staticids.nix;
|
||||
hostConfig = config;
|
||||
in {
|
||||
users.users.foundry-vtt = {
|
||||
isSystemUser = true;
|
||||
uid = cids.uids.foundry-vtt;
|
||||
home = "/var/lib/foundry-vtt";
|
||||
group = "foundry-vtt";
|
||||
createHome = true;
|
||||
};
|
||||
|
||||
users.groups.foundry-vtt = {
|
||||
gid = cids.gids.foundry-vtt;
|
||||
};
|
||||
|
||||
|
||||
containers.foundry-vtt = {
|
||||
autoStart = true;
|
||||
ephemeral = true;
|
||||
privateNetwork = true;
|
||||
hostBridge = "server";
|
||||
hostAddress = "${hostConfig.networkPrefix}.97.1";
|
||||
localAddress = "${hostConfig.networkPrefix}.97.21/24";
|
||||
bindMounts = {
|
||||
"/var/lib/foundry-vtt" = {
|
||||
hostPath = "/var/lib/foundry-vtt";
|
||||
isReadOnly = false;
|
||||
};
|
||||
};
|
||||
config = { lib, config, pkgs, ... }: {
|
||||
networking = {
|
||||
hostName = "foundry-vtt";
|
||||
useHostResolvConf = false;
|
||||
defaultGateway = {
|
||||
address = "${hostConfig.networkPrefix}.97.1";
|
||||
interface = "eth0";
|
||||
};
|
||||
nameservers = [ "${hostConfig.networkPrefix}.97.1" ];
|
||||
};
|
||||
systemd.services.foundry-vtt = {
|
||||
description = "Foundry VTT Server";
|
||||
after = [ "network.target" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
environment = {
|
||||
NODE_ENV = "production";
|
||||
};
|
||||
serviceConfig = {
|
||||
ExecStart = "${pkgs.nodejs}/bin/node ${foundry-vtt}/share/foundry-vtt/resources/app/main.js --dataPath=${config.users.users.foundry-vtt.home}";
|
||||
Restart = "always";
|
||||
User = "foundry-vtt";
|
||||
WorkingDirectory = "${config.users.users.foundry-vtt.home}";
|
||||
};
|
||||
};
|
||||
|
||||
users.users.foundry-vtt = {
|
||||
isSystemUser = true;
|
||||
uid = cids.uids.foundry-vtt;
|
||||
home = "/var/lib/foundry-vtt";
|
||||
group = "foundry-vtt";
|
||||
};
|
||||
|
||||
users.groups.foundry-vtt = {
|
||||
gid = cids.gids.foundry-vtt;
|
||||
};
|
||||
|
||||
networking.firewall = {
|
||||
enable = true;
|
||||
allowedTCPPorts = [ 30000 ];
|
||||
};
|
||||
|
||||
|
||||
system.stateVersion = "24.05";
|
||||
};
|
||||
};
|
||||
}
|
||||
30
hosts/fw/modules/fwmetrics.nix
Normal file
30
hosts/fw/modules/fwmetrics.nix
Normal file
@@ -0,0 +1,30 @@
|
||||
{ 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;
|
||||
};
|
||||
};
|
||||
}
|
||||
233
hosts/fw/modules/gitea-vm.nix
Normal file
233
hosts/fw/modules/gitea-vm.nix
Normal file
@@ -0,0 +1,233 @@
|
||||
{ lib, nixpkgs, pkgs, ... }: let
|
||||
# hostname = "git-02";
|
||||
# json = pkgs.formats.json { };
|
||||
runners = ["git-runner-1" "git-runner-2"];
|
||||
indexedRunners = lib.lists.imap1 (i: v: { name=v; value=i; }) runners;
|
||||
in {
|
||||
microvm.vms = lib.mapAttrs (runner: idx: {
|
||||
config = {
|
||||
microvm = {
|
||||
mem = 4048;
|
||||
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 = 51200;
|
||||
}
|
||||
];
|
||||
interfaces = [
|
||||
{
|
||||
type = "tap";
|
||||
id = "vm-${runner}";
|
||||
mac = "02:00:00:00:00:0${toString idx}";
|
||||
}
|
||||
];
|
||||
};
|
||||
|
||||
networking.hostName = runner;
|
||||
|
||||
virtualisation.podman.enable = true;
|
||||
|
||||
services.gitea-actions-runner.instances.${runner} = {
|
||||
enable = true;
|
||||
url = "https://git.cloonar.com";
|
||||
name = runner;
|
||||
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"
|
||||
];
|
||||
|
||||
system.stateVersion = "22.05";
|
||||
};
|
||||
}) (lib.listToAttrs (lib.lists.imap1 (i: v: { name=v; value=i; }) runners));
|
||||
|
||||
# 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;
|
||||
# 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-1 = {
|
||||
# config = {
|
||||
# microvm = {
|
||||
# mem = 4048;
|
||||
# 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-1";
|
||||
# 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
|
||||
];
|
||||
};
|
||||
}
|
||||
128
hosts/fw/modules/gitea.nix
Normal file
128
hosts/fw/modules/gitea.nix
Normal file
@@ -0,0 +1,128 @@
|
||||
{ config, pkgs, ... }:
|
||||
let
|
||||
cids = import ../modules/staticids.nix;
|
||||
domain = "git.cloonar.com";
|
||||
networkPrefix = config.networkPrefix;
|
||||
|
||||
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 = "${networkPrefix}.97.1";
|
||||
localAddress = "${networkPrefix}.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;
|
||||
};
|
||||
"/run/secrets/gitea-mailer-password" = {
|
||||
hostPath = config.sops.secrets.gitea-mailer-password.path;
|
||||
};
|
||||
};
|
||||
config = { lib, config, pkgs, ... }: {
|
||||
imports = [
|
||||
../fleet.nix
|
||||
];
|
||||
|
||||
environment.systemPackages = with pkgs; [
|
||||
vim # my preferred editor
|
||||
];
|
||||
|
||||
networking = {
|
||||
hostName = "git";
|
||||
useHostResolvConf = false;
|
||||
defaultGateway = {
|
||||
address = "${networkPrefix}.96.1";
|
||||
interface = "eth0";
|
||||
};
|
||||
firewall.enable = false;
|
||||
nameservers = [ "${networkPrefix}.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
|
||||
mailerPasswordFile = "/run/secrets/gitea-mailer-password";
|
||||
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;
|
||||
ENABLE_NOTIFY_MAIL = true;
|
||||
};
|
||||
mailer = {
|
||||
ENABLED = true;
|
||||
FROM = "Gitea Cloonar <gitea@cloonar.com>";
|
||||
PROTOCOL = "smtp+starttls";
|
||||
SMTP_ADDR = "mail.cloonar.com";
|
||||
SMTP_PORT = 587;
|
||||
USER = "gitea@cloonar.com";
|
||||
};
|
||||
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 = {};
|
||||
sops.secrets.gitea-mailer-password = {
|
||||
owner = "gitea";
|
||||
restartUnits = [ "container@git.service" ];
|
||||
};
|
||||
}
|
||||
60
hosts/fw/modules/home-assistant/3dprinter.nix
Normal file
60
hosts/fw/modules/home-assistant/3dprinter.nix
Normal file
@@ -0,0 +1,60 @@
|
||||
{ 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') }}";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
120
hosts/fw/modules/home-assistant/ac.nix
Normal file
120
hosts/fw/modules/home-assistant/ac.nix
Normal file
@@ -0,0 +1,120 @@
|
||||
{ pkgs, ... }:
|
||||
{
|
||||
services.home-assistant.extraComponents = [
|
||||
"daikin"
|
||||
"enocean"
|
||||
];
|
||||
# services.home-assistant.customComponents = [
|
||||
# (pkgs.callPackage ./custom-components/scheduler.nix { })
|
||||
# ];
|
||||
services.home-assistant.customLovelaceModules = [
|
||||
(pkgs.callPackage ./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";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
91
hosts/fw/modules/home-assistant/battery.nix
Normal file
91
hosts/fw/modules/home-assistant/battery.nix
Normal file
@@ -0,0 +1,91 @@
|
||||
{
|
||||
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"
|
||||
];
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user