mirror of
https://github.com/NixOS/nixpkgs.git
synced 2024-12-26 23:54:01 +00:00
cb10fe8aaf
Systemd units with `PrivateUsers` set get their capabilities within the user namespace only [1]. As a result they do cannot bind to privileged ports even though they *appear* like they should be able to. The units in this commit [2] set `PrivateUsers` unconditionally so binding to privileged ports is currently impossible. Granting them CAP_NET_BIND_SERVICE is useless and misleading any reader of those modules. Technically, this commit also hardens these modules ever so slightly. (There are corner cases where this could make sense (e.g. across units, using `JoinsNamspaceOf`) but this is arcane enough to not to be present in nixpkgs.) [1]: systemd.exec(5): PrivateUsers [2]: found using `rg -e 'PrivateUsers.?=\s+[^f][^a]' -l | xargs rg -e '\bCAP_' -l`
93 lines
2.9 KiB
Nix
93 lines
2.9 KiB
Nix
{ config, lib, pkgs, ... }:
|
|
|
|
let
|
|
cfg = config.services.microbin;
|
|
in
|
|
{
|
|
options.services.microbin = {
|
|
enable = lib.mkEnableOption "MicroBin is a super tiny, feature rich, configurable paste bin web application";
|
|
|
|
package = lib.mkPackageOption pkgs "microbin" { };
|
|
|
|
settings = lib.mkOption {
|
|
type = lib.types.submodule { freeformType = with lib.types; attrsOf (oneOf [ bool int str ]); };
|
|
default = { };
|
|
example = {
|
|
MICROBIN_PORT = 8080;
|
|
MICROBIN_HIDE_LOGO = false;
|
|
};
|
|
description = ''
|
|
Additional configuration for MicroBin, see
|
|
<https://microbin.eu/docs/installation-and-configuration/configuration/>
|
|
for supported values.
|
|
|
|
For secrets use passwordFile option instead.
|
|
'';
|
|
};
|
|
|
|
dataDir = lib.mkOption {
|
|
type = lib.types.str;
|
|
default = "/var/lib/microbin";
|
|
description = "Default data folder for MicroBin.";
|
|
};
|
|
|
|
passwordFile = lib.mkOption {
|
|
type = lib.types.nullOr lib.types.path;
|
|
default = null;
|
|
example = "/run/secrets/microbin.env";
|
|
description = ''
|
|
Path to file containing environment variables.
|
|
Useful for passing down secrets.
|
|
Variables that can be considered secrets are:
|
|
- MICROBIN_BASIC_AUTH_USERNAME
|
|
- MICROBIN_BASIC_AUTH_PASSWORD
|
|
- MICROBIN_ADMIN_USERNAME
|
|
- MICROBIN_ADMIN_PASSWORD
|
|
- MICROBIN_UPLOADER_PASSWORD
|
|
'';
|
|
};
|
|
};
|
|
|
|
config = lib.mkIf cfg.enable {
|
|
services.microbin.settings = with lib; {
|
|
MICROBIN_BIND = mkDefault "0.0.0.0";
|
|
MICROBIN_DISABLE_TELEMETRY = mkDefault true;
|
|
MICROBIN_LIST_SERVER = mkDefault false;
|
|
MICROBIN_PORT = mkDefault "8080";
|
|
};
|
|
|
|
systemd.services.microbin = {
|
|
after = [ "network.target" ];
|
|
wantedBy = [ "multi-user.target" ];
|
|
environment = lib.mapAttrs (_: v: if lib.isBool v then lib.boolToString v else toString v) cfg.settings;
|
|
serviceConfig = {
|
|
DevicePolicy = "closed";
|
|
DynamicUser = true;
|
|
EnvironmentFile = lib.optional (cfg.passwordFile != null) cfg.passwordFile;
|
|
ExecStart = "${cfg.package}/bin/microbin";
|
|
LockPersonality = true;
|
|
MemoryDenyWriteExecute = true;
|
|
PrivateDevices = true;
|
|
PrivateUsers = true;
|
|
ProtectClock = true;
|
|
ProtectControlGroups = true;
|
|
ProtectHostname = true;
|
|
ProtectKernelLogs = true;
|
|
ProtectKernelModules = true;
|
|
ProtectKernelTunables = true;
|
|
ProtectProc = "invisible";
|
|
ReadWritePaths = cfg.dataDir;
|
|
RestrictAddressFamilies = [ "AF_INET" "AF_INET6" ];
|
|
RestrictNamespaces = true;
|
|
RestrictRealtime = true;
|
|
StateDirectory = "microbin";
|
|
SystemCallArchitectures = [ "native" ];
|
|
SystemCallFilter = [ "@system-service" ];
|
|
WorkingDirectory = cfg.dataDir;
|
|
};
|
|
};
|
|
};
|
|
|
|
meta.maintainers = with lib.maintainers; [ surfaceflinger ];
|
|
}
|