1
0
Fork 0
forked from fi/nix-infra

Compare commits

..

16 commits

Author SHA1 Message Date
fi
44215ecfc9
Remove obsolete configuration 2026-04-05 23:59:35 +02:00
fi
654a8459eb
Route IPv6 traffic via valkyrie 2026-04-05 23:50:38 +02:00
fi
d793308ebe
Add stardew ssh key 2026-04-04 00:53:32 +02:00
fi
051571d200
Add default grafana secret key for metrics-nekomesh 2026-04-04 00:02:07 +02:00
fi
5e2c28fd13
Update mastodon to 4.5.8 2026-04-03 22:58:44 +02:00
fi
39be09bb6b
flake.lock: Update
Flake lock file updates:

• Updated input 'nixpkgs':
    'github:NixOS/nixpkgs/56ed9a39b84feaee9624111dc86869d19f4c22f3' (2026-03-30)
  → 'github:NixOS/nixpkgs/0aecba5a03727e1ac2d66378907d9a6e9c8266d0' (2026-04-03)
• Updated input 'nixpkgs-master':
    'github:NixOS/nixpkgs/98ce05a593c5d9655ddbd09fd81f7679381b5392' (2026-03-30)
  → 'github:NixOS/nixpkgs/942d1c86a6642bff0c4a440d30a7669a7a18a903' (2026-04-03)
• Updated input 'nixpkgs-unstable':
    'github:NixOS/nixpkgs/318977b8e175faba256cb35e0ca6810c7d87edf2' (2026-03-30)
  → 'github:NixOS/nixpkgs/0eac666efaa8a9afea2821f9efc7921b4ef39b4e' (2026-04-03)
2026-04-03 22:51:49 +02:00
fi
17ddc2f9c9
flake.lock: Update
Flake lock file updates:

• Updated input 'nixpkgs':
    'github:NixOS/nixpkgs/08ebc444a070153227d6f45acf979f4d5f1f97f9' (2026-02-11)
  → 'github:NixOS/nixpkgs/56ed9a39b84feaee9624111dc86869d19f4c22f3' (2026-03-30)
• Updated input 'nixpkgs-master':
    'github:NixOS/nixpkgs/8605a9be3795437e3717dab6c542d2d571369e70' (2026-02-11)
  → 'github:NixOS/nixpkgs/98ce05a593c5d9655ddbd09fd81f7679381b5392' (2026-03-30)
• Updated input 'nixpkgs-unstable':
    'github:NixOS/nixpkgs/d9ca3a4b73f19ea147c9d977d3dde8f612ac648f' (2026-02-11)
  → 'github:NixOS/nixpkgs/318977b8e175faba256cb35e0ca6810c7d87edf2' (2026-03-30)
• Updated input 'simple-nixos-mailserver':
    'gitlab:simple-nixos-mailserver/nixos-mailserver/23f0a53ca6e58e61e1ea2b86791c69b79c91656d' (2025-12-24)
  → 'gitlab:simple-nixos-mailserver/nixos-mailserver/25e6dbb8fca3b6e779c5a46fd03bd760b2165bb5' (2026-03-19)
• Updated input 'simple-nixos-mailserver/flake-compat':
    'github:edolstra/flake-compat/f387cd2afec9419c8ee37694406ca490c3f34ee5' (2025-10-27)
  → 'github:edolstra/flake-compat/5edf11c44bc78a0d334f6334cdaf7d60d732daab' (2025-12-29)
• Updated input 'simple-nixos-mailserver/git-hooks':
    'github:cachix/git-hooks.nix/7275fa67fbbb75891c16d9dee7d88e58aea2d761' (2025-11-16)
  → 'github:cachix/git-hooks.nix/8baab586afc9c9b57645a734c820e4ac0a604af9' (2026-03-07)
• Updated input 'simple-nixos-mailserver/nixpkgs':
    'github:NixOS/nixpkgs/a320ce8e6e2cc6b4397eef214d202a50a4583829' (2025-11-24)
  → 'github:NixOS/nixpkgs/826430a188181a750ffa5948daff334039c5d741' (2026-03-18)
2026-03-30 22:25:39 +02:00
fi
9862a9d21b
Update element-web to 1.12.10 2026-02-11 18:02:31 +01:00
fi
459ac4c314
Update mastodon to 4.5.6 and remove fedi fetcher 2026-02-11 17:24:44 +01:00
fi
6daef62b60
flake.lock: Update
Flake lock file updates:

• Updated input 'nixos-generators':
    'github:nix-community/nixos-generators/032a1878682fafe829edfcf5fdfad635a2efe748' (2025-11-27)
  → 'github:nix-community/nixos-generators/8946737ff703382fda7623b9fab071d037e897d5' (2026-01-30)
• Updated input 'nixpkgs':
    'github:NixOS/nixpkgs/044f759a4f4629f2be41e59b859753a091e3c089' (2026-01-04)
  → 'github:NixOS/nixpkgs/08ebc444a070153227d6f45acf979f4d5f1f97f9' (2026-02-11)
• Updated input 'nixpkgs-master':
    'github:NixOS/nixpkgs/4220734816a0091405c33fe4c113be021c8e9c34' (2026-01-05)
  → 'github:NixOS/nixpkgs/8605a9be3795437e3717dab6c542d2d571369e70' (2026-02-11)
• Updated input 'nixpkgs-unstable':
    'github:NixOS/nixpkgs/1e46161ce72e20c156dd2225d7517421236c0f22' (2026-01-05)
  → 'github:NixOS/nixpkgs/d9ca3a4b73f19ea147c9d977d3dde8f612ac648f' (2026-02-11)
2026-02-11 17:16:34 +01:00
fi
98b3e14bd6 Host element-admin on web-public-2 2026-01-18 19:36:46 +01:00
fi
4bfcfe355c Expose matrix admin api on management VPN 2026-01-18 17:56:04 +01:00
fi
8fe546c3fe Enable MAS admin cli 2026-01-18 17:41:21 +01:00
fi
770ba36ffc Remove invalid password complexity setting in MAS config
Should be a value between 0 and 4. Default is 3.
2026-01-18 17:19:30 +01:00
fi
399f53fc3e flake.lock: Update
Flake lock file updates:

• Updated input 'nixpkgs':
    'github:NixOS/nixpkgs/f376a52d0dc796aec60b5606a2676240ff1565b9' (2025-12-08)
  → 'github:NixOS/nixpkgs/044f759a4f4629f2be41e59b859753a091e3c089' (2026-01-04)
• Updated input 'nixpkgs-master':
    'github:NixOS/nixpkgs/a0ea537a4fc4c49fb1e226317829c8b32ed95d0e' (2025-12-08)
  → 'github:NixOS/nixpkgs/4220734816a0091405c33fe4c113be021c8e9c34' (2026-01-05)
• Updated input 'nixpkgs-unstable':
    'github:NixOS/nixpkgs/fc2de1563f89f0843eba27f14576d261df0e3b80' (2025-12-08)
  → 'github:NixOS/nixpkgs/1e46161ce72e20c156dd2225d7517421236c0f22' (2026-01-05)
• Updated input 'simple-nixos-mailserver':
    'gitlab:simple-nixos-mailserver/nixos-mailserver/a14fe3b293ec2720e5b7fc72ad136d22967e12ba' (2025-11-26)
  → 'gitlab:simple-nixos-mailserver/nixos-mailserver/23f0a53ca6e58e61e1ea2b86791c69b79c91656d' (2025-12-24)
2026-01-06 00:25:12 +01:00
954f7d4d08
tweak forgejo service configuration a bit making it nicer
- Enable Git LFS support, since it's nice to have.
- Enable offline mode to avoid relying on CDNs (and to not use
  Gravatar).
- Enable notification mails for repo activity.
- Put setting for default repo units into "repository" category as the
  "repo" category doesn't exist.
- Also disable all repo units except code, as they mostly aren't needed
  for private repos and can be easily enabled on-demand.
2026-01-05 20:21:52 +01:00
57 changed files with 236 additions and 648 deletions

View file

@ -4,6 +4,7 @@
enable = true;
package = pkgs.forgejo;
database.type = "postgres";
lfs.enable = true;
settings = {
DEFAULT = {
@ -17,6 +18,7 @@
ROOT_URL = "https://git.nekover.se/";
# LOCAL_ROOT_URL is apparently what Forgejo uses to access itself.
# Doesn't need to be set.
OFFLINE_MODE = true;
};
admin = {
DISABLE_REGULAR_ORG_CREATION = false;
@ -34,11 +36,10 @@
DEFAULT_USER_VISIBILITY = "limited";
DEFAULT_KEEP_EMAIL_PRIVATE = true;
ENABLE_BASIC_AUTHENTICATION = false;
};
repo = {
DEFAULT_REPO_UNITS = "repo.code,repo.issues,repo.pulls";
ENABLE_NOTIFY_MAIL = true;
};
repository = {
DEFAULT_REPO_UNITS = "repo.code";
ENABLE_PUSH_CREATE_USER = true;
ENABLE_PUSH_CREATE_ORG = true;
};

View file

@ -29,7 +29,8 @@
};
extraConfig = ''
set_real_ip_from 10.202.41.100;
set_real_ip_from 10.202.41.100; # IPv4 from web-public-2
set_real_ip_from 10.203.10.3; # IPv6 from valkyrie
real_ip_header proxy_protocol;
'';
};

View file

@ -16,7 +16,8 @@
extraConfig = ''
listen 0.0.0.0:8443 http2 ssl proxy_protocol;
set_real_ip_from 10.202.41.100;
set_real_ip_from 10.202.41.100; # IPv4 from web-public-2
set_real_ip_from 10.203.10.3; # IPv6 from valkyrie
real_ip_header proxy_protocol;
'';
};
@ -33,7 +34,8 @@
extraConfig = ''
listen 0.0.0.0:8443 http2 ssl proxy_protocol;
set_real_ip_from 10.202.41.100;
set_real_ip_from 10.202.41.100; # IPv4 from web-public-2
set_real_ip_from 10.203.10.3; # IPv6 from valkyrie
real_ip_header proxy_protocol;
'';
};

View file

@ -39,7 +39,8 @@ in
};
};
extraConfig = ''
set_real_ip_from 10.202.41.100;
set_real_ip_from 10.202.41.100; # IPv4 from web-public-2
set_real_ip_from 10.203.10.3; # IPv6 from valkyrie
real_ip_header proxy_protocol;
'';
};

View file

@ -27,7 +27,8 @@
extraConfig = ''
listen 0.0.0.0:8443 http2 ssl proxy_protocol;
set_real_ip_from 10.202.41.100;
set_real_ip_from 10.202.41.100; # IPv4 from web-public-2
set_real_ip_from 10.203.10.3; # IPv6 from valkyrie
real_ip_header proxy_protocol;
add_header Strict-Transport-Security "max-age=63072000" always;

View file

@ -1,23 +0,0 @@
{ nixpkgs-unstable, ... }:
{
containers.fedifetcher = {
nixpkgs = nixpkgs-unstable;
autoStart = true;
bindMounts = {
"/secrets" = {
hostPath = "/secrets-fedifetcher";
isReadOnly = true;
};
};
config = { ... }: {
imports = [
./fedifetcher.nix
];
networking.useHostResolvConf = true;
system.stateVersion = "24.05";
};
};
}

View file

@ -1,42 +0,0 @@
{ pkgs, lib, ... }:
{
# config copied from https://github.com/arachnist/nibylandia/blob/main/nixos/zorigami/default.nix
systemd.services.fedifetcher = {
path = [ pkgs.fedifetcher ];
description = "fetch fedi posts";
script = ''
fedifetcher
'';
environment = lib.mapAttrs' (n: v:
(lib.nameValuePair ("ff_" + builtins.replaceStrings [ "-" ] [ "_" ] n)
(builtins.toString v))) {
server = "social.nekover.se";
state-dir = "/var/lib/fedifetcher";
lock-file = "/run/fedifetcher/fedifetcher.lock";
from-lists = 1;
from-notifications = 1;
max-bookmarks = 80;
max-favourites = 40;
max-follow-requests = 80;
max-followers = 80;
max-followings = 80;
remember-hosts-for-days = 30;
remember-users-for-hours = 168;
reply-interval-in-hours = 2;
};
serviceConfig = {
DynamicUser = true;
User = "fedifetcher";
RuntimeDirectory = "fedifetcher";
RuntimeDirectoryPreserve = true;
StateDirectory = "fedifetcher";
UMask = "0077";
EnvironmentFile = [ "/secrets/mastodon-fedifetcher-access-token.secret" ];
};
};
systemd.timers.fedifetcher = {
wantedBy = [ "multi-user.target" ];
timerConfig = { OnCalendar = "*:0/5"; };
};
}

View file

@ -5,6 +5,5 @@
./mastodon.nix
./opensearch.nix
./nginx.nix
./containers/fedifetcher
];
}

View file

@ -2,8 +2,8 @@
let
tangerineUI = pkgs.fetchgit {
url = "https://github.com/nileane/TangerineUI-for-Mastodon.git";
rev = "v2.5.2";
hash = "sha256-RJPP3QynE42cr9Km8twyZrHiZnhMdNcYOOJ7nW0mx1c=";
rev = "v2.5.3";
hash = "sha256-fs/pwIwXZvSNVmlSG304CMT/hSW/RtrzraMsrhg/TbE=";
};
mastodonModern = pkgs.fetchgit {
url = "https://git.gay/freeplay/Mastodon-Modern.git";
@ -16,14 +16,14 @@ let
};
mastodonNekoverseOverlay = final: prev: {
mastodon = (prev.mastodon.override rec {
version = "4.5.2";
version = "4.5.8";
srcOverride = final.applyPatches {
src = pkgs.stdenv.mkDerivation {
name = "mastodonWithThemes";
src = pkgs.fetchgit {
url = "https://github.com/mastodon/mastodon.git";
rev = "v${version}";
sha256 = "sha256-LePly+CcM+Dv6ipX9jIWWKhy2PiF1j8vgc9CXn2o+DQ=";
sha256 = "sha256-03PdAB9KOvMgQJPx+7ik13QE18fjdLIab7zEXaPc4nk=";
};
# mastodon ships with broken symlinks, disable the check for that for now
dontCheckForBrokenSymlinks = true;

View file

@ -57,7 +57,8 @@
};
extraConfig = ''
set_real_ip_from 10.202.41.100;
set_real_ip_from 10.202.41.100; # IPv4 from web-public-2
set_real_ip_from 10.203.10.3; # IPv6 from valkyrie
real_ip_header proxy_protocol;
'';
};

View file

@ -57,13 +57,5 @@
permissions = "0640";
uploadAt = "pre-activation";
};
"mastodon-fedifetcher-access-token.secret" = {
keyCommand = keyCommandEnv ++ [ "pass" "mastodon/fedifetcher-access-token" ];
destDir = "/secrets-fedifetcher";
user = "root";
group = "root";
permissions = "0640";
uploadAt = "pre-activation";
};
};
}

View file

@ -33,6 +33,17 @@ let
}];
proxy_protocol = false;
}
{
name = "admin";
resources = [{
name = "adminapi";
}];
binds = [{
host = "localhost";
port = 8083;
}];
proxy_protocol = false;
}
];
trusted_proxies = [
"192.168.0.0/16"
@ -63,8 +74,7 @@ let
version = 2;
algorithm = "argon2id";
}
];
minimum_complexity = 8;
];
};
};
masSettingsFile = ((pkgs.formats.yaml { }).generate "mas-config" masSettings);

View file

@ -34,11 +34,25 @@
client_max_body_size ${config.services.matrix-synapse.settings.max_upload_size};
'';
};
"~ ^/_synapse/admin" = {
# Only proxy to the local host on IPv4, because localhost doesn't seem to work
# even if matrix-synapse is listening on ::1 as well.
proxyPass = "http://127.0.0.1:8008";
extraConfig = ''
# Restrict access to admin API.
allow 172.21.87.0/24; # management VPN
deny all;
# Nginx by default only allows file uploads up to 1M in size
# Increase client_max_body_size to match max_upload_size defined in homeserver.yaml
client_max_body_size ${config.services.matrix-synapse.settings.max_upload_size};
'';
};
};
extraConfig = ''
listen 0.0.0.0:8443 http2 ssl proxy_protocol;
set_real_ip_from 10.202.41.100;
set_real_ip_from 10.202.41.100; # IPv4 from web-public-2
set_real_ip_from 10.203.10.3; # IPv6 from valkyrie
real_ip_header proxy_protocol;
'';
};
@ -51,13 +65,24 @@
port = 80;
}
];
locations."/" = {
proxyPass = "http://localhost:8080";
locations = {
"/" = {
proxyPass = "http://localhost:8080";
};
"~ ^/api/admin" = {
proxyPass = "http://localhost:8083";
extraConfig = ''
# Restrict access to admin API.
allow 172.21.87.0/24; # management VPN
deny all;
'';
};
};
extraConfig = ''
listen 0.0.0.0:8443 http2 ssl proxy_protocol;
set_real_ip_from 10.202.41.100;
set_real_ip_from 10.202.41.100; # IPv4 from web-public-2
set_real_ip_from 10.203.10.3; # IPv6 from valkyrie
real_ip_header proxy_protocol;
'';
};
@ -80,7 +105,8 @@
extraConfig = ''
listen 0.0.0.0:8443 http2 ssl proxy_protocol;
set_real_ip_from 10.202.41.100;
set_real_ip_from 10.202.41.100; # IPv4 from web-public-2
set_real_ip_from 10.203.10.3; # IPv6 from valkyrie
real_ip_header proxy_protocol;
'';
};

View file

@ -13,6 +13,7 @@
admin_user = "admin";
admin_password = "$__file{/secrets/metrics-nekomesh-grafana-admin-password.secret}";
admin_email = "fi@nekover.se";
secret_key = "$__file{/secrets/metrics-nekomesh-grafana-secret-key.secret}";
};
smtp = {
enabled = true;

View file

@ -23,7 +23,8 @@
proxyWebsockets = true;
};
extraConfig = ''
set_real_ip_from 10.202.41.100;
set_real_ip_from 10.202.41.100; # IPv4 from web-public-2
set_real_ip_from 10.203.10.3; # IPv6 from valkyrie
real_ip_header proxy_protocol;
'';
};

View file

@ -17,6 +17,14 @@
permissions = "0640";
uploadAt = "pre-activation";
};
"metrics-nekomesh-grafana-secret-key.secret" = {
keyCommand = keyCommandEnv ++ [ "pass" "metrics-nekomesh/grafana/secret-key" ];
destDir = "/secrets";
user = "grafana";
group = "grafana";
permissions = "0640";
uploadAt = "pre-activation";
};
"mail-nekomesh-nekover-se.secret" = {
keyCommand = keyCommandEnv ++ [ "pass" "mail/nekomesh-nekover-se" ];
destDir = "/secrets";

View file

@ -1,33 +0,0 @@
{ ... }:
{
boot.loader.grub = {
enable = true;
device = "/dev/vda";
};
networking = {
hostName = "navidrome";
firewall = {
enable = true;
allowedTCPPorts = [ 80 443 ];
};
};
fileSystems = {
"/mnt/music" = {
device = "//10.202.40.5/music-ro";
fsType = "cifs";
options = [
"username=navidrome"
"credentials=/secrets/navidrome-samba-credentials.secret"
"iocharset=utf8"
"vers=3.1.1"
"uid=navidrome"
"gid=navidrome"
"_netdev"
];
};
};
system.stateVersion = "23.05";
}

View file

@ -1,7 +0,0 @@
{ ... }: {
imports = [
./configuration.nix
./navidrome.nix
./nginx.nix
];
}

View file

@ -1,9 +0,0 @@
{ ... }: {
services.navidrome = {
enable = true;
settings = {
Address = "unix:/run/navidrome/navidrome.socket";
MusicFolder = "/mnt/music";
};
};
}

View file

@ -1,24 +0,0 @@
{ ... }: {
services.nginx = {
enable = true;
user = "navidrome";
virtualHosts."navidrome.grzb.de" = {
forceSSL = true;
enableACME = true;
listen = [
{
addr = "0.0.0.0";
port = 80;
}
{
addr = "0.0.0.0";
port = 443;
ssl = true;
}
];
locations."/" = {
proxyPass = "http://unix:/run/navidrome/navidrome.socket";
};
};
};
}

View file

@ -1,13 +0,0 @@
{ keyCommandEnv, ... }:
{
deployment.keys = {
"navidrome-samba-credentials.secret" = {
keyCommand = keyCommandEnv ++ [ "pass" "navidrome/samba-credentials" ];
destDir = "/secrets";
user = "root";
group = "root";
permissions = "0640";
uploadAt = "pre-activation";
};
};
}

View file

@ -1,17 +0,0 @@
{ ... }:
{
boot.loader.grub = {
enable = true;
device = "/dev/vda";
};
networking = {
hostName = "netbox";
firewall = {
enable = true;
allowedTCPPorts = [ 80 443 ];
};
};
system.stateVersion = "23.05";
}

View file

@ -1,8 +0,0 @@
{ ... }:
{
imports = [
./configuration.nix
./netbox.nix
./nginx.nix
];
}

View file

@ -1,8 +0,0 @@
{ pkgs, ... }:
{
services.netbox = {
enable = true;
package = pkgs.netbox;
secretKeyFile = "/secrets/netbox-secret-key.secret";
};
}

View file

@ -1,29 +0,0 @@
{ config, ... }:
{
services.nginx = {
enable = true;
clientMaxBodySize = "25m";
user = "netbox";
virtualHosts."netbox.grzb.de" = {
forceSSL = true;
enableACME = true;
listen = [
{
addr = "0.0.0.0";
port = 80;
}
{
addr = "0.0.0.0";
port = 443;
ssl = true;
}
];
locations."/static/" = {
alias = "${config.services.netbox.dataDir}/static/";
};
locations."/" = {
proxyPass = "http://${config.services.netbox.listenAddress}:${builtins.toString config.services.netbox.port}";
};
};
};
}

View file

@ -1,11 +0,0 @@
{ keyCommandEnv, ... }:
{
deployment.keys."netbox-secret-key.secret" = {
keyCommand = keyCommandEnv ++ [ "pass" "netbox/secret-key" ];
destDir = "/secrets";
user = "netbox";
group = "netbox";
permissions = "0640";
uploadAt = "pre-activation";
};
}

View file

@ -44,7 +44,8 @@
extraConfig = ''
listen 0.0.0.0:8443 http2 ssl proxy_protocol;
set_real_ip_from 10.202.41.100;
set_real_ip_from 10.202.41.100; # IPv4 from web-public-2
set_real_ip_from 10.203.10.3; # IPv6 from valkyrie
real_ip_header proxy_protocol;
'';
};

View file

@ -1,17 +0,0 @@
{ ... }:
{
boot.loader.grub = {
enable = true;
device = "/dev/vda";
};
networking = {
hostName = "nitter";
firewall = {
enable = true;
allowedTCPPorts = [ 8443 ];
};
};
system.stateVersion = "23.05";
}

View file

@ -1,8 +0,0 @@
{ ... }:
{
imports = [
./configuration.nix
./nginx.nix
./nitter.nix
];
}

View file

@ -1,23 +0,0 @@
{ config, ... }:
{
services.nginx = {
enable = true;
virtualHosts."birdsite.nekover.se" = {
forceSSL = true;
enableACME = true;
locations."/robots.txt" = {
return = "200 \"User-agent: *\\nDisallow: /\\n\"";
};
locations."/" = {
proxyPass = "http://${config.services.nitter.server.address}:${builtins.toString config.services.nitter.server.port}";
proxyWebsockets = true;
};
extraConfig = ''
listen 0.0.0.0:8443 http2 ssl proxy_protocol;
set_real_ip_from 10.202.41.100;
real_ip_header proxy_protocol;
'';
};
};
}

View file

@ -1,21 +0,0 @@
{ ... }:
{
services.nitter = {
enable = true;
server = {
title = "Birdsite";
https = true;
address = "127.0.0.1";
port = 8080;
hostname = "birdsite.nekover.se";
};
preferences = {
theme = "Mastodon";
replaceTwitter = "birdsite.nekover.se";
infiniteScroll = true;
hlsPlayback = true;
};
};
}

View file

@ -1,17 +0,0 @@
{ ... }:
{
boot.loader.grub = {
enable = true;
device = "/dev/vda";
};
networking = {
hostName = "paperless";
firewall = {
enable = true;
allowedTCPPorts = [ 80 443 ];
};
};
system.stateVersion = "23.05";
}

View file

@ -1,9 +0,0 @@
{ ... }:
{
imports = [
./configuration.nix
./hardware-configuration.nix
./nginx.nix
./paperless.nix
];
}

View file

@ -1,30 +0,0 @@
{ ... }:
{
fileSystems = {
"/mnt/data" = {
device = "/dev/disk/by-label/data";
fsType = "ext4";
autoFormat = true;
autoResize = true;
};
"/mnt/paperless-consume" = {
device = "//10.201.40.10/paperless-consume";
fsType = "cifs";
options = [
"username=paperless"
"credentials=/secrets/paperless-samba-credentials.secret"
"iocharset=utf8"
"vers=3.1.1"
"uid=paperless"
"gid=paperless"
"_netdev"
];
};
"/var/lib/paperless" = {
depends = [ "/mnt/data" ];
device = "/mnt/data/paperless";
fsType = "none";
options = [ "bind" ];
};
};
}

View file

@ -1,31 +0,0 @@
{ config, ... }:
{
services.nginx = {
enable = true;
virtualHosts."paperless.grzb.de" = {
forceSSL = true;
enableACME = true;
listen = [
{
addr = "0.0.0.0";
port = 80;
}
{
addr = "0.0.0.0";
port = 443;
ssl = true;
}
];
locations."/" = {
proxyPass = "http://${config.services.paperless.address}:${builtins.toString config.services.paperless.port}";
proxyWebsockets = true;
extraConfig = ''
add_header Referrer-Policy "strict-origin-when-cross-origin";
'';
};
extraConfig = ''
client_max_body_size 100M;
'';
};
};
}

View file

@ -1,8 +0,0 @@
{ ... }:
{
services.paperless = {
enable = true;
consumptionDir = "/mnt/paperless-consume";
passwordFile = "/secrets/paperless-admin-password.secret";
};
}

View file

@ -1,21 +0,0 @@
{ keyCommandEnv, ... }:
{
deployment.keys = {
"paperless-admin-password.secret" = {
keyCommand = keyCommandEnv ++ [ "pass" "paperless/admin-password" ];
destDir = "/secrets";
user = "paperless";
group = "paperless";
permissions = "0640";
uploadAt = "pre-activation";
};
"paperless-samba-credentials.secret" = {
keyCommand = keyCommandEnv ++ [ "pass" "paperless/samba-credentials" ];
destDir = "/secrets";
user = "root";
group = "root";
permissions = "0640";
uploadAt = "pre-activation";
};
};
}

View file

@ -21,7 +21,8 @@
proxyPass = "http://${config.services.searx.settings.server.bind_address}:${builtins.toString config.services.searx.settings.server.port}";
};
extraConfig = ''
set_real_ip_from 10.202.41.100;
set_real_ip_from 10.202.41.100; # IPv4 from web-public-2
set_real_ip_from 10.203.10.3; # IPv6 from valkyrie
real_ip_header proxy_protocol;
'';
};

View file

@ -33,5 +33,31 @@
};
};
};
streamConfig = ''
map $ssl_preread_server_name $address {
cloud.nekover.se 10.202.41.122:8443;
element.nekover.se 10.202.41.100:8443;
element-admin.nekover.se 10.202.41.100:8443;
fi.nekover.se 10.202.41.125:8443;
git.nekover.se 10.202.41.106:8443;
hydra.nekover.se 10.202.41.121:8443;
id.nekover.se 10.202.41.124:8443;
mas.nekover.se 10.202.41.112:8443;
matrix.nekover.se 10.202.41.112:8443;
matrix-rtc.nekover.se 10.202.41.112:8443;
mesh.nekover.se 10.202.41.126:8443;
nekover.se 10.202.41.100:8443;
nix-cache.nekover.se 10.202.41.121:8443;
searx.nekover.se 10.202.41.105:8443;
social.nekover.se 10.202.41.104:8443;
}
server {
listen [::]:443;
proxy_pass $address;
ssl_preread on;
proxy_protocol on;
}
'';
};
}

View file

@ -1,17 +0,0 @@
{ ... }:
{
boot.loader.grub = {
enable = true;
device = "/dev/vda";
};
networking = {
hostName = "web-public-1";
firewall = {
enable = true;
allowedTCPPorts = [ 80 443 ];
};
};
system.stateVersion = "23.05";
}

View file

@ -1,7 +0,0 @@
{ ... }:
{
imports = [
./configuration.nix
./nginx.nix
];
}

View file

@ -1,10 +0,0 @@
{ ... }:
{
imports = [
./virtualHosts
];
services.nginx = {
enable = true;
};
}

View file

@ -1,18 +0,0 @@
{ ... }:
let
acmeDomainMap = {
"paperless.grzb.de" = "paperless.wg.grzb.de";
"navidrome.grzb.de" = "navidrome.wg.grzb.de";
};
in
{
services.nginx.virtualHosts = (builtins.mapAttrs (domain: target: {
listen = [{
addr = "0.0.0.0";
port = 80;
}];
locations."^~ /.well-known/acme-challenge/" = {
proxyPass = "http://${target}:80";
};
}) acmeDomainMap);
}

View file

@ -1,16 +0,0 @@
{ ... }:
{
imports = [
./acme-challenge.nix
];
services.nginx.virtualHosts."_" = {
listen = [{
addr = "0.0.0.0";
port = 80;
}];
locations."/" = {
return = "301 https://$host$request_uri";
};
};
}

View file

@ -16,19 +16,16 @@
stream {
map $ssl_preread_server_name $address {
anisync.grzb.de 127.0.0.1:8443;
cloud.nekover.se 10.202.41.122:8443;
element.nekover.se 127.0.0.1:8443;
element-admin.nekover.se 127.0.0.1:8443;
fi.nekover.se 10.202.41.125:8443;
gameserver.grzb.de 127.0.0.1:8443;
git.grzb.de 127.0.0.1:8443;
git.nekover.se 10.202.41.106:8443;
hydra.nekover.se 10.202.41.121:8443;
id.nekover.se 10.202.41.124:8443;
mas.nekover.se 10.202.41.112:8443;
matrix.nekover.se 10.202.41.112:8443;
matrix-rtc.nekover.se 10.202.41.112:8443;
mewtube.nekover.se 127.0.0.1:8443;
nekover.se 127.0.0.1:8443;
mesh.nekover.se 10.202.41.126:8443;
nix-cache.nekover.se 10.202.41.121:8443;
@ -37,7 +34,6 @@
}
server {
listen 0.0.0.0:443;
listen [::]:443;
proxy_pass $address;
ssl_preread on;
proxy_protocol on;

View file

@ -1,23 +0,0 @@
{ ... }:
{
services.nginx.virtualHosts."anisync.grzb.de" = {
forceSSL = true;
enableACME = true;
listen = [{
addr = "localhost";
port = 8443;
ssl = true;
extraParameters = ["proxy_protocol"];
}];
locations."/" = {
proxyPass = "http://anisync.vs.grzb.de:8080";
proxyWebsockets = true;
};
extraConfig = ''
add_header X-Content-Type-Options nosniff;
set_real_ip_from 127.0.0.1;
real_ip_header proxy_protocol;
'';
};
}

View file

@ -2,11 +2,8 @@
{
imports = [
./acme-challenge.nix
./anisync.grzb.de.nix
./element.nekover.se.nix
./gameserver.grzb.de.nix
./git.grzb.de.nix
./mewtube.nekover.se.nix
./element-admin.nekover.se.nix
./nekover.se.nix
];

View file

@ -0,0 +1,96 @@
{ config, pkgs, ... }:
let
elementAdminVersion = "0.1.10";
elementAdmin = pkgs.stdenv.mkDerivation (finalAttrs: {
pname = "element-admin";
version = elementAdminVersion;
src = pkgs.fetchzip {
url = "https://github.com/element-hq/element-admin/archive/refs/tags/v${elementAdminVersion}.zip";
sha256 = "sha256-dh7tmzAaTfKB9FuOVhLHpOIsTZK1qMvNq16HeObHOqI=";
};
nativeBuildInputs = [
pkgs.nodejs
pkgs.pnpm.configHook
];
pnpmDeps = pkgs.pnpm.fetchDeps {
inherit (finalAttrs) pname version src;
fetcherVersion = 2;
hash = "sha256-S/MdfUv6q+PaAKWYHxVY80BcpL81dOfpPVhNxEPQVE4=";
};
buildPhase = ''
pnpm build
'';
installPhase = ''
cp -a dist $out
'';
});
in
{
services.nginx.virtualHosts."element-admin.nekover.se" = {
forceSSL = true;
enableACME = true;
listen = [{
addr = "0.0.0.0";
port = 8443;
ssl = true;
extraParameters = ["proxy_protocol"];
}];
root = elementAdmin;
locations."/assets" = {
extraConfig = ''
expires 1y;
add_header Cache-Control "public, max-age=31536000, immutable";
# Security headers.
add_header X-Frame-Options "DENY" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; img-src 'self' blob: data:; font-src 'self'; connect-src *; object-src 'none'; media-src 'self'; child-src 'none'; worker-src 'self'; manifest-src 'self';" always;
add_header Permissions-Policy "geolocation=(), camera=(), microphone=(), payment=(), usb=(), magnetometer=(), accelerometer=(), gyroscope=()" always;
'';
};
locations."/" = {
index = "/index.html";
tryFiles = "$uri $uri/ /";
extraConfig = ''
# Security headers.
add_header X-Frame-Options "DENY" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; img-src 'self' blob: data:; font-src 'self'; connect-src *; object-src 'none'; media-src 'self'; child-src 'none'; worker-src 'self'; manifest-src 'self';" always;
add_header Permissions-Policy "geolocation=(), camera=(), microphone=(), payment=(), usb=(), magnetometer=(), accelerometer=(), gyroscope=()" always;
'';
};
extraConfig = ''
# Security headers.
add_header X-Frame-Options "DENY" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; img-src 'self' blob: data:; font-src 'self'; connect-src *; object-src 'none'; media-src 'self'; child-src 'none'; worker-src 'self'; manifest-src 'self';" always;
add_header Permissions-Policy "geolocation=(), camera=(), microphone=(), payment=(), usb=(), magnetometer=(), accelerometer=(), gyroscope=()" always;
# Make use of the ngx_http_realip_module to set the $remote_addr and
# $remote_port to the client address and client port, when using proxy
# protocol.
# First set our proxy protocol proxy as trusted.
set_real_ip_from 10.202.41.100; # IPv4 from web-public-2
set_real_ip_from 10.203.10.3; # IPv6 from valkyrie
# Then tell the realip_module to get the addreses from the proxy protocol
# header.
real_ip_header proxy_protocol;
'';
};
}

View file

@ -1,9 +1,9 @@
{ pkgs, ... }:
let
elementWebVersion = "1.12.2";
elementWebVersion = "1.12.10";
element-web = pkgs.fetchzip {
url = "https://github.com/vector-im/element-web/releases/download/v${elementWebVersion}/element-v${elementWebVersion}.tar.gz";
sha256 = "sha256-EZtySIQHgb+Boq97LhzFYKTEO///6YMH3O2DrAy+7Fs=";
sha256 = "sha256-YpxfV4BCXh2fffQvVsZGOfK82TpGzg6uOx7iUPqiXVE=";
};
elementWebSecurityHeaders = ''
# Configuration best practices
@ -28,7 +28,7 @@ in
];
};
listen = [{
addr = "localhost";
addr = "0.0.0.0";
port = 8443;
ssl = true;
extraParameters = ["proxy_protocol"];
@ -60,7 +60,8 @@ in
# redirect server error pages to the static page /50x.html
error_page 500 502 503 504 /50x.html;
set_real_ip_from 127.0.0.1;
set_real_ip_from 10.202.41.100; # IPv4 from web-public-2
set_real_ip_from 10.203.10.3; # IPv6 from valkyrie
real_ip_header proxy_protocol;
'';
};

View file

@ -1,28 +0,0 @@
{ ... }:
{
services.nginx.virtualHosts."gameserver.grzb.de" = {
forceSSL = true;
enableACME = true;
listen = [{
addr = "localhost";
port = 8443;
ssl = true;
extraParameters = ["proxy_protocol"];
}];
locations."/" = {
proxyPass = "http://pterodactyl.vs.grzb.de";
extraConfig = ''
proxy_redirect off;
proxy_buffering off;
proxy_request_buffering off;
'';
};
extraConfig = ''
client_max_body_size 1024m;
add_header X-Content-Type-Options nosniff;
set_real_ip_from 127.0.0.1;
real_ip_header proxy_protocol;
'';
};
}

View file

@ -1,30 +0,0 @@
{ ... }:
{
services.nginx.virtualHosts."git.grzb.de" = {
forceSSL = true;
enableACME = true;
listen = [{
addr = "localhost";
port = 8443;
ssl = true;
extraParameters = ["proxy_protocol"];
}];
locations."/" = {
proxyPass = "http://gitlab.vs.grzb.de:80";
extraConfig = ''
gzip off;
proxy_read_timeout 300;
proxy_connect_timeout 300;
proxy_redirect off;
'';
};
extraConfig = ''
client_max_body_size 1024m;
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;
set_real_ip_from 127.0.0.1;
real_ip_header proxy_protocol;
'';
};
}

View file

@ -1,20 +0,0 @@
{ ... }:
{
services.nginx.virtualHosts."mewtube.nekover.se" = {
forceSSL = true;
enableACME = true;
listen = [{
addr = "localhost";
port = 8443;
ssl = true;
extraParameters = ["proxy_protocol"];
}];
locations."/" = {
proxyPass = "http://cloudtube.vs.grzb.de:10412";
};
extraConfig = ''
set_real_ip_from 127.0.0.1;
real_ip_header proxy_protocol;
'';
};
}

View file

@ -23,7 +23,8 @@
'';
};
extraConfig = ''
set_real_ip_from 127.0.0.1;
set_real_ip_from 10.202.41.100; # IPv4 from web-public-2
set_real_ip_from 10.203.10.3; # IPv6 from valkyrie
real_ip_header proxy_protocol;
'';
};

View file

@ -8,6 +8,7 @@
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJEvM35w+UaSpDTuaG5pGPgfHcfwscr+wSZN9Z5Jle82 yuri@kiara"
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDdk3FLQRoCWxdOxg4kHcPqAu3QQOs/rY9na2Al2ilGl yuri@violet"
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICuhk+x7msByGFekRmS2SMeTT3sC4I0MtuEQXjN8MZXa fi@cherry"
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPPi3G2JfDLJeLVtdF8fEQN9S6W1xfLNmzFm74f0jN6t fi@stardew"
];
};
}

View file

@ -8,6 +8,7 @@
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDdk3FLQRoCWxdOxg4kHcPqAu3QQOs/rY9na2Al2ilGl yuri@violet"
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICuhk+x7msByGFekRmS2SMeTT3sC4I0MtuEQXjN8MZXa fi@cherry"
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIE95OjEez/yE+GIaeIoz3OwkXboLboPY4ss9nkt4FLyW fi@kiara"
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPPi3G2JfDLJeLVtdF8fEQN9S6W1xfLNmzFm74f0jN6t fi@stardew"
];
};
}

View file

@ -7,6 +7,7 @@
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJEvM35w+UaSpDTuaG5pGPgfHcfwscr+wSZN9Z5Jle82 yuri@kiara"
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDdk3FLQRoCWxdOxg4kHcPqAu3QQOs/rY9na2Al2ilGl yuri@violet"
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICuhk+x7msByGFekRmS2SMeTT3sC4I0MtuEQXjN8MZXa fi@cherry"
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPPi3G2JfDLJeLVtdF8fEQN9S6W1xfLNmzFm74f0jN6t fi@stardew"
];
};
}

48
flake.lock generated
View file

@ -19,11 +19,11 @@
"flake-compat": {
"flake": false,
"locked": {
"lastModified": 1761588595,
"narHash": "sha256-XKUZz9zewJNUj46b4AJdiRZJAvSZ0Dqj2BNfXvFlJC4=",
"lastModified": 1767039857,
"narHash": "sha256-vNpUSpF5Nuw8xvDLj2KCwwksIbjua2LZCqhV1LNRDns=",
"owner": "edolstra",
"repo": "flake-compat",
"rev": "f387cd2afec9419c8ee37694406ca490c3f34ee5",
"rev": "5edf11c44bc78a0d334f6334cdaf7d60d732daab",
"type": "github"
},
"original": {
@ -45,11 +45,11 @@
]
},
"locked": {
"lastModified": 1763319842,
"narHash": "sha256-YG19IyrTdnVn0l3DvcUYm85u3PaqBt6tI6VvolcuHnA=",
"lastModified": 1772893680,
"narHash": "sha256-JDqZMgxUTCq85ObSaFw0HhE+lvdOre1lx9iI6vYyOEs=",
"owner": "cachix",
"repo": "git-hooks.nix",
"rev": "7275fa67fbbb75891c16d9dee7d88e58aea2d761",
"rev": "8baab586afc9c9b57645a734c820e4ac0a604af9",
"type": "github"
},
"original": {
@ -103,11 +103,11 @@
]
},
"locked": {
"lastModified": 1764234087,
"narHash": "sha256-NHF7QWa0ZPT8hsJrvijREW3+nifmF2rTXgS2v0tpcEA=",
"lastModified": 1769813415,
"narHash": "sha256-nnVmNNKBi1YiBNPhKclNYDORoHkuKipoz7EtVnXO50A=",
"owner": "nix-community",
"repo": "nixos-generators",
"rev": "032a1878682fafe829edfcf5fdfad635a2efe748",
"rev": "8946737ff703382fda7623b9fab071d037e897d5",
"type": "github"
},
"original": {
@ -118,11 +118,11 @@
},
"nixpkgs": {
"locked": {
"lastModified": 1765178948,
"narHash": "sha256-Kb3mIrj4xLg2LeMvok0tpiGPis1VnrNJO0l4kW+0xmc=",
"lastModified": 1775189162,
"narHash": "sha256-fjEpcsJ0KDZ363xd+3OhOGq3AC1juI23Xas548ZPZEk=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "f376a52d0dc796aec60b5606a2676240ff1565b9",
"rev": "0aecba5a03727e1ac2d66378907d9a6e9c8266d0",
"type": "github"
},
"original": {
@ -134,11 +134,11 @@
},
"nixpkgs-master": {
"locked": {
"lastModified": 1765227377,
"narHash": "sha256-OeTF3YNuXZxN4TxluVEdCG32e5/0pYDb5exWe0RrQBY=",
"lastModified": 1775248990,
"narHash": "sha256-H/G80K7f3ZrPP8PAmSCG/pJh59zMscPA6UaiWdKgTdg=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "a0ea537a4fc4c49fb1e226317829c8b32ed95d0e",
"rev": "942d1c86a6642bff0c4a440d30a7669a7a18a903",
"type": "github"
},
"original": {
@ -150,11 +150,11 @@
},
"nixpkgs-unstable": {
"locked": {
"lastModified": 1765183668,
"narHash": "sha256-TBA7CE44IHYfvOPBWcyLncpVrrKEiXWPdOrF8CD6W84=",
"lastModified": 1775231746,
"narHash": "sha256-EFaDQ0rnuSjKfC/DUKHS4toV4rEBuWhSgyX2Yy0kp00=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "fc2de1563f89f0843eba27f14576d261df0e3b80",
"rev": "0eac666efaa8a9afea2821f9efc7921b4ef39b4e",
"type": "github"
},
"original": {
@ -166,11 +166,11 @@
},
"nixpkgs_2": {
"locked": {
"lastModified": 1764020296,
"narHash": "sha256-6zddwDs2n+n01l+1TG6PlyokDdXzu/oBmEejcH5L5+A=",
"lastModified": 1773831496,
"narHash": "sha256-JW2/QPyCVzmouqEp1H9kNa8JXd7xEhlam9sy3TYfhDY=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "a320ce8e6e2cc6b4397eef214d202a50a4583829",
"rev": "826430a188181a750ffa5948daff334039c5d741",
"type": "github"
},
"original": {
@ -197,11 +197,11 @@
"nixpkgs": "nixpkgs_2"
},
"locked": {
"lastModified": 1764185122,
"narHash": "sha256-+HUOwSIFLoyett2cvRjuFIbhobpHallfP9J2cia1apo=",
"lastModified": 1773912645,
"narHash": "sha256-QHzRqq6gh+t3F/QU9DkP7X63dDDcuIQmaDz12p7ANTg=",
"owner": "simple-nixos-mailserver",
"repo": "nixos-mailserver",
"rev": "a14fe3b293ec2720e5b7fc72ad136d22967e12ba",
"rev": "25e6dbb8fca3b6e779c5a46fd03bd760b2165bb5",
"type": "gitlab"
},
"original": {