Compare commits
23 commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3c389f912c | ||
|
|
a24aa4dde2 | ||
|
|
73c0bdebd2 | ||
|
|
3452e094ff | ||
|
|
4c61cedf91 | ||
|
|
3058e0d69c | ||
|
|
c24fbdf955 | ||
|
|
3fda43968c | ||
|
|
32fe8f82f5 | ||
|
|
0735feba26 | ||
|
|
71ded70c2b | ||
|
|
abf8f95a34 | ||
|
|
fdc7ac9673 | ||
|
|
2309f18b98 | ||
|
|
986eeb018e | ||
|
|
10adf3cc48 | ||
|
|
89473de85e | ||
|
|
2d73c41c0c | ||
|
|
5a3ab03870 | ||
|
|
76064eb931 | ||
|
|
69d712e11f | ||
|
|
d030591514 | ||
|
|
e01e5fcd66 |
31 changed files with 608 additions and 312 deletions
5
esphome/.gitignore
vendored
Normal file
5
esphome/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
# Gitignore settings for ESPHome
|
||||
# This is an example and may include too much for your use-case.
|
||||
# You can modify this file to suit your needs.
|
||||
/.esphome/
|
||||
/secrets.yaml
|
||||
56
esphome/door.yaml
Normal file
56
esphome/door.yaml
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
esphome:
|
||||
name: "door"
|
||||
friendly_name: "Door"
|
||||
platform: ESP32
|
||||
board: esp-wrover-kit
|
||||
|
||||
api:
|
||||
encryption:
|
||||
key: !secret apikey_door
|
||||
|
||||
ota:
|
||||
- platform: esphome
|
||||
password: !secret otapass_door
|
||||
|
||||
ethernet:
|
||||
type: LAN8720
|
||||
mdc_pin: GPIO23
|
||||
mdio_pin: GPIO18
|
||||
clk_mode: GPIO0_IN
|
||||
phy_addr: 1
|
||||
power_pin: GPIO16
|
||||
|
||||
logger:
|
||||
|
||||
output:
|
||||
- platform: gpio
|
||||
pin: GPIO2
|
||||
id: output_relay
|
||||
|
||||
button:
|
||||
- platform: template
|
||||
name: "door opener"
|
||||
id: btn_door_opener
|
||||
icon: mdi:lock-open
|
||||
on_press:
|
||||
- output.turn_on: output_relay
|
||||
- delay: 2s
|
||||
- output.turn_off: output_relay
|
||||
|
||||
time:
|
||||
- platform: sntp
|
||||
id: sntp_time
|
||||
timezone: Europe/Berlin
|
||||
servers:
|
||||
- 0.pool.ntp.org
|
||||
- 1.pool.ntp.org
|
||||
- 2.pool.ntp.org
|
||||
|
||||
wireguard:
|
||||
address: 10.20.16.2
|
||||
private_key: !secret wireguard_key_door
|
||||
peer_endpoint: jalr-bw.duckdns.org
|
||||
peer_public_key: Ew25M4+OxfBGfW3g98m2chq+TIgWhxpVulrsuFmwOic=
|
||||
netmask: 255.255.255.252
|
||||
peer_port: 51001
|
||||
peer_persistent_keepalive: 120s
|
||||
2
esphome/secrets.yaml.gpg
Normal file
2
esphome/secrets.yaml.gpg
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
└^cЭi5▌V└@#пмkf1▓8г^БdГЦ╦ПЗ╖CУ┴╞jMZп■Щeb0J>│╖╟P╜йpЭД╡ыP*)┤Ё┐╩м║ODж%╔ЮDЧ▌╞╫Ц2╖╠╢о0 ВрюH─▀2─ХvzЪFЭ▌┼?yL║3!┤╝░K║сцс┼Eд,|%tc4ИpZШ⌡ЧД▌#6т═koMx|Еe├┌V_9└S}7р╕в÷Bт┐]Жs°°НШtv▐ax╣╤>p╥И┴j%ZYкДог^Ф_pV║╟[Mh#╩b=щ═3~и:Ф{
|
||||
└oLOу∙MМtC╓<ar╥ZХ│&Уu╙┌,ы ╣н=z╣Ac╤>╜#lZЕOM═@╣┤ёЩiл═)Рзu╗ю╖;┘
|
||||
101
flake.lock
generated
101
flake.lock
generated
|
|
@ -7,11 +7,11 @@
|
|||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1727196810,
|
||||
"narHash": "sha256-xQzgXRlczZoFfrUdA4nD5qojCQVqpiIk82aYINQZd+U=",
|
||||
"lastModified": 1745369821,
|
||||
"narHash": "sha256-mi6cAjuBztm9gFfpiVo6mAn81cCID6nmDXh5Kmyjwyc=",
|
||||
"owner": "nix-community",
|
||||
"repo": "disko",
|
||||
"rev": "6d42596a35d34918a905e8539a44d3fc91f42b5b",
|
||||
"rev": "c5140c6079ff690e85eac0b86e254de16a79a4b7",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
|
@ -41,11 +41,11 @@
|
|||
"systems": "systems"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1726560853,
|
||||
"narHash": "sha256-X6rJYSESBVr3hBoH0WbKE5KvhPU5bloyZ2L4K60/fPQ=",
|
||||
"lastModified": 1731533236,
|
||||
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"rev": "c1dfcf08411b08f6b8615f7d8971a2bfa81d5e8a",
|
||||
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
|
@ -125,16 +125,15 @@
|
|||
"flake-compat": "flake-compat",
|
||||
"gitignore": "gitignore",
|
||||
"nixpkgs": [
|
||||
"nixpkgs-unstable"
|
||||
],
|
||||
"nixpkgs-stable": "nixpkgs-stable"
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1726745158,
|
||||
"narHash": "sha256-D5AegvGoEjt4rkKedmxlSEmC+nNLMBPWFxvmYnVLhjk=",
|
||||
"lastModified": 1742649964,
|
||||
"narHash": "sha256-DwOTp7nvfi8mRfuL1escHDXabVXFGT1VlPD1JHrtrco=",
|
||||
"owner": "cachix",
|
||||
"repo": "pre-commit-hooks.nix",
|
||||
"rev": "4e743a6920eab45e8ba0fbe49dc459f1423a4b74",
|
||||
"rev": "dcf5072734cb576d2b0c59b2ac44f5050b5eac82",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
|
@ -146,11 +145,11 @@
|
|||
},
|
||||
"nixos-hardware": {
|
||||
"locked": {
|
||||
"lastModified": 1727040444,
|
||||
"narHash": "sha256-19FNN5QT9Z11ZUMfftRplyNN+2PgcHKb3oq8KMW/hDA=",
|
||||
"lastModified": 1745392233,
|
||||
"narHash": "sha256-xmqG4MZArM1JNxPJ33s0MtuBzgnaCO9laARoU3AfP8E=",
|
||||
"owner": "nixos",
|
||||
"repo": "nixos-hardware",
|
||||
"rev": "d0cb432a9d28218df11cbd77d984a2a46caeb5ac",
|
||||
"rev": "8bf8a2a0822365bd8f44fd1a19d7ed0a1d629d64",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
|
@ -162,64 +161,16 @@
|
|||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1726969270,
|
||||
"narHash": "sha256-8fnFlXBgM/uSvBlLWjZ0Z0sOdRBesyNdH0+esxqizGc=",
|
||||
"lastModified": 1745279238,
|
||||
"narHash": "sha256-AQ7M9wTa/Pa/kK5pcGTgX/DGqMHyzsyINfN7ktsI7Fo=",
|
||||
"owner": "nixos",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "23cbb250f3bf4f516a2d0bf03c51a30900848075",
|
||||
"rev": "9684b53175fc6c09581e94cc85f05ab77464c7e3",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nixos",
|
||||
"ref": "nixos-24.05",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs-stable": {
|
||||
"locked": {
|
||||
"lastModified": 1720386169,
|
||||
"narHash": "sha256-NGKVY4PjzwAa4upkGtAMz1npHGoRzWotlSnVlqI40mo=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "194846768975b7ad2c4988bdb82572c00222c0d7",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "nixos-24.05",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs-stable_2": {
|
||||
"locked": {
|
||||
"lastModified": 1725762081,
|
||||
"narHash": "sha256-vNv+aJUW5/YurRy1ocfvs4q/48yVESwlC/yHzjkZSP8=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "dc454045f5b5d814e5862a6d057e7bb5c29edc05",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "release-24.05",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs-unstable": {
|
||||
"locked": {
|
||||
"lastModified": 1726937504,
|
||||
"narHash": "sha256-bvGoiQBvponpZh8ClUcmJ6QnsNKw0EMrCQJARK3bI1c=",
|
||||
"owner": "nixos",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "9357f4f23713673f310988025d9dc261c20e70c6",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nixos",
|
||||
"ref": "nixos-unstable",
|
||||
"ref": "nixos-24.11",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
|
|
@ -260,7 +211,6 @@
|
|||
"nix-pre-commit-hooks": "nix-pre-commit-hooks",
|
||||
"nixos-hardware": "nixos-hardware",
|
||||
"nixpkgs": "nixpkgs",
|
||||
"nixpkgs-unstable": "nixpkgs-unstable",
|
||||
"sbruder-overlay": "sbruder-overlay",
|
||||
"sops-nix": "sops-nix"
|
||||
}
|
||||
|
|
@ -279,11 +229,11 @@
|
|||
"poetry2nix": "poetry2nix"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1719952130,
|
||||
"narHash": "sha256-j38XlExNwK4ycmoNEdH/dHUd1QGdNvD3gx/UuLY+04Q=",
|
||||
"lastModified": 1743090264,
|
||||
"narHash": "sha256-0eKQMldOcNBwkzf09zJWf8io3Kd3PjGQSnhpOueWEdk=",
|
||||
"owner": "sbruder",
|
||||
"repo": "nixpkgs-overlay",
|
||||
"rev": "3487b8ce24d40cc898f3dba0a9af5e028e1d5844",
|
||||
"rev": "f107df0aba9e3d582d1c01b40392416e47fb28dd",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
|
@ -296,15 +246,14 @@
|
|||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"nixpkgs"
|
||||
],
|
||||
"nixpkgs-stable": "nixpkgs-stable_2"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1726524647,
|
||||
"narHash": "sha256-qis6BtOOBBEAfUl7FMHqqTwRLB61OL5OFzIsOmRz2J4=",
|
||||
"lastModified": 1745310711,
|
||||
"narHash": "sha256-ePyTpKEJTgX0gvgNQWd7tQYQ3glIkbqcW778RpHlqgA=",
|
||||
"owner": "Mic92",
|
||||
"repo": "sops-nix",
|
||||
"rev": "e2d404a7ea599a013189aa42947f66cede0645c8",
|
||||
"rev": "5e3e92b16d6fdf9923425a8d4df7496b2434f39c",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
|
|
|||
56
flake.nix
56
flake.nix
|
|
@ -1,31 +1,40 @@
|
|||
{
|
||||
inputs = {
|
||||
disko.inputs.nixpkgs.follows = "nixpkgs";
|
||||
disko.url = "github:nix-community/disko";
|
||||
disko = {
|
||||
url = "github:nix-community/disko";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
|
||||
flake-utils.url = "github:numtide/flake-utils";
|
||||
|
||||
nix-pre-commit-hooks.url = "github:cachix/pre-commit-hooks.nix/master";
|
||||
nix-pre-commit-hooks.inputs.flake-utils.follows = "flake-utils";
|
||||
nix-pre-commit-hooks.inputs.nixpkgs.follows = "nixpkgs-unstable";
|
||||
nix-pre-commit-hooks = {
|
||||
url = "github:cachix/pre-commit-hooks.nix/master";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
|
||||
nixpkgs.url = "github:nixos/nixpkgs/nixos-24.05";
|
||||
|
||||
nixpkgs-unstable.url = "github:nixos/nixpkgs/nixos-unstable";
|
||||
nixpkgs.url = "github:nixos/nixpkgs/nixos-24.11";
|
||||
|
||||
nixos-hardware.url = "github:nixos/nixos-hardware/master";
|
||||
|
||||
krops.url = "github:Mic92/krops";
|
||||
krops.inputs.flake-utils.follows = "flake-utils";
|
||||
krops.inputs.nixpkgs.follows = "nixpkgs";
|
||||
krops = {
|
||||
url = "github:Mic92/krops";
|
||||
inputs.flake-utils.follows = "flake-utils";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
|
||||
sops-nix.url = "github:Mic92/sops-nix";
|
||||
sops-nix.inputs.nixpkgs.follows = "nixpkgs";
|
||||
sops-nix = {
|
||||
url = "github:Mic92/sops-nix";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
|
||||
sbruder-overlay.url = "github:sbruder/nixpkgs-overlay";
|
||||
sbruder-overlay.inputs.flake-utils.follows = "flake-utils";
|
||||
sbruder-overlay.inputs.nix-pre-commit-hooks.follows = "nix-pre-commit-hooks";
|
||||
sbruder-overlay.inputs.nixpkgs.follows = "nixpkgs";
|
||||
sbruder-overlay = {
|
||||
url = "github:sbruder/nixpkgs-overlay";
|
||||
inputs = {
|
||||
flake-utils.follows = "flake-utils";
|
||||
nix-pre-commit-hooks.follows = "nix-pre-commit-hooks";
|
||||
nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
outputs =
|
||||
|
|
@ -50,8 +59,13 @@
|
|||
src = ./.;
|
||||
hooks = {
|
||||
black.enable = true;
|
||||
deadnix.enable = true;
|
||||
nixpkgs-fmt.enable = true;
|
||||
shellcheck.enable = true;
|
||||
statix = {
|
||||
enable = true;
|
||||
settings.ignore = [ ".direnv" ];
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
@ -59,13 +73,13 @@
|
|||
devShells.default = pkgs.mkShell {
|
||||
name = "fablab-nixos-config";
|
||||
|
||||
buildInputs = (with pkgs; [
|
||||
buildInputs = with pkgs; [
|
||||
black
|
||||
nixpkgs-fmt
|
||||
shellcheck
|
||||
sops
|
||||
ssh-to-pgp
|
||||
]);
|
||||
];
|
||||
|
||||
shellHook = ''
|
||||
find ${./keys} -type f -print0 | xargs -0 ${pkgs.gnupg}/bin/gpg --quiet --import
|
||||
|
|
@ -73,7 +87,7 @@
|
|||
};
|
||||
|
||||
apps = lib.mapAttrs
|
||||
(name: program: { type = "app"; program = toString program; })
|
||||
(_name: program: { type = "app"; program = toString program; })
|
||||
(flake-utils.lib.flattenTree {
|
||||
deploy = lib.recurseIntoAttrs (lib.mapAttrs
|
||||
(hostname: machine:
|
||||
|
|
@ -107,7 +121,7 @@
|
|||
});
|
||||
|
||||
packages = lib.filterAttrs
|
||||
(n: v: lib.elem system v.meta.platforms)
|
||||
(_n: v: lib.elem system v.meta.platforms)
|
||||
(flake-utils.lib.flattenTree {
|
||||
inherit (pkgs)
|
||||
fablab;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
{ ... }@inputs:
|
||||
inputs:
|
||||
let
|
||||
hardware = inputs.nixos-hardware.nixosModules;
|
||||
in
|
||||
|
|
|
|||
|
|
@ -9,13 +9,15 @@
|
|||
nixpkgs.config = { allowAliases = false; };
|
||||
|
||||
console.keyMap = "de";
|
||||
services.xserver.layout = "de";
|
||||
|
||||
services.xserver.enable = true;
|
||||
services.xserver.desktopManager.gnome.enable = true;
|
||||
services.xserver.displayManager.gdm = {
|
||||
services.xserver = {
|
||||
enable = true;
|
||||
autoSuspend = false;
|
||||
layout = "de";
|
||||
desktopManager.gnome.enable = true;
|
||||
displayManager.gdm = {
|
||||
enable = true;
|
||||
autoSuspend = false;
|
||||
};
|
||||
};
|
||||
|
||||
security.sudo.wheelNeedsPassword = false;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
{ config, lib, pkgs, modulesPath, ... }:
|
||||
{ modulesPath, ... }:
|
||||
|
||||
{
|
||||
imports = [
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
{ inputs, lib, pkgs, ... }:
|
||||
{ lib, pkgs, ... }:
|
||||
let
|
||||
ledDevices = {
|
||||
kanister = {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
{ config, ... }:
|
||||
|
||||
{
|
||||
imports = [
|
||||
|
|
@ -7,11 +7,11 @@
|
|||
./services
|
||||
];
|
||||
|
||||
networking.hostName = "raven";
|
||||
|
||||
time.timeZone = "Etc/UTC";
|
||||
|
||||
networking = {
|
||||
hostName = "raven";
|
||||
useDHCP = false;
|
||||
vlans = {
|
||||
labprod = {
|
||||
|
|
@ -51,6 +51,7 @@
|
|||
"voip"
|
||||
];
|
||||
};
|
||||
firewall.allowedTCPPorts = [ 80 443 ];
|
||||
};
|
||||
|
||||
i18n.defaultLocale = "en_US.UTF-8";
|
||||
|
|
@ -84,12 +85,19 @@
|
|||
|
||||
services.nginx.enable = true;
|
||||
|
||||
networking.firewall.allowedTCPPorts = [ 80 443 ];
|
||||
|
||||
# FIXME
|
||||
networking.hosts = {
|
||||
"192.168.94.1" = [ "raven.lab.fablab-nea.de" "labsync.lab.fablab-nea.de" ];
|
||||
};
|
||||
|
||||
fablab.luksUsbUnlock = {
|
||||
enable = true;
|
||||
devices."${config.disko.devices.disk.nvme.content.partitions.luks.content.name}" = {
|
||||
keyPath = "${config.networking.hostName}.key";
|
||||
usbDevice = "by-label/RAM_USB";
|
||||
waitForDevice = 10;
|
||||
};
|
||||
};
|
||||
|
||||
system.stateVersion = "24.05";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
{
|
||||
boot.initrd.systemd.enable = true;
|
||||
|
||||
disko.devices = {
|
||||
disk = {
|
||||
nvme = {
|
||||
|
|
@ -21,7 +23,7 @@
|
|||
size = "100%";
|
||||
content = {
|
||||
type = "luks";
|
||||
name = "raven-crypt";
|
||||
name = "raven_crypt";
|
||||
settings = {
|
||||
allowDiscards = true;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
{ config, lib, pkgs, modulesPath, ... }:
|
||||
{ modulesPath, ... }:
|
||||
|
||||
{
|
||||
imports = [
|
||||
|
|
|
|||
|
|
@ -4,6 +4,10 @@ asterisk-ari: ENC[AES256_GCM,data:2+X/DRmRlnVraWWEBXWXJ9XpFnRdD0HDlofQ7jaxNpWRKN
|
|||
asterisk-voicemail: ENC[AES256_GCM,data:4/Kbt/XMUGIIVpF9/KIMIi/Gx344dIleieVWch5J5z1gz2o5cLIF73qCj+vApDzSHcz2gTzMEKwEV6H8ZsxJse27dNBIdVq1n18oSWWAMT1iOomxxzqESLhF+HTtBIEpBVi5y5zwMRXGh/72SxKY9TXv/KHxTMp8aBhNvoCn2ze1VOcBjyNxGda4gGgFAa4LNTzxQ1B6XpfgkjsH2uY0zaAd8rrsXPrPY6TNS7JxrBLKfKshTiJCElJJJA1pCcRe4/yMqCm14J5+n3FvEOnHC+BQHX+ohJYaBcrZblWF5rH/l25BnUgP4UC9ydk3LmQiLpH20+sTWZwi/FojeID0BahdrzOk0tNCTKwNtfFp2QzYvlQPdFRCINb5k1Pz9DNLx7bSv1mvkeGNbd1YdHvEnPwYrQmAae96kg+Vl8PVRqY7ZsMsktcOfqlw8k/W4DK0G6LBA5U9G7JryS5OeS3kMMo4vQzcjU8/eZMl/XwHB0806k63wI7j3wL9Z5+DGmdLX3z3RgtJunELTcayAwerRptuwidm69hbOhmWEwkCcrR42QNVuDD8Qxp/CnwnmwUawUFBOFIBjbQApT9miOmo3e7nY5fjbf4JUbJ9/0JbT7YtZOEU9ymACobX6fweOsYUoWTXprJDwZkln8omaAbP85g4XgGGoltdTk71OviSSfN3DCKfPwPop8GZ9UEBQN9rNUyllVRoTeaweqN2VJnD/ApWj8A22i66R1CPm6ebXLOjClahs/hCKTeYHXPiDjWb5xd9c0fQBlnHaWbVYLtGzBpf0p9oU7DE2KskzZE2TDat8qCdMeqBcpEwUVGqcqq4YWDPy593XZzpG91NYDAb6GbkYHiZw+OQStEFA4SbN4YdwPB0fZN0iW+IOQPfWgUiRj2wAUYRXRpxPQ2ZDh7Ie0oZbJvhx6ulEM8nKI4q4e3pkzF7KjT2z9KzinkhvjqlpU0vfCm4BFMUcKXVskQsiDA9gz4w0m7Ei4HbyDHoUGVCUDtv0W6IfjrEUsBasxcYkown20rip/CwKTPmKy26bz6iHgUAB6f71Ms8sdKr7gHdnzOK3OBm5I+gell6SsdDDfGgQdUHJwSu8XwwJdc7Faai7+wN1stfSglm4PwuoFIH9ucgVyXrAwLJIQ==,iv:QzVHcduZhvQalSgRWRDoTpc20cYLFwzqDedET/XnBWQ=,tag:mrkXZ3J3Hiy2Q7Y06LsBuA==,type:str]
|
||||
prometheus-htpasswd: ENC[AES256_GCM,data:kUU0TqnVxQ8jLfjUpBje3eGxJw+ItD/YSNhiny1XPM0PDksnOO8Ecbyqm9W5p3WZIFc+h/FH1AsyNdhXdAhbgMNNxjebq2PNbJr/DeMWTxuf1D9q5iYpDrFGuK6r65DeCPvwN1tlTKkzJnLCqy3LLWbziANplMpmoUL7Ay3S2r5UQNgl4QIL,iv:o23da3kSbMAiF6H3zgja95As89aDK/+jWofvw9ZIjj8=,tag:VPB9YD33Xuk8IKxoBVEXdQ==,type:str]
|
||||
unpoller-password: ENC[AES256_GCM,data:nvbKOzS657tfumP93kNAD2Edw3+BN3xQ,iv:FZ169TIyHrhazji+b2V4o0XvyzqwNelnR4TkKXuNqWg=,tag:62Y1LTlI+2KdSjq8dHiuSQ==,type:str]
|
||||
nextcloud-adminpass: ENC[AES256_GCM,data:8yX92evqkh5XDuKaPdaOxXX474mE2m5b,iv:2gKYS2s2oW0s4hhug6Y8n+8M9YMxIzcTLAp5gbktfkQ=,tag:eoT892rpSKvReve4Au+uSA==,type:str]
|
||||
authelia:
|
||||
jwtSecret: ENC[AES256_GCM,data:SvFGmrW+eYQr3J9xRpo1IT2H54eX58+Li+aT461bwjS0B6cswlLF/l8O2lRduLghXy80bQDYFOzfO8t0ENowhA==,iv:0jODFRL/ic07B8hLY/6LhY/ll+2uYyKbJJZAV2aZ6sw=,tag:oyTdsbRdzheq1VJRg9/PYw==,type:str]
|
||||
storageEncryptionKey: ENC[AES256_GCM,data:4v2mpLvi3hRfQJCgek7RZmF/y0zb9WjQewckpp8IAOqq+YggFA2QLoDJW1fIINLNe0ACuPBdVCKQlgqt3ecqXQ==,iv:1qOSty0pNXCW5R4vSH4HTSAvQu/YelKVXUQqWfPcFhM=,tag:WZ7oDQSVn44jVyppeMQYUg==,type:str]
|
||||
sops:
|
||||
kms: []
|
||||
gcp_kms: []
|
||||
|
|
@ -19,8 +23,8 @@ sops:
|
|||
T2VuTEpzYmhESnJZTW5IS3orRk44ODAK/KBOctiKRH5y/zuI4sIKNK9nze6aDOmc
|
||||
Eg7zjCXX3hvmowFt45rMKODJ56Dy6uJEgu6OWMWV2M87CphyHKA5fg==
|
||||
-----END AGE ENCRYPTED FILE-----
|
||||
lastmodified: "2023-08-04T10:58:16Z"
|
||||
mac: ENC[AES256_GCM,data:yRoKVClRcbqFYM06F+83kU9s0KcoiYEx0fpr4DL39YoDDx3ZdX2aYqOEtPCGHKEccFanDsZSI4Q9jG2NEa9IykI9DDjQtci1pcNkt9VaWgPTTo2KzP086ncQHaKHyy109CjugeC2oQYIOBfSiO5b+/SP5fml2N3rhIGzROz2NRA=,iv:JR2MVuIxVhCDsx8kelTu86x4Snf6yqJ7s9vb/3bj24o=,tag:V9BadPHshitupxnAzYF3Nw==,type:str]
|
||||
lastmodified: "2024-12-03T21:53:44Z"
|
||||
mac: ENC[AES256_GCM,data:HFbHfL1i24LyNx+5QYgcMmBUwfQeZscdPFQHlgtJcM9Tsx/Y0wyn2B/veYR30GepQ0CBhC0IKsBDfL4K6AooqkhhBKHTVBINTn4ec9yholIJoepn4OmM4A6CE3xEkyE/PQwTEtABbJkMeUbLuZ1FcLYSo0vXfe4Jvs79o/svivk=,iv:lYZyVlvBuZrP7wzWWh+hJ1nlUXsLKQHpFhOZuXdQtqA=,tag:uxRhOkrjRFVhJYPsahxEFw==,type:str]
|
||||
pgp:
|
||||
- created_at: "2024-09-24T19:30:34Z"
|
||||
enc: |-
|
||||
|
|
@ -54,4 +58,4 @@ sops:
|
|||
-----END PGP MESSAGE-----
|
||||
fp: 47E7559E037A35652DBBF8AA8D3C82F9F309F8EC
|
||||
unencrypted_suffix: _unencrypted
|
||||
version: 3.7.3
|
||||
version: 3.9.1
|
||||
|
|
|
|||
|
|
@ -111,12 +111,12 @@ in
|
|||
ln -s ${cfg.package}/var/lib/asterisk/static-http/core-en_US.xml /var/lib/asterisk/documentation/core-en_US.xml
|
||||
'';
|
||||
|
||||
sops.secrets = (lib.listToAttrs (map
|
||||
sops.secrets = lib.listToAttrs (map
|
||||
(name: lib.nameValuePair "asterisk-${name}" {
|
||||
sopsFile = ../secrets.yaml;
|
||||
owner = config.users.users.asterisk.name;
|
||||
})
|
||||
secretConfigFiles));
|
||||
secretConfigFiles);
|
||||
environment.etc = lib.mapAttrs'
|
||||
(name: _: lib.nameValuePair
|
||||
"asterisk/${name}.conf"
|
||||
|
|
|
|||
76
machines/raven/services/authelia.nix
Normal file
76
machines/raven/services/authelia.nix
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
{ config, ... }:
|
||||
|
||||
let
|
||||
domain = "authelia.fablab-nea.de";
|
||||
cfg = config.services.authelia.instances.default;
|
||||
port = 9001;
|
||||
in
|
||||
{
|
||||
sops.secrets = {
|
||||
"authelia/jwtSecret" = {
|
||||
sopsFile = ../secrets.yaml;
|
||||
owner = cfg.user;
|
||||
};
|
||||
"authelia/storageEncryptionKey" = {
|
||||
sopsFile = ../secrets.yaml;
|
||||
owner = cfg.user;
|
||||
};
|
||||
};
|
||||
|
||||
services = {
|
||||
authelia.instances.default = {
|
||||
enable = true;
|
||||
settings = {
|
||||
server.address = "tcp://127.0.0.1:${toString port}/";
|
||||
access_control = {
|
||||
default_policy = "one_factor";
|
||||
};
|
||||
notifier.filesystem = {
|
||||
filename = "/var/lib/authelia-${cfg.name}/notif.txt";
|
||||
};
|
||||
storage.postgres = {
|
||||
address = "unix:///run/postgresql";
|
||||
database = "authelia-${cfg.name}";
|
||||
username = "authelia-${cfg.name}";
|
||||
password = "authelia-${cfg.name}";
|
||||
};
|
||||
authentication_backend = {
|
||||
file.path = "/var/lib/authelia-${cfg.name}/user.yml";
|
||||
};
|
||||
session = {
|
||||
cookies = [
|
||||
{
|
||||
inherit domain;
|
||||
authelia_url = "https://${domain}";
|
||||
name = "authelia_session";
|
||||
}
|
||||
];
|
||||
};
|
||||
};
|
||||
secrets = {
|
||||
jwtSecretFile = config.sops.secrets."authelia/jwtSecret".path;
|
||||
storageEncryptionKeyFile = config.sops.secrets."authelia/storageEncryptionKey".path;
|
||||
};
|
||||
};
|
||||
|
||||
postgresql = {
|
||||
ensureUsers = [{
|
||||
name = "authelia-${cfg.name}";
|
||||
ensureDBOwnership = true;
|
||||
}];
|
||||
ensureDatabases = [ "authelia-${cfg.name}" ];
|
||||
};
|
||||
|
||||
nginx.virtualHosts."${domain}" = {
|
||||
enableACME = true;
|
||||
forceSSL = true;
|
||||
extraConfig = ''
|
||||
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
|
||||
'';
|
||||
locations."/" = {
|
||||
proxyPass = "http://127.0.0.1:${toString port}";
|
||||
recommendedProxySettings = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
{ inputs, lib, pkgs, ... }:
|
||||
{ lib, pkgs, ... }:
|
||||
let
|
||||
ledDevices = {
|
||||
workbench-1 = {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
{
|
||||
imports = [
|
||||
./asterisk.nix
|
||||
./authelia.nix
|
||||
./colorchord.nix
|
||||
./dnsmasq.nix
|
||||
./dyndns.nix
|
||||
|
|
@ -8,6 +9,7 @@
|
|||
./grafana.nix
|
||||
./labsync
|
||||
./mailhog.nix
|
||||
./nextcloud.nix
|
||||
./prometheus.nix
|
||||
./unifi-controller.nix
|
||||
./wekan.nix
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
{ config, ... }:
|
||||
|
||||
let
|
||||
domain = "grafana.fablab-nea.de";
|
||||
|
|
|
|||
|
|
@ -5,39 +5,43 @@ let
|
|||
generator_port = 8695;
|
||||
in
|
||||
{
|
||||
services.opentracker.enable = true;
|
||||
services = {
|
||||
opentracker.enable = true;
|
||||
|
||||
services.nginx.virtualHosts."labsync.fablab-nea.de" = {
|
||||
addSSL = true;
|
||||
enableACME = true;
|
||||
locations = {
|
||||
"/generator/".proxyPass = "http://127.0.0.1:${toString generator_port}/";
|
||||
atftpd = {
|
||||
enable = true;
|
||||
root = pkgs.runCommand "pxelinux-tftproot" { } ''
|
||||
mkdir -p $out/pxelinux.cfg
|
||||
cp ${pkgs.syslinux}/share/syslinux/{ldlinux.c32,libcom32.c32,libutil.c32,lpxelinux.0,vesamenu.c32} $out
|
||||
cp ${./splash.png} $out/splash.png
|
||||
cp ${./pxelinux.cfg} $out/pxelinux.cfg/default
|
||||
# required to serve labsync/labsync.cfg, which is generated dynamically by a docker container
|
||||
ln -s /opt/docker/tftpgen/data $out/labsync
|
||||
'';
|
||||
};
|
||||
};
|
||||
services.nginx.virtualHosts."labsync.lab.fablab-nea.de" = {
|
||||
locations = {
|
||||
"/" = {
|
||||
root = "/opt/docker/tftpgen/data";
|
||||
extraConfig = ''
|
||||
autoindex on;
|
||||
'';
|
||||
|
||||
nginx.virtualHosts = {
|
||||
"labsync.fablab-nea.de" = {
|
||||
addSSL = true;
|
||||
enableACME = true;
|
||||
locations = {
|
||||
"/generator/".proxyPass = "http://127.0.0.1:${toString generator_port}/";
|
||||
};
|
||||
};
|
||||
"labsync.lab.fablab-nea.de" = {
|
||||
locations = {
|
||||
"/" = {
|
||||
root = "/opt/docker/tftpgen/data";
|
||||
extraConfig = ''
|
||||
autoindex on;
|
||||
'';
|
||||
};
|
||||
"/generator/".proxyPass = "http://127.0.0.1:${toString generator_port}/";
|
||||
};
|
||||
};
|
||||
"/generator/".proxyPass = "http://127.0.0.1:${toString generator_port}/";
|
||||
};
|
||||
};
|
||||
|
||||
services.atftpd = {
|
||||
enable = true;
|
||||
root = pkgs.runCommand "pxelinux-tftproot" { } ''
|
||||
mkdir -p $out/pxelinux.cfg
|
||||
cp ${pkgs.syslinux}/share/syslinux/{ldlinux.c32,libcom32.c32,libutil.c32,lpxelinux.0,vesamenu.c32} $out
|
||||
cp ${./splash.png} $out/splash.png
|
||||
cp ${./pxelinux.cfg} $out/pxelinux.cfg/default
|
||||
# required to serve labsync/labsync.cfg, which is generated dynamically by a docker container
|
||||
ln -s /opt/docker/tftpgen/data $out/labsync
|
||||
'';
|
||||
};
|
||||
|
||||
networking.firewall.allowedTCPPorts = [
|
||||
6881 # aria2
|
||||
6969 # opentracker
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
{ config, ... }:
|
||||
{
|
||||
services.mailhog.enable = true;
|
||||
}
|
||||
|
|
|
|||
59
machines/raven/services/nextcloud.nix
Normal file
59
machines/raven/services/nextcloud.nix
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
{ config, pkgs, ... }:
|
||||
|
||||
let
|
||||
domain = "nextcloud.fablab-nea.de";
|
||||
in
|
||||
{
|
||||
sops.secrets.nextcloud-adminpass = {
|
||||
sopsFile = ../secrets.yaml;
|
||||
owner = "nextcloud";
|
||||
group = "nextcloud";
|
||||
};
|
||||
services.nextcloud = {
|
||||
enable = true;
|
||||
hostName = domain;
|
||||
#secretFile =
|
||||
#config.dbpassFile
|
||||
https = true;
|
||||
config = {
|
||||
adminpassFile = config.sops.secrets.nextcloud-adminpass.path;
|
||||
dbtype = "pgsql";
|
||||
};
|
||||
settings = {
|
||||
overwriteprotocol = "https";
|
||||
|
||||
oidc_login_client_id = "nextcloud";
|
||||
oidc_login_provider_url = "https://keycloak.fablab-nea.de";
|
||||
oidc_login_attributes = {
|
||||
id = "preferred_username";
|
||||
};
|
||||
oidc_login_scope = "openid profile";
|
||||
oidc_login_button_text = "Log in with OpenID";
|
||||
oidc_login_code_challenge_method = "S256";
|
||||
};
|
||||
database.createLocally = true;
|
||||
extraApps =
|
||||
with config.services.nextcloud.package.packages.apps;
|
||||
{
|
||||
inherit
|
||||
bookmarks
|
||||
calendar
|
||||
contacts
|
||||
deck
|
||||
tasks
|
||||
;
|
||||
}
|
||||
// {
|
||||
oidc_login = pkgs.fetchNextcloudApp {
|
||||
license = "agpl3Plus";
|
||||
url = "https://github.com/pulsejet/nextcloud-oidc-login/releases/download/v3.2.0/oidc_login.tar.gz";
|
||||
sha256 = "sha256-DrbaKENMz2QJfbDKCMrNGEZYpUEvtcsiqw9WnveaPZA=";
|
||||
};
|
||||
};
|
||||
extraAppsEnable = true;
|
||||
};
|
||||
services.nginx.virtualHosts."${domain}" = {
|
||||
forceSSL = true;
|
||||
enableACME = true;
|
||||
};
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
{ config, lib, ... }:
|
||||
|
||||
let
|
||||
domain = "prometheus.fablab-nea.de";
|
||||
|
|
@ -7,137 +7,139 @@ let
|
|||
mkStaticTarget = target: mkStaticTargets (lib.singleton target);
|
||||
in
|
||||
{
|
||||
services.prometheus.exporters.node.enable = true;
|
||||
|
||||
services.prometheus = {
|
||||
enable = true;
|
||||
listenAddress = "127.0.0.1";
|
||||
webExternalUrl = "https://${domain}";
|
||||
globalConfig = {
|
||||
scrape_interval = "15s";
|
||||
evaluation_interval = "15s";
|
||||
};
|
||||
extraFlags = [
|
||||
"--storage.tsdb.retention.time=90d"
|
||||
"--web.enable-admin-api"
|
||||
];
|
||||
alertmanagers = [
|
||||
{
|
||||
static_configs = mkStaticTarget "${cfg.alertmanager.listenAddress}:${toString cfg.alertmanager.port}";
|
||||
path_prefix = "/alertmanager/";
|
||||
}
|
||||
];
|
||||
alertmanager = {
|
||||
enable = true;
|
||||
listenAddress = "127.0.0.1";
|
||||
webExternalUrl = "https://${domain}/alertmanager";
|
||||
configuration = {
|
||||
global.resolve_timeout = "2m";
|
||||
|
||||
route = {
|
||||
receiver = "matrix";
|
||||
group_by = [ "alertname" ];
|
||||
group_wait = "3m";
|
||||
};
|
||||
|
||||
receivers = [
|
||||
{
|
||||
name = "matrix";
|
||||
webhook_configs = lib.singleton {
|
||||
url = "http://localhost/webhook";
|
||||
};
|
||||
}
|
||||
];
|
||||
};
|
||||
};
|
||||
scrapeConfigs = [
|
||||
{
|
||||
job_name = "prometheus";
|
||||
static_configs = mkStaticTargets [
|
||||
"localhost:${toString cfg.port}"
|
||||
"kleinturmbuehne-router:9100"
|
||||
];
|
||||
}
|
||||
{
|
||||
job_name = "node";
|
||||
static_configs = mkStaticTargets [
|
||||
"127.0.0.1:9100"
|
||||
];
|
||||
}
|
||||
{
|
||||
job_name = "asterisk";
|
||||
metrics_path = "/";
|
||||
static_configs = mkStaticTargets [
|
||||
"127.0.0.1:8088"
|
||||
];
|
||||
}
|
||||
{
|
||||
job_name = "mikrotik";
|
||||
static_configs = mkStaticTargets [
|
||||
"${cfg.exporters.mikrotik.listenAddress}:${toString cfg.exporters.mikrotik.port}"
|
||||
];
|
||||
}
|
||||
{
|
||||
job_name = "unifi";
|
||||
static_configs = mkStaticTargets [
|
||||
"${cfg.exporters.unpoller.listenAddress}:${toString cfg.exporters.unpoller.port}"
|
||||
];
|
||||
}
|
||||
];
|
||||
rules =
|
||||
let
|
||||
mkAlert = { name, expr, for ? "1m", description ? null }: {
|
||||
alert = name;
|
||||
inherit expr for;
|
||||
annotations = lib.optionalAttrs (description != null) { inherit description; };
|
||||
};
|
||||
in
|
||||
[
|
||||
(lib.generators.toYAML { } {
|
||||
groups = lib.singleton {
|
||||
name = "alert.rules";
|
||||
rules = map mkAlert [
|
||||
{
|
||||
name = "InstanceDown";
|
||||
expr = ''up == 0'';
|
||||
description = "Instance {{ $labels.instance }} of job {{ $labels.job }} has been down for
|
||||
more than 1 minutes.";
|
||||
}
|
||||
];
|
||||
};
|
||||
})
|
||||
];
|
||||
};
|
||||
|
||||
sops.secrets.prometheus-htpasswd = {
|
||||
owner = "nginx";
|
||||
sopsFile = ../secrets.yaml;
|
||||
};
|
||||
|
||||
services.nginx.virtualHosts."${domain}" = {
|
||||
enableACME = true;
|
||||
forceSSL = true;
|
||||
services = {
|
||||
|
||||
basicAuthFile = config.sops.secrets.prometheus-htpasswd.path;
|
||||
|
||||
locations = {
|
||||
"/".proxyPass = "http://${cfg.listenAddress}:${toString cfg.port}";
|
||||
|
||||
"/alertmanager/".proxyPass = "http://${cfg.alertmanager.listenAddress}:${toString cfg.alertmanager.port}";
|
||||
};
|
||||
};
|
||||
|
||||
services.prometheus.exporters.mikrotik = {
|
||||
enable = true;
|
||||
listenAddress = "127.0.0.1";
|
||||
configuration = {
|
||||
devices = [
|
||||
prometheus = {
|
||||
exporters.node.enable = true;
|
||||
enable = true;
|
||||
listenAddress = "127.0.0.1";
|
||||
webExternalUrl = "https://${domain}";
|
||||
globalConfig = {
|
||||
scrape_interval = "15s";
|
||||
evaluation_interval = "15s";
|
||||
};
|
||||
extraFlags = [
|
||||
"--storage.tsdb.retention.time=90d"
|
||||
"--web.enable-admin-api"
|
||||
];
|
||||
features = {
|
||||
bgp = true;
|
||||
dhcp = true;
|
||||
routes = true;
|
||||
optics = true;
|
||||
alertmanagers = [
|
||||
{
|
||||
static_configs = mkStaticTarget "${cfg.alertmanager.listenAddress}:${toString cfg.alertmanager.port}";
|
||||
path_prefix = "/alertmanager/";
|
||||
}
|
||||
];
|
||||
alertmanager = {
|
||||
enable = true;
|
||||
listenAddress = "127.0.0.1";
|
||||
webExternalUrl = "https://${domain}/alertmanager";
|
||||
configuration = {
|
||||
global.resolve_timeout = "2m";
|
||||
|
||||
route = {
|
||||
receiver = "matrix";
|
||||
group_by = [ "alertname" ];
|
||||
group_wait = "3m";
|
||||
};
|
||||
|
||||
receivers = [
|
||||
{
|
||||
name = "matrix";
|
||||
webhook_configs = lib.singleton {
|
||||
url = "http://localhost/webhook";
|
||||
};
|
||||
}
|
||||
];
|
||||
};
|
||||
};
|
||||
scrapeConfigs = [
|
||||
{
|
||||
job_name = "prometheus";
|
||||
static_configs = mkStaticTargets [
|
||||
"localhost:${toString cfg.port}"
|
||||
"kleinturmbuehne-router:9100"
|
||||
];
|
||||
}
|
||||
{
|
||||
job_name = "node";
|
||||
static_configs = mkStaticTargets [
|
||||
"127.0.0.1:9100"
|
||||
];
|
||||
}
|
||||
{
|
||||
job_name = "asterisk";
|
||||
metrics_path = "/";
|
||||
static_configs = mkStaticTargets [
|
||||
"127.0.0.1:8088"
|
||||
];
|
||||
}
|
||||
{
|
||||
job_name = "mikrotik";
|
||||
static_configs = mkStaticTargets [
|
||||
"${cfg.exporters.mikrotik.listenAddress}:${toString cfg.exporters.mikrotik.port}"
|
||||
];
|
||||
}
|
||||
{
|
||||
job_name = "unifi";
|
||||
static_configs = mkStaticTargets [
|
||||
"${cfg.exporters.unpoller.listenAddress}:${toString cfg.exporters.unpoller.port}"
|
||||
];
|
||||
}
|
||||
];
|
||||
rules =
|
||||
let
|
||||
mkAlert = { name, expr, for ? "1m", description ? null }: {
|
||||
alert = name;
|
||||
inherit expr for;
|
||||
annotations = lib.optionalAttrs (description != null) { inherit description; };
|
||||
};
|
||||
in
|
||||
[
|
||||
(lib.generators.toYAML { } {
|
||||
groups = lib.singleton {
|
||||
name = "alert.rules";
|
||||
rules = map mkAlert [
|
||||
{
|
||||
name = "InstanceDown";
|
||||
expr = ''up == 0'';
|
||||
description = "Instance {{ $labels.instance }} of job {{ $labels.job }} has been down for
|
||||
more than 1 minutes.";
|
||||
}
|
||||
];
|
||||
};
|
||||
})
|
||||
];
|
||||
};
|
||||
|
||||
prometheus.exporters.mikrotik = {
|
||||
enable = true;
|
||||
listenAddress = "127.0.0.1";
|
||||
configuration = {
|
||||
devices = [
|
||||
];
|
||||
features = {
|
||||
bgp = true;
|
||||
dhcp = true;
|
||||
routes = true;
|
||||
optics = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
nginx.virtualHosts."${domain}" = {
|
||||
enableACME = true;
|
||||
forceSSL = true;
|
||||
|
||||
basicAuthFile = config.sops.secrets.prometheus-htpasswd.path;
|
||||
|
||||
locations = {
|
||||
"/".proxyPass = "http://${cfg.listenAddress}:${toString cfg.port}";
|
||||
|
||||
"/alertmanager/".proxyPass = "http://${cfg.alertmanager.listenAddress}:${toString cfg.alertmanager.port}";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,13 +1,11 @@
|
|||
{ config, pkgs, ... }:
|
||||
|
||||
let
|
||||
promCfg = config.services.prometheus;
|
||||
in
|
||||
{
|
||||
services.unifi = {
|
||||
enable = true;
|
||||
openFirewall = true;
|
||||
unifiPackage = pkgs.unifi8;
|
||||
mongodbPackage = pkgs.mongodb-7_0;
|
||||
};
|
||||
networking.firewall.allowedTCPPorts = [ 8443 ];
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
{ lib, pkgs, ... }:
|
||||
let
|
||||
serviceName = "wekan";
|
||||
databaseName = "wekandb";
|
||||
|
|
@ -62,31 +62,33 @@ in
|
|||
};
|
||||
|
||||
# Create the netowrk
|
||||
systemd.services.init-filerun-network-and-files = {
|
||||
description = "Create the network bridge ${networkName} for WeKan.";
|
||||
after = [ "network.target" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
systemd.services = {
|
||||
init-filerun-network-and-files = {
|
||||
description = "Create the network bridge ${networkName} for WeKan.";
|
||||
after = [ "network.target" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
|
||||
serviceConfig.Type = "oneshot";
|
||||
script =
|
||||
let podmancli = "${pkgs.podman}/bin/podman";
|
||||
in ''
|
||||
if ! ${podmancli} network ls --format '{{ .Name }}' | grep -qFx -- "${networkName}"; then
|
||||
${podmancli} network create "${networkName}"
|
||||
else
|
||||
echo "network already exists"
|
||||
fi
|
||||
'';
|
||||
};
|
||||
|
||||
systemd.services.wekan-restart = {
|
||||
description = "Restart Wekan services.";
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
serviceConfig.Type = "oneshot";
|
||||
script =
|
||||
let podmancli = "${pkgs.podman}/bin/podman";
|
||||
in ''
|
||||
if ! ${podmancli} network ls --format '{{ .Name }}' | grep -qFx -- "${networkName}"; then
|
||||
${podmancli} network create "${networkName}"
|
||||
else
|
||||
echo "network already exists"
|
||||
fi
|
||||
'';
|
||||
};
|
||||
|
||||
wekan-restart = {
|
||||
description = "Restart Wekan services.";
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
};
|
||||
script = ''
|
||||
${pkgs.systemd}/bin/systemctl restart "podman-${databaseName}.service" "podman-${serviceName}.service"
|
||||
'';
|
||||
};
|
||||
script = ''
|
||||
${pkgs.systemd}/bin/systemctl restart "podman-${databaseName}.service" "podman-${serviceName}.service"
|
||||
'';
|
||||
};
|
||||
|
||||
systemd.timers.wekan-restart = {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
{
|
||||
imports = [
|
||||
./base.nix
|
||||
./luksusb.nix
|
||||
./nix.nix
|
||||
./pipewire.nix
|
||||
./pubkeys.nix
|
||||
|
|
|
|||
121
modules/luksusb.nix
Normal file
121
modules/luksusb.nix
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
{ config, lib, ... }:
|
||||
let
|
||||
cfg = config.fablab.luksUsbUnlock;
|
||||
in
|
||||
{
|
||||
options.fablab.luksUsbUnlock = with lib; with lib.types; {
|
||||
enable = mkEnableOption "unlock LUKS volumes with a USB device on boot";
|
||||
devices = mkOption {
|
||||
default = { };
|
||||
example = {
|
||||
cryptroot = {
|
||||
keyPath = "/path/to/the/key";
|
||||
usbDevice = "by-label/MY_USB";
|
||||
};
|
||||
};
|
||||
type = types.attrsOf (types.submodule {
|
||||
options = {
|
||||
keyPath = mkOption {
|
||||
example = "/mykey.key";
|
||||
description = mdDoc ''
|
||||
Path to the key file inside the USB device's filesystem.
|
||||
`/` is relative to the device's filesystem root.
|
||||
'';
|
||||
type = types.str;
|
||||
};
|
||||
|
||||
usbDevice = mkOption {
|
||||
example = "by-label/BOOTKEY";
|
||||
description = mdDoc ''
|
||||
Path to the USB device that contains the keys. (Path relative to `/dev/disk/`)
|
||||
'';
|
||||
type = types.str;
|
||||
};
|
||||
|
||||
waitForDevice = mkOption {
|
||||
default = 5;
|
||||
example = 10;
|
||||
description = mdDoc ''
|
||||
How many seconds to wait for the USB device to be detected by the
|
||||
kernel.
|
||||
'';
|
||||
type = types.ints.unsigned;
|
||||
};
|
||||
};
|
||||
});
|
||||
};
|
||||
};
|
||||
config = lib.mkIf cfg.enable (
|
||||
let
|
||||
makeUsbDevPath = usbDevice: "/dev/disk/" + usbDevice;
|
||||
makeMountPath = usbDevice: "/key/" + (builtins.hashString "md5" usbDevice);
|
||||
usbFsType = "vfat";
|
||||
|
||||
mapAttrsNameValue = f: set:
|
||||
lib.listToAttrs (map f (lib.attrsToList set));
|
||||
in
|
||||
{
|
||||
boot.initrd = {
|
||||
kernelModules = [ "uas" "usbcore" "usb_storage" "vfat" "nls_cp437" "nls_iso8859_1" ];
|
||||
systemd.services =
|
||||
let
|
||||
makeService = name: { usbDevice, waitForDevice, ... }:
|
||||
let
|
||||
usbDevPath = makeUsbDevPath usbDevice;
|
||||
usbMountPath = makeMountPath usbDevice;
|
||||
in
|
||||
{
|
||||
description = "Mount ${name} key";
|
||||
wantedBy = [ "cryptsetup.target" ];
|
||||
before = [ "systemd-cryptsetup@${name}.service" ];
|
||||
after = [ "systemd-modules-load.service" ];
|
||||
unitConfig.DefaultDependencies = "no";
|
||||
serviceConfig.Type = "oneshot";
|
||||
|
||||
script = ''
|
||||
if awk -v mountpoint="${usbMountPath}" '$2==mountpoint {f=1} END {exit !f}' /proc/mounts; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
attempts=0
|
||||
while [ ! -e ${lib.escapeShellArg usbDevPath} ]; do
|
||||
sleep 1
|
||||
if [ $attempts -ge ${toString waitForDevice} ]; then
|
||||
break;
|
||||
fi
|
||||
attempts=$((attempts+1))
|
||||
done
|
||||
|
||||
if [ -e ${lib.escapeShellArg usbDevPath} ]; then
|
||||
mkdir -m0500 -p ${lib.escapeShellArg usbMountPath}
|
||||
mount \
|
||||
-n \
|
||||
-t ${lib.escapeShellArg usbFsType} \
|
||||
-o ro,fmask=0137,dmask=0027 \
|
||||
${lib.escapeShellArg usbDevPath} \
|
||||
${lib.escapeShellArg usbMountPath}
|
||||
fi
|
||||
'';
|
||||
};
|
||||
in
|
||||
mapAttrsNameValue
|
||||
({ name, value }: {
|
||||
name = "luksusb-${name}";
|
||||
value = makeService name value;
|
||||
})
|
||||
cfg.devices;
|
||||
|
||||
luks.devices = builtins.mapAttrs
|
||||
(_: { keyPath, usbDevice, ... }:
|
||||
let
|
||||
usbMountPath = makeMountPath usbDevice;
|
||||
in
|
||||
{
|
||||
keyFile = "${usbMountPath}/${keyPath}";
|
||||
keyFileTimeout = 1;
|
||||
})
|
||||
cfg.devices;
|
||||
};
|
||||
}
|
||||
);
|
||||
}
|
||||
|
|
@ -27,7 +27,6 @@ in
|
|||
|
||||
registry = with inputs; {
|
||||
nixpkgs.flake = nixpkgs;
|
||||
nixpkgs-unstable.flake = nixpkgs-unstable;
|
||||
};
|
||||
nixPath = [
|
||||
"nixpkgs=${inputs.nixpkgs}"
|
||||
|
|
@ -51,13 +50,5 @@ in
|
|||
nixpkgs.overlays = with inputs; [
|
||||
self.overlays.default
|
||||
sbruder-overlay.overlays.default
|
||||
(final: prev: {
|
||||
unstable = import nixpkgs-unstable {
|
||||
inherit (config.nixpkgs)
|
||||
config
|
||||
overlays
|
||||
system;
|
||||
};
|
||||
})
|
||||
];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
{ pkgs, ... }:
|
||||
|
||||
{
|
||||
sound.enable = true;
|
||||
hardware.pulseaudio.enable = false;
|
||||
|
||||
services.pipewire = {
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
{ lib, ... }:
|
||||
|
||||
{
|
||||
nixpkgs.config.allowUnfreePredicate = (pkg: lib.elem (lib.getName pkg) [
|
||||
nixpkgs.config.allowUnfreePredicate = pkg: lib.elem (lib.getName pkg) [
|
||||
"unifi-controller"
|
||||
"mongodb"
|
||||
]);
|
||||
];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
final: prev:
|
||||
_final: prev:
|
||||
let
|
||||
inherit (prev) callPackage recurseIntoAttrs;
|
||||
in
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ pkgs.mkShell {
|
|||
|
||||
nativeBuildInputs = with pkgs; [
|
||||
(pkgs.writeShellScriptBin "nix" ''
|
||||
exec -a nix ${pkgs.nixUnstable}/bin/nix --experimental-features "nix-command flakes" "$@"
|
||||
exec -a nix ${pkgs.nixVersions.stable}/bin/nix --experimental-features "nix-command flakes" "$@"
|
||||
'')
|
||||
];
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue