1{
2 config,
3 pkgs,
4 lib,
5 ...
6}:
7let
8 defaultSettings = {
9 db = "/var/lib/strfry";
10
11 dbParams = {
12 maxreaders = 256;
13 mapsize = 10995116277760;
14 noReadAhead = false;
15 };
16
17 events = {
18 maxEventSize = 65536;
19 rejectEventsNewerThanSeconds = 900;
20 rejectEventsOlderThanSeconds = 94608000;
21 rejectEphemeralEventsOlderThanSeconds = 60;
22 ephemeralEventsLifetimeSeconds = 300;
23 maxNumTags = 2000;
24 maxTagValSize = 1024;
25 };
26
27 relay = {
28 bind = "127.0.0.1";
29 port = 7777;
30 nofiles = 1000000;
31 realIpHeader = "";
32
33 info = {
34 name = "strfry default";
35 description = "This is a strfry instance.";
36 pubkey = "";
37 contact = "";
38 icon = "";
39 nips = "";
40 };
41
42 maxWebsocketPayloadSize = 131072;
43 maxReqFilterSize = 200;
44 autoPingSeconds = 55;
45 enableTcpKeepalive = false;
46 queryTimesliceBudgetMicroseconds = 10000;
47 maxFilterLimit = 500;
48 maxSubsPerConnection = 20;
49
50 writePolicy = {
51 plugin = "";
52 };
53
54 compression = {
55 enabled = true;
56 slidingWindow = true;
57 };
58
59 logging = {
60 dumpInAll = false;
61 dumpInEvents = false;
62 dumpInReqs = false;
63 dbScanPerf = false;
64 invalidEvents = true;
65 };
66
67 numThreads = {
68 ingester = 3;
69 reqWorker = 3;
70 reqMonitor = 3;
71 negentropy = 2;
72 };
73
74 negentropy = {
75 enabled = true;
76 maxSyncEvents = 1000000;
77 };
78 };
79 };
80
81 cfg = config.services.strfry;
82 settingsFormat = pkgs.formats.json { };
83 configFile = settingsFormat.generate "config.json" cfg.settings;
84in
85{
86 options.services.strfry = {
87 enable = lib.mkEnableOption "strfry";
88
89 package = lib.mkPackageOption pkgs "strfry" { };
90
91 settings = lib.mkOption {
92 type = settingsFormat.type;
93 default = defaultSettings;
94 apply = lib.recursiveUpdate defaultSettings;
95 description = "Configuration options to set for the Strfry service. See https://github.com/hoytech/strfry for documentation.";
96 example = lib.literalExpression ''
97 dbParams = {
98 maxreaders = 256;
99 mapsize = 10995116277760;
100 noReadAhead = false;
101 };
102 '';
103 };
104
105 };
106
107 config = lib.mkIf cfg.enable {
108 users.users.strfry = {
109 description = "Strfry daemon user";
110 group = "strfry";
111 isSystemUser = true;
112 };
113
114 users.groups.strfry = { };
115
116 systemd.services.strfry = {
117 description = "strfry";
118 wants = [ "network.target" ];
119 wantedBy = [ "multi-user.target" ];
120
121 serviceConfig = {
122 ExecStart = "${lib.getExe cfg.package} --config=${configFile} relay";
123 User = "strfry";
124 Group = "strfry";
125 Restart = "on-failure";
126
127 StateDirectory = "strfry";
128 WorkingDirectory = cfg.settings.db;
129 ReadWritePaths = [ cfg.settings.db ];
130
131 LimitNOFILE = cfg.settings.relay.nofiles;
132
133 PrivateTmp = true;
134 PrivateUsers = true;
135 PrivateDevices = true;
136 ProtectSystem = "strict";
137 ProtectHome = true;
138 NoNewPrivileges = true;
139 MemoryDenyWriteExecute = true;
140 ProtectKernelTunables = true;
141 ProtectKernelModules = true;
142 ProtectKernelLogs = true;
143 ProtectClock = true;
144 ProtectProc = "invisible";
145 ProcSubset = "pid";
146 ProtectControlGroups = true;
147 LockPersonality = true;
148 RestrictSUIDSGID = true;
149 RemoveIPC = true;
150 RestrictRealtime = true;
151 ProtectHostname = true;
152 CapabilityBoundingSet = "";
153 SystemCallFilter = [
154 "@system-service"
155 ];
156 SystemCallArchitectures = "native";
157 };
158 };
159 };
160
161 meta = {
162 doc = ./strfry.md;
163 maintainers = with lib.maintainers; [
164 felixzieger
165 ];
166 };
167}