Mobile Proxy for Go
Go's net/http client routes through a proxy when you set Transport.Proxy. For SOCKS5 you reach for golang.org/x/net/proxy. This guide wires both to a mobile proxy and triggers IP rotation against the switch API.
Prerequisites
- →Go 1.21+ installed (
go version). - →A mobile proxy slot, HTTP/SOCKS5 ports, username, password and API key from mobileproxies.org.
- →For SOCKS5:
go get golang.org/x/net/proxy.
Step-by-Step Configuration
Read credentials from the environment
# .env or your shell — never hard-code secrets export MP_HOST=proxy.mobileproxies.org export MP_HTTP_PORT=8000 export MP_SOCKS_PORT=1080 export MP_USER=u_4a9c export MP_PASS=p_2X7q export MP_API_KEY=YOUR_API_KEY export MP_SLOT=us-mob-01
HTTP proxy with net/http
package main
import (
"fmt"
"net/http"
"net/url"
"os"
"time"
)
// httpProxyClient builds an *http.Client that tunnels every request
// through the authenticated mobile proxy.
func httpProxyClient() (*http.Client, error) {
proxyURL, err := url.Parse(fmt.Sprintf(
"http://%s:%s@%s:%s",
url.QueryEscape(os.Getenv("MP_USER")),
url.QueryEscape(os.Getenv("MP_PASS")),
os.Getenv("MP_HOST"),
os.Getenv("MP_HTTP_PORT"),
))
if err != nil {
return nil, err
}
transport := &http.Transport{
Proxy: http.ProxyURL(proxyURL),
MaxIdleConns: 10,
IdleConnTimeout: 30 * time.Second,
TLSHandshakeTimeout: 15 * time.Second,
}
return &http.Client{
Transport: transport,
Timeout: 30 * time.Second,
}, nil
}SOCKS5 proxy with golang.org/x/net/proxy
package main
import (
"context"
"net"
"net/http"
"os"
"time"
"golang.org/x/net/proxy"
)
// socks5ProxyClient routes traffic through the SOCKS5 port using an
// authenticated dialer wired into http.Transport.DialContext.
func socks5ProxyClient() (*http.Client, error) {
auth := &proxy.Auth{
User: os.Getenv("MP_USER"),
Password: os.Getenv("MP_PASS"),
}
addr := net.JoinHostPort(os.Getenv("MP_HOST"), os.Getenv("MP_SOCKS_PORT"))
dialer, err := proxy.SOCKS5("tcp", addr, auth, proxy.Direct)
if err != nil {
return nil, err
}
ctxDialer := dialer.(proxy.ContextDialer)
transport := &http.Transport{
DialContext: func(ctx context.Context, network, address string) (net.Conn, error) {
return ctxDialer.DialContext(ctx, network, address)
},
}
return &http.Client{Transport: transport, Timeout: 30 * time.Second}, nil
}Make a request through the proxy
func main() {
client, err := httpProxyClient() // or socks5ProxyClient()
if err != nil {
panic(err)
}
resp, err := client.Get("https://example.com")
if err != nil {
panic(err)
}
defer resp.Body.Close()
fmt.Println("status:", resp.Status)
}Verify It Works
Hit api.ipify.org through the client and print the egress IP. It should be a carrier-owned mobile IP, never your machine's real address.
func checkIP(client *http.Client) string {
resp, err := client.Get("https://api.ipify.org?format=text")
if err != nil {
panic(err)
}
defer resp.Body.Close()
body, _ := io.ReadAll(resp.Body)
return string(body) // e.g. 100.42.x.x on a mobile ASN
}Rotate the IP
Ask the carrier for a fresh IP with a POST to the switch endpoint. The request goes direct (not through the proxy) and authenticates with your API key:
func rotate() error {
url := fmt.Sprintf(
"https://buy.mobileproxies.org/api/v1/proxies/%s/switch",
os.Getenv("MP_SLOT"),
)
req, err := http.NewRequest(http.MethodPost, url, nil)
if err != nil {
return err
}
req.Header.Set("Authorization", "Bearer "+os.Getenv("MP_API_KEY"))
resp, err := http.DefaultClient.Do(req)
if err != nil {
return err
}
defer resp.Body.Close()
if resp.StatusCode >= 300 {
return fmt.Errorf("switch failed: %s", resp.Status)
}
time.Sleep(4 * time.Second) // let the new IP bind
return nil
}Troubleshooting
"Proxy Authentication Required" (407)
The credentials never reached the proxy. Embed them in the url.Parse URL as user:pass@host, and url.QueryEscape any special characters in the password.
SOCKS5 panics on the type assertion
The proxy.ContextDialer assertion only works with recent golang.org/x/net. Run go get -u golang.org/x/net, or fall back to dialer.Dial inside a plain Dial field.
IP doesn't change after rotate()
Go reuses keep-alive connections. After a switch, call transport.CloseIdleConnections() so the next request opens a fresh tunnel on the new IP.
Related Guides
Run Go Through Mobile IPs
$5 trial. Drop in the http.Transport, point it at a carrier IP, and rotate on the API.