socks5

package module
v0.2.1 Latest Latest
Warning

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

Go to latest
Published: Jun 23, 2020 License: MIT Imports: 9 Imported by: 0

README

socks5

A simple socks5 server written in Go.

Features

  • CMD
      • CONNECT
      • BIND
      • ASSOCIATE
  • Identifier/Method
      • No Auth
      • GSSAPI
      • Username/Password
      • IANA Assigned
      • Reservered for Private Methods
      • No Accept : )
  • Miscellaneous
      • REASSEMBLY QUEUE / REASSEMBLY TIMER

Usage

  • New a Server
    • Addr: Server will listen this address.
      • Example: 127.0.0.1:1080
    • Opts: Server options.
      • AllowUDP: Server to accept ASSOCIATE CMD or not.
      • RewriteBND: See here.
      • Timeout: Control timeout of a connection.
      • ErrChan: Handle errors by yourself or just ignore them(set to nil).
  • (*Server).Listen()
  • Keep (*Server).Accept(), and handle every non-nil *Request:
    • By default, you need to implement an interface which could be converted to net.Conn.
    • If you'd like to handle ASSOCIATE (UDP relying) requests, you need to implement an interface which could be converted to net.PacketConn.
    • Use (*Request).Success() or (*Request).Fail() to handle a *Request.

Example

This is a very simple example which uses default net.Conn and net.PacketConn to handle *Request.

Code
package main

import (
	"log"
	"net"
	"strconv"
	"time"

	"github.com/capric98/socks5"
	"github.com/capric98/socks5/auth"
)

func main() {
	errs := make(chan error)
	srv := socks5.NewServer("127.0.0.1:1080", &socks5.SOpts{
		AllowUDP:   true,
		RewriteBND: net.IPv4(127, 0, 0, 1),
		Timeout:    10 * time.Second,
		ErrChan:    errs,
	})

	// You could also implement your own Authenticator interface.
	srv.SetAuth(auth.NewNoAuth())
	// Do not set NoAuth to force User&Pass auth.
	srv.SetAuth(auth.NewUaP())
	// You could add or delete user at any time, but
	// be careful to set UAP first, or else you will
	// get panic.
	srv.GetAuth(socks5.UAP).(*auth.Uap).Add("Alice", "alice_password")
	if e := srv.Listen(); e != nil {
		log.Fatal(e)
	}

	go func() {
		for e := range errs {
			// handle errors blabla...
			log.Println(e)
		}
	}()

	var DST string
	for {
		if req := srv.Accept(); req != nil {
			go func(req *socks5.Request) {
				DST = req.DST()
				switch req.CMD() {
				case socks5.CONNECT:
					now := time.Now()
					conn, err := net.DialTimeout("tcp", DST+":"+strconv.Itoa(req.DSTPort()), 30*time.Second)
					log.Println("Dial to", DST+":"+strconv.Itoa(req.DSTPort()), "in", time.Since(now).String())
					if err != nil {
						req.Fail(err)
					} else {
						req.Success(conn)
					}
				case socks5.ASSOCIATE:
					pl, e := net.ListenPacket("udp", ":")
					if e != nil {
						req.Fail(e)
					} else {
						req.Success(pl)
					}
				}
			}(req)
		}
	}
}
LESS IS MORE

Documentation

Overview

Package socks5 provides a convenient way to implement a socks5 server with flexible backends.

Index

Constants

View Source
const (
	NOAUTH byte = iota
	GSSAPI
	UAP
)

Method

View Source
const (
	CONNECT byte
	BIND
	ASSOCIATE
)

CMD

View Source
const (
	IPV4T byte

	DOMAIN
	IPV6T
)

Address Type

View Source
const (
	SUCC     byte = iota
	FAIL          // general SOCKS server failure
	FORBID        // connection not allowed by ruleset
	NUNREACH      // Network unreachable
	HUNREACH      // Host unreachable
	REFUSE        // Connection refused
	EXPIRE        // TTL expired
	NSUPPORT      // Command not supported
	ANSUP         // Address type not supported

	NOACCEPT byte = 255
)

Replies

View Source
const RSV byte = 0

RSV Reserved

View Source
const VERSION = 5

VERSION -> socks5

Variables

This section is empty.

Functions

This section is empty.

Types

type Request

type Request struct {
	// contains filtered or unexported fields
}

Request illustrate a valid socks5 request.

func (*Request) CMD

func (req *Request) CMD() byte

CMD returns a byte which represents CMD type.

func (*Request) DST added in v0.2.0

func (req *Request) DST() string

DST returns a string which represents destination.

func (*Request) DSTPort added in v0.2.0

func (req *Request) DSTPort() int

DSTPort returns destination port.

func (*Request) Fail

func (req *Request) Fail(e error)

Fail denies the Request with a given error, the server will write a response of NormalFail message to the client, then close the connection.

func (*Request) Success

func (req *Request) Success(i interface{})

Success approves the Request with an interface, the interface MUST be able to be converted to a net.Conn(CONNECT) or a net.PacketConn(ASSOCIATE).

type SOpts added in v0.2.0

type SOpts struct {
	// AllowUDP determines whether the server will accept
	// ASSOCIATE CMD or not.
	AllowUDP bool
	// RewriteBND is only available when AllowUDP is true,
	// and the server is behind a NAT network, with all
	// its UDP ports forwarded, and serving ASSOCIATE CMD
	// from clients who are not in the same intranet as the
	// server.
	// In this situation, you will want to rewrite BND.ADDR
	// in server's reply message in order to make clients
	// able to send UDP packet to BND.ADDR:BND.PORT.
	//
	// There is another situation, that you do not specify
	// Addr, in this case, "net" will listen [::] by default,
	// result in ASSOCIATE response be:
	// byte: {5 0 0 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 r1 r0}
	// (Means the client should send its udp packet to ipv6
	//  address [::]:(a random port equals {r1*256+r0}))
	// Clients will consider this kind of response as invalid,
	// so you'd better appoint RewriteBND mannually to avoid this.
	RewriteBND net.IP
	// Timeout forces the client to finish tasks in a certain time.
	// For a connection, Timeout = max{Auth + Send CMD + req.Accept()},
	// and after the (*Request).Accpet(), it will be canceled for
	// this connection.
	Timeout time.Duration
	// ErrChan is the channel to get errors or info from the server.
	// Set it to nil to ignore all errors and info.
	ErrChan chan error
}

SOpts illustrates options to a server.

type Server

type Server struct {
	// contains filtered or unexported fields
}

Server represents a socks5 server.

func NewServer added in v0.2.0

func NewServer(addr string, opt *SOpts) (s *Server)

NewServer news a server with given address and options.

func (*Server) Accept

func (s *Server) Accept() (req *Request)

Accept returns a valid request. If the server is stopped, it will return nil.

func (*Server) DelAuth added in v0.2.0

func (s *Server) DelAuth(method byte)

DelAuth deletes an authenticator of given method.

func (*Server) GetAuth added in v0.2.0

func (s *Server) GetAuth(method byte) (a auth.Authenticator)

GetAuth gets an authenticator from the server of given Method. If given Method has no Authenticator, it will return nil.

func (*Server) Listen

func (s *Server) Listen() error

Listen starts a server.

func (*Server) SetAuth added in v0.2.0

func (s *Server) SetAuth(a auth.Authenticator)

SetAuth sets an authenticator to the server. It will overwrite exsited Authenticator which has the same Method.

func (*Server) Stop added in v0.2.0

func (s *Server) Stop()

Stop stops a server. Stop a server before Listen() will cause panic.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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