On this page

Forward Proxy

Client-side proxying—HTTP CONNECT establishes a TCP tunnel to the destination for HTTPS, while SOCKS5 supports arbitrary TCP and UDP traffic forwarding. PAC turns "which traffic goes through the proxy" into programmable decision logic, rather than an all-or-nothing switch.

Overview

A forward proxy is a client-side proxy—the client configures the proxy server address, and all outbound traffic passes through the proxy. The HTTP CONNECT method allows the proxy to establish an end-to-end TCP tunnel (for HTTPS), while SOCKS5 operates at a lower level—supporting arbitrary TCP traffic and UDP forwarding. PAC provides dynamic per-URL proxy decisions. Forward proxies are symmetric to reverse proxies: the former is on the client side, the latter on the server side.

HTTP CONNECT: TCP Tunnel

When a browser is configured with an HTTP proxy, HTTPS requests are not sent directly to the target server—they use the CONNECT method to establish an end-to-end TCP tunnel:

Client → Proxy:
  CONNECT example.com:443 HTTP/1.1
  Host: example.com:443
  Proxy-Authorization: Basic <base64(user:pass)>

Proxy → example.com:443: TCP 3-way handshake
Proxy → Client:
  HTTP/1.1 200 Connection Established   ← Tunnel established

Subsequent: TLS handshake between client and server occurs directly over the tunnel:
  Client ↔ Proxy ↔ Server (TCP-level forwarding, content not inspected)
  → Proxy cannot see HTTP body (it is encrypted by TLS)
  → But proxy sees the CONNECT target (SNI in TLS ClientHello is also plaintext)

Difference between CONNECT and regular GET:

GET http://example.com/index.htmlCONNECT example.com:443
Proxy RoleHTTP proxy: parses HTTP, reconstructs requestTCP tunnel: byte-stream forwarding
TLSNot required (target uses HTTP)End-to-end Client ↔ Server
Content visible to proxyYesNo (encrypted)

SOCKS5

SOCKS5 is an HTTP-independent proxy protocol, operating at the TCP layer. Rules: 3-way handshake (method negotiation, request, reply) → pure TCP forwarding.

1. Method Negotiation (Authentication):
   Client → Server:
     VER=5, NMETHODS=1, METHODS=0x00  (0x00=no auth, 0x02=user/pass)
   Server → Client:
     VER=5, METHOD=0x00

2. Request:
   Client → Server:
     VER=5, CMD, RSV=0x00, ATYP, DST.ADDR, DST.PORT
     
     CMD: 0x01=CONNECT(TCP), 0x02=BIND(reverse connect, FTP active mode), 0x03=UDP ASSOCIATE
     ATYP: 0x01=IPv4(4 bytes), 0x03=Domain name(1 byte length + name), 0x04=IPv6(16 bytes)
     DST.PORT: 2 bytes (network byte order)

   Server → Client:
     VER=5, REP, RSV=0x00, ATYP, BND.ADDR, BND.PORT

     REP: 0x00=success, 0x01=general SOCKS server failure,
          0x02=connection not allowed, 0x03=Network unreachable,
          0x04=Host unreachable, 0x05=Connection refused,
          0x06=TTL expired, 0x07=Command not supported,
          0x08=Address type not supported

3. Data Relay: Bidirectional TCP forwarding (server transparently forwards bytes between Client and Target)

DNS Resolution

SOCKS5 client sends domain names (ATYP=0x03) instead of IP addresses → SOCKS5 server is responsible for DNS resolution.

Significance: If the client's local DNS is poisoned, the SOCKS5 server can use its own DNS (e.g., 8.8.8.8), bypassing local hijacking.

UDP ASSOCIATE

SOCKS5 also supports UDP forwarding:

Client → Server: CMD=UDP ASSOCIATE, DST.ADDR=0.0.0.0, DST.PORT=0
Server → Client: REP=success, BND.ADDR=<server UDP relay IP>, BND.PORT=<port>
Subsequent: Client sends UDP datagrams to BND.ADDR:BND.PORT, prefixed with a SOCKS5 UDP header:
  [RSV 2B][FRAG 1B][ATYP 1B][DST.ADDR][DST.PORT][DATA]

PAC

PAC is a JavaScript script that the browser executes before each request, dynamically deciding whether to use a proxy based on the URL/host:

function FindProxyForURL(url, host) {
    // LAN → Direct connection
    if (isInNet(host, "192.168.0.0", "255.255.0.0")) return "DIRECT";
    if (shExpMatch(host, "*.local"))              return "DIRECT";
    // Domestic → Direct connection
    if (shExpMatch(host, "*.cn"))                 return "DIRECT";
    // Others → Proxy
    return "PROXY 127.0.0.1:7890; SOCKS5 127.0.0.1:1080; DIRECT";
}

Difference between PAC and browser proxy settings: Traditional proxy settings are static (on/off). PAC provides dynamic per-request rules. return "DIRECT" means bypassing the proxy.

References

  • RFC: 7231 (CONNECT), 1928 (SOCKS5), 1929 (SOCKS5 user/pass auth)
  • mihomo: wiki.metacubex.one (mixed port = automatic detection of HTTP + SOCKS5)
  • Tools: curl --proxy socks5h://127.0.0.1:1080 https://example.com (socks5h = proxy performs DNS resolution)

Keywords: HTTP CONNECT, SOCKS5, PAC, forward proxy, TCP tunnel, UDP ASSOCIATE