diff --git a/modules/cloud/gotosocial/default.nix b/modules/cloud/gotosocial/default.nix new file mode 100644 index 0000000..2bc8e09 --- /dev/null +++ b/modules/cloud/gotosocial/default.nix @@ -0,0 +1,114 @@ +{ pkgs, config, lib, ... }: +with lib; +let + cfg = config.cloud.gotosocial; + + dbUser = "gotosocial"; + + configFile = pkgs.writeText "config.yml" (generators.toYAML { } { + # General + host = cfg.host; + account-domain = cfg.accountDomain; + bind-address = "localhost"; + port = cfg.port; + # Database + db-port = 0; # Use socket + db-user = dbUser; + db-database = dbUser; + # Web + web-template-base-dir = "${cfg.package}/share/web/template"; + web-asset-base-dir = "${cfg.package}/share/web/assets"; + # OIDC + oidc-enabled = true; + oidc-idp-name = "DTTH"; + oidc-scopes = [ "openid" "email" "profile" ]; + }); +in +{ + options.cloud.gotosocial = { + enable = mkEnableOption "Enable our local GtS server"; + package = mkPackageOption pkgs "gotosocial-bin" { }; + host = mkOption { + type = types.str; + description = "The GtS host"; + default = "gts.dtth.ch"; + }; + accountDomain = mkOption { + type = types.str; + description = "The GtS account domain"; + default = "dtth.ch"; + }; + port = mkOption { + type = types.int; + description = "The port to listen to"; + default = 10010; + }; + envFile = mkOption { + type = types.str; + description = "Additional environment variables to pass, as a file"; + }; + }; + + config = mkIf cfg.enable { + # System user + users.users."${dbUser}" = { + group = "${dbUser}"; + isSystemUser = true; + }; + users.groups."${dbUser}" = { }; + # Postgres + cloud.postgresql.databases = [ dbUser ]; + # Traefik + cloud.traefik.hosts = { gotosocial = { inherit (cfg) host port; }; } // + (if cfg.accountDomain != cfg.host && cfg.accountDomain != "" then { + gotosocial-wellknown = { + inherit (cfg) port; + filter = "Host(`${cfg.accountDomain}`) && (PathPrefix(`/.well-known/webfinger`) || PathPrefix(`/.well-known/nodeinfo`) || PathPrefix(`/.well-known/host-meta`))"; + }; + } else { }); + # The service itself + systemd.services.gotosocial = { + after = [ "network.target" ]; + serviceConfig = { + User = dbUser; + Group = dbUser; + ExecStart = "${cfg.package}/bin/gotosocial --config-path ${configFile} server start"; + EnvironmentFile = cfg.envFile; + # Sandboxing options to harden security + # Details for these options: https://www.freedesktop.org/software/systemd/man/systemd.exec.html + NoNewPrivileges = "yes"; + PrivateTmp = "yes"; + PrivateDevices = "yes"; + RestrictAddressFamilies = "AF_UNIX AF_INET AF_INET6"; + RestrictNamespaces = "yes"; + RestrictRealtime = "yes"; + DevicePolicy = "closed"; + ProtectSystem = "full"; + ProtectControlGroups = "yes"; + ProtectKernelModules = "yes"; + ProtectKernelTunables = "yes"; + LockPersonality = "yes"; + SystemCallFilter = "~@clock @debug @module @mount @obsolete @reboot @setuid @swap"; + + # Denying access to capabilities that should not be relevant + # Doc: https://man7.org/linux/man-pages/man7/capabilities.7.html + CapabilityBoundingSet = strings.concatStringsSep " " [ + "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 " + ]; + # You might need this if you are running as non-root on a privileged port (below 1024) + #AmbientCapabilities=CAP_NET_BIND_SERVICE + StateDirectory = "gotosocial"; + WorkingDirectory = "/var/lib/gotosocial"; + }; + wantedBy = [ "multi-user.target" ]; + }; + }; +} diff --git a/modules/common/linux/default.nix b/modules/common/linux/default.nix index bf2f2a3..4fab6e5 100644 --- a/modules/common/linux/default.nix +++ b/modules/common/linux/default.nix @@ -37,7 +37,7 @@ let virtualisation.podman = { enable = true; dockerCompat = true; - defaultNetwork.settings.dns_enabled = true; + # defaultNetwork.settings.dns_enabled = true; }; virtualisation.oci-containers.backend = "podman"; diff --git a/nki-personal-do/configuration.nix b/nki-personal-do/configuration.nix index edaf2d3..24b060e 100644 --- a/nki-personal-do/configuration.nix +++ b/nki-personal-do/configuration.nix @@ -11,6 +11,7 @@ ../modules/cloud/mail ../modules/cloud/conduit ../modules/cloud/writefreely + ../modules/cloud/gotosocial ]; common.linux.enable = false; # Don't enable the "common linux" module, this is a special machine. @@ -222,6 +223,13 @@ cloud.postgresql.databases = [ "outline" ]; cloud.traefik.hosts.outline = { host = "wiki.dtth.ch"; port = 18729; }; + # GoToSocial + sops.secrets.gts-env = { }; + cloud.gotosocial = { + enable = true; + envFile = config.sops.secrets.gts-env.path; + }; + # Minio sops.secrets.minio-credentials = { }; services.minio = { diff --git a/nki-personal-do/secrets/secrets.yaml b/nki-personal-do/secrets/secrets.yaml index 3bc3fcf..1f477d6 100644 --- a/nki-personal-do/secrets/secrets.yaml +++ b/nki-personal-do/secrets/secrets.yaml @@ -15,6 +15,7 @@ heisenbridge: ENC[AES256_GCM,data:rJY7gpcOY8nODR3KlYW1rEs54mKxr+AjNBeg1/2vTG0Gzp matrix-discord-bridge: ENC[AES256_GCM,data:/rlSjD6inKfak7HKKghH5ays5RjKmb9czGsoIOYHyTZC4A5EMucCbfn8DL1gkYXgvRHJ+QglGX/BGo5ebaxSj6nF60+aW87UG31KggOt5kkMuWsPsjvrufoc5IlNfWnXIWmqf8cdC01hmHEp7biUpI8CcfEZiD9OkOxbZcRfYqW+ttnzplFniRBjGPVZfL5g4DBbuJen5MuOrrMDo5CT+78n,iv:r9VBbDCAAElisCaDehrB6PhJHsaaHjdrk3103lmBT7o=,tag:WoNMMfyMifsL56yWq3MUOg==,type:str] authentik-env: ENC[AES256_GCM,data:CjxTaqIcpBX7ea9L3tgJDELr8HBPJdxXsrOfhsiH4cXwCEzktsNKHjF7l95ZFgI5O08q4Vlbln5Dg4xPEx33nwUesEbQrT5d+n+2YaAxmm/WInrYzF+jB7HYTXASb3rY9PWgd2C3v+YPBkJetHlTUc/k19Q7lOQRNw==,iv:cG8Bi2eCsS+v94tSJBsqp+bjVLzXZvvwX1QVVSYExL8=,tag:VmbfcxCcfi3IpKjg3f8QPw==,type:str] firezone-env: ENC[AES256_GCM,data:Guwc3ovHJyr0m0gsvcJeYDXxOsccv6ZMBJSjWa87F7BZwCXLanMetz8b/GAxe/+0qT8IBKCDvLS7B5v2DM5SYOZD2tQWnrwjU90Pjji2RZhZZy7Pc1kAmhLA6ddpBKGJTLcGxWkTnWOcv8qWEwmfNpgT+kUIDLmjQz2pIMUXiXBpheQyPLWBvIIgrBT8QxkX81LHSUDNG29r7olJv1t4oox58r/PKxnfzUkX7lMhZdIpDMbxdWCU6/F2R483YIaFAaL1BuhCkK/QbuqOPRL7yIGID+W1a0JvKsRc2oPPU7WAWyGA3CLwmJka2sTvHrxosMgY/eZYfCWDtRno6q+OA+LI5ZfFu0weA9dpiUkWLGJ2auSZtiL0Sa5D0VHxZlG2m0iD7o3bcIWUi65cb2olcABn3NikMglw6PCWXxM7E5hqAbpvwcN5JeIkTTesI6xthzT9eoUak5SSvdThrwSlc3dvMqOvmRVGD/wR8T9GcKIZoNT7wOvgltecpDbYPNgwKimHhBloMON/qKXuIaYV1dP1XQ10MMpSM1vUZl/JD24pDjFXH8XkZK6owVI2tRTTRZajQT2uB73oVN8EMPFHPdI3uwyH72NycQojIzXmDvMI/UXNsYWArWZyTwGpHbE0pr+I9rXch78pJYKvlIVFTqicE/NceeOm8bMO1O7qofk1/yiIE8RVjs7YrNNahcBrNI+97lvBNLmk9zpWU0YFtfmyDb/XxBsepwj++QY+3gJ5331ohp9BK5Ypr9pp1WRt9syKv2cwFMBIcHKMCji43NW1MqBj/2bgKGfoNAyCUaJqZ9yRcb1TwHyulvEVhJUAOeUxPHdJeA==,iv:6kPPn4Zl1lhxaEtRqq2BcMW7d1zKy/HUJzXdAgkPv7E=,tag:VaVIWg4RbOE7tnimOuqhGw==,type:str] +gts-env: ENC[AES256_GCM,data:xnL6FYNQ4Cd1XUsHcgGN0jYBPDViVAi9WsD4ewImk4IxmMyJi50xxfS6X7x5lVJ4FGcI7XvxT4uCEwSVjxKaVaDXHw/1TPaY8xQkXzZNvHI1oQvs7ULUVtQ9Mlyv08CwqJGQbptJvBmlvszuTeEqgZ0uVK8iKBbqnw9FB9v3swyfjr0VZYZt+uFCwUI6KDXSTPzTX1axzBBqdPuGDB0G8ZPMpY9nLgtBzZpj/+ozdmlHiwswdPnvTx8YrkJCurdaBzmW1gQmXpM+1xsj03jOr1bYOQ7gm5KzWhviAPdPFYmIS8GOv1Jh33Y/r1WkMvAp3HGv7OGoY8kCJp21gcbzxMH7UScFN1uQipknxrpSPkAy0I7AZD/tEpaBLObPVt3803LFQEq9neXSap7XZEj6Jcl9NppRwJjXIun5ebuiWcONGsa0XeLNNhBajzpYq217k242h8DTAht6mgS+6AohID4lIESsr2cYrXeb4PTNr2mpG/4JOzhSV/eOxc9i1GQeXX+RHXOfn5lIIbQxLwfaarorXvrgAf7jAoEzMHm9/LhYGHasBNnQoEYe0kGmEPju6Pkq769o5Am2NHeG3y0N0EEHyTBLj3P3gjEatzlBjOveBlbeIzFqnNP8VuM86neYvyhGi2+M42u3QQs/fCrXbZnhumqxPKQqNy9UZClH6gzZYMUBcPXOLDqUrDIGLst/W0KaKx/2bv25vo0d9V/fOwEkw4RGb3hibhDNe5psSsHupwU3T3EZenTiloaExfUK1yzYQJ/wXai5sZHcHK6m0nPTtGxGM8b8G367BsICFraZbW2q4fFHY7XvbGGdv6ydpxhdI69ERS7FSGWgEcJlUcxCsXE2NeLtmLgfUz0zQrEHPYo3kxJYRedmSARvUNJzZWZMb3NQ0QjqGsq1us9uo7LgPF+Ur+oeQyrKWi+4JQRKB16nxUd/HrDIXbAWxub/Fk730kZVdQ8Vus6B2lrSs+hDHoihek40Tfq1CKq8tSI=,iv:fa9Lpq3/ppG3dbYMgWtWI/sReN6bnHvXQSOSnIbpF8A=,tag:i97q7HTGLRdAkC8aF75aPg==,type:str] sops: kms: [] gcp_kms: [] @@ -48,8 +49,8 @@ sops: by9kZFlTRVdCZFkxYTVVb0RIRk8zUlkKCqMw9oL9RaYBV5Hhy3o8Nm5xmGrPH8Sd hv36sxRFFNZT/DCKaHaSRbT3mfpBZSTXJt1dgl4nZe6whH54t/1KmA== -----END AGE ENCRYPTED FILE----- - lastmodified: "2023-04-27T00:35:39Z" - mac: ENC[AES256_GCM,data:eUuISaqS6F7SegO6GHygQjkSugPF+WQSvhlhftVEJ6CuOb54SUzAKpTX1/aNWmH5kZBvkXSd/SwNUE0/2iD0ZECw3tP2KMuyVcuMJjnob9KbRgEmoMz7LAmnO6kAmPAxrkxOgYdkjgSi0Du0c2cpSNBxQ/H9S8W9KuzT3dECvH0=,iv:3J8MUa3h9+BfCixDVpwAKIQFMnJMNL8HXg2wslhPQd8=,tag:SREU8gjDTJveiEld9GRlFg==,type:str] + lastmodified: "2023-05-04T10:59:24Z" + mac: ENC[AES256_GCM,data:3/eVepYi5oxOO0VlZeYdEw84r3EPb+w8vOT8Sge2lt1ZYVgIf+4GT/xtqzq5BQi4/7AC81A8+xsNJSoZIhMMeCY1Y1KAy8CApsiu3tFCbey1aZi5oDaX2UQg8D21sy0QwrCve9sQZ38zM1Z9Bwt/JZJxwVIOEpeX1hNXHcIPrmk=,iv:bhk+YdEP/1w9fAOrhSkbOf7z2uerx58t29YWC4FCF8I=,tag:tlipMk4mUbIqup4pDPR3zQ==,type:str] pgp: [] unencrypted_suffix: _unencrypted version: 3.7.3 diff --git a/overlay.nix b/overlay.nix index 90bc8ba..06b6b4a 100644 --- a/overlay.nix +++ b/overlay.nix @@ -25,6 +25,10 @@ let libs.crane = inputs.crane.lib.${prev.system}; }; + overlay-packages = final: prev: { + gotosocial-bin = final.callPackage ./packages/x86_64-linux/gotosocial-bin.nix { }; + }; + overlay-aarch64-linux = final: prev: let optionalOverride = pkg: alt: @@ -59,6 +63,7 @@ in (import ./overlays/openrazer) overlay-unstable overlay-needs-unstable + overlay-packages overlay-imported overlay-versioning overlay-libs diff --git a/packages/x86_64-linux/gotosocial-bin.nix b/packages/x86_64-linux/gotosocial-bin.nix new file mode 100644 index 0000000..0a51417 --- /dev/null +++ b/packages/x86_64-linux/gotosocial-bin.nix @@ -0,0 +1,30 @@ +{ stdenv, lib, autoPatchelfHook }: +with lib; +let +in +stdenv.mkDerivation rec { + pname = "gotosocial-bin"; + version = "0.8.1"; + + src = builtins.fetchurl { + url = "https://github.com/superseriousbusiness/gotosocial/releases/download/v${version}/gotosocial_${version}_linux_amd64.tar.gz"; + sha256 = "sha256:0vfgz236s4zqcv4a8bylp5znina26nvckdk1vgxbqkdnip3mnirj"; + }; + + nativeBuildInputs = [ autoPatchelfHook ]; + + sourceRoot = "."; + + installPhase = '' + install -m755 -D gotosocial $out/bin/gotosocial + mkdir $out/share + cp -r web $out/share/web + cp -r example $out/share/example + ''; + + meta = with lib; { + homepage = "https://docs.gotosocial.org"; + description = "GoToSocial network"; + platforms = platforms.linux; + }; +}