diff --git a/nixos/doc/manual/release-notes/rl-2405.section.md b/nixos/doc/manual/release-notes/rl-2405.section.md index 06d6ebbd2b0a..7afc14347f5c 100644 --- a/nixos/doc/manual/release-notes/rl-2405.section.md +++ b/nixos/doc/manual/release-notes/rl-2405.section.md @@ -140,6 +140,8 @@ The pre-existing [services.ankisyncd](#opt-services.ankisyncd.enable) has been m - [systemd-lock-handler](https://git.sr.ht/~whynothugo/systemd-lock-handler/), a bridge between logind D-Bus events and systemd targets. Available as [services.systemd-lock-handler.enable](#opt-services.systemd-lock-handler.enable). +- [wastebin](https://github.com/matze/wastebin), a pastebin server written in rust. Available as [services.wastebin](#opt-services.wastebin.enable). + - [Mealie](https://nightly.mealie.io/), a self-hosted recipe manager and meal planner with a RestAPI backend and a reactive frontend application built in NuxtJS for a pleasant user experience for the whole family. Available as [services.mealie](#opt-services.mealie.enable) - [Uni-Sync](https://github.com/EightB1ts/uni-sync), a synchronization tool for Lian Li Uni Controllers. Available as [hardware.uni-sync](#opt-hardware.uni-sync.enable) diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index 0a15360f6ea5..9cbc421239ba 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -799,6 +799,7 @@ ./services/misc/transfer-sh.nix ./services/misc/tzupdate.nix ./services/misc/uhub.nix + ./services/misc/wastebin.nix ./services/misc/weechat.nix ./services/misc/workout-tracker.nix ./services/misc/xmr-stak.nix diff --git a/nixos/modules/services/misc/wastebin.nix b/nixos/modules/services/misc/wastebin.nix new file mode 100644 index 000000000000..3d0af2862683 --- /dev/null +++ b/nixos/modules/services/misc/wastebin.nix @@ -0,0 +1,158 @@ +{ config, lib, pkgs, ... }: + +let + cfg = config.services.wastebin; + inherit (lib) + mkEnableOption mkPackageOption mkIf mkOption + types mapAttrs isBool getExe boolToString optionalAttrs; +in +{ + + options.services.wastebin = { + + enable = mkEnableOption "Wastenbin pastebin service"; + + package = mkPackageOption pkgs "wastebin" { }; + + stateDir = mkOption { + type = types.path; + default = "/var/lib/wastebin"; + description = "State directory of the daemon."; + }; + + secretFile = mkOption { + type = types.nullOr types.path; + default = null; + example = "/run/secrets/wastebin.env"; + description = '' + Path to file containing sensitive environment variables. + Some variables that can be considered secrets are: + + - WASTEBIN_PASSWORD_SALT: + salt used to hash user passwords used for encrypting pastes. + + - WASTEBIN_SIGNING_KEY: + sets the key to sign cookies. If not set, a random key will be + generated which means cookies will become invalid after restarts and + paste creators will not be able to delete their pastes anymore. + ''; + }; + + settings = mkOption { + + description = '' + Additional configuration for wastebin, see + for supported values. + For secrets use secretFile option instead. + ''; + + type = types.submodule { + + freeformType = with types; attrsOf (oneOf [ bool int str ]); + + options = { + + WASTEBIN_ADDRESS_PORT = mkOption { + type = types.str; + default = "0.0.0.0:8088"; + description = "Address and port to bind to"; + }; + + WASTEBIN_BASE_URL = mkOption { + default = "http://localhost"; + example = "https://myhost.tld"; + type = types.str; + description = '' + Base URL for the QR code display. If not set, the user agent's Host + header field is used as an approximation. + ''; + }; + + WASTEBIN_CACHE_SIZE = mkOption { + default = 128; + type = types.int; + description = "Number of rendered syntax highlight items to cache. Can be disabled by setting to 0."; + }; + + WASTEBIN_DATABASE_PATH = mkOption { + default = "/var/lib/wastebin/sqlite3.db"; # TODO make this default to stateDir/sqlite3.db + type = types.str; + description = "Path to the sqlite3 database file. If not set, an in-memory database is used."; + }; + + WASTEBIN_HTTP_TIMEOUT = mkOption { + default = 5; + type = types.int; + description = "Maximum number of seconds a request can be processed until wastebin responds with 408"; + }; + + WASTEBIN_MAX_BODY_SIZE = mkOption { + default = 1024; + type = types.int; + description = "Number of bytes to accept for POST requests"; + }; + + WASTEBIN_TITLE = mkOption { + default = "wastebin"; + type = types.str; + description = "Overrides the HTML page title"; + }; + + RUST_LOG = mkOption { + default = "info"; + type = types.str; + description = + '' + Influences logging. Besides the typical trace, debug, info etc. + keys, you can also set the tower_http key to some log level to get + additional information request and response logs. + ''; + }; + }; + }; + + default = { }; + + example = { + WASTEBIN_TITLE = "My awesome pastebin"; + }; + }; + }; + + config = mkIf cfg.enable + { + systemd.services.wastebin = { + after = [ "network.target" ]; + wantedBy = [ "multi-user.target" ]; + environment = mapAttrs (_: v: if isBool v then boolToString v else toString v) cfg.settings; + serviceConfig = { + CapabilityBoundingSet = [ "CAP_NET_BIND_SERVICE" ]; + DevicePolicy = "closed"; + DynamicUser = true; + ExecStart = "${getExe cfg.package}"; + LockPersonality = true; + MemoryDenyWriteExecute = true; + PrivateDevices = true; + PrivateUsers = true; + ProtectClock = true; + ProtectControlGroups = true; + ProtectHostname = true; + ProtectKernelLogs = true; + ProtectKernelModules = true; + ProtectKernelTunables = true; + ProtectProc = "invisible"; + RestrictAddressFamilies = [ "AF_INET" "AF_INET6" ]; + RestrictNamespaces = true; + RestrictRealtime = true; + SystemCallArchitectures = [ "native" ]; + SystemCallFilter = [ "@system-service" ]; + StateDirectory = baseNameOf cfg.stateDir; + ReadWritePaths = cfg.stateDir; + } // optionalAttrs (cfg.secretFile != null) { + EnvironmentFile = cfg.secretFile; + }; + }; + }; + + meta.maintainers = with lib.maintainers; [ pinpox ]; +} diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix index 6a6ef1f6f38b..c804ce9418cd 100644 --- a/nixos/tests/all-tests.nix +++ b/nixos/tests/all-tests.nix @@ -985,6 +985,7 @@ in { vsftpd = handleTest ./vsftpd.nix {}; warzone2100 = handleTest ./warzone2100.nix {}; wasabibackend = handleTest ./wasabibackend.nix {}; + wastebin = handleTest ./wastebin.nix {}; watchdogd = handleTest ./watchdogd.nix {}; webhook = runTest ./webhook.nix; wiki-js = handleTest ./wiki-js.nix {}; diff --git a/nixos/tests/wastebin.nix b/nixos/tests/wastebin.nix new file mode 100644 index 000000000000..1cf0ff80ae99 --- /dev/null +++ b/nixos/tests/wastebin.nix @@ -0,0 +1,19 @@ +import ./make-test-python.nix ({ pkgs, lib, ... }: { + name = "wastebin"; + + meta = { + maintainers = with lib.maintainers; [ pinpox ]; + }; + + nodes.machine = { pkgs, ... }: { + services.wastebin = { + enable = true; + }; + }; + + testScript = '' + machine.wait_for_unit("wastebin.service") + machine.wait_for_open_port(8088) + machine.succeed("curl --fail http://localhost:8088/") + ''; +}) diff --git a/pkgs/by-name/wa/wastebin/package.nix b/pkgs/by-name/wa/wastebin/package.nix new file mode 100644 index 000000000000..596d1d075219 --- /dev/null +++ b/pkgs/by-name/wa/wastebin/package.nix @@ -0,0 +1,43 @@ +{ lib +, rustPlatform +, fetchFromGitHub +, pkg-config +, sqlite +, zstd +}: + +rustPlatform.buildRustPackage rec { + pname = "wastebin"; + version = "2.4.3"; + + src = fetchFromGitHub { + owner = "matze"; + repo = "wastebin"; + rev = version; + hash = "sha256-5L9ug/OOvobic3bYjz8KUkQdnaVmAb2ltXCCiZkVHOg="; + }; + + cargoHash = "sha256-KbYbsV3+xhGFgcKrdLMiQ5+1meePjXYMD9PltlO+QMA="; + + nativeBuildInputs = [ + pkg-config + ]; + + buildInputs = [ + sqlite + zstd + ]; + + env = { + ZSTD_SYS_USE_PKG_CONFIG = true; + }; + + meta = with lib; { + description = "Wastebin is a pastebin"; + homepage = "https://github.com/matze/wastebin"; + changelog = "https://github.com/matze/wastebin/blob/${src.rev}/CHANGELOG.md"; + license = licenses.mit; + maintainers = with maintainers; [ pinpox matthiasbeyer ]; + mainProgram = "wastebin"; + }; +}