socks5

package module
v0.0.9 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 1, 2023 License: MIT Imports: 20 Imported by: 0

README

go-socks5

GoDoc Go.Dev reference Action Status codecov Go Report Card License Tag

Provides the socks5 package that implements a SOCKS5. SOCKS (Secure Sockets) is used to route traffic between a client and server through an intermediate proxy layer. This can be used to bypass firewalls or NATs.

Feature

The package has the following features:

  • Support socks5 server
  • Support TCP/UDP and IPv4/IPv6
  • Unit tests
  • "No Auth" mode
  • User/Password authentication optional user addr limit
  • Support for the CONNECT command
  • Support for the ASSOCIATE command
  • Rules to do granular filtering of commands
  • Custom DNS resolution
  • Custom goroutine pool
  • buffer pool design and optional custom buffer pool
  • Custom logger
TODO

The package still needs the following:

  • Support for the BIND command
Installation

Use go get.

    go get github.com/things-go/go-socks5

Then import the socks5 server package into your own code.

    import "github.com/things-go/go-socks5"
Example

Below is a simple example of usage, more see example

package main

import (
	"log"
	"os"

	"github.com/things-go/go-socks5"
)

func main() {
	// Create a SOCKS5 server
	server := socks5.NewServer(
		socks5.WithLogger(socks5.NewLogger(log.New(os.Stdout, "socks5: ", log.LstdFlags))),
	)

	// Create SOCKS5 proxy on localhost port 8000
	if err := server.ListenAndServe("tcp", ":8000"); err != nil {
		panic(err)
	}
}
Reference

License

This project is under MIT License. See the LICENSE file for the full license text.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func SendReply

func SendReply(w io.Writer, rep uint8, bindAddr net.Addr) error

SendReply is used to send a reply message rep: reply status see statute's statute file

Types

type AddressRewriter

type AddressRewriter interface {
	Rewrite(ctx context.Context, request *Request) (context.Context, *statute.AddrSpec)
}

AddressRewriter is used to rewrite a destination transparently

type AuthContext

type AuthContext struct {
	// Provided auth method
	Method uint8
	// Payload provided during negotiation.
	// Keys depend on the used auth method.
	// For UserPass auth contains username/password
	Payload map[string]string
}

AuthContext A Request encapsulates authentication state provided during negotiation

type Authenticator

type Authenticator interface {
	Authenticate(reader io.Reader, writer io.Writer, userAddr string) (*AuthContext, error)
	GetCode() uint8
}

Authenticator provide auth

type CredentialStore

type CredentialStore interface {
	Valid(user, password, userAddr string) bool
}

CredentialStore is used to support user/pass authentication optional network addr if you want to limit user network addr,you can refuse it.

type DNSResolver

type DNSResolver struct{}

DNSResolver uses the system DNS to resolve host names

func (DNSResolver) Resolve

func (d DNSResolver) Resolve(ctx context.Context, name string) (context.Context, net.IP, error)

Resolve implement interface NameResolver

type GPool

type GPool interface {
	Submit(f func()) error
}

GPool is used to implement custom goroutine pool default use goroutine

type Interceptor

type Interceptor interface {
	// OnRequest is called when a SOCKS5 request is intercepted.
	// The request parameter contains information about the intercepted request.
	// The src parameter is the connection that the request was received on.
	// The dst parameter is the connection that the request was sent on.
	// The method should return an error if the request should be rejected.
	// The method should return a non-nil byte slice if the request should be
	// modified. The byte slice will be sent to the client as the response.
	OnRequest(ctx context.Context, request []byte, src net.Conn, dst net.Conn) ([]byte, error)

	// OnResponse is called when a SOCKS5 response is intercepted.
	// The response parameter contains information about the intercepted response.
	// The src parameter is the connection that the response was sent on.
	// The dst parameter is the connection that the response was received on.
	// The method should return an error if the response should be rejected.
	// The method should return a non-nil byte slice if the response should be
	// modified. The byte slice will be sent to the client as the response.
	OnResponse(ctx context.Context, response []byte, src net.Conn, dst net.Conn) ([]byte, error)

	OnRequestEnd(ctx context.Context, src net.Conn, dst net.Conn) error
}

Interceptor is an interface that defines methods for intercepting SOCKS5 requests and responses.

type Logger

type Logger interface {
	Errorf(format string, arg ...interface{})
}

Logger is used to provide debug logger

type NameResolver

type NameResolver interface {
	Resolve(ctx context.Context, name string) (context.Context, net.IP, error)
}

NameResolver is used to implement custom name resolution

type NoAuthAuthenticator

type NoAuthAuthenticator struct{}

NoAuthAuthenticator is used to handle the "No Authentication" mode

func (NoAuthAuthenticator) Authenticate

func (a NoAuthAuthenticator) Authenticate(_ io.Reader, writer io.Writer, _ string) (*AuthContext, error)

Authenticate implement interface Authenticator

func (NoAuthAuthenticator) GetCode

func (a NoAuthAuthenticator) GetCode() uint8

GetCode implement interface Authenticator

type Option

type Option func(s *Server)

Option user's option

func WithAssociateHandle

func WithAssociateHandle(h func(ctx context.Context, writer io.Writer, request *Request) error) Option

WithAssociateHandle is used to handle a user's associate command

func WithAuthMethods

func WithAuthMethods(authMethods []Authenticator) Option

WithAuthMethods can be provided to implement custom authentication By default, "auth-less" mode is enabled. For password-based auth use UserPassAuthenticator.

func WithBindHandle

func WithBindHandle(h func(ctx context.Context, writer io.Writer, request *Request) error) Option

WithBindHandle is used to handle a user's bind command

func WithBindIP

func WithBindIP(ip net.IP) Option

WithBindIP is used for bind or udp associate

func WithBufferPool

func WithBufferPool(bufferPool bufferpool.BufPool) Option

WithBufferPool can be provided to implement custom buffer pool By default, buffer pool use size is 32k

func WithConnectHandle

func WithConnectHandle(h func(ctx context.Context, writer io.Writer, request *Request) error) Option

WithConnectHandle is used to handle a user's connect command

func WithCredential

func WithCredential(cs CredentialStore) Option

WithCredential If provided, username/password authentication is enabled, by appending a UserPassAuthenticator to AuthMethods. If not provided, and AUthMethods is nil, then "auth-less" mode is enabled.

func WithDial

func WithDial(dial func(ctx context.Context, network, addr string) (net.Conn, error)) Option

WithDial Optional function for dialing out

func WithGPool

func WithGPool(pool GPool) Option

WithGPool can be provided to do custom goroutine pool.

func WithInterceptor

func WithInterceptor(interceptor Interceptor) Option

WithInterceptor is an interface that defines methods for intercepting SOCKS5 requests and responses.

func WithLogger

func WithLogger(l Logger) Option

WithLogger can be used to provide a custom log target. Defaults to io.Discard.

func WithPrivateKey added in v0.0.9

func WithPrivateKey(key []byte) Option

func WithResolver

func WithResolver(res NameResolver) Option

WithResolver can be provided to do custom name resolution. Defaults to DNSResolver if not provided.

func WithRewriter

func WithRewriter(rew AddressRewriter) Option

WithRewriter can be used to transparently rewrite addresses. This is invoked before the RuleSet is invoked. Defaults to NoRewrite.

func WithRootCert added in v0.0.9

func WithRootCert(cert *tls.Certificate) Option

func WithRule

func WithRule(rule RuleSet) Option

WithRule is provided to enable custom logic around permitting various commands. If not provided, NewPermitAll is used.

type PermitCommand

type PermitCommand struct {
	EnableConnect   bool
	EnableBind      bool
	EnableAssociate bool
}

PermitCommand is an implementation of the RuleSet which enables filtering supported commands

func (*PermitCommand) Allow

func (p *PermitCommand) Allow(ctx context.Context, req *Request) (context.Context, bool)

Allow implement interface RuleSet

type Request

type Request struct {
	statute.Request
	// AuthContext provided during negotiation
	AuthContext *AuthContext
	// LocalAddr of the network server listen
	LocalAddr net.Addr
	// RemoteAddr of the network that sent the request
	RemoteAddr net.Addr
	// DestAddr of the actual destination (might be affected by rewrite)
	DestAddr *statute.AddrSpec
	// Reader connect of request
	Reader io.Reader
	// RawDestAddr of the desired destination
	RawDestAddr *statute.AddrSpec
}

A Request represents request received by a server

func ParseRequest

func ParseRequest(bufConn io.Reader) (*Request, error)

ParseRequest creates a new Request from the tcp connection

type RuleSet

type RuleSet interface {
	Allow(ctx context.Context, req *Request) (context.Context, bool)
}

RuleSet is used to provide custom rules to allow or prohibit actions

func NewPermitAll

func NewPermitAll() RuleSet

NewPermitAll returns a RuleSet which allows all types of connections

func NewPermitConnAndAss

func NewPermitConnAndAss() RuleSet

NewPermitConnAndAss returns a RuleSet which allows Connect and Associate connection

func NewPermitNone

func NewPermitNone() RuleSet

NewPermitNone returns a RuleSet which disallows all types of connections

type Server

type Server struct {

	// TLS certificate to use for TLS-based connections
	TLSRootCertificate *tls.Certificate
	// Private key to use for TLS-based connections
	TLSPrivateKey []byte
	// contains filtered or unexported fields
}

Server is responsible for accepting connections and handling the details of the SOCKS5 protocol

func NewServer

func NewServer(opts ...Option) *Server

NewServer creates a new Server

func (*Server) ListenAndServe

func (sf *Server) ListenAndServe(network, addr string) error

ListenAndServe is used to create a listener and serve on it

func (*Server) Proxy

func (sf *Server) Proxy(context context.Context, dst io.Writer, src io.Reader, isRequest bool) error

Proxy is used to shuffle data from src to destination, and sends errors down a dedicated channel func (sf *Server) ProxyRequest(context context.Context, io.Writer, src io.Reader) error {

func (*Server) Serve

func (sf *Server) Serve(l net.Listener) error

Serve is used to serve connections from a listener

func (*Server) ServeConn

func (sf *Server) ServeConn(conn net.Conn) error

ServeConn is used to serve a single connection.

type StaticCredentials

type StaticCredentials map[string]string

StaticCredentials enables using a map directly as a credential store

func (StaticCredentials) Valid

func (s StaticCredentials) Valid(user, password, _ string) bool

Valid implement interface CredentialStore

type Std

type Std struct {
	*log.Logger
}

Std std logger

func NewLogger

func NewLogger(l *log.Logger) *Std

NewLogger new std logger with log.logger

func (Std) Errorf

func (sf Std) Errorf(format string, args ...interface{})

Errorf implement interface Logger

type UserPassAuthenticator

type UserPassAuthenticator struct {
	Credentials CredentialStore
}

UserPassAuthenticator is used to handle username/password based authentication

func (UserPassAuthenticator) Authenticate

func (a UserPassAuthenticator) Authenticate(reader io.Reader, writer io.Writer, userAddr string) (*AuthContext, error)

Authenticate implement interface Authenticator

func (UserPassAuthenticator) GetCode

func (a UserPassAuthenticator) GetCode() uint8

GetCode implement interface Authenticator

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL