Documentation
¶
Index ¶
- Constants
- Variables
- func NewLocalProxy(serverIP string) *localProxy
- type AuthenticationMethod
- type Authenticator
- type Config
- type NoAuthenticationRequired
- type Packet
- type PacketAuthRequest
- type PacketAuthSelect
- type PacketReply
- type PacketRequest
- type PacketUDPRequest
- type PacketUserPassAuth
- type PacketUserPassAuthStatus
- type Proxy
- type Server
- type UsernamePassword
Constants ¶
const ( USERPASS_AUTH_SUCCESS byte = 0x00 USERPASS_AUTH_FAILURE byte = 0x01 )
const ( NO_AUTHENTICATION_REQUIRED byte = 0x00 GSSAPI byte = 0x01 USERNAME_PASSWORD byte = 0x02 NO_ACCEPTABLE_METHODS byte = 0xFF )
const ( REQUEST_CMD_CONNECT byte = 0x01 REQUEST_CMD_BIND byte = 0x02 REQUEST_CMD_UDP_ASSOCIATE byte = 0x03 REQUEST_ATYP_IPV4 byte = 0x01 REQUEST_ATYP_DOMAINNAME byte = 0x03 REQUEST_ATYP_IPV6 byte = 0x04 )
const ( REPLY_REP_SUCCEEDED byte = 0x00 REPLY_REP_GENERAL_SOCKS_SERVER_ERR byte = 0x01 REPLY_REP_CONNECTION_NOT_ALLOWED byte = 0x02 REPLY_REP_NETWORK_UNREACHABLE byte = 0x03 REPLY_REP_HOST_UNREACHABLE byte = 0x04 REPLY_REP_CONNECTION_REFUSED byte = 0x05 REPLY_REP_TTL_EXPIRED byte = 0x06 REPLY_REP_COMMAND_NOT_SUPPORTED byte = 0x07 REPLY_REP_ADDRESS_TYPE_NOT_SUPP byte = 0x08 REPLY_ATYP_IPV4 byte = 0x01 REPLY_ATYP_DOMAINNAME byte = 0x03 REPLY_ATYP_IPV6 byte = 0x04 )
const ( UDP_REQUEST_NOFRAG byte = 0x00 // flushing previous reassembly queue & timer UDP_REQUEST_FRAG byte = 0x01 // creating a new reassambly queue & timer UDP_REQUEST_ATYP_IPV4 byte = 0x01 UDP_REQUEST_ATYP_DOMAINNAME byte = 0x03 UDP_REQUEST_ATYP_IPV6 byte = 0x04 UDP_RSV_EXPECTED uint16 = 0x0000 )
const (
PROTOCOL_VERSION byte = 0x05
)
const (
USERPASS_AUTH_VERSION byte = 0x01
)
Variables ¶
var ( ErrConnNotAllowed = errors.New("connection not allowed by ruleset") // 0x02 ErrNetworkUnreachable = errors.New("network unreachable") // 0x03 ErrHostUnreachable = errors.New("host unreachable") // 0x04 ErrConnectionRefused = errors.New("connection refused") // 0x05 ErrTTLExpired = errors.New("ttl expired") // 0x06 ErrCommandNotSupported = errors.New("command not supported") // 0x07 ErrAddressTypeNotSupported = errors.New("address type not supported") // 0x08 )
Errors returned by a Proxy interface implementation.
Functions ¶
func NewLocalProxy ¶ added in v0.2.0
func NewLocalProxy(serverIP string) *localProxy
NewLocalProxy creates a new localProxy with the given serverIP. If the serverIP is unknown, an empty string should be passed in.
Types ¶
type AuthenticationMethod ¶
type AuthenticationMethod interface {
// Authenticate will respond to the net.Conn with the selected authentication method.
// Then, the AuthenticationMethod should proceed and finish the authentication process.
//
// If returned error is nil, the authentication process is considered successful.
// Otherwise, the authentication process is considered failed and the connection
// MUST be closed by the caller.
Authenticate(net.Conn) error
}
AuthenticationMethod is an interface that represents a custom SOCKS5 authentication method.
type Authenticator ¶
type Authenticator struct {
Forced bool // default: false, if set to true, NO_AUTHENTICATION_REQUIRED is not accepted
UserPass map[string]string
PrivateMethods map[byte]AuthenticationMethod
}
Authenticator is used to authenticate the client. It supports Username/Password method (and No Auth method) by default and allows custom authentication methods via PrivateMethods.
type Config ¶ added in v0.3.0
type Config struct {
// Auth specifies an *Authenticator to be used by the SOCKS5 server to
// authenticate incoming SOCKS5 client connections. If nil, the SOCKS5 server
// will not require authentication.
Auth *Authenticator
// LoggingHandler specifies a handler to be used by the SOCKS5 server. If nil,
// the default logging handler will be used.
//
// TODO: switch to log/slog from experimental once it became stable in Go 1.21
LoggingHandler slog.Handler
// Proxy specifies a proxy implementation to be used by the SOCKS5 server.
//
// See proxy.go for more details about the Proxy interface and the localProxy
// implementation.
Proxy Proxy
// ConnectTimeout specifies the maximum amount of time a Server will wait for
// a Connect invocation to complete on the Proxy.
//
// If zero, no timeout is set and the Server may block indefinitely.
ConnectTimeout time.Duration
// BindTimeout specifies the maximum amount of time a Server will wait for a
// Bind invocation to complete on the Proxy. It is recommended that this value
// be set to a reasonable value to prevent port exhaustion.
//
// If zero, no timeout is set and the Server may block indefinitely.
BindTimeout time.Duration
// UDPTimeout specifies the maximum amount of time a Server will wait for a
// UDP associate invocation to complete on the Proxy.
//
// If zero, no timeout is set and the Server may block indefinitely.
UDPTimeout time.Duration
}
Config details the configuration of the SOCKS5 server.
type NoAuthenticationRequired ¶
type NoAuthenticationRequired struct{}
NoAuthenticationRequired is a AuthenticationMethod that does not require any authentication. It only responds to the client with the selected authentication method and returns nil.
func (*NoAuthenticationRequired) Authenticate ¶
func (*NoAuthenticationRequired) Authenticate(conn net.Conn) error
Authenticate implements the AuthenticationMethod interface.
type Packet ¶
type Packet interface {
// Read reads the packet from the given reader into the Packet object.
//
// SHOULD ONLY be called for client-sent packets. Calling this method
// on a server-sent packet SHOULD result in an error.
Read(io.Reader) error
// Write writes the packet to the given writer.
//
// SHOULD ONLY be called for server-sent packets. Calling this method
// on a client-sent packet SHOULD result in an error.
Write(io.Writer) error
}
Packet defines the interface for all SOCKS5 packets except the UDP request. UDP request works on net.PacketConn instead of io.Reader/io.Writer.
type PacketAuthRequest ¶
PacketAuthRequest is the packet sent by the client to request to authenticate using a certain type of authentication method.
The packet is structured as follows:
+----+----------+----------+ |VER | NMETHODS | METHODS | +----+----------+----------+ | 1 | 1 | 1 to 255 | +----+----------+----------+
type PacketAuthSelect ¶
PacketAuthSelect is the packet sent by the server to indicate the selected authentication method that client should use. Sent by the server in response to PacketAuthRequest.
The packet is structured as follows:
+----+--------+ |VER | METHOD | +----+--------+ | 1 | 1 | +----+--------+
type PacketReply ¶
type PacketReply struct {
VER byte
REP byte
RSV byte // must be 0x00, fail otherwise
ATYP byte
BNDADDR string
BNDPORT uint16
}
PacketReply is the packet sent by the server in response to a client request. Sent by the server after the client has successfully requested a command.
The packet is structured as follows:
+----+-----+-------+------+----------+----------+ |VER | REP | RSV | ATYP | BND.ADDR | BND.PORT | +----+-----+-------+------+----------+----------+ | 1 | 1 | X'00' | 1 | Variable | 2 | +----+-----+-------+------+----------+----------+
type PacketRequest ¶
PacketRequest is the packet sent by the client to request a connection to a remote host. Sent by the client after the server has successfully authenticated the client.
The packet is structured as follows:
+----+-----+-------+------+----------+----------+ |VER | CMD | RSV | ATYP | DST.ADDR | DST.PORT | +----+-----+-------+------+----------+----------+ | 1 | 1 | X'00' | 1 | Variable | 2 | +----+-----+-------+------+----------+----------+
type PacketUDPRequest ¶
type PacketUDPRequest struct {
RSV uint16
FRAG byte
ATYP byte
DSTADDR string
DSTPORT uint16
DATA []byte
ClientAddr net.Addr // Proxy Server should verify this is the same as the client
}
PacketUDPRequest is the packet sent by the client to the server to request a datagram to be sent to a remote host, or sent by the server to the client in response to previous requests.
The packet is structured as follows:
+----+------+------+----------+----------+----------+ |RSV | FRAG | ATYP | DST.ADDR | DST.PORT | DATA | +----+------+------+----------+----------+----------+ | 2 | 1 | 1 | Variable | 2 | Variable | +----+------+------+----------+----------+----------+
func (*PacketUDPRequest) Read ¶
func (p *PacketUDPRequest) Read(pc net.PacketConn) error
Read reads next UDP request from the given packet connection.
func (*PacketUDPRequest) Write ¶
func (p *PacketUDPRequest) Write(pc net.PacketConn) error
Write writes the UDP request to the given packet connection.
type PacketUserPassAuth ¶
type PacketUserPassAuth struct {
VER byte
ULEN byte
UNAME string // length: ULEN
PLEN byte
PASSWD string // length: PLEN
}
PacketUserPassAuth is the packet sent by the client to authenticate with Username/Password pair. Sent by the client after the server has selected the Username/Password authentication method.
The packet is strctured as follows:
+----+------+----------+------+----------+ |VER | ULEN | UNAME | PLEN | PASSWD | +----+------+----------+------+----------+ | 1 | 1 | 1 to 255 | 1 | 1 to 255 | +----+------+----------+------+----------+
type PacketUserPassAuthStatus ¶
PacketUserPassAuthStatus is the packet sent by the server to indicate the status of the authentication. Sent by the server in response to PacketUserPassAuth.
The packet is structured as follows:
+----+--------+ |VER | STATUS | +----+--------+ | 1 | 1 | +----+--------+
type Proxy ¶
type Proxy interface {
// Connect is used to create an outgoing TCP connection from the proxy server to the
// destination specified as dst.
// The proxy implementation SHOULD use the provided context to cancel the connection attempt
// if the context expires before the connection is established.
//
// The returned net.Conn MUST be a connection to the destination, i.e. any data written to
// it will be send to the remote destination.
// Its LocalAddr() method SHOULD return the address used to connect to the destination if known,
// otherwise it MUST return 0.0.0.0 (IPv4) or ::0 (IPv6).
Connect(ctx context.Context, dst net.Addr) (conn net.Conn, err error)
// Bind requests the proxy server to listen for an incoming (TCP) connection. The proxy
// implementation SHOULD bind a TCP address and port, and listen for the FIRST incoming
// connection on to it.
// The proxy implementation SHOULD use the provided context to cancel the connection
// attempt if the context expires before the connection is established.
//
// The returned net.Listener MUST return the address the proxy server is listening on when
// its Addr() method is called. Its Accept() method MUST block until the FIRST incoming
// connection is received, and return a net.Conn representing the incoming connection, whose
// RemoteAddr() call MUST return the address of the source and LocalAddr() call is expected to
// return the address the listener is bound to, same as the one returned by Addr() of the
// net.Listener.
//
// It is up to the implementation to decide how to handle subsequent incoming connections
// on the same address and port, as well as how to handle multiple calls to Bind() with the same
// dst address specified.
Bind(ctx context.Context, dst net.Addr) (net.Listener, error)
// UDPAssociate creates a UDP socket on the proxy server. The proxy implementation SHOULD use
// the provided context to cancel the connection attempt if the context expires before the
// connection is established.
//
// Invoking the WriteTo() method on the returned net.PacketConn sends a UDP datagram to the
// remote address specified in the function call. And UDP datagrams received from the remote
// address should be accessible by invoking ReadFrom() on the returned net.PacketConn.
UDPAssociate(ctx context.Context) (net.PacketConn, error)
// Close closes the proxy server and cleans up any resources associated with it if possible.
//
// Calling Close on a proxy server does not necessarily close any connections created by it.
// However, it SHOULD prevent any new connections from being created. If
Close() error
}
Proxy is the interface for an underlying implementation of a general-purpose proxy. It is used by Server when handling received SOCKS5 requests. Generally, when any of the methods on Proxy is called, it is expected that the Proxy implementation will either dial out to a remote proxy server for the proxy request, or handle the request locally.
type Server ¶
type Server struct {
// contains filtered or unexported fields
}
Server acts like an automatic SOCKS5 server which wraps an existing net.Listener.
func NewServer ¶
NewServer creates a new Server.
Wrap or Listen must be called explicitly before the server can accept connections from SOCKS5 clients.
func (*Server) Close ¶
Close stops the Server from accepting new incoming connections from SOCKS5 clients. This function does not guarantee the termination of any established connection.
type UsernamePassword ¶
UsernamePassword is a AuthenticationMethod that requires username/password authentication.
func (*UsernamePassword) Authenticate ¶
func (up *UsernamePassword) Authenticate(conn net.Conn) error
Authenticate implements the AuthenticationMethod interface.