nixos/mollysocket: init

This commit is contained in:
Robert Schütz 2024-01-05 03:10:12 -08:00
parent d39618aa2d
commit 078994248a
6 changed files with 169 additions and 0 deletions

View file

@ -87,6 +87,8 @@ The pre-existing [services.ankisyncd](#opt-services.ankisyncd.enable) has been m
- [transfer-sh](https://github.com/dutchcoders/transfer.sh), a tool that supports easy and fast file sharing from the command-line. Available as [services.transfer-sh](#opt-services.transfer-sh.enable).
- [MollySocket](https://github.com/mollyim/mollysocket) which allows getting Signal notifications via UnifiedPush.
- [Suwayomi Server](https://github.com/Suwayomi/Suwayomi-Server), a free and open source manga reader server that runs extensions built for [Tachiyomi](https://tachiyomi.org). Available as [services.suwayomi-server](#opt-services.suwayomi-server.enable).
- [ping_exporter](https://github.com/czerwonk/ping_exporter), a Prometheus exporter for ICMP echo requests. Available as [services.prometheus.exporters.ping](#opt-services.prometheus.exporters.ping.enable).

View file

@ -726,6 +726,7 @@
./services/misc/mbpfan.nix
./services/misc/mediatomb.nix
./services/misc/metabase.nix
./services/misc/mollysocket.nix
./services/misc/moonraker.nix
./services/misc/mqtt2influxdb.nix
./services/misc/n8n.nix

View file

@ -0,0 +1,133 @@
{ config, lib, pkgs, ... }:
let
inherit (lib) getExe mkIf mkOption mkEnableOption optionals types;
cfg = config.services.mollysocket;
configuration = format.generate "mollysocket.conf" cfg.settings;
format = pkgs.formats.toml { };
package = pkgs.writeShellScriptBin "mollysocket" ''
MOLLY_CONF=${configuration} exec ${getExe pkgs.mollysocket} "$@"
'';
in {
options.services.mollysocket = {
enable = mkEnableOption ''
[MollySocket](https://github.com/mollyim/mollysocket) for getting Signal
notifications via UnifiedPush
'';
settings = mkOption {
default = { };
description = ''
Configuration for MollySocket. Available options are listed
[here](https://github.com/mollyim/mollysocket#configuration).
'';
type = types.submodule {
freeformType = format.type;
options = {
host = mkOption {
default = "127.0.0.1";
description = "Listening address of the web server";
type = types.str;
};
port = mkOption {
default = 8020;
description = "Listening port of the web server";
type = types.port;
};
allowed_endpoints = mkOption {
default = [ "*" ];
description = "List of UnifiedPush servers";
example = [ "https://ntfy.sh" ];
type = with types; listOf str;
};
allowed_uuids = mkOption {
default = [ "*" ];
description = "UUIDs of Signal accounts that may use this server";
example = [ "abcdef-12345-tuxyz-67890" ];
type = with types; listOf str;
};
};
};
};
environmentFile = mkOption {
default = null;
description = ''
Environment file (see {manpage}`systemd.exec(5)` "EnvironmentFile="
section for the syntax) passed to the service. This option can be
used to safely include secrets in the configuration.
'';
example = "/run/secrets/mollysocket";
type = with types; nullOr path;
};
logLevel = mkOption {
default = "info";
description = "Set the {env}`RUST_LOG` environment variable";
example = "debug";
type = types.str;
};
};
config = mkIf cfg.enable {
environment.systemPackages = [
package
];
# see https://github.com/mollyim/mollysocket/blob/main/mollysocket.service
systemd.services.mollysocket = {
description = "MollySocket";
wantedBy = [ "multi-user.target" ];
after = [ "network-online.target" ];
wants = [ "network-online.target" ];
environment.RUST_LOG = cfg.logLevel;
serviceConfig = let
capabilities = [ "" ] ++ optionals (cfg.settings.port < 1024) [ "CAP_NET_BIND_SERVICE" ];
in {
EnvironmentFile = cfg.environmentFile;
ExecStart = "${getExe package} server";
KillSignal = "SIGINT";
Restart = "on-failure";
StateDirectory = "mollysocket";
TimeoutStopSec = 5;
WorkingDirectory = "/var/lib/mollysocket";
# hardening
AmbientCapabilities = capabilities;
CapabilityBoundingSet = capabilities;
DevicePolicy = "closed";
DynamicUser = true;
LockPersonality = true;
MemoryDenyWriteExecute = true;
NoNewPrivileges = true;
PrivateDevices = true;
PrivateTmp = true;
PrivateUsers = true;
ProcSubset = "pid";
ProtectClock = true;
ProtectControlGroups = true;
ProtectHome = true;
ProtectHostname = true;
ProtectKernelLogs = true;
ProtectKernelModules = true;
ProtectKernelTunables = true;
ProtectProc = "invisible";
ProtectSystem = "strict";
RemoveIPC = true;
RestrictAddressFamilies = [ "AF_INET" "AF_INET6" ];
RestrictNamespaces = true;
RestrictRealtime = true;
RestrictSUIDSGID = true;
SystemCallArchitectures = "native";
SystemCallFilter = [ "@system-service" "~@resources" "~@privileged" ];
UMask = "0077";
};
};
};
meta.maintainers = with lib.maintainers; [ dotlambda ];
}

View file

@ -540,6 +540,7 @@ in {
mobilizon = handleTest ./mobilizon.nix {};
mod_perl = handleTest ./mod_perl.nix {};
molly-brown = handleTest ./molly-brown.nix {};
mollysocket = handleTest ./mollysocket.nix { };
monado = handleTest ./monado.nix {};
monica = handleTest ./web-apps/monica.nix {};
mongodb = handleTest ./mongodb.nix {};

View file

@ -0,0 +1,27 @@
import ./make-test-python.nix ({ pkgs, lib, ... }:
let
port = 1234;
in {
name = "mollysocket";
meta.maintainers = with lib.maintainers; [ dotlambda ];
nodes.mollysocket = { ... }: {
services.mollysocket = {
enable = true;
settings = {
inherit port;
};
};
};
testScript = ''
import json
mollysocket.wait_for_unit("mollysocket.service")
mollysocket.wait_for_open_port(${toString port})
out = mollysocket.succeed("curl --fail http://127.0.0.1:${toString port}")
assert json.loads(out)["mollysocket"]["version"] == "${toString pkgs.mollysocket.version}"
'';
})

View file

@ -6,6 +6,7 @@
, sqlite
, stdenv
, darwin
, nixosTests
}:
rustPlatform.buildRustPackage rec {
@ -42,6 +43,10 @@ rustPlatform.buildRustPackage rec {
"--skip=ws::tls::tests::connect_trusted_server"
];
passthru.tests = {
inherit (nixosTests) mollysocket;
};
meta = {
changelog = "https://github.com/mollyim/mollysocket/releases/tag/${version}";
description = "Get Signal notifications via UnifiedPush";