Merge branch 'main' into lint

This commit is contained in:
asmogo 2024-08-04 11:40:54 +02:00 committed by GitHub
commit fa8a21e044
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 187 additions and 32 deletions

1
.gitignore vendored
View File

@ -1,4 +1,5 @@
localhost.crt localhost.crt
localhost.key localhost.key
.idea .idea
.vscode
nostr nostr

View File

@ -31,9 +31,12 @@ services:
networks: networks:
nostr: nostr:
environment: environment:
- NOSTR_RELAYS=ws://nostr-relay:8080 - NOSTR_RELAYS=ws://nostr-relay:7777
- NOSTR_PRIVATE_KEY= - NOSTR_PRIVATE_KEY=
- BACKEND_HOST=mint:3338 - BACKEND_HOST=mint:3338
depends_on:
- mint
- nostr
exit-https: exit-https:
build: build:
context: . context: .
@ -43,9 +46,12 @@ services:
networks: networks:
nostr: nostr:
environment: environment:
- NOSTR_RELAYS=ws://nostr-relay:8080 - NOSTR_RELAYS=ws://nostr-relay:7777
- NOSTR_PRIVATE_KEY= - NOSTR_PRIVATE_KEY=
- BACKEND_HOST=:4443 - BACKEND_HOST=:4443
depends_on:
- mint
- nostr
entry: entry:
build: build:
context: . context: .
@ -56,16 +62,17 @@ services:
networks: networks:
nostr: nostr:
environment: environment:
- NOSTR_RELAYS=ws://nostr-relay:8080 - NOSTR_RELAYS=ws://nostr-relay:7777
depends_on:
- nostr
nostr: nostr:
image: scsibug/nostr-rs-relay:latest image: carroarmato0/strfry:latest
container_name: nostr-relay container_name: nostr-relay
ports: ports:
- 8080:8080 - 7777:7777
networks: networks:
nostr: nostr:
restart: always restart: always
volumes: volumes:
- ./nostr/data:/usr/src/app/db:Z - ./strfry/data:/app/strfry-db/:Z
- ./nostr/config/config.toml:/usr/src/app/config.toml:ro,Z - ./strfry/strfry.conf:/app/strfry.conf:ro,Z
user: 100:100

View File

@ -61,15 +61,10 @@ func NewExit(ctx context.Context, exitNodeConfig *config.ExitConfig) *Exit {
// generate new private key // generate new private key
exitNodeConfig.NostrPrivateKey = nostr.GeneratePrivateKey() exitNodeConfig.NostrPrivateKey = nostr.GeneratePrivateKey()
slog.Warn(generateKeyMessage, "key", exitNodeConfig.NostrPrivateKey) slog.Warn(generateKeyMessage, "key", exitNodeConfig.NostrPrivateKey)
} else {
pubKey, err := nostr.GetPublicKey(exitNodeConfig.NostrPrivateKey)
if err != nil {
panic(err)
}
slog.Info("using public key", "key", pubKey)
} }
// get public key from private key // get public key from private key
pubKey, err := nostr.GetPublicKey(exitNodeConfig.NostrPrivateKey) pubKey, err := nostr.GetPublicKey(exitNodeConfig.NostrPrivateKey)
slog.Info("using public key", "key", pubKey)
if err != nil { if err != nil {
panic(err) panic(err)
} }

View File

@ -9,9 +9,6 @@ import (
"crypto/x509/pkix" "crypto/x509/pkix"
"encoding/pem" "encoding/pem"
"fmt" "fmt"
"github.com/asmogo/nws/protocol"
"github.com/nbd-wtf/go-nostr"
"github.com/nbd-wtf/go-nostr/nip04"
"log/slog" "log/slog"
"math/big" "math/big"
"net/http" "net/http"
@ -19,14 +16,18 @@ import (
"net/url" "net/url"
"os" "os"
"time" "time"
"github.com/asmogo/nws/protocol"
"github.com/nbd-wtf/go-nostr"
"github.com/nbd-wtf/go-nostr/nip04"
) )
func (e *Exit) StartReverseProxy(httpTarget string, port int32) error { func (e *Exit) StartReverseProxy(httpTarget string, port int32) error {
ctx := context.Background() ctx := context.Background()
ev := e.pool.QuerySingle(ctx, e.config.NostrRelays, nostr.Filter{ ev := e.pool.QuerySingle(ctx, e.config.NostrRelays, nostr.Filter{
Authors: []string{e.publicKey}, Authors: []string{e.publicKey},
Kinds: []int{nostr.KindTextNote}, Kinds: []int{protocol.KindCertificateEvent},
Tags: nostr.TagMap{"p": []string{e.nprofile}}, Tags: nostr.TagMap{"p": []string{e.publicKey}},
}) })
var cert tls.Certificate var cert tls.Certificate
if ev == nil { if ev == nil {
@ -40,8 +41,8 @@ func (e *Exit) StartReverseProxy(httpTarget string, port int32) error {
// load private key from file // load private key from file
privateKeyEvent := e.pool.QuerySingle(ctx, e.config.NostrRelays, nostr.Filter{ privateKeyEvent := e.pool.QuerySingle(ctx, e.config.NostrRelays, nostr.Filter{
Authors: []string{e.publicKey}, Authors: []string{e.publicKey},
Kinds: []int{nostr.KindEncryptedDirectMessage}, Kinds: []int{protocol.KindPrivateKeyEvent},
Tags: nostr.TagMap{"p": []string{e.nprofile}}, Tags: nostr.TagMap{"p": []string{e.publicKey}},
}) })
if privateKeyEvent == nil { if privateKeyEvent == nil {
return fmt.Errorf("failed to find encrypted direct message") return fmt.Errorf("failed to find encrypted direct message")
@ -125,7 +126,7 @@ func (e *Exit) createAndStoreCertificateData(ctx context.Context) (*tls.Certific
certPEM := pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: certBytes}) certPEM := pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: certBytes})
keyPEM := pem.EncodeToMemory(&pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(priv)}) keyPEM := pem.EncodeToMemory(&pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(priv)})
// save key pem to file // save key pem to file
err := os.WriteFile(fmt.Sprintf("%s.key", e.nprofile), keyPEM, 0644) err := os.WriteFile(fmt.Sprintf("%s.key", e.publicKey), keyPEM, 0644)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -146,8 +147,8 @@ func (e *Exit) storePrivateKey(ctx context.Context, keyPEM []byte) error {
if err != nil { if err != nil {
return err return err
} }
event, err := s.CreateSignedEvent(e.publicKey, nostr.KindEncryptedDirectMessage, nostr.Tags{ event, err := s.CreateSignedEvent(e.publicKey, protocol.KindPrivateKeyEvent, nostr.Tags{
nostr.Tag{"p", e.nprofile}, nostr.Tag{"p", e.publicKey},
}, protocol.WithData(keyPEM)) }, protocol.WithData(keyPEM))
if err != nil { if err != nil {
return err return err
@ -169,10 +170,10 @@ func (e *Exit) storeCertificate(ctx context.Context, certPEM []byte) (*tls.Certi
event := nostr.Event{ event := nostr.Event{
CreatedAt: nostr.Now(), CreatedAt: nostr.Now(),
PubKey: e.publicKey, PubKey: e.publicKey,
Kind: nostr.KindTextNote, Kind: protocol.KindCertificateEvent,
Content: string(certPEM), Content: string(certPEM),
Tags: nostr.Tags{ Tags: nostr.Tags{
nostr.Tag{"p", e.nprofile}, nostr.Tag{"p", e.publicKey},
}, },
} }
err := event.Sign(e.config.NostrPrivateKey) err := event.Sign(e.config.NostrPrivateKey)

View File

@ -6,6 +6,7 @@ import (
"strconv" "strconv"
"time" "time"
"github.com/asmogo/nws/protocol"
"github.com/nbd-wtf/go-nostr" "github.com/nbd-wtf/go-nostr"
) )
@ -18,9 +19,8 @@ func (e *Exit) announceExitNode(ctx context.Context) error {
event := nostr.Event{ event := nostr.Event{
PubKey: e.publicKey, PubKey: e.publicKey,
CreatedAt: nostr.Now(), CreatedAt: nostr.Now(),
Kind: nostr.KindTextNote, Kind: protocol.KindAnnouncementEvent,
Tags: nostr.Tags{ Tags: nostr.Tags{
nostr.Tag{"n", "nws"},
nostr.Tag{"expiration", strconv.FormatInt(time.Now().Add(time.Second*10).Unix(), 20)}, nostr.Tag{"expiration", strconv.FormatInt(time.Now().Add(time.Second*10).Unix(), 20)},
}, },
} }

View File

@ -3,10 +3,12 @@ package netstr
import ( import (
"context" "context"
"fmt" "fmt"
"github.com/nbd-wtf/go-nostr"
"net" "net"
"strings" "strings"
"time" "time"
"github.com/asmogo/nws/protocol"
"github.com/nbd-wtf/go-nostr"
) )
// NostrDNS does not resolve anything // NostrDNS does not resolve anything
@ -36,9 +38,8 @@ func (d NostrDNS) Resolve(ctx context.Context, name string) (context.Context, ne
} }
since := nostr.Timestamp(time.Now().Add(-time.Second * 10).Unix()) since := nostr.Timestamp(time.Now().Add(-time.Second * 10).Unix())
ev := d.pool.QuerySingle(ctx, d.nostrRelays, nostr.Filter{ ev := d.pool.QuerySingle(ctx, d.nostrRelays, nostr.Filter{
Kinds: []int{nostr.KindTextNote}, Kinds: []int{protocol.KindAnnouncementEvent},
Since: &since, Since: &since,
Tags: nostr.TagMap{"n": []string{"nws"}},
}) })
if ev == nil { if ev == nil {
return ctx, nil, fmt.Errorf("failed to find exit node event") return ctx, nil, fmt.Errorf("failed to find exit node event")

View File

@ -9,7 +9,16 @@ import (
) )
// KindEphemeralEvent represents the unique identifier for ephemeral events. // KindEphemeralEvent represents the unique identifier for ephemeral events.
const KindEphemeralEvent int = 38333 const KindEphemeralEvent int = 28333
// KindAnnouncementEvent represents the unique identifier for announcement events.
const KindAnnouncementEvent int = 38333
// KindCertificateEvent represents the unique identifier for certificate events.
const KindCertificateEvent int = 38334
// KindPrivateKeyEvent represents the unique identifier for private key events.
const KindPrivateKeyEvent int = 38335
// EventSigner represents a signer that can create and sign events. // EventSigner represents a signer that can create and sign events.
// //

141
strfry/strfry.conf Normal file
View File

@ -0,0 +1,141 @@
##
## Default strfry config
##
# Directory that contains the strfry LMDB database (restart required)
db = "./strfry-db/"
dbParams {
# Maximum number of threads/processes that can simultaneously have LMDB transactions open (restart required)
maxreaders = 256
# Size of mmap() to use when loading LMDB (default is 10TB, does *not* correspond to disk-space used) (restart required)
mapsize = 10995116277760
# Disables read-ahead when accessing the LMDB mapping. Reduces IO activity when DB size is larger than RAM. (restart required)
noReadAhead = false
}
events {
# Maximum size of normalised JSON, in bytes
maxEventSize = 65536
# Events newer than this will be rejected
rejectEventsNewerThanSeconds = 900
# Events older than this will be rejected
rejectEventsOlderThanSeconds = 94608000
# Ephemeral events older than this will be rejected
rejectEphemeralEventsOlderThanSeconds = 60
# Ephemeral events will be deleted from the DB when older than this
ephemeralEventsLifetimeSeconds = 300
# Maximum number of tags allowed
maxNumTags = 2000
# Maximum size for tag values, in bytes
maxTagValSize = 1024
}
relay {
# Interface to listen on. Use 0.0.0.0 to listen on all interfaces (restart required)
bind = "0.0.0.0"
# Port to open for the nostr websocket protocol (restart required)
port = 7777
# Set OS-limit on maximum number of open files/sockets (if 0, don't attempt to set) (restart required)
nofiles = 1000000
# HTTP header that contains the client's real IP, before reverse proxying (ie x-real-ip) (MUST be all lower-case)
realIpHeader = ""
info {
# NIP-11: Name of this server. Short/descriptive (< 30 characters)
name = "strfry default"
# NIP-11: Detailed information about relay, free-form
description = "This is a strfry instance."
# NIP-11: Administrative nostr pubkey, for contact purposes
pubkey = ""
# NIP-11: Alternative administrative contact (email, website, etc)
contact = ""
# NIP-11: URL pointing to an image to be used as an icon for the relay
icon = ""
}
# Maximum accepted incoming websocket frame size (should be larger than max event) (restart required)
maxWebsocketPayloadSize = 131072
# Websocket-level PING message frequency (should be less than any reverse proxy idle timeouts) (restart required)
autoPingSeconds = 55
# If TCP keep-alive should be enabled (detect dropped connections to upstream reverse proxy)
enableTcpKeepalive = false
# How much uninterrupted CPU time a REQ query should get during its DB scan
queryTimesliceBudgetMicroseconds = 10000
# Maximum records that can be returned per filter
maxFilterLimit = 500
# Maximum number of subscriptions (concurrent REQs) a connection can have open at any time
maxSubsPerConnection = 20
writePolicy {
# If non-empty, path to an executable script that implements the writePolicy plugin logic
plugin = ""
}
compression {
# Use permessage-deflate compression if supported by client. Reduces bandwidth, but slight increase in CPU (restart required)
enabled = true
# Maintain a sliding window buffer for each connection. Improves compression, but uses more memory (restart required)
slidingWindow = true
}
logging {
# Dump all incoming messages
dumpInAll = false
# Dump all incoming EVENT messages
dumpInEvents = false
# Dump all incoming REQ/CLOSE messages
dumpInReqs = false
# Log performance metrics for initial REQ database scans
dbScanPerf = false
# Log reason for invalid event rejection? Can be disabled to silence excessive logging
invalidEvents = true
}
numThreads {
# Ingester threads: route incoming requests, validate events/sigs (restart required)
ingester = 3
# reqWorker threads: Handle initial DB scan for events (restart required)
reqWorker = 3
# reqMonitor threads: Handle filtering of new events (restart required)
reqMonitor = 3
# negentropy threads: Handle negentropy protocol messages (restart required)
negentropy = 2
}
negentropy {
# Support negentropy protocol messages
enabled = true
# Maximum records that sync will process before returning an error
maxSyncEvents = 1000000
}
}