Skip to content

Commit 4fa076a

Browse files
committed
First commit
0 parents  commit 4fa076a

File tree

5 files changed

+219
-0
lines changed

5 files changed

+219
-0
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
/strfry/db/

Dockerfile

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
FROM ubuntu:jammy as build
2+
3+
WORKDIR /build
4+
RUN apt update && apt install -y --no-install-recommends \
5+
git g++ make pkg-config libtool ca-certificates \
6+
libyaml-perl libtemplate-perl libregexp-grammars-perl libssl-dev zlib1g-dev \
7+
liblmdb-dev libflatbuffers-dev libsecp256k1-dev \
8+
libzstd-dev
9+
10+
RUN git clone --branch 0.9.6 https://github.com/hoytech/strfry.git && cd strfry/ \
11+
&& git submodule update --init \
12+
&& make setup-golpe \
13+
&& make clean \
14+
&& make -j4
15+
16+
FROM ubuntu:jammy as runner
17+
18+
EXPOSE 7777
19+
20+
RUN curl -fsSL https://deno.land/install.sh | sh
21+
RUN apt-get update && apt-get install -y --no-install-recommends \
22+
vim \
23+
liblmdb0 libflatbuffers1 libsecp256k1-0 libb2-1 libzstd1 \
24+
&& rm -rf /var/lib/apt/lists/*
25+
26+
COPY ./strfry/config/strfry.conf /etc/strfry.conf
27+
28+
RUN mkdir -p /app/strfry-db
29+
COPY ./strfry/plugins/ /app/plugins/
30+
31+
RUN chmod +x /app/plugins/allowed_rules.js
32+
33+
WORKDIR /app
34+
COPY --from=build /build/strfry/strfry strfry
35+
36+
ENTRYPOINT ["/app/strfry", "relay"]

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# nosrelay

strfry/config/strfry.conf

+137
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
##
2+
## Default strfry config for relayable/strfry Docker
3+
##
4+
5+
# Directory that contains the strfry LMDB database (restart required)
6+
db = "./strfry-db/"
7+
8+
dbParams {
9+
# Maximum number of threads/processes that can simultaneously have LMDB transactions open (restart required)
10+
maxreaders = 2024
11+
12+
# Size of mmap() to use when loading LMDB (default is 10TB, does *not* correspond to disk-space used) (restart required)
13+
mapsize = 10995116277760
14+
}
15+
16+
relay {
17+
# Interface to listen on. Use 0.0.0.0 to listen on all interfaces (restart required)
18+
bind = "0.0.0.0"
19+
20+
# Port to open for the nostr websocket protocol (restart required)
21+
port = 7777
22+
23+
# Set OS-limit on maximum number of open files/sockets (if 0, don't attempt to set) (restart required)
24+
nofiles = 1000000
25+
26+
# HTTP header that contains the client's real IP, before reverse proxying (ie x-real-ip) (MUST be all lower-case)
27+
realIpHeader = "x-forwarded-for"
28+
29+
info {
30+
# NIP-11: Name of this server. Short/descriptive (< 30 characters)
31+
name = "nos.social strfry relay"
32+
33+
# NIP-11: Detailed information about relay, free-form
34+
description = "This is a strfry instance handled by nos.social"
35+
36+
# NIP-11: Administrative nostr pubkey, for contact purposes
37+
pubkey = "89ef92b9ebe6dc1e4ea398f6477f227e95429627b0a33dc89b640e137b256be5"
38+
39+
# NIP-11: Alternative administrative contact (email, website, etc)
40+
contact = "https://nos.social"
41+
}
42+
43+
# Maximum accepted incoming websocket frame size (should be larger than max event and yesstr msg) (restart required)
44+
maxWebsocketPayloadSize = 131072
45+
46+
# Websocket-level PING message frequency (should be less than any reverse proxy idle timeouts) (restart required)
47+
autoPingSeconds = 55
48+
49+
# If TCP keep-alive should be enabled (detect dropped connections to upstream reverse proxy)
50+
enableTcpKeepalive = true
51+
52+
# How much uninterrupted CPU time a REQ query should get during its DB scan
53+
queryTimesliceBudgetMicroseconds = 10000
54+
55+
# Maximum records that can be returned per filter
56+
maxFilterLimit = 500
57+
58+
# Maximum number of subscriptions (concurrent REQs) a connection can have open at any time
59+
maxSubsPerConnection = 100
60+
61+
writePolicy {
62+
# If non-empty, path to an executable script that implements the writePolicy plugin logic
63+
plugin = "/app/plugins/allowed_rules.js"
64+
65+
# Number of seconds to search backwards for lookback events when starting the writePolicy plugin (0 for no lookback)
66+
lookbackSeconds = 0
67+
}
68+
69+
compression {
70+
# Use permessage-deflate compression if supported by client. Reduces bandwidth, but slight increase in CPU (restart required)
71+
enabled = true
72+
73+
# Maintain a sliding window buffer for each connection. Improves compression, but uses more memory (restart required)
74+
slidingWindow = true
75+
}
76+
77+
logging {
78+
# Dump all incoming messages
79+
dumpInAll = false
80+
81+
# Dump all incoming EVENT messages
82+
dumpInEvents = false
83+
84+
# Dump all incoming REQ/CLOSE messages
85+
dumpInReqs = false
86+
87+
# Log performance metrics for initial REQ database scans
88+
dbScanPerf = false
89+
}
90+
91+
numThreads {
92+
# Ingester threads: route incoming requests, validate events/sigs (restart required)
93+
ingester = 5
94+
95+
# reqWorker threads: Handle initial DB scan for events (restart required)
96+
reqWorker = 5
97+
98+
# reqMonitor threads: Handle filtering of new events (restart required)
99+
reqMonitor = 3
100+
101+
# yesstr threads: Experimental yesstr protocol (restart required)
102+
yesstr = 1
103+
}
104+
105+
negentropy {
106+
# Support negentropy protocol messages
107+
enabled = false
108+
109+
# Maximum records that sync will process before returning an error
110+
maxSyncEvents = 1000000
111+
}
112+
}
113+
114+
events {
115+
# Maximum size of normalised JSON, in bytes
116+
maxEventSize = 65536
117+
118+
# Events newer than this will be rejected
119+
rejectEventsNewerThanSeconds = 900
120+
121+
# Events older than this will be rejected
122+
rejectEventsOlderThanSeconds = 94608000
123+
124+
# Ephemeral events older than this will be rejected
125+
rejectEphemeralEventsOlderThanSeconds = 60
126+
127+
# Ephemeral events will be deleted from the DB when older than this
128+
ephemeralEventsLifetimeSeconds = 300
129+
130+
# Maximum number of tags allowed
131+
maxNumTags = 2000
132+
133+
# Maximum size for tag values, in bytes
134+
maxTagValSize = 1024
135+
}
136+
137+

strfry/plugins/allowed_rules.js

+44
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
#!/usr/bin/env -S deno run
2+
3+
const WHITELIST = {
4+
pubs: {
5+
"56d4b3d6310fadb7294b7f041aab469c5ffc8991b1b1b331981b96a246f6ae65": true, // Tagr
6+
},
7+
eventKinds: [
8+
0, // Metadata
9+
3, // Contacts
10+
1059, // Gift wrap messages
11+
10002, // Relay list metadata
12+
],
13+
};
14+
15+
import { stdin, stdout } from "node:process";
16+
import { createInterface } from "node:readline";
17+
18+
const rl = createInterface({
19+
input: stdin,
20+
output: stdout,
21+
terminal: false,
22+
});
23+
24+
rl.on("line", (line) => {
25+
let req = JSON.parse(line);
26+
27+
if (req.type !== "new") {
28+
return;
29+
}
30+
31+
let res = { id: req.event.id }; // must echo the event's id
32+
33+
const isAllowedPub = ALLOWED.pubs.hasOwnProperty(req.event.pubkey);
34+
const isAllowedEventKind = ALLOWED.eventKinds.includes(req.event.kind);
35+
36+
if (isAllowedPub || isAllowedEventKind) {
37+
res.action = "accept";
38+
} else {
39+
res.action = "reject";
40+
res.msg = "blocked: not on white-list";
41+
}
42+
43+
console.log(JSON.stringify(res));
44+
});

0 commit comments

Comments
 (0)