mirror of
https://github.com/asmogo/nws.git
synced 2025-01-18 18:11:33 +00:00
Added new MessageType for ConnectReverse.
Added PublicAddress configuration to entry node.
This commit is contained in:
parent
e261e422c1
commit
9cfbd2329d
@ -9,7 +9,7 @@ import (
|
|||||||
func main() {
|
func main() {
|
||||||
// load the configuration
|
// load the configuration
|
||||||
// from the environment
|
// from the environment
|
||||||
cfg, err := config.LoadConfig[config.ProxyConfig]()
|
cfg, err := config.LoadConfig[config.EntryConfig]()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
@ -9,8 +9,9 @@ import (
|
|||||||
"github.com/joho/godotenv"
|
"github.com/joho/godotenv"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ProxyConfig struct {
|
type EntryConfig struct {
|
||||||
NostrRelays []string `env:"NOSTR_RELAYS" envSeparator:";"`
|
NostrRelays []string `env:"NOSTR_RELAYS" envSeparator:";"`
|
||||||
|
PublicAddress string `env:"PUBLIC_ADDRESS"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type ExitConfig struct {
|
type ExitConfig struct {
|
||||||
|
@ -231,7 +231,7 @@ func (e *Exit) handleConnect(ctx context.Context, msg nostr.IncomingEvent, proto
|
|||||||
func (e *Exit) handleConnectReverse(ctx context.Context, protocolMessage *protocol.Message, isTLS bool) {
|
func (e *Exit) handleConnectReverse(ctx context.Context, protocolMessage *protocol.Message, isTLS bool) {
|
||||||
e.mutexMap.Lock(protocolMessage.Key.String())
|
e.mutexMap.Lock(protocolMessage.Key.String())
|
||||||
defer e.mutexMap.Unlock(protocolMessage.Key.String())
|
defer e.mutexMap.Unlock(protocolMessage.Key.String())
|
||||||
connection, err := net.Dial("tcp", ":1234")
|
connection, err := net.Dial("tcp", protocolMessage.Destination)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -11,13 +11,20 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type DialOptions struct {
|
||||||
|
Pool *nostr.SimplePool
|
||||||
|
PublicAddress string
|
||||||
|
ConnectionID uuid.UUID
|
||||||
|
MessageType protocol.MessageType
|
||||||
|
}
|
||||||
|
|
||||||
// DialSocks connects to a destination using the provided SimplePool and returns a Dialer function.
|
// DialSocks connects to a destination using the provided SimplePool and returns a Dialer function.
|
||||||
// It creates a new Connection using the specified context, private key, destination address, subscription flag, and connectionID.
|
// It creates a new Connection using the specified context, private key, destination address, subscription flag, and connectionID.
|
||||||
// It parses the destination address to get the public key and relays.
|
// It parses the destination address to get the public key and relays.
|
||||||
// It creates a signed event using the private key, public key, and destination address.
|
// It creates a signed event using the private key, public key, and destination address.
|
||||||
// It ensures that the relays are available in the pool and publishes the signed event to each relay.
|
// It ensures that the relays are available in the pool and publishes the signed event to each relay.
|
||||||
// Finally, it returns the Connection and nil error. If there are any errors, nil connection and the error are returned.
|
// Finally, it returns the Connection and nil error. If there are any errors, nil connection and the error are returned.
|
||||||
func DialSocks(pool *nostr.SimplePool, connectionID uuid.UUID) func(ctx context.Context, net_, addr string) (net.Conn, error) {
|
func DialSocks(options DialOptions) func(ctx context.Context, net_, addr string) (net.Conn, error) {
|
||||||
return func(ctx context.Context, net_, addr string) (net.Conn, error) {
|
return func(ctx context.Context, net_, addr string) (net.Conn, error) {
|
||||||
addr = strings.ReplaceAll(addr, ".", "")
|
addr = strings.ReplaceAll(addr, ".", "")
|
||||||
key := nostr.GeneratePrivateKey()
|
key := nostr.GeneratePrivateKey()
|
||||||
@ -25,7 +32,7 @@ func DialSocks(pool *nostr.SimplePool, connectionID uuid.UUID) func(ctx context.
|
|||||||
WithPrivateKey(key),
|
WithPrivateKey(key),
|
||||||
WithDst(addr),
|
WithDst(addr),
|
||||||
WithSub(),
|
WithSub(),
|
||||||
WithUUID(connectionID))
|
WithUUID(options.ConnectionID))
|
||||||
|
|
||||||
publicKey, relays, err := ParseDestination(addr)
|
publicKey, relays, err := ParseDestination(addr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -38,16 +45,20 @@ func DialSocks(pool *nostr.SimplePool, connectionID uuid.UUID) func(ctx context.
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
opts := []protocol.MessageOption{
|
opts := []protocol.MessageOption{
|
||||||
protocol.WithType(protocol.MessageConnectReverse),
|
protocol.WithType(options.MessageType),
|
||||||
protocol.WithUUID(connectionID),
|
protocol.WithUUID(options.ConnectionID),
|
||||||
protocol.WithDestination(addr),
|
}
|
||||||
|
if options.PublicAddress != "" {
|
||||||
|
opts = append(opts, protocol.WithDestination(options.PublicAddress))
|
||||||
|
} else {
|
||||||
|
opts = append(opts, protocol.WithDestination(addr)) // todo -- use public key instead
|
||||||
}
|
}
|
||||||
ev, err := signer.CreateSignedEvent(publicKey, protocol.KindEphemeralEvent,
|
ev, err := signer.CreateSignedEvent(publicKey, protocol.KindEphemeralEvent,
|
||||||
nostr.Tags{nostr.Tag{"p", publicKey}},
|
nostr.Tags{nostr.Tag{"p", publicKey}},
|
||||||
opts...)
|
opts...)
|
||||||
|
|
||||||
for _, relayUrl := range relays {
|
for _, relayUrl := range relays {
|
||||||
relay, err := pool.EnsureRelay(relayUrl)
|
relay, err := options.Pool.EnsureRelay(relayUrl)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
slog.Error("error creating relay", err)
|
slog.Error("error creating relay", err)
|
||||||
continue
|
continue
|
||||||
|
@ -11,14 +11,14 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type Proxy struct {
|
type Proxy struct {
|
||||||
config *config.ProxyConfig // the configuration for the gateway
|
config *config.EntryConfig // the configuration for the gateway
|
||||||
// a list of nostr relays to publish events to
|
// a list of nostr relays to publish events to
|
||||||
relays []*nostr.Relay // deprecated -- should be used for default relay configuration
|
relays []*nostr.Relay // deprecated -- should be used for default relay configuration
|
||||||
pool *nostr.SimplePool
|
pool *nostr.SimplePool
|
||||||
socksServer *socks5.Server
|
socksServer *socks5.Server
|
||||||
}
|
}
|
||||||
|
|
||||||
func New(ctx context.Context, config *config.ProxyConfig) *Proxy {
|
func New(ctx context.Context, config *config.EntryConfig) *Proxy {
|
||||||
s := &Proxy{
|
s := &Proxy{
|
||||||
config: config,
|
config: config,
|
||||||
pool: nostr.NewSimplePool(ctx),
|
pool: nostr.NewSimplePool(ctx),
|
||||||
@ -32,7 +32,7 @@ func New(ctx context.Context, config *config.ProxyConfig) *Proxy {
|
|||||||
BindIP: net.IP{0, 0, 0, 0},
|
BindIP: net.IP{0, 0, 0, 0},
|
||||||
Logger: nil,
|
Logger: nil,
|
||||||
Dial: nil,
|
Dial: nil,
|
||||||
}, s.pool)
|
}, s.pool, config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/asmogo/nws/netstr"
|
"github.com/asmogo/nws/netstr"
|
||||||
|
"github.com/asmogo/nws/protocol"
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
"io"
|
"io"
|
||||||
"net"
|
"net"
|
||||||
@ -169,10 +170,20 @@ func (s *Server) handleConnect(ctx context.Context, conn net.Conn, req *Request)
|
|||||||
// Attempt to connect
|
// Attempt to connect
|
||||||
dial := s.config.Dial
|
dial := s.config.Dial
|
||||||
ch := make(chan net.Conn)
|
ch := make(chan net.Conn)
|
||||||
|
connectionID := uuid.New()
|
||||||
|
options := netstr.DialOptions{
|
||||||
|
Pool: s.pool,
|
||||||
|
PublicAddress: s.config.entryConfig.PublicAddress,
|
||||||
|
ConnectionID: connectionID,
|
||||||
|
}
|
||||||
if dial == nil {
|
if dial == nil {
|
||||||
connectionID := uuid.New()
|
if s.tcpListener != nil {
|
||||||
s.tcpListener.AddConnectChannel(connectionID, ch)
|
s.tcpListener.AddConnectChannel(connectionID, ch)
|
||||||
dial = netstr.DialSocks(s.pool, connectionID)
|
options.MessageType = protocol.MessageConnectReverse
|
||||||
|
} else {
|
||||||
|
options.MessageType = protocol.MessageConnect
|
||||||
|
}
|
||||||
|
dial = netstr.DialSocks(options)
|
||||||
}
|
}
|
||||||
target, err := dial(ctx, "tcp", req.realDestAddr.FQDN)
|
target, err := dial(ctx, "tcp", req.realDestAddr.FQDN)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -197,11 +208,14 @@ func (s *Server) handleConnect(ctx context.Context, conn net.Conn, req *Request)
|
|||||||
return fmt.Errorf("failed to send reply: %v", err)
|
return fmt.Errorf("failed to send reply: %v", err)
|
||||||
}
|
}
|
||||||
// read
|
// read
|
||||||
|
var connR net.Conn
|
||||||
// wait for the connection
|
if options.MessageType == protocol.MessageConnectReverse {
|
||||||
connR := <-ch
|
// wait for the connection
|
||||||
defer connR.Close()
|
connR = <-ch
|
||||||
|
defer connR.Close()
|
||||||
|
} else {
|
||||||
|
connR = target
|
||||||
|
}
|
||||||
// Start proxying
|
// Start proxying
|
||||||
errCh := make(chan error, 2)
|
errCh := make(chan error, 2)
|
||||||
go Proxy(connR, conn, errCh)
|
go Proxy(connR, conn, errCh)
|
||||||
|
@ -3,6 +3,7 @@ package socks5
|
|||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/asmogo/nws/config"
|
||||||
"github.com/nbd-wtf/go-nostr"
|
"github.com/nbd-wtf/go-nostr"
|
||||||
"log"
|
"log"
|
||||||
"net"
|
"net"
|
||||||
@ -49,6 +50,8 @@ type Config struct {
|
|||||||
|
|
||||||
// Optional function for dialing out
|
// Optional function for dialing out
|
||||||
Dial func(ctx context.Context, network, addr string) (net.Conn, error)
|
Dial func(ctx context.Context, network, addr string) (net.Conn, error)
|
||||||
|
|
||||||
|
entryConfig *config.EntryConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
var ErrorNoServerAvailable = fmt.Errorf("no socks server available")
|
var ErrorNoServerAvailable = fmt.Errorf("no socks server available")
|
||||||
@ -63,7 +66,7 @@ type Server struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// New creates a new Server and potentially returns an error
|
// New creates a new Server and potentially returns an error
|
||||||
func New(conf *Config, pool *nostr.SimplePool) (*Server, error) {
|
func New(conf *Config, pool *nostr.SimplePool, config *config.EntryConfig) (*Server, error) {
|
||||||
// Ensure we have at least one authentication method enabled
|
// Ensure we have at least one authentication method enabled
|
||||||
if len(conf.AuthMethods) == 0 {
|
if len(conf.AuthMethods) == 0 {
|
||||||
if conf.Credentials != nil {
|
if conf.Credentials != nil {
|
||||||
@ -87,15 +90,21 @@ func New(conf *Config, pool *nostr.SimplePool) (*Server, error) {
|
|||||||
if conf.Logger == nil {
|
if conf.Logger == nil {
|
||||||
conf.Logger = log.New(os.Stdout, "", log.LstdFlags)
|
conf.Logger = log.New(os.Stdout, "", log.LstdFlags)
|
||||||
}
|
}
|
||||||
listener, err := NewTCPListener()
|
if conf.entryConfig == nil {
|
||||||
if err != nil {
|
conf.entryConfig = config
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
go listener.Start()
|
|
||||||
server := &Server{
|
server := &Server{
|
||||||
config: conf,
|
config: conf,
|
||||||
pool: pool,
|
pool: pool,
|
||||||
tcpListener: listener,
|
}
|
||||||
|
if conf.entryConfig.PublicAddress != "" {
|
||||||
|
listener, err := NewTCPListener()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
go listener.Start()
|
||||||
|
server.tcpListener = listener
|
||||||
}
|
}
|
||||||
server.authMethods = make(map[uint8]Authenticator)
|
server.authMethods = make(map[uint8]Authenticator)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user