🔥 LAUNCH SALE — up to +60% bonus traffic · Residential from $0.67/GB · code BACK15 Claim →
Log in Get proxies
PyProxy is back — buy residential, ISP, mobile & datacenter proxies directly, from $0.67/GB. Launch bonus up to +60%.
Guide · tunnel proxies

What are the common ways to set up a tunnel proxy?

A tunnel proxy forwards your connection instead of rewriting it, and in practice it means one endpoint you configure once while rotation happens behind it. Here are the four forms it takes, with the commands for each.

What “tunnel proxy” means

It is not a protocol, and nobody has standardised the term, which is why the phrase causes confusion. It is used in two overlapping ways, and both matter.

Technically, a tunnel proxy forwards a connection rather than interpreting it. An ordinary HTTP proxy reads your request, makes its own request upstream and hands you back the response. A tunnelling proxy opens a pipe to the destination and copies bytes in both directions without touching them, so anything that runs over TCP — TLS, WebSocket, a database wire protocol — passes through intact.

Commercially, a tunnel proxy is a single endpoint you configure once, behind which the provider handles the pool of exit addresses and the rotation. Your application has one hostname, one port and one set of credentials, forever; everything that changes, changes on the far side. The forms below are what people are actually setting up when they ask how to build one.

An HTTP proxy with CONNECT

This is the most common tunnel on the internet and most people use it without noticing. When a client wants HTTPS through an HTTP proxy, it cannot ask the proxy to fetch the page — the content is encrypted. Instead it asks for a tunnel:

CONNECT example.com:443 HTTP/1.1
Host: example.com:443
Proxy-Authorization: Basic dXNlcjpwYXNz

HTTP/1.1 200 Connection established

After that 200, the proxy is a dumb pipe, and the TLS handshake happens end to end between your client and the destination. curl does this automatically whenever the target is HTTPS:

curl -x http://USERNAME:PASSWORD@proxy.example.com:8080 https://httpbin.org/ip

To make the whole shell use it, export the standard variables, and keep loopback traffic out of the tunnel:

export http_proxy="http://USERNAME:PASSWORD@proxy.example.com:8080"
export https_proxy="$http_proxy"
export no_proxy="localhost,127.0.0.1,::1"

The limitation to know about: many proxies allow CONNECT only to port 443. If you need a tunnel to a database port or a WebSocket service on an unusual port, check that first, because the failure looks like a network problem rather than a policy one.

An SSH tunnel

If you have a shell account on a server, you already have a tunnel proxy. Two flags cover almost every case.

Dynamic forwarding: a local SOCKS proxy

ssh -D 1080 -N -C you@server.example.net

-D 1080 opens a SOCKS5 listener on your own machine; -N means do not run a shell, just forward; -C compresses. Point anything that speaks SOCKS at it:

curl --socks5-hostname 127.0.0.1:1080 https://httpbin.org/ip

Use --socks5-hostname, not --socks5, so that DNS is resolved at the far end rather than locally — otherwise your resolver still sees every hostname you visit.

Local forwarding: one port to one destination

ssh -N -L 8080:internal.example.com:80 you@server.example.net
curl http://127.0.0.1:8080/

Here 127.0.0.1:8080 on your machine becomes port 80 on internal.example.com as reached from the SSH server. This is the right tool for a service that is only visible inside someone's network, and for applications that cannot be told about proxies at all.

To keep either of them alive, add keepalives and let something restart the tunnel:

autossh -M 0 -f -N -D 1080 \
  -o "ServerAliveInterval 30" -o "ServerAliveCountMax 3" \
  you@server.example.net

What an SSH tunnel does not give you is variety. Every connection exits from that one server at one fixed address, which is perfect for reaching your own infrastructure and useless for anything that needs to look like many different ordinary visitors.

A backconnect gateway

A backconnect gateway is the shape most people mean when they buy a “tunnel proxy”. One hostname and one port sit in front of a pool of exit addresses. You connect to the gateway, it picks an exit, and your request leaves from there. There is no list of addresses to maintain, no health checking to write, and no configuration change when the pool changes, because the only thing your code ever knows is the gateway.

curl -x http://USERNAME-country-us:PASSWORD@gw.pyproxy.com:1111 https://httpbin.org/ip

The same line, repeated, comes out of different addresses. That is the rotation: it applies to new connections, not to connections already open, so a long-lived session stays where it started until it reconnects.

A local forwarder, for tools that cannot authenticate

Plenty of software accepts only a bare host and port for its proxy setting, with nowhere to put a username and password, and plenty more speaks SOCKS when your gateway speaks HTTP. The general fix is a small forwarder running on your own machine: it listens locally with no authentication, and adds the credentials and the protocol translation on the way out.

With gost that is one command — an HTTP listener in front of an authenticated upstream:

gost -L=http://127.0.0.1:8080 \
     -F=http://USERNAME-country-us:PASSWORD@gw.pyproxy.com:1111

Or a SOCKS5 listener in front of the same upstream, which is how you serve an application that insists on SOCKS while the provider is HTTP only:

gost -L=socks5://127.0.0.1:1080 \
     -F=http://USERNAME-country-us:PASSWORD@gw.pyproxy.com:1111

Either way the application is configured with nothing but 127.0.0.1 and a port. The same thing is achievable with 3proxy if you prefer a config file:

nserver 1.1.1.1
auth none
allow * 127.0.0.1
parent 1000 http gw.pyproxy.com 1111 USERNAME-country-us PASSWORD
proxy -p8080 -i127.0.0.1
Bind the local listener to 127.0.0.1, never to 0.0.0.0. A forwarder with no authentication that is reachable from the network is an open proxy carrying your paid credentials, and it will be found.

This pattern is also how you give each worker its own exit: run several listeners, each with a different session token in its upstream username, and point one worker at each port.

Where a per-gigabyte gateway fits, and how the username carries the options

An SSH tunnel is the answer when you need one stable address you are accountable for. A local forwarder is plumbing. The gateway is the part that decides what your traffic looks like from the outside, and on a per-gigabyte residential product the controls live in the username rather than in the hostname — which is what makes it work with any client that has a proxy field at all.

UsernameWhat you get
USERNAMEA rotating exit from the pool on each new connection
USERNAME-country-usThe same, restricted to exits in the United States
USERNAME-country-us-session-abc123One US exit held for about thirty minutes

The endpoint stays gw.pyproxy.com on port 1111 throughout, so switching country or pinning a session is a string change in your configuration and nothing else. PyProxy's residential pool is HTTP and HTTPS only — it does not support SOCKS5 — which is exactly the case the SOCKS-speaking local forwarder above exists to cover. Billing is per gigabyte on one balance shared with the ISP, mobile and datacenter products, and the traffic does not expire, so a tunnel that sits idle between jobs costs nothing while it waits.

PyProxy residential starts at $0.67/GB with traffic that never expires. Link Telegram to a new account and the first gigabyte is free — no card, no deposit.
See proxy plans Get 1 GB free

Questions people ask

What is a tunnel proxy?

A proxy that forwards a raw connection rather than rewriting the traffic inside it, and in commercial use a single endpoint you configure once while the rotation and the pool of exit addresses are handled behind it. An HTTP proxy doing CONNECT, a SOCKS listener from an SSH tunnel and a backconnect gateway are all tunnel proxies in that sense.

How do I turn an SSH connection into a proxy?

Run ssh -D 1080 -N -C user@server and SSH opens a local SOCKS listener on port 1080 whose traffic exits from that server. Point a browser or curl --socks5-hostname 127.0.0.1:1080 at it. Use ssh -L for forwarding one local port to one specific destination instead.

Does a tunnel proxy rotate my IP address?

Only if something behind it does. An SSH tunnel always exits from the same server, so the address never changes. A backconnect gateway is a single hostname in front of a rotating pool, so each new connection can leave from a different address unless you pin one with a session token.

My tool cannot handle a proxy username and password. What now?

Run a small local forwarder that accepts a plain connection on 127.0.0.1 and adds the credentials upstream. A single gost command will do it, and the application only ever sees a local host and port with no authentication. Bind it to the loopback address so nothing else on the network can use it.