From 2ccb01f1f3e41e5be652ef2464dc33c2aa78e867 Mon Sep 17 00:00:00 2001 From: dd dd Date: Fri, 2 Aug 2024 00:37:01 +0200 Subject: [PATCH] publish exit node events --- exit/exit.go | 6 ++++++ exit/nostr.go | 51 +++++++++++++++++++++++++++++------------------ netstr/dns.go | 25 +++++++++++++++++++---- proxy/proxy.go | 15 ++++++-------- socks5/request.go | 28 +++++++++++++------------- 5 files changed, 79 insertions(+), 46 deletions(-) diff --git a/exit/exit.go b/exit/exit.go index 451b93f..0de3f9e 100644 --- a/exit/exit.go +++ b/exit/exit.go @@ -61,6 +61,12 @@ func NewExit(ctx context.Context, exitNodeConfig *config.ExitConfig) *Exit { // generate new private key exitNodeConfig.NostrPrivateKey = nostr.GeneratePrivateKey() 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 pubKey, err := nostr.GetPublicKey(exitNodeConfig.NostrPrivateKey) diff --git a/exit/nostr.go b/exit/nostr.go index 086f65f..0417953 100644 --- a/exit/nostr.go +++ b/exit/nostr.go @@ -3,6 +3,8 @@ package exit import ( "context" "log/slog" + "strconv" + "time" "github.com/nbd-wtf/go-nostr" ) @@ -11,26 +13,37 @@ func (e *Exit) announceExitNode(ctx context.Context) error { if !e.config.Public { return nil } - // create a event - event := nostr.Event{ - PubKey: e.publicKey, - CreatedAt: nostr.Now(), - Kind: nostr.KindTextNote, - Content: "", - Tags: nostr.Tags{nostr.Tag{"n", "nws"}}, - } - err := event.Sign(e.config.NostrPrivateKey) - if err != nil { - return err - } - // publish the event - for _, relay := range e.relays { - err = relay.Publish(ctx, event) - if err != nil { - slog.Error("could not publish event", "error", err) - // do not return here, try to publish the event to other relays + + go func() { + for { + time.Sleep(time.Second * 10) + // create update event + // create a event + + event := nostr.Event{ + PubKey: e.publicKey, + CreatedAt: nostr.Now(), + Kind: nostr.KindTextNote, + Content: "", + Tags: nostr.Tags{nostr.Tag{"n", "nws"}, nostr.Tag{"expiration", strconv.FormatInt(time.Now().Add(time.Second*10).Unix(), 20)}}, + } + + err := event.Sign(e.config.NostrPrivateKey) + if err != nil { + slog.Error("could not sign event", "error", err) + continue + } + // publish the event + for _, relay := range e.relays { + err = relay.Publish(ctx, event) + if err != nil { + slog.Error("could not publish event", "error", err) + // do not return here, try to publish the event to other relays + } + } } - } + }() + return nil } diff --git a/netstr/dns.go b/netstr/dns.go index d59d113..55b6318 100644 --- a/netstr/dns.go +++ b/netstr/dns.go @@ -6,12 +6,20 @@ import ( "github.com/nbd-wtf/go-nostr" "net" "strings" + "time" ) // NostrDNS does not resolve anything type NostrDNS struct { - Pool *nostr.SimplePool - NostrRelays []string + pool *nostr.SimplePool + nostrRelays []string +} + +func NewNostrDNS(pool *nostr.SimplePool, nostrRelays []string) *NostrDNS { + return &NostrDNS{ + pool: pool, + nostrRelays: nostrRelays, + } } func (d NostrDNS) Resolve(ctx context.Context, name string) (context.Context, net.IP, error) { @@ -23,12 +31,21 @@ func (d NostrDNS) Resolve(ctx context.Context, name string) (context.Context, ne if err != nil { return ctx, nil, err } - ev := d.Pool.QuerySingle(ctx, d.NostrRelays, nostr.Filter{ - Tags: nostr.TagMap{"n": []string{"nws"}}, + if d.pool == nil { + return ctx, nil, fmt.Errorf("pool is nil") + } + since := nostr.Timestamp(time.Now().Add(-time.Second * 10).Unix()) + ev := d.pool.QuerySingle(ctx, d.nostrRelays, nostr.Filter{ + Kinds: []int{nostr.KindTextNote}, + Since: &since, + Tags: nostr.TagMap{"n": []string{"nws"}}, }) if ev == nil { return ctx, nil, fmt.Errorf("failed to find exit node event") } + if ev.CreatedAt < since { + return ctx, nil, fmt.Errorf("exit node event is expired") + } ctx = context.WithValue(ctx, "publicKey", ev.PubKey) return ctx, addr.IP, err } diff --git a/proxy/proxy.go b/proxy/proxy.go index 2ecfa1c..68f5237 100644 --- a/proxy/proxy.go +++ b/proxy/proxy.go @@ -26,15 +26,12 @@ func New(ctx context.Context, config *config.EntryConfig) *Proxy { socksServer, err := socks5.New(&socks5.Config{ AuthMethods: nil, Credentials: nil, - Resolver: netstr.NostrDNS{ - Pool: s.pool, - NostrRelays: config.NostrRelays, - }, - Rules: nil, - Rewriter: nil, - BindIP: net.IP{0, 0, 0, 0}, - Logger: nil, - Dial: nil, + Resolver: netstr.NewNostrDNS(s.pool, config.NostrRelays), + Rules: nil, + Rewriter: nil, + BindIP: net.IP{0, 0, 0, 0}, + Logger: nil, + Dial: nil, }, s.pool, config) if err != nil { panic(err) diff --git a/socks5/request.go b/socks5/request.go index ece9574..5e8f3c9 100644 --- a/socks5/request.go +++ b/socks5/request.go @@ -34,7 +34,7 @@ const ( ) var ( - unrecognizedAddrType = fmt.Errorf("Unrecognized address type") + unrecognizedAddrType = fmt.Errorf("unrecognized address type") ) // AddressRewriter is used to rewrite a destination transparently @@ -96,7 +96,7 @@ func NewRequest(bufConn io.Reader) (*Request, error) { // Read the version byte header := []byte{0, 0, 0} if _, err := io.ReadAtLeast(bufConn, header, 3); err != nil { - return nil, fmt.Errorf("Failed to get command version: %v", err) + return nil, fmt.Errorf("failed to get command version: %w", err) } // Ensure we are compatible @@ -129,9 +129,9 @@ func (s *Server) handleRequest(req *Request, conn net.Conn) error { ctx_, addr, err := s.config.Resolver.Resolve(ctx, dest.FQDN) if err != nil { if err := SendReply(conn, hostUnreachable, nil); err != nil { - return fmt.Errorf("Failed to send reply: %v", err) + return fmt.Errorf("failed to send reply: %w", err) } - return fmt.Errorf("Failed to resolve destination '%v': %v", dest.FQDN, err) + return fmt.Errorf("failed to resolve destination '%v': %w", dest.FQDN, err) } ctx = ctx_ dest.IP = addr @@ -162,7 +162,7 @@ func (s *Server) handleRequest(req *Request, conn net.Conn) error { return s.handleAssociate(ctx, conn, req) default: if err := SendReply(conn, commandNotSupported, nil); err != nil { - return fmt.Errorf("failed to send reply: %v", err) + return fmt.Errorf("failed to send reply: %w", err) } return fmt.Errorf("unsupported command: %d", req.Command) } @@ -173,9 +173,9 @@ func (s *Server) handleConnect(ctx context.Context, conn net.Conn, req *Request, // Check if this is allowed if ctx_, ok := s.config.Rules.Allow(ctx, req); !ok { if err := SendReply(conn, ruleFailure, nil); err != nil { - return fmt.Errorf("Failed to send reply: %v", err) + return fmt.Errorf("failed to send reply: %w", err) } - return fmt.Errorf("Connect to %v blocked by rules", req.DestAddr) + return fmt.Errorf("connect to %v blocked by rules", req.DestAddr) } else { ctx = ctx_ } @@ -214,7 +214,7 @@ func (s *Server) handleConnect(ctx context.Context, conn net.Conn, req *Request, local := target.LocalAddr().(*net.TCPAddr) bind := AddrSpec{IP: local.IP, Port: local.Port} if err := SendReply(conn, successReply, &bind); err != nil { - return fmt.Errorf("failed to send reply: %v", err) + return fmt.Errorf("failed to send reply: %w", err) } // read if options.MessageType == protocol.MessageConnectReverse { @@ -244,7 +244,7 @@ func (s *Server) handleBind(ctx context.Context, conn net.Conn, req *Request) er // Check if this is allowed if ctx_, ok := s.config.Rules.Allow(ctx, req); !ok { if err := SendReply(conn, ruleFailure, nil); err != nil { - return fmt.Errorf("Failed to send reply: %v", err) + return fmt.Errorf("failed to send reply: %w", err) } return fmt.Errorf("Bind to %v blocked by rules", req.DestAddr) } else { @@ -253,7 +253,7 @@ func (s *Server) handleBind(ctx context.Context, conn net.Conn, req *Request) er // TODO: Support bind if err := SendReply(conn, commandNotSupported, nil); err != nil { - return fmt.Errorf("Failed to send reply: %v", err) + return fmt.Errorf("failed to send reply: %w", err) } return nil } @@ -263,16 +263,16 @@ func (s *Server) handleAssociate(ctx context.Context, conn net.Conn, req *Reques // Check if this is allowed if ctx_, ok := s.config.Rules.Allow(ctx, req); !ok { if err := SendReply(conn, ruleFailure, nil); err != nil { - return fmt.Errorf("Failed to send reply: %v", err) + return fmt.Errorf("failed to send reply: %w", err) } - return fmt.Errorf("Associate to %v blocked by rules", req.DestAddr) + return fmt.Errorf("associate to %v blocked by rules", req.DestAddr) } else { ctx = ctx_ } // TODO: Support associate if err := SendReply(conn, commandNotSupported, nil); err != nil { - return fmt.Errorf("Failed to send reply: %v", err) + return fmt.Errorf("failed to send reply: %w", err) } return nil } @@ -357,7 +357,7 @@ func SendReply(w io.Writer, resp uint8, addr *AddrSpec) error { addrPort = uint16(addr.Port) default: - return fmt.Errorf("Failed to format address: %v", addr) + return fmt.Errorf("failed to format address: %v", addr) } // Format the message