aboutsummaryrefslogtreecommitdiff
path: root/services
diff options
context:
space:
mode:
Diffstat (limited to 'services')
-rw-r--r--services/caddy.nix104
-rw-r--r--services/goaccess.nix136
2 files changed, 240 insertions, 0 deletions
diff --git a/services/caddy.nix b/services/caddy.nix
new file mode 100644
index 0000000..9870af0
--- /dev/null
+++ b/services/caddy.nix
@@ -0,0 +1,104 @@
+{
+ lib,
+ config,
+ ...
+}: let
+ cfg = config.caddy;
+in {
+ options = {
+ caddy = {
+ globalConfig = lib.mkOption {
+ description = "Configuration for top level stuff (ex. dns server api keys)";
+ type = lib.types.lines;
+ default = "";
+ };
+ tld = lib.mkOption {
+ description = "Your publically accessable domain name";
+ type = lib.types.str;
+ };
+ hostname = lib.mkOption {
+ description = "Your computers hostname";
+ type = lib.types.str;
+ };
+ virtualHosts = lib.mkOption {
+ description = "Magically configure caddy for services";
+ type = lib.types.attrsOf (lib.types.submodule ({config, ...}: {
+ options = {
+ serviceName = lib.mkOption {
+ type = lib.types.str;
+ default = config._module.args.name;
+ internal = true;
+ };
+ access = lib.mkOption {
+ type = lib.types.enum ["public" "private"];
+ description = "public: accessable at {serviceName}.my.tld. private: accessable at {serviceName}.{hostname}";
+ };
+ logFile = lib.mkOption {
+ type = lib.types.str;
+ description = "what to name the log file under /var/log/caddy";
+ default = "${config.serviceName}.log";
+ };
+ reverseProxy = lib.mkOption {
+ type = with lib.types; nullOr str;
+ description = "configure caddy to reverse-proxy this port or unix domain socket (ex. 127.0.0.1:8080 or unix//var/run/my_socket)";
+ default = null;
+ };
+ virtualHostConfig = lib.mkOption {
+ type = lib.types.lines;
+ description = "manual config lines to add to the caddy config";
+ default = "";
+ };
+ };
+ }));
+ default = {};
+ };
+ };
+ };
+ config = {
+ configData."caddyfile".text =
+ ''
+ {
+ ${cfg.globalConfig}
+ }
+ ''
+ ++ (cfg.virtualHosts
+ |> map (vhost_cfg: let
+ target =
+ if vhost_cfg.access == "public"
+ then
+ (
+ if vhost_cfg.serviceName != "root"
+ then "${vhost_cfg.serviceName}.${cfg.tld}"
+ else cfg.tld
+ )
+ else
+ (
+ if vhost_cfg.serviceName != "root"
+ then "${vhost_cfg.serviceName}.${cfg.hostName}"
+ else cfg.hostname
+ );
+ in ''
+ log {
+ output file /var/log/caddy/${vhost_cfg.logFile}
+ }
+
+ ${target} {
+ ${
+ if vhost_cfg.access == "private"
+ then "tls internal"
+ else ""
+ }
+ ${
+ if vhost_cfg.reverseProxy != null
+ then "reverse_proxy ${vhost_cfg.reverseProxy}"
+ else ""
+ }
+ ${vhost_cfg.virtualHostConfig}
+ }
+ '')
+ |> builtins.concatStringsSep "\n\n");
+
+ services."caddy".systemd.service = {
+ };
+ };
+}
diff --git a/services/goaccess.nix b/services/goaccess.nix
new file mode 100644
index 0000000..dd6b26d
--- /dev/null
+++ b/services/goaccess.nix
@@ -0,0 +1,136 @@
+{
+ lib,
+ pkgs,
+ config,
+ inputs,
+ ...
+}: let
+ cfg = config.goaccess;
+in {
+ options."caddy-goaccess" = {
+ timeZone = lib.mkOption {
+ type = lib.types.str;
+ description = "time zone";
+ };
+ logFile = lib.mkOption {
+ type = lib.types.str;
+ description = "caddy log file for goaccess to read (must be chmod 775)";
+ };
+ websocketUrl = lib.mkOption {
+ type = lib.types.str;
+ description = "url that the frontend should use to attach to the service websocket";
+ };
+ };
+ config = let
+ settings = {
+ unix-socket = "/run/caddy-goaccess/socket";
+ ws-url = cfg.websocketUrl;
+
+ date-format = "%s";
+ log-format = "CADDY";
+ tz = cfg.timeZone;
+ log-file = cfg.logFile;
+ geoip-database = inputs.geolite-db;
+
+ output = "/run/caddy-goaccess/index.html";
+ real-time-html = "true";
+ external-assets = "true";
+ all-static-files = "false";
+ html-report-title = "stats@ganymede";
+ hl-header = "true";
+ agent-list = "false";
+ with-output-resolver = "false";
+ http-method = "yes";
+ http-protocol = "yes";
+ "4xx-to-unique-count" = "false";
+ ignore-crawlers = "false";
+ crawlers-only = "false";
+ unknowns-as-crawlers = "false";
+ real-os = "true";
+ };
+ in {
+ configData."goaccess.conf".text = settings |> builtins.mapAttrs (k: v: "${k} ${toString v}") |> builtins.attrValues |> lib.concatStringsSep "\n";
+ services."caddy-goaccess" = {
+ systemd.socket = {
+ description = "caddy-goaccess uds";
+ socketConfig = {
+ ListenStream = "/run/caddy-goaccess/socket";
+ SocketMode = "0660";
+ SocketUser = "goaccess";
+ SocketGroup = "caddy";
+ };
+ wantedBy = ["sockets.target"];
+ };
+
+ systemd.service = {
+ description = "GoAccess Real-Time Log Analyzer";
+ restartIfChanged = true;
+ wants = ["network-online.target" "caddy.service"];
+ after = ["network-online.target" "caddy.service"];
+ requires = ["caddy-goaccess.socket"];
+
+ serviceConfig = {
+ Type = "simple";
+
+ DynamicUser = true;
+ SupplimentaryGroup = "caddy"; # to read caddy log files
+ RuntimeDirectory = "caddy-goaccess"; # /run/caddy-goaccess
+ ExecStart = "${pkgs.goaccess}/bin/goaccess -p ${config.configData."goaccess.conf".path}";
+
+ # hardening stuff
+ AmbientCapabilities = [];
+ CapabilityBoundingSet = [
+ "~CAP_RAWIO"
+ "~CAP_MKNOD"
+ "~CAP_AUDIT_CONTROL"
+ "~CAP_AUDIT_READ"
+ "~CAP_AUDIT_WRITE"
+ "~CAP_SYS_BOOT"
+ "~CAP_SYS_TIME"
+ "~CAP_SYS_MODULE"
+ "~CAP_SYS_PACCT"
+ "~CAP_LEASE"
+ "~CAP_LINUX_IMMUTABLE"
+ "~CAP_IPC_LOCK"
+ "~CAP_BLOCK_SUSPEND"
+ "~CAP_WAKE_ALARM"
+ "~CAP_SYS_TTY_CONFIG"
+ "~CAP_MAC_ADMIN"
+ "~CAP_MAC_OVERRIDE"
+ "~CAP_NET_ADMIN"
+ "~CAP_NET_BROADCAST"
+ "~CAP_NET_RAW"
+ "~CAP_SYS_ADMIN"
+ "~CAP_SYS_PTRACE"
+ "~CAP_SYSLOG"
+ ];
+ DevicePolicy = "closed";
+ KeyringMode = "private";
+ LockPersonality = true;
+ NoNewPrivileges = true;
+ PrivateDevices = true;
+ PrivateMounts = true;
+ PrivateTmp = true;
+ ProtectClock = true;
+ ProtectControlGroups = true;
+ ProtectHome = true;
+ ProtectHostname = true;
+ ProtectKernelLogs = true;
+ ProtectKernelModules = true;
+ ProtectKernelTunables = true;
+ ProtectSystem = "full";
+ RemoveIPC = true;
+ RestrictAddressFamilies = [
+ "AF_UNIX"
+ "AF_INET"
+ "AF_INET6"
+ ];
+ RestrictNamespaces = true;
+ RestrictRealtime = true;
+ };
+
+ wantedBy = ["multi-user.target"];
+ };
+ };
+ };
+}