WIP
This commit is contained in:
Generated
+17
@@ -18,6 +18,22 @@
|
|||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"dotfiles": {
|
||||||
|
"flake": false,
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1778400209,
|
||||||
|
"narHash": "sha256-mEGIHZaTmQulmWLg3C8r0wdpEllFcKWeAt+3FLa4grM=",
|
||||||
|
"owner": "aloslider",
|
||||||
|
"repo": "dotfiles",
|
||||||
|
"rev": "e01f5de3b98f3c85997db571eeaef855bbda80a3",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "aloslider",
|
||||||
|
"repo": "dotfiles",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
"home-manager": {
|
"home-manager": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"nixpkgs": [
|
"nixpkgs": [
|
||||||
@@ -89,6 +105,7 @@
|
|||||||
"root": {
|
"root": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"disko": "disko",
|
"disko": "disko",
|
||||||
|
"dotfiles": "dotfiles",
|
||||||
"home-manager": "home-manager",
|
"home-manager": "home-manager",
|
||||||
"nixpkgs": "nixpkgs_2",
|
"nixpkgs": "nixpkgs_2",
|
||||||
"sops-nix": "sops-nix"
|
"sops-nix": "sops-nix"
|
||||||
|
|||||||
@@ -1,15 +1,20 @@
|
|||||||
{
|
{
|
||||||
inputs = {
|
inputs = {
|
||||||
nixpkgs.url = "github:nixos/nixpkgs?ref=nixos-unstable";
|
nixpkgs.url = "github:nixos/nixpkgs?ref=nixos-unstable";
|
||||||
|
disko.url = "github:nix-community/disko";
|
||||||
|
dotfiles = {
|
||||||
|
url = "github:aloslider/dotfiles";
|
||||||
|
flake = false;
|
||||||
|
};
|
||||||
home-manager = {
|
home-manager = {
|
||||||
url = "github:nix-community/home-manager";
|
url = "github:nix-community/home-manager";
|
||||||
inputs.nixpkgs.follows = "nixpkgs";
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
};
|
};
|
||||||
disko.url = "github:nix-community/disko";
|
|
||||||
sops-nix.url = "github:mic92/sops-nix";
|
sops-nix.url = "github:mic92/sops-nix";
|
||||||
};
|
};
|
||||||
|
|
||||||
outputs = { self, nixpkgs, ... }@inputs:
|
outputs =
|
||||||
|
{ self, nixpkgs, ... }@inputs:
|
||||||
let
|
let
|
||||||
system = "x86_64-linux";
|
system = "x86_64-linux";
|
||||||
pkgs = nixpkgs;
|
pkgs = nixpkgs;
|
||||||
@@ -29,6 +34,7 @@
|
|||||||
inherit system;
|
inherit system;
|
||||||
specialArgs = {
|
specialArgs = {
|
||||||
inherit inputs;
|
inherit inputs;
|
||||||
|
inherit (inputs) disko;
|
||||||
lib = customLib;
|
lib = customLib;
|
||||||
};
|
};
|
||||||
modules = [
|
modules = [
|
||||||
|
|||||||
@@ -2,6 +2,9 @@
|
|||||||
{
|
{
|
||||||
imports = [
|
imports = [
|
||||||
./git.nix
|
./git.nix
|
||||||
./zsh.nix
|
./packages.nix
|
||||||
|
./podman.nix
|
||||||
|
./selfhosted
|
||||||
|
./sops.nix
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
{ config, pkgs, ... }:
|
||||||
|
{
|
||||||
|
home.packages = with pkgs; [
|
||||||
|
chezmoi
|
||||||
|
fzf
|
||||||
|
lazygit
|
||||||
|
lazydocker
|
||||||
|
sops
|
||||||
|
];
|
||||||
|
}
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
{ config, ... }:
|
{ config, ... }:
|
||||||
{
|
{
|
||||||
programs.zsh = {
|
services.podman = {
|
||||||
enable = true;
|
enable = true;
|
||||||
envExtra = "";
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
{ config, lib, ... }:
|
||||||
|
with lib;
|
||||||
|
{
|
||||||
|
options.selfhosted.common = {
|
||||||
|
networkName = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
};
|
||||||
|
dataDir = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = {
|
||||||
|
sops.secrets = {
|
||||||
|
"domains/serv" = { };
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
{ config, ... }:
|
||||||
|
let
|
||||||
|
prefix = "sh-";
|
||||||
|
cfg = config.selfhosted;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
imports = [
|
||||||
|
./common.nix
|
||||||
|
|
||||||
|
./homarr
|
||||||
|
./netbird
|
||||||
|
./pocket-id
|
||||||
|
./vaultwarden
|
||||||
|
];
|
||||||
|
|
||||||
|
config.selfhosted = {
|
||||||
|
common = {
|
||||||
|
networkName = "selfhosted";
|
||||||
|
dataDir = "/mnt/data";
|
||||||
|
};
|
||||||
|
homarr = {
|
||||||
|
name = "${prefix}homarr";
|
||||||
|
subdomain = "dash";
|
||||||
|
};
|
||||||
|
netbird =
|
||||||
|
let
|
||||||
|
nbPrefix = "${prefix}nb-";
|
||||||
|
in
|
||||||
|
{
|
||||||
|
subdomain = "nb";
|
||||||
|
traefik = {
|
||||||
|
name = "${nbPrefix}traefik";
|
||||||
|
};
|
||||||
|
dashboard = {
|
||||||
|
name = "${nbPrefix}dashboard";
|
||||||
|
};
|
||||||
|
server = {
|
||||||
|
name = "${nbPrefix}server";
|
||||||
|
};
|
||||||
|
proxy = {
|
||||||
|
name = "${nbPrefix}proxy";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
pocket-id = {
|
||||||
|
name = "${prefix}pocket-id";
|
||||||
|
subdomain = "id";
|
||||||
|
};
|
||||||
|
vaultwarden = {
|
||||||
|
name = "${prefix}vaultwarden";
|
||||||
|
subdomain = "vault";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
{ config, lib, ... }:
|
||||||
|
with lib;
|
||||||
|
let
|
||||||
|
common = config.selfhosted.common;
|
||||||
|
cfg = config.selfhosted.homarr;
|
||||||
|
hostDataPath = "${common.dataDir}/homarr/data";
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options.selfhosted.homarr = {
|
||||||
|
name = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
};
|
||||||
|
subdomain = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = {
|
||||||
|
sops.secrets = {
|
||||||
|
"homarr/enc_key" = { };
|
||||||
|
};
|
||||||
|
|
||||||
|
services.podman.containers."${cfg.name}" = {
|
||||||
|
image = "ghcr.io/homarr-labs/homarr:v1.60.0";
|
||||||
|
network = common.networkName;
|
||||||
|
environment = {
|
||||||
|
SECRET_ENCRYPTION_KEY = "${config.sops.secrets."homarr/enc_key".path}";
|
||||||
|
};
|
||||||
|
volumes = [
|
||||||
|
"${hostDataPath}:/appdata"
|
||||||
|
];
|
||||||
|
autoStart = true;
|
||||||
|
extraConfig = {
|
||||||
|
Quadlet = {
|
||||||
|
DefaultDependencies = false;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,195 @@
|
|||||||
|
{ config, ... }:
|
||||||
|
let
|
||||||
|
cfg = config.selfhosted.netbird;
|
||||||
|
poCfg = config.selfhosted.pocket-id;
|
||||||
|
domain = config.sops.placeholder."domains/serv";
|
||||||
|
fullDomain = "${cfg.subdomain}.${domain}";
|
||||||
|
in
|
||||||
|
{
|
||||||
|
sops.secrets = {
|
||||||
|
"netbird/traefik/letsEncryptEmail" = { };
|
||||||
|
"netbird/auth/client_id" = { };
|
||||||
|
"netbird/auth/client_secret" = { };
|
||||||
|
"netbird/server/auth_secret" = { };
|
||||||
|
"netbird/server/enc_key" = { };
|
||||||
|
"netbird/proxy/token" = { };
|
||||||
|
};
|
||||||
|
|
||||||
|
sops.templates."nb-traefik.yaml".content = ''
|
||||||
|
log:
|
||||||
|
level: INFO
|
||||||
|
|
||||||
|
providers:
|
||||||
|
file:
|
||||||
|
filename: /etc/traefik/dynamic.yaml
|
||||||
|
|
||||||
|
entryPoints:
|
||||||
|
web:
|
||||||
|
address: ":80"
|
||||||
|
http:
|
||||||
|
redirections:
|
||||||
|
entryPoint:
|
||||||
|
to: websecure
|
||||||
|
scheme: https
|
||||||
|
|
||||||
|
websecure:
|
||||||
|
address: ":443"
|
||||||
|
|
||||||
|
certificatesResolvers:
|
||||||
|
letsencrypt:
|
||||||
|
acme:
|
||||||
|
email: ${config.sops.placeholder."netbird/traefik/letsEncryptEmail"}
|
||||||
|
storage: /letsencrypt/acme.json
|
||||||
|
tlsChallenge: true
|
||||||
|
'';
|
||||||
|
|
||||||
|
sops.templates."nb-traefik-dynamic.yaml".content =
|
||||||
|
let
|
||||||
|
nbServerName = "nb-server";
|
||||||
|
nbServerH2cName = "nb-server-h2c";
|
||||||
|
nbDashboardName = "nb-dashboard";
|
||||||
|
in
|
||||||
|
''
|
||||||
|
http:
|
||||||
|
routers:
|
||||||
|
nb-relay:
|
||||||
|
rule: Host(`${fullDomain}`) && PathPrefix(`/relay`)
|
||||||
|
entryPoints:
|
||||||
|
- websecure
|
||||||
|
tls:
|
||||||
|
certResolver: letsencrypt
|
||||||
|
service: ${nbServerName}
|
||||||
|
priority: 110
|
||||||
|
|
||||||
|
nb-ws-signal:
|
||||||
|
rule: Host(`${fullDomain}`) && PathPrefix(`/ws-proxy/signal`)
|
||||||
|
entryPoints:
|
||||||
|
- websecure
|
||||||
|
tls:
|
||||||
|
certResolver: letsencrypt
|
||||||
|
service: ${nbServerName}
|
||||||
|
priority: 110
|
||||||
|
|
||||||
|
nb-ws-management:
|
||||||
|
rule: Host(`${fullDomain}`) && PathPrefix(`/ws-proxy/management`)
|
||||||
|
entryPoints:
|
||||||
|
- websecure
|
||||||
|
tls:
|
||||||
|
certResolver: letsencrypt
|
||||||
|
service: ${nbServerName}
|
||||||
|
priority: 110
|
||||||
|
|
||||||
|
nb-grpc-signal:
|
||||||
|
rule: Host(`${fullDomain}`) && PathPrefix(`/signalexchange.SignalExchange/`)
|
||||||
|
entryPoints:
|
||||||
|
- websecure
|
||||||
|
tls:
|
||||||
|
certResolver: letsencrypt
|
||||||
|
service: ${nbServerH2cName}
|
||||||
|
priority: 100
|
||||||
|
|
||||||
|
nb-grpc-management:
|
||||||
|
rule: Host(`${fullDomain}`) && PathPrefix(`/management.ManagementService/`)
|
||||||
|
entryPoints:
|
||||||
|
- websecure
|
||||||
|
tls:
|
||||||
|
certResolver: letsencrypt
|
||||||
|
service: ${nbServerH2cName}
|
||||||
|
priority: 100
|
||||||
|
|
||||||
|
nb-api:
|
||||||
|
rule: Host(`${fullDomain}`) && PathPrefix(`/api`)
|
||||||
|
entryPoints:
|
||||||
|
- websecure
|
||||||
|
tls:
|
||||||
|
certResolver: letsencrypt
|
||||||
|
service: ${nbServerName}
|
||||||
|
priority: 90
|
||||||
|
|
||||||
|
${nbDashboardName}:
|
||||||
|
rule: Host(`${fullDomain}`)
|
||||||
|
entryPoints:
|
||||||
|
- websecure
|
||||||
|
tls:
|
||||||
|
certResolver: letsencrypt
|
||||||
|
service: ${nbDashboardName}
|
||||||
|
priority: 10
|
||||||
|
|
||||||
|
services:
|
||||||
|
${nbServerName}:
|
||||||
|
loadBalancer:
|
||||||
|
servers:
|
||||||
|
- url: http://${cfg.server.name}:80
|
||||||
|
|
||||||
|
${nbServerH2cName}:
|
||||||
|
loadBalancer:
|
||||||
|
servers:
|
||||||
|
- url: http://${cfg.server.name}:80
|
||||||
|
scheme: h2c
|
||||||
|
|
||||||
|
${nbDashboardName}:
|
||||||
|
loadBalancer:
|
||||||
|
servers:
|
||||||
|
- url: http://${cfg.dashboard.name}:80
|
||||||
|
tcp:
|
||||||
|
serversTransports:
|
||||||
|
pp-v2:
|
||||||
|
proxyProtocol:
|
||||||
|
version: 2
|
||||||
|
'';
|
||||||
|
|
||||||
|
sops.templates."nb-dashboard.env".content = ''
|
||||||
|
NETBIRD_MGMT_API_ENDPOINT=https://${fullDomain}
|
||||||
|
NETBIRD_MGMT_GRPC_API_ENDPOINT=https://${fullDomain}
|
||||||
|
|
||||||
|
AUTH_AUDIENCE=${cfg.dashboard.name}
|
||||||
|
AUTH_CLIENT_ID=${config.sops.placeholder."netbird/auth/client_id"}
|
||||||
|
AUTH_CLIENT_SECRET=${config.sops.placeholder."netbird/auth/client_secret"}
|
||||||
|
AUTH_AUTHORITY=https://${poCfg.subdomain}.${domain}
|
||||||
|
USE_AUTH0=false
|
||||||
|
AUTH_SUPPORTED_SCOPES=openid profile email groups
|
||||||
|
AUTH_REDIRECT_URI=/nb-auth
|
||||||
|
AUTH_SILENT_REDIRECT_URI=/nb-silent-auth
|
||||||
|
|
||||||
|
LETSENCRYPT_DOMAIN=none
|
||||||
|
LETSENCRYPT_EMAIL=${config.sops.placeholder."netbird/traefik/letsEncryptEmail"}
|
||||||
|
'';
|
||||||
|
|
||||||
|
sops.templates."nb-config.yaml".content = ''
|
||||||
|
server:
|
||||||
|
listenAddress: ":80"
|
||||||
|
exposedAddress: "https://${fullDomain}"
|
||||||
|
stunPorts:
|
||||||
|
- 3478
|
||||||
|
metricsPort: 9090
|
||||||
|
healthcheckAddress: ":9000"
|
||||||
|
logLevel: "info"
|
||||||
|
logFile: "console"
|
||||||
|
|
||||||
|
authSecret: "${config.sops.placeholder."netbird/server/auth_secret"}"
|
||||||
|
|
||||||
|
auth:
|
||||||
|
issuer: "https://${poCfg.subdomain}.${domain}"
|
||||||
|
clientID: "${config.sops.placeholder."netbird/auth/client_id"}"
|
||||||
|
clientSecret: "${config.sops.placeholder."netbird/auth/client_secret"}"
|
||||||
|
|
||||||
|
reverseProxy:
|
||||||
|
trustedHTTPProxies:
|
||||||
|
- "127.0.0.1/32"
|
||||||
|
|
||||||
|
store:
|
||||||
|
engine: "sqlite"
|
||||||
|
encryptionKey: "${config.sops.placeholder."netbird/server/enc_key"}"
|
||||||
|
'';
|
||||||
|
|
||||||
|
sops.templates."nb-proxy.env".content = ''
|
||||||
|
NB_PROXY_DOMAIN=${fullDomain}
|
||||||
|
NB_PROXY_TOKEN=${config.sops.placeholder."netbird/proxy/token"}
|
||||||
|
NB_PROXY_MANAGEMENT_ADDRESS=http://${cfg.server.name}:80
|
||||||
|
NB_PROXY_ALLOW_INSECURE=true
|
||||||
|
NB_PROXY_ADDRESS=:8443
|
||||||
|
NB_PROXY_ACME_CERTIFICATES=true
|
||||||
|
NB_PROXY_ACME_CHALLENGE_TYPE=tls-alpn-01
|
||||||
|
NB_PROXY_CERTIFICATE_DIRECTORY=/certs
|
||||||
|
'';
|
||||||
|
}
|
||||||
@@ -0,0 +1,110 @@
|
|||||||
|
{
|
||||||
|
config,
|
||||||
|
lib,
|
||||||
|
pkgs,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
with lib;
|
||||||
|
let
|
||||||
|
common = config.selfhosted.common;
|
||||||
|
cfg = config.selfhosted.netbird;
|
||||||
|
hostDataPath = "${common.dataDir}/netbird";
|
||||||
|
in
|
||||||
|
{
|
||||||
|
imports = [
|
||||||
|
./config.nix
|
||||||
|
];
|
||||||
|
|
||||||
|
options.selfhosted.netbird = {
|
||||||
|
subdomain = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
};
|
||||||
|
traefik = {
|
||||||
|
name = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
dashboard = {
|
||||||
|
name = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
server = {
|
||||||
|
name = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
proxy = {
|
||||||
|
name = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = {
|
||||||
|
services.podman.containers.${cfg.traefik.name} = {
|
||||||
|
image = "traefik:v3.6";
|
||||||
|
network = common.networkName;
|
||||||
|
ports = [
|
||||||
|
"0.0.0.0:80:80"
|
||||||
|
"0.0.0.0:443:443"
|
||||||
|
];
|
||||||
|
autoStart = true;
|
||||||
|
volumes = [
|
||||||
|
"${hostDataPath}/traefik/letsencrypt:/letsencrypt"
|
||||||
|
"${config.sops.templates."nb-traefik.yaml".path}:/etc/traefik/config.yaml"
|
||||||
|
"${config.sops.templates."nb-traefik-dynamic.yaml".path}:/etc/traefik/dynamic.yaml"
|
||||||
|
];
|
||||||
|
extraConfig = {
|
||||||
|
Quadlet = {
|
||||||
|
DefaultDependencies = false;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
services.podman.containers.${cfg.dashboard.name} = {
|
||||||
|
image = "netbirdio/dashboard:v2.37.1";
|
||||||
|
network = common.networkName;
|
||||||
|
environmentFile = [ "${config.sops.templates."nb-dashboard.env".path}" ];
|
||||||
|
autoStart = true;
|
||||||
|
extraConfig = {
|
||||||
|
Quadlet = {
|
||||||
|
DefaultDependencies = false;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
services.podman.containers.${cfg.server.name} = {
|
||||||
|
image = "netbirdio/netbird-server:0.70.5";
|
||||||
|
network = common.networkName;
|
||||||
|
ports = [
|
||||||
|
"0.0.0.0:3478:3478/udp"
|
||||||
|
];
|
||||||
|
autoStart = true;
|
||||||
|
volumes = [
|
||||||
|
"${hostDataPath}/server/data:/var/lib/netbird"
|
||||||
|
"${config.sops.templates."nb-config.yaml".path}:/etc/netbird/config.yaml"
|
||||||
|
];
|
||||||
|
extraConfig = {
|
||||||
|
Quadlet = {
|
||||||
|
DefaultDependencies = false;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
services.podman.containers.${cfg.proxy.name} = {
|
||||||
|
image = "netbirdio/reverse-proxy:0.70.5";
|
||||||
|
network = common.networkName;
|
||||||
|
environmentFile = [ "${config.sops.templates."nb-proxy.env".path}" ];
|
||||||
|
autoStart = true;
|
||||||
|
volumes = [
|
||||||
|
"${hostDataPath}/proxy/certs:/certs"
|
||||||
|
];
|
||||||
|
extraConfig = {
|
||||||
|
Quadlet = {
|
||||||
|
DefaultDependencies = false;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
{ config, ... }:
|
||||||
|
let
|
||||||
|
cfg = config.selfhosted.pocket-id;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
sops.secrets = {
|
||||||
|
"pocket_id/enc_key" = { };
|
||||||
|
};
|
||||||
|
|
||||||
|
sops.templates."pocket-id.env" = {
|
||||||
|
content = ''
|
||||||
|
APP_URL=https://${cfg.subdomain}.${config.sops.placeholder."domains/serv"}
|
||||||
|
ENCRYPTION_KEY=${config.sops.placeholder."pocket_id/enc_key"}
|
||||||
|
TRUST_PROXY=true
|
||||||
|
ANALYTICS_DISABLED=true
|
||||||
|
PUID=1000
|
||||||
|
PGID=1000
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
{ config, lib, ... }:
|
||||||
|
with lib;
|
||||||
|
let
|
||||||
|
common = config.selfhosted.common;
|
||||||
|
cfg = config.selfhosted.pocket-id;
|
||||||
|
hostDataPath = "${common.dataDir}/pocket-id/data";
|
||||||
|
in
|
||||||
|
{
|
||||||
|
imports = [
|
||||||
|
./config.nix
|
||||||
|
];
|
||||||
|
|
||||||
|
options.selfhosted.pocket-id = {
|
||||||
|
name = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
};
|
||||||
|
subdomain = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = {
|
||||||
|
services.podman.containers.${cfg.name} = {
|
||||||
|
image = "ghcr.io/pocket-id/pocket-id:v2";
|
||||||
|
network = common.networkName;
|
||||||
|
environmentFile = [ "${config.sops.templates."pocket-id.env".path}" ];
|
||||||
|
volumes = [
|
||||||
|
"${hostDataPath}:/app/data"
|
||||||
|
];
|
||||||
|
autoStart = true;
|
||||||
|
extraConfig = {
|
||||||
|
Quadlet = {
|
||||||
|
DefaultDependencies = false;
|
||||||
|
};
|
||||||
|
Container = {
|
||||||
|
HealthCmd = ''"/app/pocket-id" "healthcheck"'';
|
||||||
|
HealthInterval = "1m30s";
|
||||||
|
HealthTimeout = "5s";
|
||||||
|
HealthRetries = "2";
|
||||||
|
HealthStartPeriod = "10s";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
{ config, ... }:
|
||||||
|
let
|
||||||
|
cfg = config.selfhosted.vaultwarden;
|
||||||
|
poCfg = config.selfhosted.pocket-id;
|
||||||
|
domain = config.sops.placeholder."domains/serv";
|
||||||
|
in
|
||||||
|
{
|
||||||
|
sops.secrets = {
|
||||||
|
"vaultwarden/client_id" = { };
|
||||||
|
"vaultwarden/client_secret" = { };
|
||||||
|
};
|
||||||
|
|
||||||
|
sops.templates."vaultwarden.env".content = ''
|
||||||
|
DOMAIN=https://${cfg.subdomain}.${domain}
|
||||||
|
LOG_LEVEL=info,vaultwarden::sso=debug
|
||||||
|
SIGNUPS_ALLOWED=false
|
||||||
|
SSO_ENABLED=false
|
||||||
|
SSO_DEBUG_TOKENS=true
|
||||||
|
SSO_ONLY=false
|
||||||
|
SSO_AUTHORITY=https://${poCfg.subdomain}.${domain}
|
||||||
|
SSO_CLIENT_ID=${config.sops.placeholder."vaultwarden/client_id"}
|
||||||
|
SSO_CLIENT_SECRET=${config.sops.placeholder."vaultwarden/client_secret"}
|
||||||
|
SSO_AUTH_ONLY_NOT_SESSION=true
|
||||||
|
SSO_PKCE=true
|
||||||
|
'';
|
||||||
|
}
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
{ config, lib, ... }:
|
||||||
|
with lib;
|
||||||
|
let
|
||||||
|
common = config.selfhosted.common;
|
||||||
|
cfg = config.selfhosted.vaultwarden;
|
||||||
|
hostDataPath = "${common.dataDir}/vaultwarden/data";
|
||||||
|
in
|
||||||
|
{
|
||||||
|
imports = [
|
||||||
|
./config.nix
|
||||||
|
];
|
||||||
|
|
||||||
|
options.selfhosted.vaultwarden = {
|
||||||
|
enable = mkEnableOption "Enable container";
|
||||||
|
name = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
};
|
||||||
|
subdomain = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = {
|
||||||
|
services.podman.containers.${cfg.name} = {
|
||||||
|
image = "docker.io/vaultwarden/server:1.36.0";
|
||||||
|
network = config.selfhosted.common.networkName;
|
||||||
|
environmentFile = [ "${config.sops.templates."vaultwarden.env".path}" ];
|
||||||
|
volumes = [
|
||||||
|
"${hostDataPath}:/data"
|
||||||
|
];
|
||||||
|
autoStart = true;
|
||||||
|
extraConfig = {
|
||||||
|
Quadlet = {
|
||||||
|
DefaultDependencies = false;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
{ config, ... }:
|
||||||
|
{
|
||||||
|
imports = [
|
||||||
|
./network.nix
|
||||||
|
./containers
|
||||||
|
];
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
{ config, ... }:
|
||||||
|
let
|
||||||
|
common = config.selfhosted.common;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
services.podman = {
|
||||||
|
networks.${common.networkName} = {
|
||||||
|
driver = "bridge";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
{ config, dotfiles, sops-nix, ... }:
|
||||||
|
{
|
||||||
|
imports = [
|
||||||
|
sops-nix.homeManagerModules.sops
|
||||||
|
];
|
||||||
|
|
||||||
|
sops = {
|
||||||
|
defaultSopsFile = "${dotfiles}/dot_config/sops/secrets.yaml";
|
||||||
|
age.keyFile = "${config.xdg.configHome}/age/key.txt";
|
||||||
|
};
|
||||||
|
|
||||||
|
home.file.".sops.yaml".source = "${dotfiles}/dot_sops.yaml";
|
||||||
|
|
||||||
|
xdg.configFile."sops" = {
|
||||||
|
source = "${dotfiles}/dot_config/sops";
|
||||||
|
recursive = true;
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
{
|
{
|
||||||
config,
|
config,
|
||||||
pkgs,
|
|
||||||
lib,
|
|
||||||
inputs,
|
inputs,
|
||||||
|
lib,
|
||||||
|
pkgs,
|
||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
{
|
{
|
||||||
@@ -11,6 +11,9 @@
|
|||||||
];
|
];
|
||||||
|
|
||||||
home-manager = {
|
home-manager = {
|
||||||
|
extraSpecialArgs = {
|
||||||
|
inherit (inputs) disko dotfiles sops-nix;
|
||||||
|
};
|
||||||
useGlobalPkgs = true;
|
useGlobalPkgs = true;
|
||||||
useUserPackages = true;
|
useUserPackages = true;
|
||||||
users.benq =
|
users.benq =
|
||||||
@@ -22,15 +25,11 @@
|
|||||||
"home/benq/core"
|
"home/benq/core"
|
||||||
]
|
]
|
||||||
++ (map (f: "home/benq/optional/${f}") [
|
++ (map (f: "home/benq/optional/${f}") [
|
||||||
|
|
||||||
])
|
])
|
||||||
))
|
))
|
||||||
];
|
];
|
||||||
|
|
||||||
home.packages = with pkgs; [
|
|
||||||
chezmoi
|
|
||||||
lazygit
|
|
||||||
lazydocker
|
|
||||||
];
|
|
||||||
home.stateVersion = "25.05";
|
home.stateVersion = "25.05";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -3,8 +3,10 @@
|
|||||||
imports = [
|
imports = [
|
||||||
./disko.nix
|
./disko.nix
|
||||||
./locale.nix
|
./locale.nix
|
||||||
|
./netbird.nix
|
||||||
./nix.nix
|
./nix.nix
|
||||||
./packages.nix
|
./packages.nix
|
||||||
./sops.nix
|
./sops.nix
|
||||||
|
./zsh.nix
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
config,
|
config,
|
||||||
disko,
|
disko,
|
||||||
lib,
|
lib,
|
||||||
inputs,
|
|
||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
with lib;
|
with lib;
|
||||||
@@ -11,7 +10,7 @@ let
|
|||||||
in
|
in
|
||||||
{
|
{
|
||||||
imports = [
|
imports = [
|
||||||
inputs.disko.nixosModules.disko
|
disko.nixosModules.disko
|
||||||
];
|
];
|
||||||
|
|
||||||
options.disko.cfg = {
|
options.disko.cfg = {
|
||||||
|
|||||||
@@ -0,0 +1,4 @@
|
|||||||
|
{ config, ... }:
|
||||||
|
{
|
||||||
|
services.netbird.enable = true;
|
||||||
|
}
|
||||||
@@ -1,8 +1,13 @@
|
|||||||
{ congif, pkgs, ... }:
|
{ congif, pkgs, ... }:
|
||||||
{
|
{
|
||||||
environment.systemPackages = with pkgs; [
|
environment.systemPackages = with pkgs; [
|
||||||
|
age
|
||||||
|
bind
|
||||||
|
btop
|
||||||
git
|
git
|
||||||
neovim
|
jq
|
||||||
|
openssl
|
||||||
tmux
|
tmux
|
||||||
|
tree
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
{ config, ... }:
|
||||||
|
{
|
||||||
|
# programs.zsh.enable = true;
|
||||||
|
programs.nix-ld.enable = true;
|
||||||
|
}
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
{ config, pkgs, ... }:
|
|
||||||
{
|
|
||||||
virtualisation.docker = {
|
|
||||||
enable = true;
|
|
||||||
rootless = {
|
|
||||||
enable = true;
|
|
||||||
setSocketVariable = true;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
security.wrappers = {
|
|
||||||
docker-rootlesskit = {
|
|
||||||
owner = "root";
|
|
||||||
group = "root";
|
|
||||||
capabilities = "cap_net_bind_service+ep";
|
|
||||||
source = "${pkgs.rootlesskit}/bin/rootlesskit";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
config,
|
config,
|
||||||
lib,
|
lib,
|
||||||
inputs,
|
pkgs,
|
||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
with lib;
|
with lib;
|
||||||
@@ -9,11 +9,16 @@ with lib;
|
|||||||
users = {
|
users = {
|
||||||
mutableUsers = false;
|
mutableUsers = false;
|
||||||
users.benq = {
|
users.benq = {
|
||||||
|
shell = pkgs.zsh;
|
||||||
isNormalUser = true;
|
isNormalUser = true;
|
||||||
|
ignoreShellProgramCheck = true;
|
||||||
hashedPasswordFile = config.sops.secrets.benq-password.path;
|
hashedPasswordFile = config.sops.secrets.benq-password.path;
|
||||||
openssh.authorizedKeys.keys = [
|
openssh.authorizedKeys.keys = [
|
||||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAeIuJzR68xA4ugJjtWbwvaWEU852Hg9FAAhXNw8ou43 benq"
|
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAeIuJzR68xA4ugJjtWbwvaWEU852Hg9FAAhXNw8ou43 benq"
|
||||||
];
|
];
|
||||||
|
linger = true;
|
||||||
|
subUidRanges = [ { startUid = 100000; count = 65536; } ];
|
||||||
|
subGidRanges = [ { startGid = 100000; count = 65536; } ];
|
||||||
extraGroups =
|
extraGroups =
|
||||||
let
|
let
|
||||||
ifTheyExist = groups: filter (group: hasAttr group config.users.groups) groups;
|
ifTheyExist = groups: filter (group: hasAttr group config.users.groups) groups;
|
||||||
@@ -21,7 +26,6 @@ with lib;
|
|||||||
flatten [
|
flatten [
|
||||||
"wheel"
|
"wheel"
|
||||||
(ifTheyExist [
|
(ifTheyExist [
|
||||||
"docker"
|
|
||||||
"git"
|
"git"
|
||||||
"networkmanager"
|
"networkmanager"
|
||||||
"video"
|
"video"
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
{ config, ... }:
|
{ config, ... }:
|
||||||
{
|
{
|
||||||
boot.loader = {
|
boot.loader = {
|
||||||
systemd-boot.enable = true;
|
systemd-boot = {
|
||||||
|
enable = true;
|
||||||
|
configurationLimit = 5;
|
||||||
|
};
|
||||||
efi.canTouchEfiVariables = true;
|
efi.canTouchEfiVariables = true;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
{
|
{
|
||||||
config,
|
config,
|
||||||
lib,
|
lib,
|
||||||
|
pkgs,
|
||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
{
|
{
|
||||||
@@ -16,7 +17,6 @@
|
|||||||
]
|
]
|
||||||
++ (map (f: "hosts/common/optional/${f}") [
|
++ (map (f: "hosts/common/optional/${f}") [
|
||||||
"bbr.nix"
|
"bbr.nix"
|
||||||
"docker.nix"
|
|
||||||
"endlessh.nix"
|
"endlessh.nix"
|
||||||
"fail2ban.nix"
|
"fail2ban.nix"
|
||||||
"openssh.nix"
|
"openssh.nix"
|
||||||
@@ -25,5 +25,6 @@
|
|||||||
];
|
];
|
||||||
|
|
||||||
disko.cfg.mainDevice = "/dev/disk/by-id/ata-AMD_R5M120G8_07092225C0040";
|
disko.cfg.mainDevice = "/dev/disk/by-id/ata-AMD_R5M120G8_07092225C0040";
|
||||||
|
environment.shells = [ pkgs.zsh ];
|
||||||
system.stateVersion = "26.05";
|
system.stateVersion = "26.05";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,25 +2,13 @@
|
|||||||
{
|
{
|
||||||
networking = {
|
networking = {
|
||||||
hostName = "homelab";
|
hostName = "homelab";
|
||||||
useDHCP = false;
|
|
||||||
dhcpcd.enable = false;
|
|
||||||
defaultGateway = "192.168.88.1";
|
|
||||||
nameservers = [ "192.168.88.1" ];
|
|
||||||
|
|
||||||
interfaces.enp7s0.ipv4.addresses = [
|
|
||||||
{
|
|
||||||
address = "192.168.88.5";
|
|
||||||
prefixLength = 24;
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
firewall = {
|
firewall = {
|
||||||
allowedTCPPorts = [
|
allowedTCPPorts = [ 22 80 443 6969 ];
|
||||||
22
|
allowedUDPPorts = [ 3478 ];
|
||||||
80
|
|
||||||
443
|
|
||||||
];
|
|
||||||
allowedUDPPorts = [ ];
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
boot.kernel.sysctl = {
|
||||||
|
"net.ipv4.ip_unprivileged_port_start" = 80;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user