proxifier

package module
v1.7.6 Latest Latest
Warning

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

Go to latest
Published: May 19, 2024 License: GPL-3.0 Imports: 10 Imported by: 0

README

GitHub go.mod Go version GitHub Tag Static Badge

Proxifier

Reliable proxy client library for Go programs.

Features
  • TLS
  • SOCKS4
  • SOCKS5
  • HTTP (HTTP FORWARD)
  • HTTPS (HTTP TUNNEL)
  • Auth
Todo
  • SOCKS4/a support

Examples

HTTPS AUTH

HTTPS TUNNEL mechanism with authentication.

package main

import (
	"io"
	"log"
	"net"
	"time"

	"crypto/tls"

	"github.com/Z3NTL3/proxifier"
)

func main() {
	httpClient := proxifier.HTTPClient{
		TLS: true,
		Auth: proxifier.Auth{
			Username: "hello",
			Password: "world",
		},
	}

	conn, err := httpClient.PROXY("https://httpbin.org/ip", proxifier.Context{
		Resolver: net.ParseIP("117.74.65.207"),
		Port: 54417,
	}, time.Second * 10); if err != nil {
		log.Fatal(err)
	}
	defer conn.Close()

	tlsConn := tls.Client(conn, &tls.Config{
		InsecureSkipVerify: true,
	})

	if _, err = tlsConn.Write([]byte("GET /ip HTTP/1.1\r\nHost: httpbin.org\r\nConnection: close\r\n\r\n")); err != nil {
		log.Fatal(err)
	}
	
	resp, err := io.ReadAll(tlsConn)
	if err != nil {
		log.Fatal(err)
	}
	log.Println(string(resp))
}
/*
RESULT:

~\Documents\sockstests via 🐹 v1.22.2 took 7s
❯ go run .
2024/05/17 18:49:27 HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
Server: CherryPy/3.2.5
Www-Authenticate: Basic realm="Broadband Router"
Date: Fri, 17 May 2024 16:49:28 GMT
Content-Length: 32
Connection: close

{
  "origin": "117.74.65.207"
}
*/
HTTPS NO AUTH

HTTPS TUNNEL with no authentication

package main

import (
	"io"
	"log"
	"net"
	"time"

	"crypto/tls"

	"github.com/Z3NTL3/proxifier"
)

func main() {
	httpClient := proxifier.HTTPClient{
		TLS: true,
	}

	conn, err := httpClient.PROXY("https://httpbin.org/ip", proxifier.Context{
		Resolver: net.ParseIP("117.74.65.207"),
		Port: 54417,
	}, time.Second * 10); if err != nil {
		log.Fatal(err)
	}
	defer conn.Close()

	tlsConn := tls.Client(conn, &tls.Config{
		InsecureSkipVerify: true,
	})

	if _, err = tlsConn.Write([]byte("GET /ip HTTP/1.1\r\nHost: httpbin.org\r\nConnection: close\r\n\r\n")); err != nil {
		log.Fatal(err)
	}
	
	resp, err := io.ReadAll(tlsConn)
	if err != nil {
		log.Fatal(err)
	}
	log.Println(string(resp))
}
/*
RESULT:

~\Documents\sockstests via 🐹 v1.22.2 took 7s
❯ go run .
2024/05/17 18:49:27 HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
Server: CherryPy/3.2.5
Www-Authenticate: Basic realm="Broadband Router"
Date: Fri, 17 May 2024 16:49:28 GMT
Content-Length: 32
Connection: close

{
  "origin": "117.74.65.207"
}
*/
HTTP NO AUTH

HTTP FORWARD with no authentication.

package main

import (
	"io"
	"log"
	"net"
	"time"

	"github.com/Z3NTL3/proxifier"
)

func main() {
	httpClient := proxifier.HTTPClient{}

	conn, err := httpClient.PROXY("https://httpbin.org/ip", proxifier.Context{
		Resolver: net.ParseIP("85.209.2.126"),
		Port:     4444,
	}, time.Second*10)
	if err != nil {
		log.Fatal(err)
	}
	defer conn.Close()

	resp, err := io.ReadAll(conn)
	if err != nil {
		log.Fatal(err)

	}

	log.Println(string(resp))
}
/*
RESULT:

~\Documents\sockstests via 🐹 v1.22.2 took 3s
❯ go run .
2024/05/17 18:35:41 HTTP/1.1 200 OK
Server: nginx/1.14.0 (Ubuntu)
Date: Fri, 17 May 2024 16:35:41 GMT
Content-Type: application/json
Content-Length: 31
Connection: close
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true

{
  "origin": "85.209.2.126"
}
*/
HTTP AUTH

HTTP FORWARD with authentication

package main

import (
	"io"
	"log"
	"net"
	"time"

	"github.com/Z3NTL3/proxifier"
)

func main() {
	httpClient := proxifier.HTTPClient{
		Auth: proxifier.Auth{
			Username: "hello",
			Password: "world",
		},
	}

	conn, err := httpClient.PROXY("https://httpbin.org/ip", proxifier.Context{
		Resolver: net.ParseIP("85.209.2.126"),
		Port:     4444,
	}, time.Second*10)
	if err != nil {
		log.Fatal(err)
	}
	defer conn.Close()

	resp, err := io.ReadAll(conn)
	if err != nil {
		log.Fatal(err)

	}

	log.Println(string(resp))
}
/*
RESULT:

~\Documents\sockstests via 🐹 v1.22.2 took 3s
❯ go run .
2024/05/17 18:35:41 HTTP/1.1 200 OK
Server: nginx/1.14.0 (Ubuntu)
Date: Fri, 17 May 2024 16:35:41 GMT
Content-Type: application/json
Content-Length: 31
Connection: close
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true

{
  "origin": "85.209.2.126"
}
*/
SOCKS5 NO AUTH

With no authentication

package main

import (
	"io"
	"log"
	"net"
	"time"

	"context"
	"crypto/tls"

	"github.com/Z3NTL3/proxifier"
)

func main() {
	addr, err := proxifier.LookupHost("httpbin.org")
	if err != nil {
		log.Fatal(err)
	}

	target := proxifier.Context{
		Resolver: net.ParseIP(addr[0]),
		Port:     443,
	}

	proxy := proxifier.Context{
		Resolver: net.ParseIP("38.154.227.167"),
		Port:     5868,
	}

	client, err := proxifier.New(&proxifier.Socks5Client{},target, proxy)
	if err != nil {
		log.Fatal(err)
	}

	ctx, cancel := context.WithTimeout(context.Background(), time.Second*15)
	defer cancel()
	
	if err := proxifier.Connect(client, ctx); err != nil {
		log.Fatal(err)
	}

	defer client.Close()
	client.SetLinger(0)


	tlsConn := tls.Client(client, &tls.Config{
		InsecureSkipVerify: true,
	})

	if _, err := tlsConn.Write([]byte("GET /ip HTTP/1.1\r\nHost: httpbin.org\r\nConnection: close\r\n\r\n")); err != nil {
		log.Fatal(err)
	}

	data, err := io.ReadAll(tlsConn)
	if err != nil {
		log.Fatal(err)
	}

	log.Println(string(data))
}
/*
RESULT:

~\Documents\sockstests via 🐹 v1.22.2 
❯ go run .
2024/05/17 18:44:03 HTTP/1.1 200 OK
Date: Fri, 17 May 2024 16:44:03 GMT
Content-Type: application/json
Content-Length: 33
Connection: close
Server: gunicorn/19.9.0
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true

{
  "origin": "38.154.227.167"
}
*/
SOCKS4
package main

import (
	"context"
	"crypto/tls"
	"io"
	"log"
	"net"
	"time"

	"github.com/Z3NTL3/proxifier"
)

func main() {
	addr, err := proxifier.LookupHost("httpbin.org")
	if err != nil {
		log.Fatal(err)
	}

	target := proxifier.Context{
		Resolver: net.ParseIP(addr[0]),
		Port:     443,
	}

	proxy := proxifier.Context{
		Resolver: net.ParseIP("174.64.199.82"),
		Port:     4145,
	}

	client, err := proxifier.New(&proxifier.Socks4Client{},target, proxy)
	if err != nil {
		log.Fatal(err)
	}

	ctx, cancel := context.WithTimeout(context.Background(), time.Second*15)
	defer cancel()
	
	if err := proxifier.Connect(client, ctx); err != nil {
		log.Fatal(err)
	}

	defer client.Close()
	client.SetLinger(0)

	tlsConn := tls.Client(client, &tls.Config{
		InsecureSkipVerify: true,
	})

	if _, err := tlsConn.Write([]byte("GET /ip HTTP/1.1\r\nHost: httpbin.org\r\nConnection: close\r\n\r\n")); err != nil {
		log.Fatal(err)
	}

	data, err := io.ReadAll(tlsConn)
	if err != nil {
		log.Fatal(err)
	}

	log.Println(string(data))
}
/*
RESULT:

~\Documents\sockstests via 🐹 v1.22.2 took 6s
❯ go run .
2024/05/17 18:54:00 HTTP/1.1 200 OK
Date: Fri, 17 May 2024 16:54:00 GMT
Content-Type: application/json
Content-Length: 32
Connection: close
Server: gunicorn/19.9.0
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true

{
  "origin": "174.64.199.82"
}
*/
SOCKS5 AUTH

With authentication.

package main

import (
	"context"
	"crypto/tls"
	"io"
	"log"
	"net"
	"time"

	"github.com/Z3NTL3/proxifier"
)

func main() {
	addr, err := proxifier.LookupHost("httpbin.org")
	if err != nil {
		log.Fatal(err)
	}

	target := proxifier.Context{
		Resolver: net.ParseIP(addr[0]),
		Port:     443,
	}

	proxy := proxifier.Context{
		Resolver: net.ParseIP("38.154.227.167"),
		Port:     5868,
	}

	client, err := proxifier.New(&proxifier.Socks5Client{},target, proxy)
	if err != nil {
		log.Fatal(err)
	}
	
	{
		client.Auth.Username = "lqafmzlx"
		client.Auth.Password = "i9mzzjv4qdz2"
	}

	ctx, cancel := context.WithTimeout(context.Background(), time.Second*15)
	defer cancel()
	
	if err := proxifier.Connect(client, ctx); err != nil {
		log.Fatal(err)
	}

	defer client.Close()
	client.SetLinger(0)

	tlsConn := tls.Client(client, &tls.Config{
		InsecureSkipVerify: true,
	})

	if _, err := tlsConn.Write([]byte("GET /ip HTTP/1.1\r\nHost: httpbin.org\r\nConnection: close\r\n\r\n")); err != nil {
		log.Fatal(err)
	}

	data, err := io.ReadAll(tlsConn)
	if err != nil {
		log.Fatal(err)
	}

	log.Println(string(data))
}
/*
RESULT:

~\Documents\sockstests via 🐹 v1.22.2 
❯ go run .
2024/05/17 18:37:49 HTTP/1.1 200 OK
Date: Fri, 17 May 2024 16:37:49 GMT
Content-Type: application/json
Content-Length: 33
Connection: close
Server: gunicorn/19.9.0
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true

{
  "origin": "38.154.227.167"
}
*/

Documentation

Index

Constants

View Source
const (
	CMD  Command = 0x01 // stream connection
	NULL byte    = 0x00 // null byte
)
View Source
const (
	SOCKS4 byte = 0x04
)
View Source
const (
	SOCKS5 byte = 0x05
)

Variables

View Source
var (
	// Err: not an ipv4 address
	ErrNotIPV4 error = errors.New("not ipv4 address")
	// Err: not one of IPV4 or IPV6
	ErrInvalidIPAddr error = errors.New("not one of IPV4 or IPV6")
	// Err: failed writing header packet(s)
	ErrHeaderWrite error = errors.New("failed writing header packet(s)")
	// Err: authentication failed
	ErrAuthFailed error = errors.New("authentication failed")
	// Err: ATYP not supported
	ErrATYP error = errors.New("ATYP not supported")
	// Err: domain name not resolveable
	ErrDomain error = errors.New("domain name not resolveable")
	// Err: not a HTTPS proxy
	ErrNotHTTPSProxy error = errors.New("not a HTTPS proxy")

	// Err: to big can be max of 255 in length
	ErrToBigMax255 error = errors.New("to big can be max of 255 in length")
)
View Source
var DefaultTimeout_Host time.Duration = time.Second * 5

Default timeout for LookupHost. Can be changed if desired

View Source
var (
	UID_NULL []byte = []byte{NULL} // for convenience

)

Functions

func Connect

func Connect[T SocksClient](client T, ctx context.Context) error

Tunnels through proxy to target. On failure returns error.

“ctx“ is a context.Context used for timeout/cancellation signal.

func IsAccepted

func IsAccepted(inputs ...any) bool

Reports whether one of IPV4/6 or host.

func IsIP

func IsIP(inputs ...net.IP) bool

Reports whether “inputs“ contain any valid IPV4/6 address.

func IsIPV4

func IsIPV4(inputs ...net.IP) bool

Reports whether “inputs“ contain any invalid IPV4 address

func IsIPV6

func IsIPV6(inputs ...net.IP) bool

Reports whether “inputs“ contain any invalid IPV6 address.

func LookupHost

func LookupHost(input string) (addr []string, err error)

Resolves domain. Used for input validation

func Max255

func Max255(inputs ...string) bool

Reports whether one of inputs exceed max length of 255

func New

func New[T SocksClient](client T, target, proxy Context) (T, error)

Creates new SocksClient.

“target“ and “proxy“ comfort Context

On failure, returns error.

func ValidateDomain added in v1.7.5

func ValidateDomain(input string) bool

Wrapper for LookupHost. With additional validation.

Types

type Auth

type Auth struct {
	Username string // Username
	Password string // Password
}

Authentication credentials

type Client

type Client struct {
	*net.TCPConn // underyling tcp connection
	// contains filtered or unexported fields
}

Core proxy client

type Command

type Command = byte

TCP/IP stream

type Conn

type Conn = net.Conn

type Context

type Context struct {
	Resolver interface{}
	Port     int
}

Detail about the network to handshake

type HTTPClient

type HTTPClient struct {
	Auth      // Authentication
	TLS  bool // TLS
}

Client for both HTTP and HTTPS proxy

Implements HTTP FORWARD and HTTP TUNNEL mechanism.

func (*HTTPClient) PROXY

func (c *HTTPClient) PROXY(url string, proxy Context, timeout time.Duration) (conn Conn, err error)

Doc

Tunnels through given proxy, for HTTPS you should set proxifier.HTTPClient to true, which will perform HTTPS proxy (HTTP TUNNEL) rather than HTTP proxy (HTTP FORWARD). Defaults to false which is HTTP proxy aka HTTP proxy (HTTP FORWARD).

Only HTTP TUNNEL (HTTPS) allows arbitrary data after initial handshake.

type Socks4Client

type Socks4Client struct {
	Client        // core client
	UID    []byte // userid, defaults to null
}

SOCKS5 client

type Socks5Client

type Socks5Client struct {
	Client // core client
	Auth   // authentication context
}

SOCKS5 client

type SocksClient

type SocksClient interface {
	*Socks4Client | *Socks5Client
	// contains filtered or unexported methods
}

Proxy client which implements SOCKS4/SOCKS5

Jump to

Keyboard shortcuts

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