Merge branch 'master' of ssh://git.giugl.io/peperunas/nixos

This commit is contained in:
Giulio De Pasquale 2023-06-06 13:33:06 -07:00
commit c805cc3dcb
45 changed files with 1032 additions and 776 deletions

42
flake.lock generated
View File

@ -4,52 +4,51 @@
"inputs": { "inputs": {
"nixpkgs": [ "nixpkgs": [
"nixpkgs" "nixpkgs"
], ]
"utils": "utils"
}, },
"locked": { "locked": {
"lastModified": 1681092193, "lastModified": 1685599623,
"narHash": "sha256-JerCqqOqbT2tBnXQW4EqwFl0hHnuZp21rIQ6lu/N4rI=", "narHash": "sha256-Tob4CMOVHue0D3RzguDBCtUmX5ji2PsdbQDbIOIKvsc=",
"owner": "nix-community", "owner": "nix-community",
"repo": "home-manager", "repo": "home-manager",
"rev": "f9edbedaf015013eb35f8caacbe0c9666bbc16af", "rev": "93db05480c0c0f30382d3e80779e8386dcb4f9dd",
"type": "github" "type": "github"
}, },
"original": { "original": {
"owner": "nix-community", "owner": "nix-community",
"ref": "release-22.11", "ref": "release-23.05",
"repo": "home-manager", "repo": "home-manager",
"type": "github" "type": "github"
} }
}, },
"nixos-unstable": { "nixos-unstable": {
"locked": { "locked": {
"lastModified": 1681147610, "lastModified": 1685931219,
"narHash": "sha256-v4D4kTiQszI/3UXbeEYfpYtSdSD64DyAwB4rLK6i8mQ=", "narHash": "sha256-8EWeOZ6LKQfgAjB/USffUSELPRjw88A+xTcXnOUvO5M=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "a9a909139f21c687d856fd3b19d7fb70439c7863", "rev": "7409480d5c8584a1a83c422530419efe4afb0d19",
"type": "github" "type": "github"
}, },
"original": { "original": {
"owner": "NixOS", "owner": "NixOS",
"ref": "master", "ref": "nixos-unstable",
"repo": "nixpkgs", "repo": "nixpkgs",
"type": "github" "type": "github"
} }
}, },
"nixpkgs": { "nixpkgs": {
"locked": { "locked": {
"lastModified": 1681041438, "lastModified": 1686059680,
"narHash": "sha256-NmRGMklxBZ8Ol47CKMQxAU1F+v8ySpsHAAiC7ZL4vxY=", "narHash": "sha256-sp0WlCIeVczzB0G8f8iyRg3IYW7KG31mI66z7HIZwrI=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "48dcbaf7fa799509cbec85d55b8d62dcf1477d57", "rev": "a558f7ac29f50c4b937fb5c102f587678ae1c9fb",
"type": "github" "type": "github"
}, },
"original": { "original": {
"owner": "NixOS", "owner": "NixOS",
"ref": "nixos-22.11", "ref": "release-23.05",
"repo": "nixpkgs", "repo": "nixpkgs",
"type": "github" "type": "github"
} }
@ -60,21 +59,6 @@
"nixos-unstable": "nixos-unstable", "nixos-unstable": "nixos-unstable",
"nixpkgs": "nixpkgs" "nixpkgs": "nixpkgs"
} }
},
"utils": {
"locked": {
"lastModified": 1667395993,
"narHash": "sha256-nuEHfE/LcWyuSWnS8t12N1wc105Qtau+/OdUAjtQ0rA=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "5aed5285a952e0b949eb3ba02c12fa4fcfef535f",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
} }
}, },
"root": "root", "root": "root",

View File

@ -1,9 +1,9 @@
{ {
inputs = { inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-22.11"; nixpkgs.url = "github:NixOS/nixpkgs/release-23.05";
nixos-unstable.url = "github:NixOS/nixpkgs/master"; nixos-unstable.url = "github:NixOS/nixpkgs/nixos-unstable";
home-manager = { home-manager = {
url = "github:nix-community/home-manager/release-22.11"; url = "github:nix-community/home-manager/release-23.05";
inputs.nixpkgs.follows = "nixpkgs"; inputs.nixpkgs.follows = "nixpkgs";
}; };
}; };
@ -30,6 +30,11 @@
inherit system; inherit system;
config.allowUnfree = true; config.allowUnfree = true;
config.permittedInsecurePackages = [
"openssl-1.1.1t"
"openssl-1.1.1u"
];
}; };
wrapUtils = { pkgs, unstablePkgs, system }: wrapUtils = { pkgs, unstablePkgs, system }:

View File

@ -1,34 +1,26 @@
{ lib, ... }: { config, lib, ... }:
let let
domain = "htbaz.giugl.io"; domain = "htbaz.giugl.io";
network = import ./network.nix;
auth_block = (import ./openid.nix { inherit lib; }).openresty_oidc_block;
in in
{ {
services = { services.bazarr = {
bazarr = {
enable = true; enable = true;
group = "media"; group = "media";
}; };
nginx.virtualHosts.${domain} = { architect.vhost.${domain} = with config.architect.networks; {
forceSSL = true; dnsInterfaces = [ "wireguard" "tailscale" ];
enableACME = true;
locations."/" = { locations."/" = {
proxyPass = "http://127.0.0.1:6767"; allowLan = true;
extraConfig = auth_block { port = 6767;
access_role = "bazarr";
};
};
};
};
networking.extraHosts = '' allow = [
${network.architect-lan} ${domain} wireguard.net
${network.architect-wg} ${domain} tailscale.net
${network.architect-ts} ${domain} ];
''; };
};
users.groups.media.members = [ "bazarr" ]; users.groups.media.members = [ "bazarr" ];
} }

View File

@ -1,9 +1,11 @@
{ lib, ... }: { config, lib, ... }:
let let
domain = "books.giugl.io"; domain = "books.giugl.io";
network = import ./network.nix;
auth_block = (import ./openid.nix { inherit lib; }).openresty_oidc_block; auth_block = (import ./openid.nix { inherit lib; }).openresty_oidc_block;
utilities = import ./utilities.nix { inherit lib config; };
inherit (utilities) architectInterfaceAddress;
in in
{ {
services = { services = {
@ -29,9 +31,9 @@ in
}; };
networking.extraHosts = '' networking.extraHosts = ''
${network.architect-lan} ${domain} ${architectInterfaceAddress "lan"} ${domain}
${network.architect-wg} ${domain} ${architectInterfaceAddress "wireguard"} ${domain}
${network.architect-ts} ${domain} ${architectInterfaceAddress "tailscale"} ${domain}
''; '';
users.groups.media.members = [ "calibre-web" ]; users.groups.media.members = [ "calibre-web" ];

View File

@ -1,11 +1,13 @@
{ config, pkgs, ... }: { config, pkgs, lib, ... }:
let let
pubkeys = [ pubkeys = [
"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQC1we38/N+t8Ah5yrLof8QUwhrob7/VXFKIddaJeOVBLuDVnW7ljiAtdtEiL69D/DV4Ohmt5wMvkAAjfuHmim6FD9A6lzPbSU4KH9W2dcckszKbbI636kuDwem/xui6BW3wJa6P+0xW5ksygEAkzcK2PXuC2b4B9uwhuUdKahiGMKDxISG/WianqAe72cGMfNkYvion3Y1VsMLUdm48d2ABnxNpr7NI9B5iJ8dziOft9gpgfz13CCQRlReo75gk/4xI+vSNrQp7eR+wzJy2/dZg/T8jtyA9Q6jVxrxBpqQ1LNXkAKaJkGo9OabF6Wgpzp+YTAurL4nwR2NaJxwFuyoKvACQy0ai4jrS3206gC6JXZv8ktZMZrwUN+jPqCwfgh5qObFkAqKCxbp52ioDek2MQLdOvzQBX//DBhGEp5rzHGLZ3vhRIiiQiaof5sF5zWiYDW5mqezSPNxJPX/BrTP/Wbs/jpwTLBh3wytiia0S1WXQmya89bqzTPFiDWvTRA62EVKB/JaQtPQQOFAxWwg799DMycPeZ81xttZOyMtI/MZSddyqx2S8fWGwvToZQvuZ38mSIpFseLM1IkgabRIrAmat5SBNGGy9Dqa0eMEa7bwIY/4CMB1y6HMTnaoMXA6cnQfHMoB/zyTZ6oTXIeqeOyiZsK+RN0Mvahj8mXi7dw== giulio@giulio-X230" "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQC1we38/N+t8Ah5yrLof8QUwhrob7/VXFKIddaJeOVBLuDVnW7ljiAtdtEiL69D/DV4Ohmt5wMvkAAjfuHmim6FD9A6lzPbSU4KH9W2dcckszKbbI636kuDwem/xui6BW3wJa6P+0xW5ksygEAkzcK2PXuC2b4B9uwhuUdKahiGMKDxISG/WianqAe72cGMfNkYvion3Y1VsMLUdm48d2ABnxNpr7NI9B5iJ8dziOft9gpgfz13CCQRlReo75gk/4xI+vSNrQp7eR+wzJy2/dZg/T8jtyA9Q6jVxrxBpqQ1LNXkAKaJkGo9OabF6Wgpzp+YTAurL4nwR2NaJxwFuyoKvACQy0ai4jrS3206gC6JXZv8ktZMZrwUN+jPqCwfgh5qObFkAqKCxbp52ioDek2MQLdOvzQBX//DBhGEp5rzHGLZ3vhRIiiQiaof5sF5zWiYDW5mqezSPNxJPX/BrTP/Wbs/jpwTLBh3wytiia0S1WXQmya89bqzTPFiDWvTRA62EVKB/JaQtPQQOFAxWwg799DMycPeZ81xttZOyMtI/MZSddyqx2S8fWGwvToZQvuZ38mSIpFseLM1IkgabRIrAmat5SBNGGy9Dqa0eMEa7bwIY/4CMB1y6HMTnaoMXA6cnQfHMoB/zyTZ6oTXIeqeOyiZsK+RN0Mvahj8mXi7dw== giulio@giulio-X230"
]; ];
hostname = "architect"; domain = "devs.giugl.io";
network = import ./network.nix;
utilities = import ./utilities.nix { inherit lib config; };
inherit (utilities) generateDeviceStrings;
in in
{ {
imports = [ imports = [
@ -37,11 +39,32 @@ in
#./calibre.nix #./calibre.nix
./docker.nix ./docker.nix
./keycloak.nix ./keycloak.nix
./runas.nix # ./runas.nix
./tailscale.nix ./tailscale.nix
./searx.nix # ./searx.nix
#./plex.nix
./headscale.nix
]; ];
architect = {
networks.lan = {
interface = "enp5s0";
net = "10.0.0.0/24";
devices = {
vodafoneStation = { address = "192.168.1.1"; hostname = "vodafone.station"; };
architect = { address = "10.0.0.250"; hostname = "architect.${domain}"; };
router = { address = "10.0.0.1"; hostname = "router.${domain}"; };
dvr = { address = "10.0.0.3"; hostname = "dvr.${domain}"; };
};
};
firewall = {
openTCP = [ 22 ];
openTCPVPN = [ 22 ];
};
};
time.timeZone = "Europe/Rome"; time.timeZone = "Europe/Rome";
users.users.giulio.openssh.authorizedKeys.keys = pubkeys; users.users.giulio.openssh.authorizedKeys.keys = pubkeys;
boot = { boot = {
@ -58,13 +81,15 @@ in
}; };
}; };
kernelParams = [ kernelParams = with config.architect.networks.lan; [
"ip=${network.architect-lan}::10.0.0.1:255.255.255.0::${network.wan-if}:off" "ip=${devices.architect.address}::${devices.router.address}:255.255.255.0::${interface}:off"
"nvme_core.default_ps_max_latency_us=5500" "nvme_core.default_ps_max_latency_us=5500"
"zfs_arc_max=1073741824" "zfs_arc_max=1073741824"
"memmap=32M$0x4ca6f9478" "memmap=32M$0x4ca6f9478"
]; ];
kernelPackages = pkgs.linuxPackages;
kernel.sysctl = { "net.ipv4.ip_forward" = 1; }; kernel.sysctl = { "net.ipv4.ip_forward" = 1; };
loader = { loader = {
@ -77,32 +102,23 @@ in
supportedFilesystems = [ "zfs" ]; supportedFilesystems = [ "zfs" ];
zfs.requestEncryptionCredentials = true; zfs.requestEncryptionCredentials = true;
tmpOnTmpfsSize = "50%"; tmp.tmpfsSize = "50%";
}; };
networking = { networking = with config.architect.networks.lan; {
hostName = hostname; hostName = "architect";
hostId = "49350853"; hostId = "49350853";
useDHCP = false; useDHCP = false;
defaultGateway = "10.0.0.1"; defaultGateway = devices.router.address;
interfaces = { interfaces = {
enp5s0.ipv4.addresses = [{ ${interface}.ipv4.addresses = [{
address = network.architect-lan; address = devices.architect.address;
prefixLength = 24; prefixLength = 24;
}]; }];
enp6s0.useDHCP = false; enp6s0.useDHCP = false;
wlp4s0.useDHCP = false; wlp4s0.useDHCP = false;
}; };
extraHosts = '' extraHosts = (generateDeviceStrings config.architect.networks.lan.devices) + ''
127.0.0.1 ${hostname}.devs.giugl.io localhost
# LAN
${network.architect-lan} ${hostname}.devs.giugl.io
${network.dvr-lan} dvr.devs.giugl.io
${network.nas-lan} nas.devs.giugl.io
${network.router-lan} router-manduria.devs.giugl.io
192.168.1.1 vodafone.station
# Blacklist # Blacklist
0.0.0.0 metrics.plex.tv 0.0.0.0 metrics.plex.tv
@ -130,11 +146,6 @@ in
driSupport = true; driSupport = true;
}; };
architect.firewall = {
openTCP = [ 22 ];
openTCPVPN = [ 22 ];
};
services = { services = {
fwupd.enable = true; fwupd.enable = true;
das_watchdog.enable = true; das_watchdog.enable = true;
@ -142,8 +153,12 @@ in
xserver.videoDrivers = [ "nvidia" ]; xserver.videoDrivers = [ "nvidia" ];
openssh = { openssh = {
enable = true; enable = true;
passwordAuthentication = false;
kbdInteractiveAuthentication = false; settings = {
PasswordAuthentication = false;
KbdInteractiveAuthentication = false;
};
extraConfig = '' extraConfig = ''
MaxAuthTries 15 MaxAuthTries 15
''; '';
@ -153,6 +168,7 @@ in
environment = { environment = {
variables = { LIBVA_DRIVER_NAME = "vdpau"; }; variables = { LIBVA_DRIVER_NAME = "vdpau"; };
systemPackages = with pkgs; [ cachix ]; systemPackages = with pkgs; [ cachix linuxPackages.usbip ];
}; };
} }

View File

@ -2,9 +2,11 @@
let let
domain = "htdel.giugl.io"; domain = "htdel.giugl.io";
network = import ./network.nix;
auth_block = (import ./openid.nix { inherit lib; }).openresty_oidc_block; auth_block = (import ./openid.nix { inherit lib; }).openresty_oidc_block;
utilities = import ./utilities.nix { inherit lib config; };
inherit (utilities) architectInterfaceAddress;
listenPorts = [ 51413 51414 ]; listenPorts = [ 51413 51414 ];
in in
{ {
@ -54,9 +56,9 @@ in
}; };
networking.extraHosts = '' networking.extraHosts = ''
${network.architect-lan} ${domain} ${architectInterfaceAddress "lan"} ${domain}
${network.architect-wg} ${domain} ${architectInterfaceAddress "wireguard"} ${domain}
${network.architect-ts} ${domain} ${architectInterfaceAddress "tailscale"} ${domain}
''; '';
users.groups.media.members = [ "deluge" ]; users.groups.media.members = [ "deluge" ];

View File

@ -1,48 +1,53 @@
{ config, pkgs, lib, ... }: { config, pkgs, lib, ... }:
let let
adguard_webui_port = 3031; domain = "adguard.architect.devs.giugl.io";
adguard_dns_port = "5300";
dnscrypt_listen_port = "5353";
in in
{ {
architect.firewall.openUDPVPN = [ 53 ]; architect = {
firewall.openUDPVPN = [ 53 ];
vhost.${domain} = {
dnsInterfaces = [ "lan" "tailscale" "wireguard" ];
locations."/" = with config; {
port = services.adguardhome.settings.bind_port;
allow = with architect.networks; [ lan.net tailscale.net ];
deny = [
architect.networks."lan".devices.router.address
];
};
};
};
services = { services = {
dnsmasq = { dnsmasq = {
enable = true; enable = true;
# adguard port settings = {
servers = [ "127.0.0.1#${adguard_dns_port}" ]; server = [ "127.0.0.1#${toString config.services.adguardhome.settings.dns.port}" ];
extraConfig = '' localise-queries = true;
localise-queries min-cache-ttl = 120;
min-cache-ttl=120 max-cache-ttl = 2400;
max-cache-ttl=2400 domain = [
''; "runas.rocks"
"giugl.io"
"devs.runas.rocks"
"devs.giugl.io"
];
};
}; };
adguardhome = { adguardhome = {
enable = true;
port = adguard_webui_port;
};
dnscrypt-proxy2 = {
enable = true; enable = true;
settings = { settings = {
listen_addresses = [ "127.0.0.1:${dnscrypt_listen_port}" ]; bind_port = 5353;
ipv4_servers = true; dns = {
ipv6_servers = false; port = 5300;
block_ipv6 = true; };
dnscrypt_servers = true; upstream_dns = [
doh_servers = true; "tls://architect.d65174.dns.nextdns.io"
require_nolog = true; "https://dns.nextdns.io/d65174/architect"
require_nofilter = true; ];
timeout = 350;
lb_strategy = "p4";
lb_estimator = true;
ignore_system_dns = true;
fallback_resolvers = [ "1.1.1.1:53" "9.9.9.9:53" ];
cache_min_ttl = 450;
cache_max_ttl = 2400;
}; };
}; };
}; };

View File

@ -1,10 +1,23 @@
{ config, ... }:
{ {
virtualisation.docker = { architect.networks.docker = {
interface = "docker0";
net = "172.17.0.0/16";
};
virtualisation = {
oci-containers.backend = "docker";
docker = {
enable = true; enable = true;
extraOptions = '' extraOptions = ''
--dns 127.0.0.1 --dns 10.0.0.250 --data-root /docker --dns 127.0.0.1 --dns ${config.architect.networks.lan.devices.architect.address} --data-root /docker
''; '';
enableOnBoot = false; enableOnBoot = false;
daemon.settings.iptables = false;
}; };
};
users.users.giulio.extraGroups = [ "docker" ]; users.users.giulio.extraGroups = [ "docker" ];
} }

View File

@ -1,9 +1,14 @@
{ config, pkgs, ... }: { { config, pkgs, ... }:
{
services.fail2ban = { services.fail2ban = {
enable = true; enable = true;
package = pkgs.fail2ban; package = pkgs.fail2ban;
packageFirewall = pkgs.nftables; packageFirewall = pkgs.nftables;
bantime-increment.enable = true; bantime-increment.enable = true;
ignoreIP = [ "10.0.0.0/24" "10.3.0.0/24" ]; ignoreIP = [
config.architect.networks.lan.net
config.architect.networks.tailscale.net
];
}; };
} }

View File

@ -1,13 +1,38 @@
{ config, lib, ... }: { config, lib, ... }:
with import ./network.nix;
with lib;
let let
openTCP = concatMapStringsSep "," (x: toString x) config.architect.firewall.openTCP; openTCP = lib.concatMapStringsSep "," (x: toString x) config.architect.firewall.openTCP;
openUDP = concatMapStringsSep "," (x: toString x) config.architect.firewall.openUDP; openUDP = lib.concatMapStringsSep "," (x: toString x) config.architect.firewall.openUDP;
openTCPVPN = concatMapStringsSep "," (x: toString x) config.architect.firewall.openTCPVPN; openTCPVPN = lib.concatMapStringsSep "," (x: toString x) config.architect.firewall.openTCPVPN;
openUDPVPN = concatMapStringsSep "," (x: toString x) config.architect.firewall.openUDPVPN; openUDPVPN = lib.concatMapStringsSep "," (x: toString x) config.architect.firewall.openUDPVPN;
deviceAddress = interface: device:
config.architect.networks.${interface}.devices.${device}.address;
gdevices = [
(deviceAddress "tailscale" "architect")
(deviceAddress "tailscale" "dodino")
(deviceAddress "tailscale" "manduria")
(deviceAddress "tailscale" "kmerr")
(deviceAddress "tailscale" "chuck")
];
wireguardToWAN = [
(deviceAddress "wireguard" "shield")
(deviceAddress "wireguard" "parina")
(deviceAddress "wireguard" "parina-ipad")
(deviceAddress "wireguard" "germano")
];
frameccaDevices = [
(deviceAddress "wireguard" "framecca")
(deviceAddress "wireguard" "framecca_one")
(deviceAddress "wireguard" "framecca_two")
(deviceAddress "wireguard" "framecca_three")
(deviceAddress "wireguard" "framecca_four")
];
clientToClientWireguard = frameccaDevices;
in in
{ {
networking = { networking = {
@ -17,7 +42,7 @@ in
nftables = { nftables = {
enable = true; enable = true;
ruleset = '' ruleset = with config.architect.networks; ''
table ip raw { table ip raw {
chain PREROUTING { chain PREROUTING {
type filter hook prerouting priority raw; policy accept; type filter hook prerouting priority raw; policy accept;
@ -29,6 +54,9 @@ in
} }
table ip nat { table ip nat {
chain DOCKER {
type nat hook prerouting priority dstnat; policy accept;
}
chain PREROUTING { chain PREROUTING {
type nat hook prerouting priority dstnat; policy accept; type nat hook prerouting priority dstnat; policy accept;
} }
@ -43,11 +71,11 @@ in
chain POSTROUTING { chain POSTROUTING {
type nat hook postrouting priority srcnat; policy accept; type nat hook postrouting priority srcnat; policy accept;
oifname ${wan-if} ip saddr {${ oifname ${lan.interface} ip saddr {${
lib.concatStringsSep "," towan-wg lib.concatStringsSep "," wireguardToWAN
}} masquerade }} masquerade
oifname ${wan-if} ip saddr ${docker-net} masquerade oifname ${lan.interface} ip saddr ${docker.net} masquerade
oifname ${wan-if} ip saddr ${tailscale-net} masquerade oifname ${lan.interface} ip saddr ${tailscale.net} masquerade
} }
} }
@ -57,12 +85,13 @@ in
ct state invalid,untracked drop comment "drop invalid" ct state invalid,untracked drop comment "drop invalid"
ip daddr 255.255.255.255 accept comment "allow broadcast traffic" ip daddr 255.255.255.255 accept comment "allow broadcast traffic"
ip daddr 224.0.0.0/4 accept comment "allow multicast traffic" ip daddr 224.0.0.0/4 accept comment "allow multicast traffic"
iifname ${wan-if} ip saddr ${vpn-net} drop comment "bind any ip to intf ${wan-if}" iifname ${lan.interface} ip saddr ${wireguard.net} drop comment "bind any ip to intf ${lan.interface}"
iifname ${wan-if} ip saddr 127.0.0.0/8 drop comment "bind any ip to intf ${wan-if}" iifname ${lan.interface} ip saddr 127.0.0.0/8 drop comment "bind any ip to intf ${lan.interface}"
iifname ${wan-if} accept comment "bind any ip to intf ${wan-if}" iifname ${lan.interface} accept comment "bind any ip to intf ${lan.interface}"
iifname ${vpn-if} ip saddr ${vpn-net} accept comment "bind ip ${vpn-net} to intf ${vpn-if}" iifname ${wireguard.interface} ip saddr ${wireguard.net} accept comment "bind ip ${wireguard.net} to intf ${wireguard.interface}"
iifname ${docker-if} ip saddr ${docker-net} accept comment "bind ip ${docker-net} to intf ${docker-if}" iifname ${docker.interface} ip saddr ${docker.net} accept comment "bind ip ${docker.net} to intf ${docker.interface}"
iifname ${tailscale-if} ip saddr ${tailscale-net} accept iifname ${tailscale.interface} ip saddr ${tailscale.net} accept
iifname ${tailscale.interface} ip saddr 100.100.100.100/32 accept
iifname "lo" accept comment "bind any ip to intf lo" iifname "lo" accept comment "bind any ip to intf lo"
jump mangle_drop jump mangle_drop
} }
@ -115,17 +144,17 @@ in
iifname "lo" accept comment "loopback" iifname "lo" accept comment "loopback"
ip daddr 255.255.255.255 accept comment "allow broadcast traffic" ip daddr 255.255.255.255 accept comment "allow broadcast traffic"
ip daddr 224.0.0.0/4 accept comment "allow multicast traffic" ip daddr 224.0.0.0/4 accept comment "allow multicast traffic"
ip saddr ${lan-net} accept comment "lan > local" ip saddr ${lan.net} accept comment "lan > local"
ip saddr ${tailscale-net} accept comment "tailscale > local" iifname ${docker.interface} accept
ip saddr ${tailscale.net} accept comment "tailscale > local"
ip saddr {${lib.concatStringsSep "," gdevices}} accept comment "vpn > local" ip saddr {${lib.concatStringsSep "," gdevices}} accept comment "vpn > local"
iifname ${wan-if} tcp dport {${openTCP}} accept iifname ${lan.interface} tcp dport {${openTCP}} accept
iifname ${wan-if} udp dport {${openUDP}} accept iifname ${lan.interface} udp dport {${openUDP}} accept
iifname ${vpn-if} tcp dport {${openTCPVPN}} accept iifname ${wireguard.interface} tcp dport {${openTCPVPN}} accept
iifname ${vpn-if} udp dport {${openUDPVPN}} accept iifname ${wireguard.interface} udp dport {${openUDPVPN}} accept
iifname ${vpn-if} icmp type echo-request accept iifname ${wireguard.interface} icmp type echo-request accept
iifname ${docker-if} udp dport 53 accept
jump filter_drop jump filter_drop
} }
@ -134,17 +163,17 @@ in
ct state established,related accept ct state established,related accept
# client to client # client to client
ip saddr {${lib.concatStringsSep "," c2c-wg}} ip daddr {${ ip saddr {${lib.concatStringsSep "," clientToClientWireguard}} ip daddr {${
lib.concatStringsSep "," c2c-wg lib.concatStringsSep "," clientToClientWireguard
}} accept }} accept
# nat to wan # nat to wan
oifname ${wan-if} ip saddr {${ oifname ${lan.interface} ip saddr {${
lib.concatStringsSep "," towan-wg lib.concatStringsSep "," wireguardToWAN
}} accept }} accept
oifname ${wan-if} ip saddr ${docker-net} accept oifname ${lan.interface} ip saddr ${docker.net} accept
oifname ${wan-if} ip saddr ${tailscale-net} accept oifname ${lan.interface} ip saddr ${tailscale.net} accept
jump filter_drop jump filter_drop
} }

View File

@ -2,40 +2,30 @@
let let
domain = "git.giugl.io"; domain = "git.giugl.io";
network = import ./network.nix;
in in
{ {
architect.firewall.openTCP = [ config.services.gitea.settings.server.SSH_PORT ]; architect = {
firewall.openTCP = [ config.services.gitea.settings.server.SSH_PORT ];
vhost.${domain} = {
dnsInterfaces = [ "lan" "tailscale" "wireguard" ];
locations."/".port = config.services.gitea.settings.server.HTTP_PORT;
};
};
services.gitea = { services.gitea = {
enable = true; enable = true;
database.type = "sqlite3"; database.type = "sqlite3";
domain = domain;
appName = "Gitea"; appName = "Gitea";
rootUrl = "https://${domain}"; # https://github.com/NixOS/nixpkgs/issues/235442#issuecomment-1574329453
lfs.enable = true;
settings = { settings = {
server = { server = {
LFS_START_SERVER = true; DOMAIN = domain;
ROOT_URL = "https://${domain}";
SSH_PORT = 22; SSH_PORT = 22;
HTTP_PORT = 3001;
}; };
openid.enable_openid_signin = true; openid.enable_openid_signin = true;
}; };
}; };
services.nginx.virtualHosts.${domain} = {
forceSSL = true;
enableACME = true;
locations."/" = {
proxyPass = "http://127.0.0.1:3000";
# it does not work, it breaks gitea's web portal
# extraConfig = auth_block { access_role = "git"; };
};
};
networking.extraHosts = ''
${network.architect-lan} ${domain}
${network.architect-wg} ${domain}
${network.architect-ts} ${domain}
'';
} }

View File

@ -0,0 +1,51 @@
{ config, pkgs, lib, ... }:
let
domain = "vipienne.giugl.io";
in
{
architect.firewall = {
openUDP = [ config.services.tailscale.port ];
};
services = {
headscale = {
enable = true;
package = pkgs.unstablePkgs.headscale;
port = 1194;
address = "0.0.0.0";
settings = {
server_url = "https://${domain}";
log.level = "debug";
dns_config = {
magic_dns = true;
base_domain = "giugl.io";
override_local_dns = true;
nameservers = [ config.architect.networks.tailscale.devices.architect.address ];
};
logtail.enabled = false;
ip_prefixes = [ config.architect.networks.tailscale.net ];
noise.private_key_path = "/var/lib/headscale/noise_private.key";
};
};
nginx.virtualHosts.${domain} = {
forceSSL = true;
enableACME = true;
extraConfig = ''
ssl_protocols TLSv1.2 TLSv1.3;
'';
locations."/" = {
proxyPass =
"http://127.0.0.1:${toString config.services.headscale.port}";
proxyWebsockets = true;
recommendedProxySettings = true;
extraConfig = ''
proxy_buffering off;
add_header Strict-Transport-Security "max-age=15552000; includeSubDomains" always;
'';
};
};
};
}

View File

@ -1,27 +1,16 @@
{ lib, pkgs, ... }: { config, lib, pkgs, ... }:
let let
domain = "tube.giugl.io"; domain = "tube.giugl.io";
network = import ./network.nix;
in in
{ {
services = { services.invidious = {
invidious = {
enable = true; enable = true;
port = 9092;
package = pkgs.unstablePkgs.invidious; package = pkgs.unstablePkgs.invidious;
}; };
nginx.virtualHosts.${domain} = { architect.vhost.${domain} = {
forceSSL = true; dnsInterfaces = [ "lan" "tailscale" "wireguard" ];
enableACME = true; locations."/".port = config.services.invidious.port;
locations."/" = { proxyPass = "http://127.0.0.1:9092"; };
}; };
};
networking.extraHosts = ''
${network.architect-lan} ${domain}
${network.architect-wg} ${domain}
${network.architect-ts} ${domain}
'';
} }

View File

@ -1,63 +1,50 @@
{ pkgs, lib, ... }: { config, pkgs, lib, ... }:
let let
network = import ./network.nix;
domain = "media.giugl.io"; domain = "media.giugl.io";
auth_block = (import ./openid.nix { inherit lib; }).openresty_oidc_block; port = 8096;
allowLan = true;
in in
{ {
# needed since StateDirectory does not accept symlinks # needed since StateDirectory does not accept symlinks
systemd.services.jellyfin.serviceConfig.StateDirectory = lib.mkForce ""; systemd.services.jellyfin.serviceConfig.StateDirectory = lib.mkForce "";
services = { architect.vhost.${domain} = with config.architect.networks; {
jellyfin = { dnsInterfaces = [ "lan" "wireguard" "tailscale" ];
locations = {
"/" = {
inherit port allowLan;
allow = [
wireguard.net
tailscale.net
];
};
"/socket" = {
inherit port allowLan;
proxyWebsockets = true;
allow = [
wireguard.net
tailscale.net
];
};
};
};
services.jellyfin = {
enable = true; enable = true;
group = "media"; group = "media";
package = pkgs.unstablePkgs.jellyfin; package = pkgs.unstablePkgs.jellyfin;
}; };
nginx.virtualHosts.${domain} = { users.groups = {
forceSSL = true; media.members = [ "jellyfin" ];
enableACME = true; video.members = [ "jellyfin" ];
extraConfig = auth_block { access_role = "jellyfin"; whitelisted_ips = network.gdevices; } + render.members = [ "jellyfin" ];
''
# External Javascript (such as cast_sender.js for Chromecast) must be whitelisted.
#add_header Content-Security-Policy "default-src https: data: blob: http://image.tmdb.org; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' https://www.gstatic.com/cv/js/sender/v1/cast_sender.js https://www.gstatic.com/eureka/clank/95/cast_sender.js https://www.gstatic.com/eureka/clank/96/cast_sender.js https://www.gstatic.com/eureka/clank/97/cast_sender.js https://www.youtube.com blob:; worker-src 'self' blob:; connect-src 'self'; object-src 'none'; frame-ancestors 'self'";
# Disable buffering when the nginx proxy gets very resource heavy upon streaming
proxy_buffering off;
'';
locations."/" = {
proxyPass = "http://127.0.0.1:8096";
# extraConfig = ''
# allow 10.0.0.0/24;
# allow 10.3.0.0/24;
# deny all;
# '';
}; };
locations."/socket" = {
proxyPass = "http://127.0.0.1:8096";
proxyWebsockets = true;
# extraConfig = ''
# allow 10.0.0.0/24;
# allow 10.3.0.0/24;
# deny all;
# '';
};
};
};
networking.extraHosts = ''
${network.architect-lan} ${domain}
${network.architect-wg} ${domain}
${network.architect-ts} ${domain}
'';
users.groups.media.members = [ "jellyfin" ];
users.groups.video.members = [ "jellyfin" ];
users.groups.render.members = [ "jellyfin" ];
fileSystems."/tmp/jellyfin" = { fileSystems."/tmp/jellyfin" = {
device = "none"; device = "none";
fsType = "tmpfs"; fsType = "tmpfs";

View File

@ -1,8 +1,10 @@
{ pkgs, config, ... }: { pkgs, lib, config, ... }:
let let
network = import ./network.nix;
domain = "auth.giugl.io"; domain = "auth.giugl.io";
utilities = import ./utilities.nix { inherit lib config; };
inherit (utilities) architectInterfaceAddress;
in in
{ {
services = { services = {
@ -73,8 +75,8 @@ in
}; };
networking.extraHosts = '' networking.extraHosts = ''
${network.architect-lan} ${domain} ${architectInterfaceAddress "lan"} ${domain}
${network.architect-wg} ${domain} ${architectInterfaceAddress "wireguard"} ${domain}
${network.architect-ts} ${domain} ${architectInterfaceAddress "tailscale"} ${domain}
''; '';
} }

View File

@ -1,26 +1,16 @@
{ lib, pkgs, ... }: { config, lib, pkgs, ... }:
let let
domain = "reddit.giugl.io"; domain = "reddit.giugl.io";
network = import ./network.nix;
in in
{ {
services = { services.libreddit = {
libreddit = {
enable = true; enable = true;
port = 9090; port = 9090;
}; };
nginx.virtualHosts.${domain} = { architect.vhost.${domain} = {
forceSSL = true; dnsInterfaces = [ "lan" "tailscale" "wireguard" ];
enableACME = true; locations."/".port = config.services.libreddit.port;
locations."/" = { proxyPass = "http://127.0.0.1:9090"; };
}; };
};
networking.extraHosts = ''
${network.architect-lan} ${domain}
${network.architect-wg} ${domain}
${network.architect-ts} ${domain}
'';
} }

View File

@ -0,0 +1,82 @@
{ config, lib, ... }:
let
domain = "photos.giugl.io";
backendPort = 8001;
frontendPort = 3000;
in
{
architect.vhost.${domain} = {
dnsInterfaces = [ "tailscale" ];
locations."/" = {
host = "172.17.0.1";
port = frontendPort;
# allowLan = true;
# allow = [ config.architect.networks."tailscale".net ];
};
locations."~ ^/(api|media)/" = {
host = "172.17.0.1";
port = backendPort;
# allowLan = true;
# allow = [ config.architect.networks."tailscale".net ];
};
locations."/ws" = {
host = "172.17.0.1";
port = backendPort;
proxyWebsockets = true;
# allowLan = true;
# allow = [ config.architect.networks."tailscale".net ];
};
};
services.redis.servers."librephotos" = {
enable = true;
port = 1233;
bind = "172.17.0.1";
extraParams = [ "--protected-mode no" ];
};
virtualisation.oci-containers = {
containers = {
librephotos-front = {
image = "reallibrephotos/librephotos-frontend:latest";
autoStart = true;
ports = [
"172.17.0.1:${toString frontendPort}:${toString frontendPort}"
];
};
librephotos-back = {
image = "reallibrephotos/librephotos:latest";
autoStart = true;
ports = [
"172.17.0.1:${toString backendPort}:${toString backendPort}"
];
environment = {
SECRET_KEY = "LOLOL";
BACKEND_HOST = domain;
ADMIN_EMAIL = "me@giugl.io";
ADMIN_USERNAME = "giulio";
ADMIN_PASSWORD = "giulio";
ALLOWED_HOSTS = domain;
DB_BACKEND = "mysql";
DB_NAME = "librephotos";
DB_USER = "librephotos";
DB_PASS = "librephotos";
DB_HOST = "172.17.0.1";
DB_PORT = toString config.services.mysql.settings.mysqld.port;
REDIS_HOST = "172.17.0.1";
REDIS_PORT = toString config.services.redis.servers."librephotos".port;
MAPBOX_API_KEY = "SOME_KEY";
WEB_CONCURRENCY = "24";
DEBUG = "0";
};
};
};
};
}

View File

@ -1,9 +1,11 @@
{ lib, ... }: { config, lib, ... }:
let let
domain = "htlid.giugl.io"; domain = "htlid.giugl.io";
network = import ./network.nix;
auth_block = (import ./openid.nix { inherit lib; }).openresty_oidc_block; auth_block = (import ./openid.nix { inherit lib; }).openresty_oidc_block;
utilities = import ./utilities.nix { inherit lib config; };
inherit (utilities) architectInterfaceAddress;
in in
{ {
services = { services = {
@ -25,9 +27,9 @@ in
}; };
networking.extraHosts = '' networking.extraHosts = ''
${network.architect-lan} ${domain} ${architectInterfaceAddress "lan"} ${domain}
${network.architect-wg} ${domain} ${architectInterfaceAddress "wireguard"} ${domain}
${network.architect-ts} ${domain} ${architectInterfaceAddress "tailscale"} ${domain}
''; '';
users.groups.media.members = [ "lidarr" ]; users.groups.media.members = [ "lidarr" ];

View File

@ -1,9 +1,11 @@
{ pkgs, lib, ... }: { config, pkgs, lib, ... }:
let let
domain = "runas.rocks"; domain = "runas.rocks";
network = import ./network.nix;
db_name = "matrix-synapse-runas.rocks"; db_name = "matrix-synapse-runas.rocks";
utilities = import ./utilities.nix { inherit lib config; };
inherit (utilities) architectInterfaceAddress;
in in
{ {
services = { services = {
@ -111,9 +113,8 @@ in
}; };
networking.extraHosts = '' networking.extraHosts = ''
${network.architect-lan} ${domain} ${architectInterfaceAddress "lan"} ${domain}
${network.architect-wg} ${domain} ${architectInterfaceAddress "wireguard"} ${domain}
${network.architect-ts} ${domain} ${architectInterfaceAddress "tailscale"} ${domain}
''; '';
} }

View File

@ -1,8 +1,10 @@
{ config, pkgs, ... }: { lib, config, pkgs, ... }:
let let
domain = "minecraft.giugl.io"; domain = "minecraft.giugl.io";
network = import ./network.nix;
utilities = import ./utilities.nix { inherit lib config; };
inherit (utilities) architectInterfaceAddress;
in in
{ {
architect.firewall.openTCP = [ 25565 ]; architect.firewall.openTCP = [ 25565 ];
@ -16,8 +18,8 @@ in
}; };
networking.extraHosts = '' networking.extraHosts = ''
${network.architect-lan} ${domain} ${architectInterfaceAddress "lan"} ${domain}
${network.architect-wg} ${domain} ${architectInterfaceAddress "wireguard"} ${domain}
${network.architect-ts} ${domain} ${architectInterfaceAddress "tailscale"} ${domain}
''; '';
} }

View File

@ -1,12 +1,17 @@
{ lib, ... }: { config, lib, pkgs, ... }:
let let
domain = "s3.giugl.io"; domain = "s3.giugl.io";
network = import ./network.nix;
utilities = import ./utilities.nix { inherit lib config; };
inherit (utilities) architectInterfaceAddress;
in in
{ {
services = { services = {
minio.enable = true; minio = {
enable = true;
package = pkgs.minio_legacy_fs;
};
nginx.virtualHosts.${domain} = { nginx.virtualHosts.${domain} = {
forceSSL = true; forceSSL = true;
@ -15,9 +20,8 @@ in
proxyPass = "http://127.0.0.1:9000"; proxyPass = "http://127.0.0.1:9000";
extraConfig = '' extraConfig = ''
client_max_body_size 500M; client_max_body_size 500M;
allow 10.0.0.0/24; allow ${config.architect.networks.lan.net};
${lib.concatMapStrings (x: "allow ${x};") network.gdevices } allow ${config.architect.networks.tailscale.net};
allow ${network.manduria-wg};
deny all; deny all;
''; '';
}; };
@ -25,8 +29,8 @@ in
}; };
networking.extraHosts = '' networking.extraHosts = ''
${network.architect-lan} ${domain} ${architectInterfaceAddress "lan"} ${domain}
${network.architect-wg} ${domain} ${architectInterfaceAddress "wireguard"} ${domain}
${network.architect-ts} ${domain} ${architectInterfaceAddress "tailscale"} ${domain}
''; '';
} }

View File

@ -1,15 +1,12 @@
{ lib, pkgs, ... }: { config, lib, pkgs, ... }:
let let
domain = "music.runas.rocks"; domain = "music.runas.rocks";
network = import ./network.nix;
library_path = "/media/Music"; library_path = "/media/Music";
beets_config = "/media/beets.conf"; beets_config = "/media/beets.conf";
auth_block = (import ./openid.nix { inherit lib; }).openresty_oidc_block;
in in
{ {
services = { services.navidrome = {
navidrome = {
enable = true; enable = true;
settings = { settings = {
@ -24,68 +21,61 @@ in
}; };
}; };
nginx.virtualHosts.${domain} = { architect.vhost.${domain} = {
forceSSL = true; dnsInterfaces = [ "lan" "tailscale" "wireguard" ];
enableACME = true;
locations."/" = { locations."/" = {
proxyPass = "http://127.0.0.1:4533"; port = 4533;
}; allowLan = true;
extraConfig = auth_block { access_role = "navidrome"; }; allow = [ config.architect.networks."tailscale".net ];
}; };
}; };
systemd.services = { # systemd.services = {
"beets-update" = { # "beets-update" = {
enable = true; # enable = true;
# requires = [ "remove-badmp3.service" "remove-badflac.service" ]; # # requires = [ "remove-badmp3.service" "remove-badflac.service" ];
before = [ "beets-import.service" ]; # before = [ "beets-import.service" ];
serviceConfig = { # serviceConfig = {
Type = "oneshot"; # Type = "oneshot";
ExecStart = "${pkgs.beets}/bin/beet -c ${beets_config} update"; # ExecStart = "${pkgs.beets}/bin/beet -c ${beets_config} update";
}; # };
}; # };
"beets-import" = { # "beets-import" = {
enable = true; # enable = true;
path = [ pkgs.imagemagick ]; # path = [ pkgs.imagemagick ];
requires = [ "beets-update.service" ]; # requires = [ "beets-update.service" ];
after = [ "beets-update.service" ]; # after = [ "beets-update.service" ];
serviceConfig = { # serviceConfig = {
Type = "oneshot"; # Type = "oneshot";
ExecStart = # ExecStart =
"${pkgs.beets}/bin/beet -c ${beets_config} import --flat -q ${library_path}"; # "${pkgs.beets}/bin/beet -c ${beets_config} import --flat -q ${library_path}";
}; # };
startAt = "weekly"; # startAt = "weekly";
}; # };
"remove-badmp3" = { # "remove-badmp3" = {
enable = true; # enable = true;
before = [ "beets-import.service" "beets-update.service" ]; # before = [ "beets-import.service" "beets-update.service" ];
serviceConfig = { # serviceConfig = {
Type = "oneshot"; # Type = "oneshot";
ExecStart = '' # ExecStart = ''
${pkgs.findutils}/bin/find ${library_path} -name "*.mp3" -type f -exec ${pkgs.bash}/bin/sh -c '${pkgs.mp3val}/bin/mp3val "{}" | grep -Pi error 1>/dev/null && ${pkgs.busybox}/bin/rm "{}"' \; # ${pkgs.findutils}/bin/find ${library_path} -name "*.mp3" -type f -exec ${pkgs.bash}/bin/sh -c '${pkgs.mp3val}/bin/mp3val "{}" | grep -Pi error 1>/dev/null && ${pkgs.busybox}/bin/rm "{}"' \;
''; # '';
}; # };
}; # };
"remove-badflac" = { # "remove-badflac" = {
enable = true; # enable = true;
before = [ "beets-import.service" "beets-update.service" ]; # before = [ "beets-import.service" "beets-update.service" ];
serviceConfig = { # serviceConfig = {
Type = "oneshot"; # Type = "oneshot";
ExecStart = '' # ExecStart = ''
${pkgs.findutils}/bin/find ${library_path} -name "*.flac" -type f -exec ${pkgs.bash}/bin/sh -c '${pkgs.flac}/bin/flac -st "{}" || ${pkgs.busybox}/bin/rm "{}"' \; # ${pkgs.findutils}/bin/find ${library_path} -name "*.flac" -type f -exec ${pkgs.bash}/bin/sh -c '${pkgs.flac}/bin/flac -st "{}" || ${pkgs.busybox}/bin/rm "{}"' \;
''; # '';
}; # };
}; # };
}; # };
networking.extraHosts = ''
${network.architect-lan} ${domain}
${network.architect-wg} ${domain}
${network.architect-ts} ${domain}
'';
users.groups.media.members = [ "navidrome" ]; users.groups.media.members = [ "navidrome" ];
} }

View File

@ -1,64 +0,0 @@
rec {
# interfaces
wan-if = "enp5s0";
vpn-if = "wg0";
proxy-if = "proxy";
docker-if = "docker0";
tailscale-if = "ts0";
# nets
lan-net = "10.0.0.0/24";
vpn-net = "10.3.0.0/24";
external_lan-net = "192.168.1.0/24";
docker-net = "172.17.0.0/16";
tailscale-net = "100.64.0.0/10";
# ips
router-lan = "10.0.0.1";
dvr-lan = "10.0.0.2";
nas-lan = "10.0.0.3";
architect-lan = "10.0.0.250";
architect-wg = "10.3.0.1";
manduria-wg = "10.3.0.5";
antonio-wg = "10.3.0.6";
gbeast-wg = "10.3.0.7";
shield-wg = "10.3.0.12";
salvatore-wg = "10.3.0.16";
papa-wg = "10.3.0.17";
defy-wg = "10.3.0.18";
germano-wg = "10.3.0.19";
flavio-wg = "10.3.0.20";
tommy-wg = "10.3.0.21";
alain-wg = "10.3.0.22";
dima-wg = "10.3.0.23";
mikey-wg = "10.3.0.24";
andrew-wg = "10.3.0.25";
mikeylaptop-wg = "10.3.0.26";
andrewdesktop-wg = "10.3.0.27";
jacopo-wg = "10.3.0.28";
frznn-wg = "10.3.0.29";
ludo-wg = "10.3.0.30";
parina-wg = "10.3.0.31";
nilo-wg = "10.3.0.32";
parina-ipad-wg = "10.3.0.33";
kclvm-wg = "10.3.0.34";
framecca-wg = "10.3.0.35";
framecca_one-wg = "10.3.0.36";
framecca_two-wg = "10.3.0.37";
framecca_three-wg = "10.3.0.38";
framecca_four-wg = "10.3.0.39";
giuliophone-ts = "100.68.68.46";
architect-ts = "100.67.205.28";
giuliopc-ts = "100.124.78.64";
dodino-ts = "100.106.244.35";
framecca-devices = [ framecca-wg framecca_one-wg framecca_three-wg framecca_four-wg ];
c2c-wg = framecca-devices;
# groups
gdevices = [ giuliophone-ts architect-ts giuliopc-ts dodino-ts ];
towan-wg = [ shield-wg parina-wg parina-ipad-wg germano-wg ] ++ framecca-devices;
}

View File

@ -1,15 +1,22 @@
{ pkgs, ... }: { pkgs, config, lib, ... }:
let let
domain = "cloud.giugl.io"; domain = "cloud.giugl.io";
network = import ./network.nix;
redis_port = 6379; redis_port = 6379;
utilities = import ./utilities.nix { inherit lib config; };
inherit (utilities) architectInterfaceAddress;
in in
{ {
services = { services = {
nginx.virtualHosts.${domain} = {
forceSSL = true;
enableACME = true;
};
mysql = { mysql = {
enable = true; enable = true;
package = pkgs.unstablePkgs.mysql80; package = pkgs.mariadb;
}; };
redis = { redis = {
@ -24,8 +31,9 @@ in
enable = true; enable = true;
hostName = domain; hostName = domain;
https = true; https = true;
package = pkgs.unstablePkgs.nextcloud25; package = pkgs.unstablePkgs.nextcloud26;
datadir = "/services/nextcloud"; datadir = "/services/nextcloud";
configureRedis = true;
caching = { caching = {
redis = true; redis = true;
}; };
@ -33,15 +41,16 @@ in
autoUpdateApps.enable = true; autoUpdateApps.enable = true;
autoUpdateApps.startAt = "05:00:00"; autoUpdateApps.startAt = "05:00:00";
maxUploadSize = "50G";
config = { config = {
overwriteProtocol = "https"; overwriteProtocol = "https";
dbtype = "mysql"; dbtype = "mysql";
dbuser = "oc_giulio2"; dbuser = "nextcloud";
dbhost = "localhost"; dbhost = "localhost";
dbname = "nextcloud_final"; dbname = "nextcloud";
dbpassFile = "/secrets/nextcloud/dbpass.txt"; dbpassFile = "/secrets/nextcloud/dbpass.txt";
adminpassFile = "/secrets/nextcloud/adminpass.txt"; adminpassFile = "/secrets/nextcloud/dbpass.txt";
adminuser = "giulio";
extraTrustedDomains = [ "${domain}" ]; extraTrustedDomains = [ "${domain}" ];
}; };
}; };
@ -53,13 +62,9 @@ in
}; };
networking.extraHosts = '' networking.extraHosts = ''
${network.architect-lan} ${domain} ${architectInterfaceAddress "lan"} ${domain}
${network.architect-wg} ${domain} ${architectInterfaceAddress "wireguard"} ${domain}
${network.architect-ts} ${domain} ${architectInterfaceAddress "tailscale"} ${domain}
''; '';
services.nginx.virtualHosts.${domain} = {
forceSSL = true;
enableACME = true;
};
} }

View File

@ -8,7 +8,7 @@
services.nginx = { services.nginx = {
enable = true; enable = true;
package = pkgs.openresty; package = pkgs.nginx;
recommendedGzipSettings = true; recommendedGzipSettings = true;
recommendedOptimisation = true; recommendedOptimisation = true;
recommendedProxySettings = true; recommendedProxySettings = true;
@ -32,63 +32,64 @@
}; };
}; };
appendHttpConfig = # appendHttpConfig =
let # let
extraPureLuaPackages = with pkgs.luajitPackages; [ # extraPureLuaPackages = with pkgs.luajitPackages; [
lua-resty-openidc # lua-resty-openidc
lua-resty-http # lua-resty-http
lua-resty-session # lua-resty-session
lua-resty-jwt # lua-resty-jwt
lua-resty-openssl # lua-resty-openssl
]; # ];
luaPath = pkg: "${pkg}/share/lua/5.1/?.lua"; # luaPath = pkg: "${pkg}/share/lua/5.1/?.lua";
makeLuaPath = lib.concatMapStringsSep ";" luaPath; # makeLuaPath = lib.concatMapStringsSep ";" luaPath;
in # in
'' # ''
# https://stackoverflow.com/questions/38931468/nginx-reverse-proxy-error14077438ssl-ssl-do-handshake-failed # # https://stackoverflow.com/questions/38931468/nginx-reverse-proxy-error14077438ssl-ssl-do-handshake-failed
proxy_ssl_server_name on; # proxy_ssl_server_name on;
lua_package_path '${makeLuaPath extraPureLuaPackages};;'; # lua_package_path '${makeLuaPath extraPureLuaPackages};;';
lua_ssl_trusted_certificate /etc/ssl/certs/ca-certificates.crt; # lua_ssl_trusted_certificate /etc/ssl/certs/ca-certificates.crt;
lua_ssl_verify_depth 5; # lua_ssl_verify_depth 5;
# cache for OIDC discovery metadata # # cache for OIDC discovery metadata
lua_shared_dict discovery 1m; # lua_shared_dict discovery 1m;
lua_shared_dict jwks 1m; # lua_shared_dict jwks 1m;
# https://github.com/openresty/lua-resty-redis/issues/159 # # https://github.com/openresty/lua-resty-redis/issues/159
resolver local=on ipv6=off; # resolver local=on ipv6=off;
init_worker_by_lua_block { # init_worker_by_lua_block {
function check_role (res, role) # function check_role (res, role)
if res.user.roles == nil then # if res.user.roles == nil then
return false # return false
end # end
for _,v in pairs(res.user.roles) do # for _,v in pairs(res.user.roles) do
if string.lower(v) == role then # if string.lower(v) == role then
return true # return true
end # end
end # end
return false # return false
end # end
function is_ip_whitelisted(ip, whitelist) # function is_ip_whitelisted(ip, whitelist)
for _, x in ipairs(whitelist) do # for _, x in ipairs(whitelist) do
if ip == x then # if ip == x then
return true # return true
end # end
end # end
return false # return false
end # end
} # }
''; # '';
appendConfig = '' appendConfig = ''
worker_processes 24; worker_processes 24;
''; '';
}; };
users.groups.acme.members = [ "nginx" ]; users.groups.acme.members = [ "nginx" ];
} }

View File

@ -1,34 +1,22 @@
{ lib, ... }: { config, lib, ... }:
let let
domain = "htnzb.giugl.io"; domain = "htnzb.giugl.io";
network = import ./network.nix;
auth_block = (import ./openid.nix { inherit lib; }).openresty_oidc_block;
in in
{ {
services = { services.nzbget = {
nzbget = {
enable = true; enable = true;
group = "media"; group = "media";
}; };
nginx.virtualHosts.${domain} = { architect.vhost.${domain} = {
forceSSL = true; dnsInterfaces = [ "tailscale" "wireguard" "lan" ];
enableACME = true;
locations."/" = {
proxyPass = "http://127.0.0.1:6789";
extraConfig = auth_block {
access_role = "nzbget";
};
};
};
};
networking.extraHosts = '' locations."/" = {
${network.architect-lan} ${domain} port = 6789;
${network.architect-wg} ${domain} allowLan = true;
${network.architect-ts} ${domain} };
''; };
users.groups.media.members = [ "nzbget" ]; users.groups.media.members = [ "nzbget" ];
} }

View File

@ -3,46 +3,48 @@
{ {
openresty_oidc_block = openresty_oidc_block =
{ access_role ? "", whitelisted_ips ? [ ] }: '' { access_role ? "", whitelisted_ips ? [ ] }: ''
access_by_lua_block {
local opts = {
discovery = "https://auth.giugl.io/realms/master/.well-known/openid-configuration",
client_id = "nginx",
client_secret = "9C6BYxPhTbrRS4DIwd3Smk7e11ABmnt8",
logout_path = "/logout",
redirect_after_logout_uri = "/",
redirect_uri = "/redirect_uri",
keepalive = "yes",
accept_none_alg = true,
revoke_tokens_on_logout = true,
-- access token valid for a day
access_token_expires_in = 86400
}
${lib.optionalString (whitelisted_ips != []) ''
local whitelist = {${lib.strings.concatMapStringsSep "," (x: "\"${x}\"") whitelisted_ips}}
if is_ip_whitelisted(ngx.var.remote_addr, whitelist) then
return
end
''}
-- call introspect for OAuth 2.0 Bearer Access Token validation
local res, err = require("resty.openidc").authenticate(opts)
if err then
ngx.status = 403
ngx.say(err)
ngx.exit(ngx.HTTP_FORBIDDEN)
end
${lib.optionalString (access_role != "") ''
if not check_role(res, "${access_role}") then
ngx.status = 401
ngx.header.content_type = 'text/html';
ngx.say("You are not authorized to access this page. Please contact Er Pepotto.")
ngx.exit(ngx.HTTP_UNAUTHORIZED)
end
''}
}
''; '';
# access_by_lua_block {
# local opts = {
# discovery = "https://auth.giugl.io/realms/master/.well-known/openid-configuration",
# client_id = "nginx",
# client_secret = "9C6BYxPhTbrRS4DIwd3Smk7e11ABmnt8",
# logout_path = "/logout",
# redirect_after_logout_uri = "/",
# redirect_uri = "/redirect_uri",
# keepalive = "yes",
# accept_none_alg = true,
# revoke_tokens_on_logout = true,
# -- access token valid for a day
# access_token_expires_in = 86400
# }
# ${lib.optionalString (whitelisted_ips != []) ''
# local whitelist = {${lib.strings.concatMapStringsSep "," (x: "\"${x}\"") whitelisted_ips}}
# if is_ip_whitelisted(ngx.var.remote_addr, whitelist) then
# return
# end
# ''}
# -- call introspect for OAuth 2.0 Bearer Access Token validation
# local res, err = require("resty.openidc").authenticate(opts)
# if err then
# ngx.status = 403
# ngx.say(err)
# ngx.exit(ngx.HTTP_FORBIDDEN)
# end
# ${lib.optionalString (access_role != "") ''
# if not check_role(res, "${access_role}") then
# ngx.status = 401
# ngx.header.content_type = 'text/html';
# ngx.say("You are not authorized to access this page. Please contact Er Pepotto.")
# ngx.exit(ngx.HTTP_UNAUTHORIZED)
# end
# ''}
# }
# '';
} }

View File

@ -2,8 +2,13 @@
with lib; with lib;
let
utilities = import ./utilities.nix { inherit lib config; };
inherit (utilities) architectInterfaceAddress;
in
{ {
options.architect.firewall = { options.architect = {
firewall = {
openTCP = mkOption { openTCP = mkOption {
type = types.listOf types.int; type = types.listOf types.int;
default = [ ]; default = [ ];
@ -22,4 +27,130 @@ with lib;
}; };
}; };
networks = mkOption {
type = types.attrsOf (types.submodule {
options = {
interface = mkOption {
type = types.str;
description = "The network interface name.";
};
net = mkOption {
type = types.str;
description = "The network address in CIDR format.";
};
devices = mkOption {
type = types.attrsOf (types.submodule {
options = {
address = mkOption {
type = types.str;
description = "The IP address of the device.";
};
hostname = mkOption {
type = types.str;
description = "The hostname of the device.";
};
};
});
default = { };
description = "An attribute set of devices with their configurations.";
};
};
});
default = { };
description = "An attribute set of networks with their configurations.";
};
vhost = mkOption {
type = types.attrsOf (types.submodule {
options = {
dnsInterfaces = mkOption {
type = types.listOf types.str;
default = [ ];
description = "List of interfaces to add extra DNS hosts for this vhost.";
};
locations = mkOption {
type = types.attrsOf (types.submodule {
options = {
extraConfig = mkOption {
type = types.str;
description = "Extra configuration for the location.";
default = "";
};
allowLan = mkOption {
type = types.bool;
default = false;
};
proxyWebsockets = mkOption {
type = types.bool;
default = false;
};
host = mkOption {
type = types.str;
description = "The host for the location.";
default = "127.0.0.1";
};
port = mkOption {
type = types.int;
description = "The port number for the location.";
};
allow = mkOption {
type = types.listOf types.str;
default = [ ];
description = "IP address or CIDR block to allow.";
};
deny = mkOption {
type = types.listOf types.str;
default = [ ];
description = "IP address or CIDR block to deny.";
};
};
});
default = { };
description = "An attribute set of location configurations.";
};
};
});
default = { };
description = "An attribute set of domain configurations.";
};
};
config = {
services.nginx.virtualHosts = mapAttrs
(domain: conf: {
forceSSL = true;
enableACME = true;
locations = mapAttrs
(path: location: {
proxyPass = "http://${location.host}:${toString location.port}";
proxyWebsockets = location.proxyWebsockets;
extraConfig = ''
${optionalString location.allowLan "deny 10.0.0.1;"}
${concatMapStringsSep "\n" (denyCIDR: "deny ${denyCIDR};") location.deny}
${concatMapStringsSep "\n" (allowCIDR: "allow ${allowCIDR};") location.allow}
${optionalString location.allowLan ''allow ${config.architect.networks."lan".net};''}
'' + location.extraConfig;
})
conf.locations;
})
config.architect.vhost;
networking.extraHosts = concatStringsSep "\n" (
mapAttrsToList
(domain: conf: concatMapStringsSep "\n"
(iface: "${architectInterfaceAddress iface} ${domain}")
conf.dnsInterfaces)
config.architect.vhost
);
};
} }

View File

@ -0,0 +1,37 @@
{ config, pkgs, lib, ... }:
let
domain = "photos.giugl.io";
in
{
services.photoprism = {
enable = true;
package = pkgs.photoprism;
originalsPath = "/var/lib/private/photoprism/originals";
address = "0.0.0.0";
settings = {
PHOTOPRISM_DEFAULT_LOCALE = "en";
PHOTOPRISM_DATABASE_DRIVER = "mysql";
PHOTOPRISM_DATABASE_NAME = "photoprism";
PHOTOPRISM_DATABASE_SERVER = "/run/mysqld/mysqld.sock";
PHOTOPRISM_DATABASE_USER = "photoprism";
PHOTOPRISM_SITE_URL = "https://${domain}";
PHOTOPRISM_SITE_TITLE = "PePrism";
PHOTOPRISM_FFMPEG_ENCODER = "nvidia";
PHOTOPRISM_INIT = "tensorflow";
NVIDIA_VISIBLE_DEVICES = "all";
NVIDIA_DRIVER_CAPABILITIES = "compute,video,utility";
PHOTOPRISM_FFMPEG_BIN = "${pkgs.ffmpeg}/bin/ffmpeg";
};
};
architect.vhost.${domain} = {
dnsInterfaces = [ "tailscale" "lan" ];
locations."/" = {
port = config.services.photoprism.port;
allowLan = true;
allow = [ config.architect.networks."tailscale".net ];
proxyWebsockets = true;
};
};
}

View File

@ -1,16 +1,25 @@
{ pkgs, lib, ... }: { pkgs, config, lib, ... }:
let let
domain = "media.giugl.io"; domain = "plex.giugl.io";
network = import ./network.nix; port = 32400;
utilities = import ./utilities.nix { inherit lib config; };
inherit (utilities) architectInterfaceAddress;
in in
{ {
architect.firewall = {
openTCP = [ 32400 3005 8324 32469 ];
openUDP = [ 1900 5353 32410 32412 32413 32414 ];
};
services.plex = { services.plex = {
enable = true; enable = true;
package = pkgs.unstablePkgs.plex; package = pkgs.unstablePkgs.plex;
dataDir = "/plex"; # dataDir = "/plex";
}; };
services.nginx = { services.nginx = {
enable = true; enable = true;
# give a name to the virtual host. It also becomes the server name. # give a name to the virtual host. It also becomes the server name.
@ -19,10 +28,6 @@ in
enableACME = true; enableACME = true;
http2 = true; http2 = true;
extraConfig = '' extraConfig = ''
allow 10.3.0.0/24;
allow 10.0.0.0/24;
deny all;
#Some players don't reopen a socket and playback stops totally instead of resuming after an extended pause #Some players don't reopen a socket and playback stops totally instead of resuming after an extended pause
send_timeout 100m; send_timeout 100m;
@ -77,15 +82,17 @@ in
# Buffering off send to the client as soon as the data is received from Plex. # Buffering off send to the client as soon as the data is received from Plex.
proxy_redirect off; proxy_redirect off;
proxy_buffering off; proxy_buffering off;
add_header 'Content-Security-Policy' 'upgrade-insecure-requests';
''; '';
locations."/" = { proxyPass = "http://127.0.0.1:32400"; }; locations."/" = { proxyPass = "http://127.0.0.1:${toString port}"; };
}; };
}; };
networking.extraHosts = '' networking.extraHosts = ''
${network.architect-lan} ${domain} ${architectInterfaceAddress "lan"} ${domain}
${network.architect-wg} ${domain} ${architectInterfaceAddress "wireguard"} ${domain}
${network.architect-ts} ${domain} ${architectInterfaceAddress "tailscale"} ${domain}
''; '';
users.groups.media.members = [ "plex" ]; users.groups.media.members = [ "plex" ];

View File

@ -4,7 +4,9 @@ let
domain = "xmpp.giugl.io"; domain = "xmpp.giugl.io";
conference_domain = "conference.${domain}"; conference_domain = "conference.${domain}";
upload_domain = "uploads.${domain}"; upload_domain = "uploads.${domain}";
network = import ./network.nix;
utilities = import ./utilities.nix { inherit lib config; };
inherit (utilities) architectInterfaceAddress;
in in
{ {
architect.firewall = { architect.firewall = {
@ -42,9 +44,9 @@ in
}; };
networking.extraHosts = '' networking.extraHosts = ''
${network.architect-lan} ${domain} ${architectInterfaceAddress "lan"} ${domain}
${network.architect-wg} ${domain} ${architectInterfaceAddress "wireguard"} ${domain}
${network.architect-ts} ${domain} ${architectInterfaceAddress "tailscale"} ${domain}
''; '';
users.groups = { users.groups = {

View File

@ -1,40 +1,19 @@
{ lib, ... }: { config, lib, ... }:
let let
domain = "htpro.giugl.io"; domain = "htpro.giugl.io";
network = import ./network.nix;
in in
{ {
services = { services.prowlarr.enable = true;
prowlarr.enable = true;
architect.vhost.${domain} = {
dnsInterfaces = [ "tailscale" "wireguard" ];
nginx.virtualHosts.${domain} = {
forceSSL = true;
enableACME = true;
locations."/" = { locations."/" = {
proxyPass = "http://127.0.0.1:9696"; port = 9696;
extraConfig = '' allowLan = true;
allow 10.0.0.0/24;
${lib.concatMapStrings (x: "allow ${x};") network.gdevices}
deny all;
'';
};
# locations."/api" = {
# proxyPass = "http://127.0.0.1:9696/prowlarr/api";
# };
#
# locations."/Content" = {
# proxyPass = "http://127.0.0.1:9696/prowlarr/Content";
# };
}; };
}; };
networking.extraHosts = ''
${network.architect-lan} ${domain}
${network.architect-wg} ${domain}
${network.architect-ts} ${domain}
'';
users.groups.media.members = [ "prowlarr" ]; users.groups.media.members = [ "prowlarr" ];
} }

View File

@ -1,34 +1,26 @@
{ lib, ... }: { config, lib, ... }:
let let
domain = "htrad.giugl.io"; domain = "htrad.giugl.io";
network = import ./network.nix;
auth_block = (import ./openid.nix { inherit lib; }).openresty_oidc_block;
in in
{ {
services = { services.radarr = {
radarr = {
enable = true; enable = true;
group = "media"; group = "media";
}; };
nginx.virtualHosts.${domain} = { architect.vhost.${domain} = with config.architect.networks; {
forceSSL = true; dnsInterfaces = [ "wireguard" "tailscale" ];
enableACME = true;
locations."/" = { locations."/" = {
proxyPass = "http://127.0.0.1:7878"; port = 7878;
extraConfig = auth_block { allowLan = true;
access_role = "radarr";
};
};
};
};
networking.extraHosts = '' allow = [
${network.architect-lan} ${domain} wireguard.net
${network.architect-wg} ${domain} tailscale.net
${network.architect-ts} ${domain} ];
''; };
};
users.groups.media.members = [ "radarr" ]; users.groups.media.members = [ "radarr" ];
} }

View File

@ -1,14 +1,17 @@
{ services, pkgs, lib, makeBinPath, ... }: { config, pkgs, lib, ... }:
let let
domain = "runas.rocks"; domain = "runas.rocks";
runas_root = "/var/lib/runas.rocks/dist"; runas_root = "/var/lib/runas.rocks/dist";
service_name = "runas.rocks-pull"; service_name = "runas.rocks-pull";
network = import ./network.nix;
mkStartScript = name: pkgs.writeShellScript "${name}.sh" '' mkStartScript = name: pkgs.writeShellScript "${name}.sh" ''
set -euo pipefail set -euo pipefail
cd ${runas_root} cd ${runas_root}
git pull origin main --rebase git pull origin main --rebase
''; '';
utilities = import ./utilities.nix { inherit lib config; };
inherit (utilities) architectInterfaceAddress;
in in
{ {
services.nginx.virtualHosts.${domain} = { services.nginx.virtualHosts.${domain} = {
@ -39,8 +42,8 @@ in
}; };
networking.extraHosts = '' networking.extraHosts = ''
${network.architect-lan} ${domain} ${architectInterfaceAddress "lan"} ${domain}
${network.architect-wg} ${domain} ${architectInterfaceAddress "wireguard"} ${domain}
${network.architect-ts} ${domain} ${architectInterfaceAddress "tailscale"} ${domain}
''; '';
} }

View File

@ -1,34 +1,22 @@
{ lib, ... }: { config, lib, ... }:
let let
domain = "htson.giugl.io"; domain = "htson.giugl.io";
network = import ./network.nix;
auth_block = (import ./openid.nix { inherit lib; }).openresty_oidc_block;
in in
{ {
services = { services.sonarr = {
sonarr = {
enable = true; enable = true;
group = "media"; group = "media";
}; };
nginx.virtualHosts.${domain} = { architect.vhost.${domain} = {
forceSSL = true; dnsInterfaces = [ "tailscale" "wireguard" ];
enableACME = true;
locations."/" = {
proxyPass = "http://127.0.0.1:8989";
extraConfig = auth_block {
access_role = "sonarr";
};
};
};
};
networking.extraHosts = '' locations."/" = {
${network.architect-lan} ${domain} port = 6969;
${network.architect-wg} ${domain} allowLan = true;
${network.architect-ts} ${domain} };
''; };
users.groups.media.members = [ "sonarr" ]; users.groups.media.members = [ "sonarr" ];
} }

View File

@ -1,24 +1,38 @@
{ config, lib, ... }: { pkgs, config, lib, ... }:
let let
network = import ./network.nix; domain = "devs.giugl.io";
ifname = "ts0"; utilities = import ./utilities.nix { inherit lib config; };
inherit (utilities) generateDeviceStrings;
in in
{ {
architect.firewall.openUDP = [ config.services.tailscale.port ]; architect = {
networks.tailscale = {
interface = "ts0";
net = "100.64.0.0/10";
devices = {
architect = { address = "100.64.0.1"; hostname = "architect.${domain}"; };
kmerr = { address = "100.64.0.2"; hostname = "kmerr.${domain}"; };
chuck = { address = "100.64.0.4"; hostname = "chuck.${domain}"; };
dodino = { address = "100.64.0.5"; hostname = "dodino.${domain}"; };
manduria = { address = "100.64.0.6"; hostname = "manduria.${domain}"; };
tommy = { address = "100.64.0.7"; hostname = "tommy.${domain}"; };
ucsb-workstation = { address = "100.64.0.8"; hostname = "ucsb-workstation.${domain}"; };
alfredo = { address = "100.64.0.9"; hostname = "alfredo.${domain}"; };
parallels = { address = "100.64.0.3"; hostname = "parallels.${domain}"; };
};
};
};
services = { services = {
tailscale = { tailscale = {
enable = true; enable = true;
interfaceName = ifname; interfaceName = config.architect.networks.tailscale.interface;
package = pkgs.unstablePkgs.tailscale;
}; };
}; };
networking.extraHosts = '' networking.extraHosts = generateDeviceStrings config.architect.networks.tailscale.devices;
${network.architect-ts} architect.devs.giugl.io
${network.giuliopc-ts} kmerr.devs.giugl.io
${network.dodino-ts} dodino.devs.giugl.io
${network.giuliophone-ts} chuck.devs.giugl.io
'';
} }

View File

@ -0,0 +1,13 @@
{ config, lib, ... }:
{
# device.address device.hostname
generateDeviceStrings = devices: lib.concatStringsSep "\n"
(lib.mapAttrsToList (name: device: "${device.address} ${device.hostname}") devices);
getDeviceAddress = interface: device:
config.architect.networks.${interface}.devices.${device}.address;
architectInterfaceAddress = interface:
config.architect.networks.${interface}.devices.architect.address;
}

View File

@ -1,208 +1,214 @@
{ config, lib, ... }: { config, lib, ... }:
with import ./network.nix;
let let
listenPort = 1194; listenPort = 1194;
domain = "devs.giugl.io";
interface = "wireguard";
utilities = import ./utilities.nix { inherit lib config; };
inherit (utilities) generateDeviceStrings getDeviceAddress;
getWireguardDeviceAddress = getDeviceAddress "wireguard";
in in
{ {
architect.firewall = { architect = {
firewall = {
openUDP = lib.singleton listenPort; openUDP = lib.singleton listenPort;
openUDPVPN = lib.singleton listenPort; openUDPVPN = lib.singleton listenPort;
}; };
networks.${interface} = {
interface = "wg0";
net = "10.3.0.0/24";
devices = {
architect = { address = "10.3.0.1"; hostname = "architect.${domain}"; };
antonio = { address = "10.3.0.6"; hostname = "antonio.${domain}"; };
gbeast = { address = "10.3.0.7"; hostname = "gbeast.${domain}"; };
shield = { address = "10.3.0.12"; hostname = "shield.${domain}"; };
salvatore = { address = "10.3.0.16"; hostname = "salvatore.${domain}"; };
papa = { address = "10.3.0.17"; hostname = "papa.${domain}"; };
defy = { address = "10.3.0.18"; hostname = "defy.${domain}"; };
germano = { address = "10.3.0.19"; hostname = "germano.${domain}"; };
flavio = { address = "10.3.0.20"; hostname = "flavio.${domain}"; };
alain = { address = "10.3.0.22"; hostname = "alain.${domain}"; };
dima = { address = "10.3.0.23"; hostname = "dima.${domain}"; };
mikey = { address = "10.3.0.24"; hostname = "mikey.${domain}"; };
andrew = { address = "10.3.0.25"; hostname = "andrew.${domain}"; };
mikeylaptop = { address = "10.3.0.26"; hostname = "mikeylaptop.${domain}"; };
andrewdesktop = { address = "10.3.0.27"; hostname = "andrewdesktop.${domain}"; };
jacopo = { address = "10.3.0.28"; hostname = "jacopo.${domain}"; };
frznn = { address = "10.3.0.29"; hostname = "frznn.${domain}"; };
ludo = { address = "10.3.0.30"; hostname = "ludo.${domain}"; };
parina = { address = "10.3.0.31"; hostname = "parina.${domain}"; };
nilo = { address = "10.3.0.32"; hostname = "nilo.${domain}"; };
parina-ipad = { address = "10.3.0.33"; hostname = "parina-ipad.${domain}"; };
kclvm = { address = "10.3.0.34"; hostname = "kclvm.${domain}"; };
framecca = { address = "10.3.0.35"; hostname = "framecca.${domain}"; };
framecca_one = { address = "10.3.0.36"; hostname = "framecca_one.${domain}"; };
framecca_two = { address = "10.3.0.37"; hostname = "framecca_two.${domain}"; };
framecca_three = { address = "10.3.0.38"; hostname = "framecca_three.${domain}"; };
framecca_four = { address = "10.3.0.39"; hostname = "framecca_four.${domain}"; };
};
};
};
networking = { networking = {
extraHosts = '' extraHosts = generateDeviceStrings config.architect.networks.wireguard.devices;
${architect-wg} architect.devs.giugl.io
${manduria-wg} manduria.devs.giugl.io
${antonio-wg} antonio.devs.giugl.io
${gbeast-wg} gbeast.devs.giugl.io
${shield-wg} shield.devs.giugl.io
${salvatore-wg} salvatore.devs.giugl.io
${papa-wg} papa.devs.giugl.io
${defy-wg} defy.devs.giugl.io
${germano-wg} germano.devs.giugl.io
${tommy-wg} tommy.devs.giugl.io
${alain-wg} alain.devs.giugl.io
${dima-wg} dima.devs.giugl.io
${mikey-wg} mikey.devs.giugl.io
${andrew-wg} andrew.devs.giugl.io
${mikeylaptop-wg} mikeylaptop.devs.giugl.io
${frznn-wg} frznn.devs.giugl.io
${ludo-wg} ludo.devs.giugl.io
${parina-wg} parina.devs.giugl.io
${parina-ipad-wg} parinaipad.devs.giugl.io
${nilo-wg} nilo.devs.giugl.io
${kclvm-wg} kclvm.devs.giugl.io
${framecca-wg} framecca.devs.giugl.io
'';
wireguard = { wireguard = {
interfaces.${vpn-if} = { interfaces.${config.architect.networks.wireguard.interface} = {
inherit listenPort; inherit listenPort;
ips = [ "10.3.0.1/24" ]; ips = [ "${config.architect.networks.wireguard.devices.architect.address}/24" ];
privateKeyFile = "/secrets/wireguard/server.key"; privateKeyFile = "/secrets/wireguard/server.key";
peers = [ peers = [
{
# Manduria
allowedIPs = [ manduria-wg ];
publicKey = "wT38oXvDQ8g0hI+pAXQobOWf/Wott2zhwo8TLvXK400=";
}
{ {
# Antonio # Antonio
allowedIPs = [ antonio-wg ]; allowedIPs = [ (getWireguardDeviceAddress "antonio") ];
publicKey = "SPndCvEzuLHtGAQV8u/4dfLlFHoPcXS3L98oFOwTljc="; publicKey = "SPndCvEzuLHtGAQV8u/4dfLlFHoPcXS3L98oFOwTljc=";
} }
{ {
# GBEAST # GBEAST
allowedIPs = [ gbeast-wg ]; allowedIPs = [ (getWireguardDeviceAddress "gbeast") ];
publicKey = "XiK+wk+DErz0RmCWRxuaJN1cvdj+3DoiU6tcR+uZfAI="; publicKey = "XiK+wk+DErz0RmCWRxuaJN1cvdj+3DoiU6tcR+uZfAI=";
} }
{ {
# shield # shield
allowedIPs = [ shield-wg ]; allowedIPs = [ (getWireguardDeviceAddress "shield") ];
publicKey = "1GaV/M48sHqQTrBVRQ+jrFU2pUMmv2xkguncVcwPCFs="; publicKey = "1GaV/M48sHqQTrBVRQ+jrFU2pUMmv2xkguncVcwPCFs=";
} }
{ {
# salvatore # salvatore
allowedIPs = [ salvatore-wg ]; allowedIPs = [ (getWireguardDeviceAddress "salvatore") ];
publicKey = "fhlnBHeMyHZKLUCTSA9kmkKoM5x/qzz/rnCJrUh3Gzs="; publicKey = "fhlnBHeMyHZKLUCTSA9kmkKoM5x/qzz/rnCJrUh3Gzs=";
} }
{ {
# papa # papa
allowedIPs = [ papa-wg ]; allowedIPs = [ (getWireguardDeviceAddress "papa") ];
publicKey = "oGHygt02Oni3IFbScKD0NVEfHKCp6bpw68aq5g4RrAA="; publicKey = "oGHygt02Oni3IFbScKD0NVEfHKCp6bpw68aq5g4RrAA=";
} }
{ {
# defy # defy
allowedIPs = [ defy-wg ]; allowedIPs = [ (getWireguardDeviceAddress "defy") ];
publicKey = "Cvi/eto7E6Ef+aiL81ou7x12fJCeuXrf/go9fxEqXG4="; publicKey = "Cvi/eto7E6Ef+aiL81ou7x12fJCeuXrf/go9fxEqXG4=";
} }
{ {
# germano # germano
allowedIPs = [ germano-wg ]; allowedIPs = [ (getWireguardDeviceAddress "germano") ];
publicKey = "LJ0DHY1sFVLQb3ngUGGH0HxbDOPb9KCUPSaYcjr5Uiw="; publicKey = "LJ0DHY1sFVLQb3ngUGGH0HxbDOPb9KCUPSaYcjr5Uiw=";
} }
{ {
# flavio # flavio
allowedIPs = [ flavio-wg ]; allowedIPs = [ (getWireguardDeviceAddress "flavio") ];
publicKey = "Yg0P+yHi/9SZHyoel8jT9fmmu+irLYmT8yMp/CZoaSg="; publicKey = "Yg0P+yHi/9SZHyoel8jT9fmmu+irLYmT8yMp/CZoaSg=";
} }
{
# tommy
allowedIPs = [ tommy-wg ];
publicKey = "tytknU7wql1d0A2provX3RP7CNcEIajfgBJKoSyVLgo=";
}
{ {
# alain # alain
allowedIPs = [ alain-wg ]; allowedIPs = [ (getWireguardDeviceAddress "alain") ];
publicKey = "/o2msFJoUL4yovcIQJTU8c1faFtekrjSBBWJABouWno="; publicKey = "/o2msFJoUL4yovcIQJTU8c1faFtekrjSBBWJABouWno=";
} }
{ {
# dima # dima
allowedIPs = [ dima-wg ]; allowedIPs = [ (getWireguardDeviceAddress "dima") ];
publicKey = "svzWYIZ6v+cLCp/emGG7mx2YpBJqw2fqjVuHZy7b6H0="; publicKey = "svzWYIZ6v+cLCp/emGG7mx2YpBJqw2fqjVuHZy7b6H0=";
} }
{ {
# mikey # mikey
allowedIPs = [ mikey-wg ]; allowedIPs = [ (getWireguardDeviceAddress "mikey") ];
publicKey = "ewbDdX3z7nxG2aPIf9TogXkhxPlGipLFcy6XfyDC6gI="; publicKey = "ewbDdX3z7nxG2aPIf9TogXkhxPlGipLFcy6XfyDC6gI=";
} }
{ {
# andrew # andrew
allowedIPs = [ andrew-wg ]; allowedIPs = [ (getWireguardDeviceAddress "andrew") ];
publicKey = "LP/FgST9fmBQSoKQFq9sFGvjRFOtRooMcuEcjuqaoWM="; publicKey = "LP/FgST9fmBQSoKQFq9sFGvjRFOtRooMcuEcjuqaoWM=";
} }
{ {
# mikey laptop # mikey laptop
allowedIPs = [ mikeylaptop-wg ]; allowedIPs = [ (getWireguardDeviceAddress "mikeylaptop") ];
publicKey = "kz/pY/PgV+dwF1JZ2It4r5B5QfRSQM7HkbFCdvd5Yxk="; publicKey = "kz/pY/PgV+dwF1JZ2It4r5B5QfRSQM7HkbFCdvd5Yxk=";
} }
{ {
# andrew desktop # andrew desktop
allowedIPs = [ andrewdesktop-wg ]; allowedIPs = [ (getWireguardDeviceAddress "andrewdesktop") ];
publicKey = "rpYr3JNLIzxpxzFuQuaHFEl/XvPEPfwLbDETBP8KYXI="; publicKey = "rpYr3JNLIzxpxzFuQuaHFEl/XvPEPfwLbDETBP8KYXI=";
} }
{ {
# laptop desktop # laptop desktop
allowedIPs = [ jacopo-wg ]; allowedIPs = [ (getWireguardDeviceAddress "jacopo") ];
publicKey = "W/taWI79bPIKOolVVu5xZfiJnPw9K91Xn1zhcM0+4g0="; publicKey = "W/taWI79bPIKOolVVu5xZfiJnPw9K91Xn1zhcM0+4g0=";
} }
{ {
# frznn # frznn
allowedIPs = [ frznn-wg ]; allowedIPs = [ (getWireguardDeviceAddress "frznn") ];
publicKey = "dXcrdME6VnnE5PBYwvUmayf7cn2wpcExeCR9gIXOO0o="; publicKey = "dXcrdME6VnnE5PBYwvUmayf7cn2wpcExeCR9gIXOO0o=";
} }
{ {
# ludo # ludo
allowedIPs = [ ludo-wg ]; allowedIPs = [ (getWireguardDeviceAddress "ludo") ];
publicKey = "ecrxdzx7tQZwMPxZOjHUvxZT2xY79B6XEDIW+fhEtEM="; publicKey = "ecrxdzx7tQZwMPxZOjHUvxZT2xY79B6XEDIW+fhEtEM=";
} }
{ {
# parina # parina
allowedIPs = [ parina-wg ]; allowedIPs = [ (getWireguardDeviceAddress "parina") ];
publicKey = "7nubNnfGsg4/7KemMDn9r99mNK8RFU9uOFFqaYv6rUA="; publicKey = "7nubNnfGsg4/7KemMDn9r99mNK8RFU9uOFFqaYv6rUA=";
} }
{ {
# nilo # nilo
allowedIPs = [ nilo-wg ]; allowedIPs = [ (getWireguardDeviceAddress "nilo") ];
publicKey = "lhTEDJ9WnizvEHTd5kN21fTHF27HNk+fPLQnB1B3LW0="; publicKey = "lhTEDJ9WnizvEHTd5kN21fTHF27HNk+fPLQnB1B3LW0=";
} }
{ {
# parina ipad # parina ipad
allowedIPs = [ parina-ipad-wg ]; allowedIPs = [ (getWireguardDeviceAddress "parina-ipad") ];
publicKey = "ezkCzl2qC7Hd7rFKfqMa0JXDKRhVqy79H52rA06x7mU="; publicKey = "ezkCzl2qC7Hd7rFKfqMa0JXDKRhVqy79H52rA06x7mU=";
} }
{ {
# kcl vm # kcl vm
allowedIPs = [ kclvm-wg ]; allowedIPs = [ (getWireguardDeviceAddress "kclvm") ];
publicKey = "jVBaY8AhgAA7myVjU/PJPDUCOjsCi23LT+pGZUoNEkE="; publicKey = "jVBaY8AhgAA7myVjU/PJPDUCOjsCi23LT+pGZUoNEkE=";
} }
{ {
allowedIPs = [ framecca-wg ]; allowedIPs = [ (getWireguardDeviceAddress "framecca") ];
publicKey = "w0XPu5GcDA2vpNk3KCFRdWNVVQHRtAPApEsK1h3Ovyk="; publicKey = "w0XPu5GcDA2vpNk3KCFRdWNVVQHRtAPApEsK1h3Ovyk=";
} }
{ {
allowedIPs = [ framecca_one-wg ]; allowedIPs = [ (getWireguardDeviceAddress "framecca_one") ];
publicKey = "5PnmExv78fU3SS8liUWY/oBCcJ48wzmz/70O0U7K/xs="; publicKey = "5PnmExv78fU3SS8liUWY/oBCcJ48wzmz/70O0U7K/xs=";
} }
{ {
allowedIPs = [ framecca_two-wg ]; allowedIPs = [ (getWireguardDeviceAddress "framecca_two") ];
publicKey = "FbWfh2rL3OYLTDIte+MgctqL/bphn38eqpNy/chc3wM="; publicKey = "FbWfh2rL3OYLTDIte+MgctqL/bphn38eqpNy/chc3wM=";
} }
{ {
allowedIPs = [ framecca_three-wg ]; allowedIPs = [ (getWireguardDeviceAddress "framecca_three") ];
publicKey = "Z3LRFs6CO0kUh4J3pf+HcPsWch3hUAwJBG8/b0Kqnxs="; publicKey = "Z3LRFs6CO0kUh4J3pf+HcPsWch3hUAwJBG8/b0Kqnxs=";
} }
{ {
allowedIPs = [ framecca_four-wg ]; allowedIPs = [ (getWireguardDeviceAddress "framecca_four") ];
publicKey = "g/Ta12igzxSlCxy7KP865qf+l3+r1LjOo6UXjulmPBc="; publicKey = "g/Ta12igzxSlCxy7KP865qf+l3+r1LjOo6UXjulmPBc=";
} }
]; ];

View File

@ -27,21 +27,20 @@
modules = [ modules = [
{ {
imports = users_mod ++ roles_mod ++ add_imports ++ [ imports = users_mod ++
roles_mod ++
add_imports ++ [
(mkSysRole "common") (mkSysRole "common")
(mkSysRole "acme") (mkSysRole "acme")
(mkUser { name = "root"; roles = [ ]; })
]; ];
home-manager = { home-manager = {
users.root.imports = [ (mkHomeRole "common") ];
extraSpecialArgs.unstablePkgs = unstablePkgs; extraSpecialArgs.unstablePkgs = unstablePkgs;
useGlobalPkgs = true; useGlobalPkgs = true;
}; };
system.stateVersion = "22.11"; system.stateVersion = "23.05";
environment.shells = [ pkgs.zsh ];
users.defaultUserShell = pkgs.zsh;
} }
home-manager.nixosModules.home-manager home-manager.nixosModules.home-manager

View File

@ -6,20 +6,26 @@
roles_mod = (map (r: mkHomeRole r) roles); roles_mod = (map (r: mkHomeRole r) roles);
in in
{ {
users.groups.plugdev = { };
fileSystems."/home/${name}/Downloads" = { fileSystems."/home/${name}/Downloads" = {
device = "tmpfs"; device = "tmpfs";
fsType = "tmpfs"; fsType = "tmpfs";
options = [ "size=3G" ]; options = [ "size=3G" ];
}; };
users.users.${name} = { users = {
isNormalUser = true; users.${name} = {
isNormalUser = name != "root";
extraGroups = [ "wheel" "plugdev" ]; extraGroups = [ "wheel" "plugdev" ];
shell = pkgs.zsh;
};
}; };
home-manager.users.${name}.imports = [ (mkHomeRole "common") ] ++ roles_mod; programs.zsh.enable = true;
home-manager.users.${name}.imports = [
(mkHomeRole "common")
(mkHomeRole "zsh")
] ++ roles_mod;
}; };
mkHMUser = { name, roles ? [ ] }: mkHMUser = { name, roles ? [ ] }:

View File

@ -1,10 +1,10 @@
{ ... }: { options, lib, config, ... }:
{ {
security.acme = { config.security.acme = {
acceptTerms = true; acceptTerms = true;
defaults = { defaults = {
email = "sysadmin@giugl.io"; email = "letsencrypt@depasquale.giugl.io";
}; };
}; };
} }

View File

@ -1,7 +1,9 @@
{ config, pkgs, lib, ... }: { config, pkgs, lib, ... }:
{ {
boot.tmpOnTmpfs = true; boot.tmp = {
useTmpfs = true;
};
console = { console = {
keyMap = "us"; keyMap = "us";
@ -41,7 +43,6 @@
glances glances
tcpdump tcpdump
restic restic
neovim
tmux tmux
parted parted
unzip unzip
@ -50,5 +51,6 @@
nmap nmap
ripgrep ripgrep
jq jq
helix
]; ];
} }

View File

@ -11,9 +11,10 @@
home-manager home-manager
ripgrep ripgrep
ydiff ydiff
nix-index
] ]
++ lib.optional (!stdenv.isDarwin) pastebinit; ++ lib.optional (!stdenv.isDarwin) pastebinit;
stateVersion = "22.11"; stateVersion = "23.05";
}; };
} }

View File

@ -118,7 +118,6 @@
nodePackages.vscode-langservers-extracted nodePackages.vscode-langservers-extracted
nodePackages.typescript nodePackages.typescript
nodePackages.svelte-language-server nodePackages.svelte-language-server
swiProlog
nixpkgs-fmt nixpkgs-fmt
]; ];
}; };

View File

@ -14,6 +14,8 @@
initExtra = '' initExtra = ''
any-nix-shell zsh --info-right | source /dev/stdin any-nix-shell zsh --info-right | source /dev/stdin
source ${pkgs.nix-index}/etc/profile.d/command-not-found.sh
''; '';
}; };
} }