| 1 | { |
| 2 | config, |
| 3 | pkgs, |
| 4 | inputs, |
| 5 | ... |
| 6 | }: |
| 7 | let |
| 8 | logviewer = import "${inputs.ofborg-viewer}/release.nix" { inherit pkgs; }; |
| 9 | in |
| 10 | { |
| 11 | systemd.services.ofborg-logapi = { |
| 12 | description = "ofBorg log api"; |
| 13 | |
| 14 | wantedBy = [ "ofborg.target" ]; |
| 15 | bindsTo = [ "ofborg.target" ]; |
| 16 | restartTriggers = [ config.environment.etc."ofborg.json".source ]; |
| 17 | |
| 18 | stopIfChanged = false; |
| 19 | unitConfig.StartLimitIntervalSec = 0; |
| 20 | serviceConfig = { |
| 21 | # Filesystem stuff |
| 22 | ProtectSystem = "strict"; # Prevent writing to most of / |
| 23 | ProtectHome = true; # Prevent accessing /home and /root |
| 24 | PrivateTmp = true; # Give an own directory under /tmp |
| 25 | PrivateDevices = true; # Deny access to most of /dev |
| 26 | ProtectKernelTunables = true; # Protect some parts of /sys |
| 27 | ProtectControlGroups = true; # Remount cgroups read-only |
| 28 | RestrictSUIDSGID = true; # Prevent creating SETUID/SETGID files |
| 29 | PrivateMounts = true; # Give an own mount namespace |
| 30 | RemoveIPC = true; |
| 31 | UMask = "0077"; |
| 32 | |
| 33 | Restart = "always"; |
| 34 | RestartSec = "5s"; |
| 35 | ExecStart = "${pkgs.ofborg}/bin/logapi /etc/ofborg.json"; |
| 36 | User = "ofborg-logapi"; |
| 37 | Group = "ofborg-logapi"; |
| 38 | |
| 39 | # Capabilities |
| 40 | CapabilityBoundingSet = ""; # Allow no capabilities at all |
| 41 | NoNewPrivileges = true; # Disallow getting more capabilities. This is also implied by other options. |
| 42 | |
| 43 | # Kernel stuff |
| 44 | ProtectKernelModules = true; # Prevent loading of kernel modules |
| 45 | SystemCallArchitectures = "native"; # Usually no need to disable this |
| 46 | ProtectKernelLogs = true; # Prevent access to kernel logs |
| 47 | ProtectClock = true; # Prevent setting the RTC |
| 48 | |
| 49 | # Misc |
| 50 | LockPersonality = true; # Prevent change of the personality |
| 51 | ProtectHostname = true; # Give an own UTS namespace |
| 52 | RestrictRealtime = true; # Prevent switching to RT scheduling |
| 53 | MemoryDenyWriteExecute = true; # Maybe disable this for interpreters like python |
| 54 | PrivateUsers = true; # If anything randomly breaks, it's mostly because of this |
| 55 | RestrictNamespaces = true; |
| 56 | SystemCallFilter = "@system-service"; |
| 57 | }; |
| 58 | }; |
| 59 | |
| 60 | users = { |
| 61 | users.ofborg-logapi = { |
| 62 | isSystemUser = true; |
| 63 | group = "ofborg-logapi"; |
| 64 | description = "ofBorg Log Api"; |
| 65 | extraGroups = [ "ofborg-logs" ]; |
| 66 | }; |
| 67 | groups.ofborg-logapi = { }; |
| 68 | users.nginx.extraGroups = [ "ofborg-logs" ]; |
| 69 | }; |
| 70 | |
| 71 | services.nginx.virtualHosts."logs.ofborg.org" = { |
| 72 | forceSSL = true; |
| 73 | enableACME = true; |
| 74 | root = "${logviewer}/website"; |
| 75 | |
| 76 | locations = { |
| 77 | "/logfile/" = { |
| 78 | alias = "/var/log/ofborg/"; |
| 79 | extraConfig = '' |
| 80 | add_header Access-Control-Allow-Origin "*"; |
| 81 | add_header Access-Control-Request-Method "GET"; |
| 82 | add_header Content-Security-Policy "default-src 'none'; sandbox;"; |
| 83 | add_header Content-Type "text/plain; charset=utf-8"; |
| 84 | add_header X-Content-Type-Options "nosniff"; |
| 85 | add_header X-Frame-Options "deny"; |
| 86 | add_header X-XSS-Protection "1; mode=block"; |
| 87 | ''; |
| 88 | }; |
| 89 | |
| 90 | "/logs/" = { |
| 91 | proxyPass = "http://[::1]:9898"; |
| 92 | extraConfig = '' |
| 93 | add_header Access-Control-Allow-Origin "*"; |
| 94 | add_header Access-Control-Request-Method "GET"; |
| 95 | add_header Content-Security-Policy "default-src 'none'; sandbox;"; |
| 96 | add_header X-Content-Type-Options "nosniff"; |
| 97 | add_header X-XSS-Protection "1; mode=block"; |
| 98 | ''; |
| 99 | }; |
| 100 | }; |
| 101 | }; |
| 102 | } |