diff --git a/.sops.yaml b/.sops.yaml index 9746bad..99fcf13 100644 --- a/.sops.yaml +++ b/.sops.yaml @@ -64,6 +64,13 @@ creation_rules: - *dominik - *dominik2 - *ldap-server-arm + - path_regex: hosts/fw/modules/web/[^/]+\.yaml$ + key_groups: + - age: + - *bitwarden + - *dominik + - *dominik2 + - *web-02 - path_regex: utils/modules/lego/[^/]+\.yaml$ key_groups: - age: diff --git a/hosts/fw/modules/dnsmasq.nix b/hosts/fw/modules/dnsmasq.nix index f41f098..1104f1d 100644 --- a/hosts/fw/modules/dnsmasq.nix +++ b/hosts/fw/modules/dnsmasq.nix @@ -90,7 +90,8 @@ address = [ "/fw.cloonar.com/${config.networkPrefix}.97.1" "/omada.cloonar.com/${config.networkPrefix}.97.2" - "/pc.cloonar.com/${config.networkPrefix}.96.5" + "/web-02.cloonar.com/${config.networkPrefix}.97.5" + "/phpldapadmin.cloonar.com/${config.networkPrefix}.97.5" "/home-assistant.cloonar.com/${config.networkPrefix}.97.20" "/mopidy.cloonar.com/${config.networkPrefix}.97.21" "/snapcast.cloonar.com/${config.networkPrefix}.97.21" diff --git a/hosts/fw/modules/web/default.nix b/hosts/fw/modules/web/default.nix index 3fcfad8..4957903 100644 --- a/hosts/fw/modules/web/default.nix +++ b/hosts/fw/modules/web/default.nix @@ -54,6 +54,7 @@ in { ../../utils/modules/lego/lego.nix # ../../utils/modules/borgbackup.nix + ./phpldapadmin.nix ./zammad.nix ./proxies.nix ./matrix.nix @@ -61,6 +62,9 @@ in { networkPrefix = config.networkPrefix; + sops.age.sshKeyPaths = [ "/persist/etc/ssh/ssh_host_ed25519_key" ]; + sops.defaultSopsFile = ./secrets.yaml; + time.timeZone = "Europe/Vienna"; systemd.network.networks."10-lan" = { @@ -116,10 +120,6 @@ in { # backups # borgbackup.repo = "u149513-sub2@u149513-sub2.your-backup.de:borg"; - - sops.age.sshKeyPaths = [ "/persist/etc/ssh/ssh_host_ed25519_key" ]; - sops.defaultSopsFile = ./secrets.yaml; - networking.firewall = { enable = true; allowedTCPPorts = [ 22 80 443 ]; diff --git a/hosts/fw/modules/web/phpldapadmin.nix b/hosts/fw/modules/web/phpldapadmin.nix new file mode 100644 index 0000000..76023ca --- /dev/null +++ b/hosts/fw/modules/web/phpldapadmin.nix @@ -0,0 +1,95 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + phpldapadmin = pkgs.callPackage ../../pkgs/phpldapadmin.nix {}; + fpm = config.services.phpfpm.pools.phpldapadmin; + stateDir = "/var/lib/phpldapadmin"; + domain = "phpldapadmin.cloonar.com"; +in +{ + + users.users.phpldapadmin = { + description = "PHPLdapAdmin Service"; + home = stateDir; + useDefaultShell = true; + group = "phpldapadmin"; + isSystemUser = true; + }; + + users.groups.phpldapadmin = { }; + + sops.secrets.phpldapadmin.owner = "phpldapadmin"; + + environment.etc."phpldapadmin/env".source = config.sops.secrets.phpldapadmin.path; + + services.nginx = { + enable = true; + virtualHosts = { + "${domain}" = { + forceSSL = true; + enableACME = true; + acmeRoot = null; + root = stateDir; + locations."/" = { + root = "${phpldapadmin}/public"; + index = "index.php"; + extraConfig = '' + location ~* \.php(/|$) { + fastcgi_split_path_info ^(.+\.php)(/.+)$; + fastcgi_pass unix:${fpm.socket}; + + fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; + fastcgi_param PATH_INFO $fastcgi_path_info; + + include ${pkgs.nginx}/conf/fastcgi_params; + include ${pkgs.nginx}/conf/fastcgi.conf; + } + ''; + }; + }; + }; + }; + + environment.etc.nginx_allowed_groups = { + text = "employees"; + mode = "0444"; + }; + + security.pam.services.nginx.text = '' + # auth required pam_listfile.so \ + # item=group sense=allow onerr=fail file=/etc/nginx_allowed_groups + auth required ${pkgs.nss_pam_ldapd}/lib/security/pam_ldap.so + account required ${pkgs.nss_pam_ldapd}/lib/security/pam_ldap.so + ''; + + services.phpfpm.pools.phpldapadmin = { + user = "phpldapadmin"; + phpOptions = '' + error_log = 'stderr' + log_errors = on + ''; + settings = mapAttrs (name: mkDefault) { + "listen.owner" = "nginx"; + "listen.group" = "nginx"; + "listen.mode" = "0660"; + "pm" = "dynamic"; + "pm.max_children" = 75; + "pm.start_servers" = 2; + "pm.min_spare_servers" = 1; + "pm.max_spare_servers" = 20; + "pm.max_requests" = 500; + "catch_workers_output" = true; + }; + phpEnv."PATH" = pkgs.lib.makeBinPath [ + pkgs.which + phpldapadmin + ]; + }; + + systemd.tmpfiles.rules = [ + "d '${stateDir}' 0750 phpldapadmin phpldapadmin - -" + ]; + +} diff --git a/hosts/fw/modules/web/secrets.yaml b/hosts/fw/modules/web/secrets.yaml index db256f4..23eb14d 100644 --- a/hosts/fw/modules/web/secrets.yaml +++ b/hosts/fw/modules/web/secrets.yaml @@ -3,32 +3,46 @@ borg-ssh-key: ENC[AES256_GCM,data:b/xZnUTfi85IG1s897CBF1HD7BTswQUatbotyZfLmbhxXx zammad-key-base: ENC[AES256_GCM,data:HO9MuwcwjryuXr5No8sCPfso5bpLtQCoczrC/R214ecVIFwwH1uhMeNO8Tlh6EjRLPo7aVTSz87Vx5yaNVezvHCs55G6TT9mcNS/v/V7sbFz9dNIgbFblY3gFIAa4cViioYc71wdb7d4Tta7qhse5zQ41KhAqCWuGDgFErQA4Oc=,iv:b1wY8fW0psircSlNXwDjPzNWK8NyAMNqegitNcqV6U4=,tag:oQ7nyO9TKOOu6IF7ODzpPA==,type:str] dendrite-private-key: ENC[AES256_GCM,data:ZHDIa/iYSZGofE67JU63fHRdKbs/ZyEJY45tV6H8WZAOcduGafPYBo2NCZ7nqLbc2Z9dUUgsrpzvkQ3+VaWqFUv7YsE+CbCx4CeiLGMkj8EAGzX4rkJGHMzkkc2UT7v9znCnKACS3fZtU69trqVMcf1PzgqepOHMBku37dzpwOQC/Tc3UTuO72M=,iv:Ljun1/ruY9cDBm9vu62riUrpGjrWtFFx90GeE7uc3Yo=,tag:FF4xPb1SDhK/4ITr/idvYg==,type:str] matrix-shared-secret: ENC[AES256_GCM,data:HeS4PT0R+TRU6Htwa5TChjK1VAjAdgSS8tSnva+ga3f+mEfJPTQ02pEvS2WFvcnchmEjNYy39zL/rbtX,iv:4yR+VgdJY3VcvLg18v+5jbJDSkFzaeyLNAZ0k8ivjdQ=,tag:RA96iSFDUdlXq30c/vkvpA==,type:str] +phpldapadmin: ENC[AES256_GCM,data:CJBFQfi0qJmPQcxPcneHcXFsIku0a+xdv7rmrKzC0XsBcn3N/dP8cGBbkC/GcH2OWBhRWFNFm0GOEALbJa/1z/hFxbxn1QJlfglglaXHNjiwJqND51GmNzd+5GJ39RHR7w06fVABgCrDM60DChJLy0Iql/eCITYhZUGpoLd4I+fKXy9zggVIzAA3tTYziJNuaBQuMe/i8V8AIt0DBefrEBITyl3wi/+Y4utLXiEUPOWPGCYfS+Xp7LcHiTJ2rZzwKJjYPiPs+7UYx2IsT2+ksJtSHR0+ibUHXNzebBTmAZ3+YBoyeBvdw2VmsgJeCUTC2SLnBAsR4J3AoSDQcZ0XrHq2oIzZC/Mf5g==,iv:iHx495CM8LHqrsiNPwzFXZQxWJZ5kCgWYvgwirjy7Uw=,tag:c7FvYuYzYjqH/Bqs7FbMzA==,type:str] sops: - kms: [] - gcp_kms: [] - azure_kv: [] - hc_vault: [] age: + - recipient: age14grjcxaq4h55yfnjxvnqhtswxhj9sfdcvyas4lwvpa8py27pjy2sv3g6v7 + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBiZmRBZm8wL3ZQdUZMSjRG + cnFWTjNhc2gvd3pURkdjdEpZdUE2ZE9nVFdnCnEvRGlScFJVUGZRenV3VXI5cU85 + NkZ6clplbzZnR1ZWY0YvMy84WWRiMUEKLS0tIHliOE9KYTdlUlFEb2NuRE0yYWJm + OEhCZmphWVVjU3k1VHRDMnJWTUpQQVUK1M7fgK+d/KlbTzvt9CKj6cGgzZ+vwsfE + zqUbyJ/5UpmrU/3kQMxBMBmb8HsA8b/1itzOn4F54SF1Xm7CFDLTUQ== + -----END AGE ENCRYPTED FILE----- - recipient: age16veg3fmvpfm7a89a9fc8dvvsxmsthlm70nfxqspr6t8vnf9wkcwsvdq38d enc: | -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBoUWdTYlRjWDJvemF5Q2sr - VCtrS2dTTGRwUlNIWHd0WkVCRkRMcGhuTzE0ClNic1FmQ05UNWQwbGc4TUFMNGlI - K0RhK2pqUGY3UElmK1pNUEkxV2xGUTQKLS0tIFRORE9JTDRZK0MwZUJoc2xlcHFH - bmp3ZW14TVdCMHhkSi84NE5neDdrY3cKYfgu7aqvG6wQmEFhmzieXFGoQpyffPXj - jiHrAPjBBFy21wdYf0nQXNMzekqOMJwOj0oNA2b5omprPxjB9uns4Q== + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBwaEpvdkdvSHZQTXZXbXZa + ckZrTW9qNW9SMzN2TkVaZTRlT1NKSm56Q1JzCnIxY1k3Q2VjTy9OSlZPbEZkVDBi + UWVCRHE5bWlDaVEyWERXeUdsL1BFYkUKLS0tIEhoK05uMVpzYXJFZHBRcDlZb296 + YWRTZmljUTJEQW5lUzdMa3N0Y045MlUK0lAs4L5D0DIKuxuHJmGbOu6SX1Y4KNJo + VsgVUd9wU9r/ApoiaicAPNn0jyH3B8sGk1JGtrisL5eldc6Z5phR4g== + -----END AGE ENCRYPTED FILE----- + - recipient: age1v6p8dan2t3w9h94fz4flldl32082j3s9x6zqq7u5j66keth9aphsd6pvch + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBlVEdRWkR4YzJNU2Z3ZW9t + VGNHM3gxZUM0SDlaMzBleHU3a3lsZ1M0dlNJCnF3R1JtUUZCZE9CV2NUVG9la2I5 + R0hadEw2RldTS3J3cDdDQkp0OG4vZmsKLS0tIHl4UVpBejlFbkRycEZjSTNyditY + S3VRckhkNGRzR0VOOVBaRmZCT1lxM0kKThIJN/jw3tjaqaf1C5s6+K5BMBrMer2z + YNhhar3iomZbWvwJ5OW4dneU9p0drrcl5LR9tSAoTiSxIbfBZf+d0A== -----END AGE ENCRYPTED FILE----- - recipient: age1gjm4c3swt8u88e36gf2qlg3syxfc0ly94u64c42f2tsf24npw4csa6e4fw enc: | -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBUUjQxWnBMQXo3QmF1STUw - bHh1NDhvQXZIQ2RiOUx5OU5Wc3BVSEJDUEZVCmVzeFk5SWpMbVV4VUdsRmhiaWwz - bTJDY1pJRXJvNUdCSXJqQ3Byd3lWN2sKLS0tIHRKdXRNc1BYcURBRVNlenk1OEl3 - Q05BN0VnQ0haeHBobWhRV0EzL3dLSEkKWlALiX5mvG8y0WUc8yFWMbcpSRrSGoQx - SHaOlDCjYvViZ7GPRLqnSwDGZ1clC6JsTbwKXrMsWdZBKvSO/VIWQw== + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAzOEhSaklkdnJoY0dOU3dt + T1lyVVdVZ1VoRmQ4RURPN1ZjYWhPeU01T2gwCjFmbHZ3SThub2psTjBHOWk3M0hP + WFk2RXFnM3AzSHhraEJmRmxWZzRFVE0KLS0tIDdteWVZKzJVNXdyZDJTbE43Zldr + WDdHb1I5dVFCcHJ0ejVhOXFIb1pKRlUKkCS05OVL7xvkZ1oh16GTCnateuXao9ZK + 6sMZ7/c9tafLH52psnjeUEJK15Bw8DihFjFctyIh242j8TtXXqxBYg== -----END AGE ENCRYPTED FILE----- - lastmodified: "2024-10-14T16:53:41Z" - mac: ENC[AES256_GCM,data:DUi6zUrZBMVaYZ/BvWny7RwPgXe+vQ+odO30fGe8iZHj9d3gzB95F75CqIgENi4gVOA4CQDADE+p45z/mtl04HAh7RiT0/k21RSdQcH2W9AX525fOzeqbxbPA/tXJOctwGrytFwlK9UdJULXkJCwYrJnwNc0XPnBk1FodTykXWs=,iv:q/eapgTVL/rifrrZeIcXT5VO9bEoS4EmmEhYJ2xHvQ4=,tag:xb0Qj/wu17cLTkvefsDqiw==,type:str] - pgp: [] + lastmodified: "2025-06-10T11:35:59Z" + mac: ENC[AES256_GCM,data:1r8IFSyvVmwSR9j9DROAbN6GmnQo8cg+Z1wCvg2hv/lql5FbeLgFUvVHYQvPGJK6cRUTM+7T010AZOZSWKJM2K3KqiinWLdVVM1G1Bvhv8T4epL2RHq65OgMd5jJFrMLYoyJmHUp3AkzlPeYJDtrvxGCB5B88H1L+ifZtV0pKJQ=,iv:uOnWxuPiPJkmc+wBf4EYihTLeugcyM4MX4AkYncfAFg=,tag:HWHGROye6YMR/cLm/C2G1Q==,type:str] unencrypted_suffix: _unencrypted - version: 3.8.1 + version: 3.10.2 diff --git a/hosts/fw/pkgs/phpldapadmin.nix b/hosts/fw/pkgs/phpldapadmin.nix new file mode 100644 index 0000000..2a0bf15 --- /dev/null +++ b/hosts/fw/pkgs/phpldapadmin.nix @@ -0,0 +1,36 @@ +{ fetchurl, lib, stdenv, nodejs_24, php, phpPackages }: + +stdenv.mkDerivation rec { + pname = "phpLDAPadmin"; + version = "2.1.4"; + + src = fetchurl { + url = "https://github.com/leenooks/phpLDAPadmin/archive/${version}.tar.gz"; + sha256 = "sha256-hkigC458YSgAZVCzVznix8ktDBuQm+UH3ujXn9Umylc="; + }; + + # Pull in PHP itself and Composer + buildInputs = [ php nodejs_24 ]; + nativeBuildInputs = [ phpPackages.composer ]; + + # Let composer do its work + buildPhase = '' + # install all PHP dependencies into vendor/ + npm i + npm run prod + composer i --no-dev + ''; + + installPhase = '' + mkdir -p $out + # copy everything—including the newly created vendor/ directory + cp -r . $out/ + ln -sf /etc/phpldapadmin/env $out/.env + ''; + + meta = { + description = "phpLDAPadmin"; + license = lib.licenses.gpl3; + platforms = lib.platforms.all; + }; +} diff --git a/hosts/nb/configuration.nix b/hosts/nb/configuration.nix index fab55d1..59307d2 100644 --- a/hosts/nb/configuration.nix +++ b/hosts/nb/configuration.nix @@ -237,6 +237,8 @@ in { # epicenter.works "10.14.0.0/16" "10.25.0.0/16" + "188.34.191.144/32" # web-arm + "91.107.201.241" # mail ]; endpoint = "vpn.cloonar.com:51820"; # ToDo: route to endpoint not automatically configured https://wiki.archlinux.org/index.php/WireGuard#Loop_routing https://discourse.nixos.org/t/solved-minimal-firewall-setup-for-wireguard-client/7577 persistentKeepalive = 25; diff --git a/hosts/web-arm/sites/dialog-relations.cloonar.dev.nix b/hosts/web-arm/sites/dialog-relations.cloonar.dev.nix index 9c1bf20..b44fc07 100644 --- a/hosts/web-arm/sites/dialog-relations.cloonar.dev.nix +++ b/hosts/web-arm/sites/dialog-relations.cloonar.dev.nix @@ -5,6 +5,6 @@ authorizedKeys = [ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIG1jkPi2LbnzP5hM4Mpt6rh+Vq5pTe63+zS3QvVyA4Ma" ]; - phpPackage = pkgs.php83; + phpPackage = pkgs.php84; }; } diff --git a/hosts/web-arm/sites/dialog-relations.pub b/hosts/web-arm/sites/dialog-relations.pub deleted file mode 100644 index b3433b2..0000000 --- a/hosts/web-arm/sites/dialog-relations.pub +++ /dev/null @@ -1 +0,0 @@ -ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIG1jkPi2LbnzP5hM4Mpt6rh+Vq5pTe63+zS3QvVyA4Ma dominik@nb-01 diff --git a/hosts/web-arm/sites/paraclub.at.nix b/hosts/web-arm/sites/paraclub.at.nix index d108d2f..cec6869 100644 --- a/hosts/web-arm/sites/paraclub.at.nix +++ b/hosts/web-arm/sites/paraclub.at.nix @@ -23,7 +23,7 @@ in { locations."/".extraConfig = '' index index.html; - error_page 404 /404.html; + error_page 404 /de/404.html; ''; locations."~* \.(js|jpg|gif|png|webp|css|woff2)$".extraConfig = ''