diff --git a/config/hosts/forgejo/forgejo.nix b/config/hosts/forgejo/forgejo.nix index c60c00f..2b2aea8 100644 --- a/config/hosts/forgejo/forgejo.nix +++ b/config/hosts/forgejo/forgejo.nix @@ -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; }; diff --git a/config/hosts/mastodon/containers/fedifetcher/default.nix b/config/hosts/mastodon/containers/fedifetcher/default.nix deleted file mode 100644 index 3f2617e..0000000 --- a/config/hosts/mastodon/containers/fedifetcher/default.nix +++ /dev/null @@ -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"; - }; - }; -} diff --git a/config/hosts/mastodon/containers/fedifetcher/fedifetcher.nix b/config/hosts/mastodon/containers/fedifetcher/fedifetcher.nix deleted file mode 100644 index 7194c25..0000000 --- a/config/hosts/mastodon/containers/fedifetcher/fedifetcher.nix +++ /dev/null @@ -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"; }; - }; -} diff --git a/config/hosts/mastodon/default.nix b/config/hosts/mastodon/default.nix index dc52ff4..5651eb8 100644 --- a/config/hosts/mastodon/default.nix +++ b/config/hosts/mastodon/default.nix @@ -5,6 +5,5 @@ ./mastodon.nix ./opensearch.nix ./nginx.nix - ./containers/fedifetcher ]; } diff --git a/config/hosts/mastodon/mastodon.nix b/config/hosts/mastodon/mastodon.nix index aa4fea4..06d516d 100644 --- a/config/hosts/mastodon/mastodon.nix +++ b/config/hosts/mastodon/mastodon.nix @@ -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.6"; 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-m2LDNyv2jxsp5zPKOfQWvtBG8bD8iuBWBEoz+L0OvNk="; }; # mastodon ships with broken symlinks, disable the check for that for now dontCheckForBrokenSymlinks = true; diff --git a/config/hosts/mastodon/secrets.nix b/config/hosts/mastodon/secrets.nix index 986a64b..88413c7 100644 --- a/config/hosts/mastodon/secrets.nix +++ b/config/hosts/mastodon/secrets.nix @@ -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"; - }; }; } diff --git a/config/hosts/matrix/matrix-authentication-service.nix b/config/hosts/matrix/matrix-authentication-service.nix index 53674ad..e13bdd9 100644 --- a/config/hosts/matrix/matrix-authentication-service.nix +++ b/config/hosts/matrix/matrix-authentication-service.nix @@ -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); diff --git a/config/hosts/matrix/nginx.nix b/config/hosts/matrix/nginx.nix index ce3ab3d..f4ddec6 100644 --- a/config/hosts/matrix/nginx.nix +++ b/config/hosts/matrix/nginx.nix @@ -34,6 +34,19 @@ 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; @@ -51,8 +64,18 @@ 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; diff --git a/config/hosts/web-public-2/nginx.nix b/config/hosts/web-public-2/nginx.nix index 608d6a7..066f3d2 100644 --- a/config/hosts/web-public-2/nginx.nix +++ b/config/hosts/web-public-2/nginx.nix @@ -19,6 +19,7 @@ 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; diff --git a/config/hosts/web-public-2/virtualHosts/default.nix b/config/hosts/web-public-2/virtualHosts/default.nix index 53294f7..445a087 100644 --- a/config/hosts/web-public-2/virtualHosts/default.nix +++ b/config/hosts/web-public-2/virtualHosts/default.nix @@ -4,6 +4,7 @@ ./acme-challenge.nix ./anisync.grzb.de.nix ./element.nekover.se.nix + ./element-admin.nekover.se.nix ./gameserver.grzb.de.nix ./git.grzb.de.nix ./mewtube.nekover.se.nix diff --git a/config/hosts/web-public-2/virtualHosts/element-admin.nekover.se.nix b/config/hosts/web-public-2/virtualHosts/element-admin.nekover.se.nix new file mode 100644 index 0000000..69c3a9a --- /dev/null +++ b/config/hosts/web-public-2/virtualHosts/element-admin.nekover.se.nix @@ -0,0 +1,95 @@ +{ 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 = "localhost"; + 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 127.0.0.1; + # Then tell the realip_module to get the addreses from the proxy protocol + # header. + real_ip_header proxy_protocol; + ''; + }; +} diff --git a/config/hosts/web-public-2/virtualHosts/element.nekover.se.nix b/config/hosts/web-public-2/virtualHosts/element.nekover.se.nix index 7576beb..74b7820 100644 --- a/config/hosts/web-public-2/virtualHosts/element.nekover.se.nix +++ b/config/hosts/web-public-2/virtualHosts/element.nekover.se.nix @@ -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 diff --git a/flake.lock b/flake.lock index 1ba87cf..06a3d59 100644 --- a/flake.lock +++ b/flake.lock @@ -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": 1770802195, + "narHash": "sha256-vabHY4acHLmaB7Ak9FKzk2wSEKhAS/yXL7SBySB/S5U=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "f376a52d0dc796aec60b5606a2676240ff1565b9", + "rev": "08ebc444a070153227d6f45acf979f4d5f1f97f9", "type": "github" }, "original": { @@ -134,11 +134,11 @@ }, "nixpkgs-master": { "locked": { - "lastModified": 1765227377, - "narHash": "sha256-OeTF3YNuXZxN4TxluVEdCG32e5/0pYDb5exWe0RrQBY=", + "lastModified": 1770824979, + "narHash": "sha256-OedDmV9we3oOdiz9xjLiQCajwRa8WWcE/rOF3y/VlVc=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "a0ea537a4fc4c49fb1e226317829c8b32ed95d0e", + "rev": "8605a9be3795437e3717dab6c542d2d571369e70", "type": "github" }, "original": { @@ -150,11 +150,11 @@ }, "nixpkgs-unstable": { "locked": { - "lastModified": 1765183668, - "narHash": "sha256-TBA7CE44IHYfvOPBWcyLncpVrrKEiXWPdOrF8CD6W84=", + "lastModified": 1770818322, + "narHash": "sha256-tttCN+yrhM7svQW6DqtS3JV9POrRJAaS/e0xuUHBTEM=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "fc2de1563f89f0843eba27f14576d261df0e3b80", + "rev": "d9ca3a4b73f19ea147c9d977d3dde8f612ac648f", "type": "github" }, "original": { @@ -197,11 +197,11 @@ "nixpkgs": "nixpkgs_2" }, "locked": { - "lastModified": 1764185122, - "narHash": "sha256-+HUOwSIFLoyett2cvRjuFIbhobpHallfP9J2cia1apo=", + "lastModified": 1766537863, + "narHash": "sha256-HEt+wbazRgJYeY+lgj65bxhPyVc4x7NEB2bs5NU6DF8=", "owner": "simple-nixos-mailserver", "repo": "nixos-mailserver", - "rev": "a14fe3b293ec2720e5b7fc72ad136d22967e12ba", + "rev": "23f0a53ca6e58e61e1ea2b86791c69b79c91656d", "type": "gitlab" }, "original": {