Skip to main content

Concepts

To understand this library to it's full extent, some simple concepts have to be understood.

Context

type Context struct {
Resolver interface{}
Port int
}

A context is a struct that shapes information about a machine. For example, to provide Proxifier with the knowledge about what proxy server to tunnel through, and the definition of a target.

Here's a sample

main.go
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))
}

Wiring TLS

To wire with TLS this line is essential

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

For HTTP(s) it is also essential to set TLS field to true of a HttpClient, you can completely ignore this detail if you're using a SocksClient.

httpClient := proxifier.HTTPClient{
+ TLS: true,
}

Authentication

proxifier.Auth

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

This is the struct you would pass on to HTTPClient's Auth field if authentication is preferred, leave it empty if you do not want to authenticate.

Socks

For SOCKS4 and SOCKS5 a different struct is introduced.

func New[T SocksClient](client T, target, proxy Context) (T, error)
type SocksClient interface {
*Socks4Client | *Socks5Client
// contains filtered or unexported methods
}

Here's a sample for a SOCKS5 TLS connection

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"
}
*/