Skip to content
intermediate

How to Set Up Smartproxy Proxies on Linux with curl and Python for CLI Automation

Route curl and Python traffic through Smartproxy residential or datacenter proxies on Linux, verify your exit IP, pin sticky sessions, and schedule recurring checks with cron or systemd.

Linux SOCKS5 HTTP(S)

Overview

This tutorial shows how to send command-line and Python traffic through a proxy on Linux, including authentication, exit-IP verification, session pinning, and scheduled runs. Smartproxy is used here as the suggested provider because it offers residential and datacenter proxies over HTTP and SOCKS5 with flat monthly billing and a 65M+ IP pool, but every step works with any proxy service that exposes the same protocols.

By the end of this guide you will be able to:

  • Authenticate to your proxy endpoint from the shell with curl
  • Confirm that outbound traffic exits from the proxy IP rather than your own
  • Use the same endpoint from Python with requests
  • Pin a sticky session or rotate IPs between requests
  • Automate health checks with cron or a systemd timer

Prerequisites

  • A Linux host (commands below use Debian/Ubuntu; Fedora and Arch equivalents are noted)
  • curl and Python 3.8 or newer
  • A Smartproxy account with an active plan and proxy credentials
  • The endpoint host and ports for the product you want to use, copied from the dashboard inside your Smartproxy account
  • Outbound access on the proxy port, and no corporate firewall or VPN client that blocks it

Step 1 — Install the required tools

Install curl and Python, then create an isolated environment for the Python client.

sudo apt update
sudo apt install -y curl python3 python3-venv

On Fedora or RHEL-based systems use:

sudo dnf install -y curl python3

Create a virtual environment and install the HTTP client plus SOCKS support:

python3 -m venv ~/.venvs/proxy
source ~/.venvs/proxy/bin/activate
pip install --upgrade pip
pip install 'requests[socks]'

The requests[socks] extra pulls in PySocks, which is what makes socks5h:// URLs work in Python.

Step 2 — Store credentials outside your scripts

Hard-coding credentials into scripts or committing them to a repository is the most common way proxy accounts leak. Keep them in a single file with restrictive permissions and load it only when needed.

install -d -m 700 ~/.config/smartproxy
install -m 600 /dev/null ~/.config/smartproxy/env

Open the file in your editor and replace each placeholder with the values shown in your provider dashboard:

# ~/.config/smartproxy/env
# Replace every REPLACE_WITH_ value using the endpoint and credentials
# from your provider dashboard. Do not commit this file to version control.
export SP_PROXY_HOST="REPLACE_WITH_ENDPOINT_HOST"
export SP_PROXY_PORT_HTTP="REPLACE_WITH_HTTP_PORT"
export SP_PROXY_PORT_SOCKS5="REPLACE_WITH_SOCKS5_PORT"
export SP_PROXY_USER="REPLACE_WITH_PROXY_USERNAME"
export SP_PROXY_PASS="REPLACE_WITH_PROXY_PASSWORD"

Load the variables into your current shell:

set -a; . ~/.config/smartproxy/env; set +a

If you use both residential and datacenter products, keep a separate variable pair for each, because they usually have different hosts or ports.

Step 3 — Choose between HTTP and SOCKS5

Both protocols are supported by Smartproxy, and the right choice depends on what you are sending through the tunnel.

Traffic type Recommended protocol Why
HTTPS requests from curl, requests, or scrapers HTTP proxy (CONNECT tunnel) Simplest to configure, works with every HTTP client, and passes the destination hostname to the proxy
Non-HTTP traffic such as SSH, SMTP, or custom TCP clients SOCKS5 Protocol-agnostic, forwards arbitrary TCP streams
Tools that cannot handle proxy authentication natively SOCKS5 Credentials are handled by the client library rather than the target tool
Maximum client compatibility HTTP Universally supported by HTTP libraries and most CLI tools

If you only ever fetch HTTPS URLs, start with HTTP and switch to SOCKS5 only if a tool requires it.

Step 4 — Test the connection with curl

Send a request through the HTTP proxy and print the exit IP that the destination sees:

curl -sS --max-time 30 \
  --proxy "http://${SP_PROXY_HOST}:${SP_PROXY_PORT_HTTP}" \
  --proxy-user "${SP_PROXY_USER}:${SP_PROXY_PASS}" \
  'https://api.ipify.org?format=json'

Now test the same endpoint over SOCKS5. The --socks5-hostname variant resolves DNS at the proxy, which prevents local DNS lookups from leaking your real location:

curl -sS --max-time 30 \
  --socks5-hostname "${SP_PROXY_HOST}:${SP_PROXY_PORT_SOCKS5}" \
  --proxy-user "${SP_PROXY_USER}:${SP_PROXY_PASS}" \
  'https://api.ipify.org?format=json'

Compare the result with a direct request that bypasses the proxy entirely:

curl -sS 'https://api.ipify.org?format=json'

If the proxied IP differs from the direct IP, traffic is exiting through the proxy. Run the proxied command a few times to see whether the exit IP changes; that tells you whether you are on a rotating or sticky endpoint.

Step 5 — Pin a sticky session or rotate on every request

Rotating behaviour is the default on most residential endpoints: each new connection may leave through a different IP. For logins, multi-step forms, or checkout-style flows you usually want the same IP for a whole sequence of requests.

Your provider builds sticky usernames from a session token. Append the token to the proxy username using the exact pattern shown in the session generator in your dashboard, which commonly looks like a suffix on the username:

export SP_SESSION_ID="$(openssl rand -hex 4)"
export SP_SESSION_USER="${SP_PROXY_USER}-session-${SP_SESSION_ID}"

Then substitute $SP_SESSION_USER wherever the commands above use $SP_PROXY_USER. Reuse the same token for the duration of the task, and generate a new token when you want a fresh exit IP.

Goal Approach
Collect many independent pages Default rotating username, one request per connection
Keep a login or cart intact Reuse one session token for the whole workflow
Distribute load across a region Use the same session token with a fixed country or city if your plan exposes those options in the dashboard
Isolate parallel workers Give each worker process its own randomly generated session token

Step 6 — Use the proxy from Python

With the environment file loaded, the same variables are available to Python. This example uses the HTTP proxy for an HTTPS request:

import os
from urllib.parse import quote

import requests

host = os.environ['SP_PROXY_HOST']
port = os.environ['SP_PROXY_PORT_HTTP']
user = quote(os.environ['SP_PROXY_USER'], safe='')
password = quote(os.environ['SP_PROXY_PASS'], safe='')

proxies = {
    'http': f'http://{user}:{password}@{host}:{port}',
    'https': f'http://{user}:{password}@{host}:{port}',
}

response = requests.get(
    'https://api.ipify.org?format=json',
    proxies=proxies,
    timeout=30,
)
response.raise_for_status()
print(response.json())

To switch to SOCKS5, change only the scheme and port. The socks5h scheme performs remote DNS resolution, matching curl --socks5-hostname:

socks_port = os.environ['SP_PROXY_PORT_SOCKS5']
socks_proxies = {
    'http': f'socks5h://{user}:{password}@{host}:{socks_port}',
    'https': f'socks5h://{user}:{password}@{host}:{socks_port}',
}

Two practical notes:

  • Always set an explicit timeout. Proxy networks are large and individual exit nodes can be slow or unavailable, and a missing timeout turns a bad node into a hung process.
  • Percent-encode the username and password, as shown with quote(), because session delimiters and special characters break proxy URLs if they are passed through raw.

A small retry wrapper makes scripts far more resilient:

import requests
from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry

session = requests.Session()
session.proxies.update(proxies)
session.mount('https://', HTTPAdapter(max_retries=Retry(
    total=3,
    backoff_factor=1,
    status_forcelist=[429, 500, 502, 503, 504],
)))

Step 7 — Run the check on a schedule

Save the verification snippet as ~/scripts/check_proxy.py, then schedule it with cron so credential problems and dead endpoints surface early.

# Rotate a log of exit IPs every hour
0 * * * * set -a; . $HOME/.config/smartproxy/env; set +a; $HOME/.venvs/proxy/bin/python $HOME/scripts/check_proxy.py >> $HOME/proxy-check.log 2>&1

The same job as a systemd service and timer, which is easier to monitor with journalctl:

# ~/.config/systemd/user/proxy-check.service
[Unit]
Description=Verify proxy exit IP

[Service]
Type=oneshot
EnvironmentFile=%h/.config/smartproxy/env
ExecStart=%h/.venvs/proxy/bin/python %h/scripts/check_proxy.py
# ~/.config/systemd/user/proxy-check.timer
[Unit]
Description=Run the proxy check hourly

[Timer]
OnCalendar=hourly
Persistent=true

[Install]
WantedBy=timers.target

Enable and start it with:

systemctl --user daemon-reload
systemctl --user enable --now proxy-check.timer
systemctl --user list-timers proxy-check.timer

Troubleshooting

Symptom Likely cause Fix
407 Proxy Authentication Required Wrong username or password, or special characters not URL-encoded Re-copy credentials from the dashboard and percent-encode them with quote() in Python
curl: (5) Could not resolve proxy Host variable is empty or misspelled Run echo "$SP_PROXY_HOST" and re-source the env file
curl: (7) Failed to connect or a timeout Port blocked by a firewall, VPN, or the wrong port for the product Confirm the port in the dashboard and test it with nc -zv "$SP_PROXY_HOST" "$SP_PROXY_PORT_HTTP"
curl: (56) CONNECT tunnel failed The exit node dropped the connection or the destination rejected the request Retry, and reduce concurrency if it happens constantly
Requests work in a browser but fail in curl over SOCKS5 Local DNS resolution Add --socks5-hostname instead of --socks5
Python raises Missing dependencies for SOCKS support PySocks is not installed Activate the venv and run pip install 'requests[socks]'
Exit IP never changes You are reusing a sticky session token Generate a new session ID for each worker
Exit IP equals your own IP Proxy variables were not loaded, or a tool bypassed the proxy Re-source the env file and re-run the direct-versus-proxied comparison

Additional checks worth running when something behaves unexpectedly:

  1. Print the resolved variables with env | grep SP_PROXY to rule out shell-scoping mistakes.
  2. Test both protocols; if SOCKS5 works and HTTP does not, the issue is with the client configuration rather than the endpoint.
  3. Log the exit IP alongside the timestamp in your job output so you can correlate failures with specific nodes.

Summary

  • Smartproxy exposes residential and datacenter proxies over HTTP and SOCKS5 with flat monthly billing, which makes it a reasonable suggested provider for CLI and scripting workflows.
  • Keep credentials in a chmod 600 environment file and load them with set -a; . file; set +a instead of embedding them in scripts.
  • Use the HTTP proxy for HTTPS-only tooling and --socks5-hostname or socks5h:// when you need protocol-agnostic forwarding or remote DNS resolution.
  • Verify setup by comparing a proxied request to a direct one; matching IPs mean the proxy was bypassed.
  • Append a session token to the username for sticky workflows, and generate a new token per worker for parallel rotating jobs.
  • Wire the same check into cron or a systemd timer so credential expiry and dead endpoints are noticed before a production run fails.