Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

github.com/hindungwang/socks5

Package Overview
Dependencies
Alerts
File Explorer
Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

github.com/hindungwang/socks5

  • v0.0.0-20220809151053-c494c1de65f0
  • Source
  • Go
  • Socket score

Version published
Created
Source

socks5

This is a Golang implementation of the Socks5 protocol library.
To see in this SOCKS Protocol Version 5.
This library is also compatible with Socks4 and Socks4a.

Contents

Features

  • socks5:
    • command: CONNECT, UDP ASSOCIATE, BIND.
    • auth methods:
      • Username/Password authentication.
      • No Authentication Required.
  • socks4:
    • command: CONNECT, BIND.
    • auth: (no support).
  • sock4a: same as socks4.
  • Custom client and server authenticator.
  • Easy to read source code.
  • Similar to the Golang standard library experience.

Installation

$ go get "github.com/haochen233/socks5"`

Examples

Server example

simple (no authentication):

package main

import (
	"log"
	"github.com/haochen233/socks5"
)

func main() {
	// create socks server.
	srv := &socks5.Server{
		// socks server listen address.
		Addr: "127.0.0.1:1080",
		// UDP assocaite and bind command listen ip.
		// Don't need port, the port will automatically chosen.
		BindIP: "127.0.0.1",
		// if nil server will provide no authentication required method.
		Authenticators: nil,
	}

	// start listen
	err := srv.ListenAndServe()
	if err != nil {
		log.Fatal(err)
	}
}


username/password authentication in memory:

package main

import (
	"crypto/md5"
	"log"

	"github.com/haochen233/socks5"
)

func main() {
	// create a username/password store in memory.
	var userStorage socks5.UserPwdStore = socks5.NewMemeryStore(md5.New(), "secret")
	// set a pair of username/password.
	userStorage.Set("admin", "123456")

	srv := &socks5.Server{
		Addr:   "127.0.0.1:1080",
		BindIP: "127.0.0.1",
		// enable username/password method and authenticator.
		Authenticators: map[socks5.METHOD]socks5.Authenticator{
			socks5.USERNAME_PASSWORD: socks5.UserPwdAuth{UserPwdStore: userStorage},
			// There is already an authentication method.
			// If want enable no authentication required method.
			// you should enable it explicit.
			socks5.NO_AUTHENTICATION_REQUIRED: socks5.NoAuth{},
		},
	}

	err := srv.ListenAndServe()
	if err != nil {
		log.Fatal(err)
	}
}

custom transporter to transmit data between client and remote.

package main

import (
	"log"
	"net"

	"github.com/haochen233/socks5"
)

// simulate to impl socks5.Transporter interface.
// transport encrypted data.
type cryptTransport struct {
}

func (c *cryptTransport) TransportTCP(client *net.TCPConn, remote *net.TCPConn) <-chan error {
	//encrypt data and send to remote
	//decrypt data and send to client
	return nil
}

func (c *cryptTransport) TransportUDP(server *socks5.UDPConn, request *socks5.Request) error {
	panic("implement me")
	return nil
}

func main() {
	server := &socks5.Server{
		Addr:   "127.0.0.1:1080",
		BindIP: "127.0.0.1",
		// replace default Transporter interface
		Transporter: &cryptTransport{},
	}

	err := server.ListenAndServe()
	if err != nil {
		log.Fatal(err)
	}
}

Client example

CONNECT usage:

package main

import (
	"log"

	"github.com/haochen233/socks5"
)

func main() {
	// create socks client
	clnt := socks5.Client{
		ProxyAddr: "127.0.0.1:1080",
		// Authenticator supported by the client.
		// It must not be nil.
		Auth: map[socks5.METHOD]socks5.Authenticator{
			// If client want send NO_AUTHENTICATION_REQUIRED method to server, must
			// add socks5.NoAuth authenticator explicitly
			socks5.NO_AUTHENTICATION_REQUIRED: &socks5.NoAuth{},
		},
	}

	// client send CONNECT command and get a tcp connection.
	// and use this connection transit data between you and www.google.com:80.
	conn, err := clnt.Connect(socks5.Version5, "www.baidu.com:80")
	if err != nil {
		log.Fatal(err)
	}

	// close connection.
	conn.Close()
}

UDP_ASSOCIATE usage:

package main

import (
	"fmt"
	"log"

	"github.com/haochen233/socks5"
)

func main() {
	clnt := socks5.Client{
		ProxyAddr: "127.0.0.1:1080",
		// client provide USERNAME_PASSWORD method and 
		// NO_AUTHENTICATION_REQUIRED.
		Auth: map[socks5.METHOD]socks5.Authenticator{
			socks5.NO_AUTHENTICATION_REQUIRED: &socks5.NoAuth{},
			socks5.USERNAME_PASSWORD:          &socks5.UserPasswd{Username: "admin", Password: "123456"},
		},
	}

	// client send UDP_ASSOCIATE command and get a udp connection.
	// Empty local addr string a local address (127.0.0.1:port) is automatically chosen.
	// you can specific a address to tell socks server which client address will
	// send udp data. Such as clnt.UDPForward("127.0.0.1:9999").
	conn, err := clnt.UDPForward("")
	if err != nil {
		log.Fatal(err)
	}
	defer conn.Close()

	// send every datagram should add UDP request header.
	someData := []byte("some data")
	// dest addr where are you send to.
	destAddr, _ := socks5.ParseAddress("127.0.0.1:9190")
	// packing socks5 UDP data with dest addr.
	pakcedData, err := socks5.PackUDPData(destAddr, someData)
	// final send you data
	conn.Write(pakcedData)

	// on the contrary.
	// you should unpacked the packet, after received  every packedData.
	buf := make([]byte, 65507)
	conn.Read(buf)

	// unpacking data.
	destAddr, unpackedData, err := socks5.UnpackUDPData(buf)
	// operate your udp data. 
	fmt.Println(unpackedData)
}

BIND usage:

package main

import (
	"encoding/binary"
	"github.com/haochen233/socks5"
	"log"
)

func main() {
	c := socks5.Client{
		ProxyAddr: "172.16.1.28:1080",
		Auth: map[socks5.METHOD]socks5.Authenticator{
			socks5.USERNAME_PASSWORD:          &socks5.UserPasswd{"admin", "123456"},
			socks5.NO_AUTHENTICATION_REQUIRED: &socks5.NoAuth{},
		},
	}

	// connect
	conn1, err := c.Connect(5, "127.0.0.1:9000")
	if err != nil {
		log.Fatal(err)
	}

	dest := "127.0.0.1:9001"
	// bind
	bindAddr, errors, conn2, err := c.Bind(4, dest)
	if err != nil {
		log.Fatal(err)
	}

	// An example tell dest about socks server bind address 
	// via CONNECT proxy connection.
	port := make([]byte, 2)
	binary.BigEndian.PutUint16(port, bindAddr.Port)
	conn1.Write(append(bindAddr.Addr, port...))

	// wait the second reply. if nil the dest already
	// established with socks server.
	err = <-errors
	if err != nil {
		log.Fatal(err)
		return
	}

	// bind success
	_, err = conn2.Write([]byte("hello"))
	if err != nil {
		return
		log.Fatal(err)
	}
}

FAQ:

  • Server default enable socks4. How to disable socks4 support?
    when you initialize a socks5 server, you should spefic this flag to disable explicitly.
    server := &socks5.Server{
        DisableSocks4: true,
    }
    

FAQs

Package last updated on 09 Aug 2022

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc