Torna al blog

Configurazione del proxy per curl e wget: esempi pratici per amministratori di sistema e DevOps

Guida completa alla configurazione dei proxy per curl e wget con esempi pratici di codice, supporto SOCKS5, autenticazione e automazione nei pipeline CI/CD.

📅3 aprile 2026
```html

Se gestisci server, scrivi script di automazione o distribuisci applicazioni in un'infrastruttura aziendale, prima o poi ti troverai di fronte alla necessità di instradare il traffico curl o wget attraverso un proxy. Questo può essere un proxy aziendale, un modo per aggirare le geo-restrizioni durante il download di pacchetti, o la rotazione degli IP durante richieste massicce a API esterne. In questo articolo, ci concentreremo solo sulla pratica: comandi, configurazioni, esempi di codice senza fronzoli.

1. Come curl e wget funzionano con i proxy: meccanismi di base

Prima di immergersi nelle configurazioni, è importante capire cosa succede sotto il cofano. Entrambi gli strumenti supportano due protocolli proxy principali: HTTP/HTTPS e SOCKS5. La meccanica è diversa e questo influisce su quale tipo di proxy scegliere per un compito specifico.

Proxy HTTP funziona come intermediario a livello di protocollo applicativo. Quando curl invia una richiesta attraverso un proxy HTTP, dice letteralmente al server proxy: "fai una richiesta GET a questo URL al posto mio". Per il traffico HTTPS viene utilizzato il metodo CONNECT: curl chiede al proxy di stabilire un tunnel verso l'host di destinazione, dopo di che il handshake TLS avviene direttamente tra il client e il server di destinazione. Questo è importante: in questo caso, il proxy non vede il contenuto del traffico HTTPS.

SOCKS5 opera a un livello più basso: instrada le connessioni TCP/UDP senza legarsi al protocollo di livello applicativo. Questo rende SOCKS5 più versatile: può instradare non solo HTTP/HTTPS, ma anche altri protocolli. Inoltre, SOCKS5 supporta la risoluzione DNS lato server proxy: questo è critico per prevenire perdite DNS.

💡 Differenza chiave per la pratica:

Se devi semplicemente scaricare un file o fare una richiesta API, un proxy HTTP è sufficiente. Se hai bisogno di completa anonimato, di aggirare le perdite DNS o di lavorare con protocolli non standard, utilizza SOCKS5.

curl supporta entrambi i protocolli nativamente sin dalle prime versioni. wget storicamente ha avuto un supporto più limitato per SOCKS5: nelle versioni precedenti (fino alla 1.19) non c'è affatto supporto per SOCKS5, solo per proxy HTTP. Questo deve essere considerato quando si scrivono script che devono funzionare su diverse distribuzioni.

Puoi controllare la versione di wget con il comando wget --version. Per curl, usa curl --version, lì potrai anche vedere con quali protocolli è stata compilata la libreria libcurl.

2. Variabili d'ambiente: il modo più veloce per configurare

Il modo più elegante per configurare un proxy per curl e wget è attraverso le variabili d'ambiente. Questo funziona a livello di sistema: non è necessario modificare ogni script, basta impostare le variabili una volta nella sessione o aggiungerle al profilo utente.

Entrambi gli strumenti leggono le stesse variabili standard:

# Per il traffico HTTP
export http_proxy="http://proxy.example.com:3128"

# Per il traffico HTTPS
export https_proxy="http://proxy.example.com:3128"

# Duplichiamo in maiuscolo (alcuni programmi leggono solo queste)
export HTTP_PROXY="http://proxy.example.com:3128"
export HTTPS_PROXY="http://proxy.example.com:3128"

# Per FTP (se necessario)
export ftp_proxy="http://proxy.example.com:3128"

# Eccezioni — indirizzi che NON passano attraverso il proxy
export no_proxy="localhost,127.0.0.1,::1,192.168.0.0/16,.internal.company.com"

Un aspetto importante: curl è sensibile al maiuscolo/minuscolo delle variabili a seconda della versione. Per evitare sorprese, imposta sempre entrambe le versioni: in minuscolo e maiuscolo. Questa è una pratica standard in DevOps.

Per applicare le impostazioni in modo permanente per un utente specifico, aggiungi le righe a ~/.bashrc o ~/.profile. Per script e servizi di sistema, usa /etc/environment o nel file unit di systemd tramite la direttiva Environment=.

# /etc/systemd/system/myservice.service
[Service]
Environment="http_proxy=http://proxy.example.com:3128"
Environment="https_proxy=http://proxy.example.com:3128"
Environment="no_proxy=localhost,127.0.0.1"
ExecStart=/usr/bin/myapp

Se il proxy richiede autenticazione, il nome utente e la password vengono inseriti direttamente nell'URL della variabile:

export http_proxy="http://username:[email protected]:3128"
export https_proxy="http://username:[email protected]:3128"

⚠️ Sicurezza:

Non memorizzare le password in chiaro in .bashrc o nelle variabili d'ambiente sui server di produzione. Utilizza soluzioni di vault (HashiCorp Vault, AWS Secrets Manager) o almeno limita i diritti sul file delle variabili.

3. Flag curl per lavorare con i proxy: analisi completa

curl offre un ricco insieme di flag per gestire i proxy direttamente dalla riga di comando. Questo è utile quando è necessario fare una richiesta una tantum attraverso un proxy, senza modificare le impostazioni di sistema.

Il flag principale è -x o --proxy:

# Proxy HTTP di base
curl -x http://proxy.example.com:3128 https://api.example.com/data

# Forma breve
curl -x proxy.example.com:3128 https://api.example.com/data

# Con specifica del protocollo
curl --proxy http://proxy.example.com:3128 https://api.example.com/data

# Controllare l'IP esterno attraverso il proxy
curl -x http://proxy.example.com:3128 https://api.ipify.org

Per ignorare le variabili d'ambiente e stabilire una connessione diretta (bypassando il proxy configurato), si utilizza il flag --noproxy:

# Ignorare il proxy per un host specifico
curl --noproxy "internal.company.com" https://internal.company.com/api

# Ignorare completamente il proxy (anche se sono impostate le variabili d'ambiente)
curl --noproxy "*" https://api.example.com/data

Flag utili per il debugging delle connessioni proxy:

# Modalità verbose: mostra tutti gli header, incluso CONNECT al proxy
curl -v -x http://proxy.example.com:3128 https://api.example.com/data

# Solo gli header della risposta
curl -I -x http://proxy.example.com:3128 https://api.example.com/data

# Mostrare il tempo di connessione attraverso il proxy
curl -w "Connect: %{time_connect}s\nTotal: %{time_total}s\n" \
  -x http://proxy.example.com:3128 \
  -o /dev/null -s https://api.example.com/data

Configurare il proxy tramite il file di configurazione ~/.curlrc è comodo se non si desidera specificare i flag ogni volta:

# ~/.curlrc
proxy = http://proxy.example.com:3128
proxy-user = username:password
noproxy = localhost,127.0.0.1,.internal.company.com

Per script di sistema, puoi creare un file di configurazione separato e specificarlo esplicitamente tramite curl -K /path/to/config — questo consente di avere profili proxy diversi per compiti diversi.

4. Configurazione del proxy in wget: flag e file di configurazione

wget è meno flessibile di curl, ma per compiti tipici — scaricare file, mirrorare siti in modo ricorsivo — le sue capacità sono più che sufficienti. Il proxy in wget può essere configurato in tre modi: tramite variabili d'ambiente (già trattate), tramite flag della riga di comando e tramite il file di configurazione ~/.wgetrc.

Flag della riga di comando wget per il proxy:

# Proxy HTTP tramite flag
wget -e use_proxy=yes \
     -e http_proxy=http://proxy.example.com:3128 \
     https://example.com/file.tar.gz

# HTTPS tramite proxy
wget -e use_proxy=yes \
     -e https_proxy=http://proxy.example.com:3128 \
     https://example.com/file.tar.gz

# Con autenticazione
wget -e use_proxy=yes \
     -e http_proxy=http://username:[email protected]:3128 \
     https://example.com/file.tar.gz

# Disabilitare il proxy per un comando specifico (se sono impostate le variabili d'ambiente)
wget --no-proxy https://internal.company.com/file.tar.gz

Il file di configurazione ~/.wgetrc è il modo preferito per una configurazione permanente:

# ~/.wgetrc
use_proxy = on
http_proxy = http://proxy.example.com:3128
https_proxy = http://proxy.example.com:3128
ftp_proxy = http://proxy.example.com:3128
no_proxy = localhost,127.0.0.1,.internal.company.com

# Se il proxy richiede autenticazione
proxy_user = username
proxy_password = secretpassword

Per applicazioni di sistema (tutti gli utenti) si utilizza /etc/wgetrc — lo stesso formato, ma applicato globalmente. Utile per server dove tutte le operazioni di download devono passare attraverso un proxy aziendale.

Esempio pratico: download ricorsivo di un sito tramite proxy con limitazione della profondità e della velocità:

wget -e use_proxy=yes \
     -e http_proxy=http://proxy.example.com:3128 \
     --recursive \
     --level=2 \
     --limit-rate=500k \
     --wait=1 \
     --random-wait \
     --user-agent="Mozilla/5.0 (compatible; Googlebot/2.1)" \
     https://example.com/docs/

5. Proxy SOCKS5 in curl e wget: configurazione ed esempi

SOCKS5 è un protocollo più preferibile per compiti in cui l'anonimato è importante o per lavorare con porte non standard. Per gli amministratori di sistema e gli ingegneri DevOps, SOCKS5 è spesso utilizzato quando si lavora attraverso tunnel SSH, così come quando ci si connette a proxy residenziali, che simulano il traffico di utenti reali.

In curl, SOCKS5 è supportato tramite un prefisso speciale nell'URL del proxy:

# SOCKS5 con risoluzione DNS lato client (potenziale perdita DNS!)
curl --socks5 proxy.example.com:1080 https://api.example.com/data

# SOCKS5 con risoluzione DNS lato proxy (consigliato!)
curl --socks5-hostname proxy.example.com:1080 https://api.example.com/data

# Tramite flag -x con specifica del protocollo
curl -x socks5h://proxy.example.com:1080 https://api.example.com/data

# Con autenticazione
curl -x socks5h://username:[email protected]:1080 https://api.example.com/data

# SOCKS5 tramite variabile d'ambiente
export all_proxy="socks5h://proxy.example.com:1080"
curl https://api.example.com/data

📌 socks5 vs socks5h — qual è la differenza?

socks5 — la richiesta DNS viene eseguita localmente, attraverso il proxy passa solo la connessione TCP per IP. Possibile perdita DNS.
socks5h (h = hostname) — la richiesta DNS viene eseguita sul server proxy. Massima anonimato. Consigliato per la maggior parte dei compiti.

Uno scenario popolare in DevOps è l'uso di SSH come proxy SOCKS5 per tunnelare il traffico attraverso un bastion host:

# Apriamo un tunnel SSH con SOCKS5 sulla porta locale 1080
ssh -D 1080 -f -C -q -N [email protected]

# Ora utilizziamo questo tunnel in curl
curl -x socks5h://localhost:1080 https://internal-api.private.network/data

# Oppure tramite variabile d'ambiente per tutte le richieste nella sessione
export all_proxy="socks5h://localhost:1080"
wget https://internal-resource.private.network/file.tar.gz

wget supporta SOCKS5 a partire dalla versione 1.19. Nelle versioni più vecchie (CentOS 7, Ubuntu 16.04) sarà necessario utilizzare soluzioni alternative: proxychains, tsocks, o passare a curl per compiti che richiedono SOCKS5.

6. Autenticazione sul proxy: login e password

La maggior parte dei proxy commerciali e dei server proxy aziendali richiede autenticazione. Ci sono diversi modi per trasmettere le credenziali, ognuno con i propri vantaggi e svantaggi in termini di sicurezza.

Metodo 1: Credenziali nell'URL — semplice, ma non sicuro (la password è visibile nell'elenco dei processi):

curl -x http://user:p%[email protected]:3128 https://api.example.com/data
# I caratteri speciali nella password devono essere URL-encoded: @ → %40, : → %3A

Metodo 2: Flag --proxy-user in curl — la password non deve essere specificata nella riga di comando, curl la richiederà interattivamente:

# Login e password nel flag (ancora visibili in ps aux)
curl -x http://proxy.example.com:3128 \
     --proxy-user "username:password" \
     https://api.example.com/data

# Solo login — curl chiederà la password interattivamente
curl -x http://proxy.example.com:3128 \
     --proxy-user "username" \
     https://api.example.com/data

Metodo 3: Tramite file .netrc — il più sicuro per gli script:

# ~/.netrc
machine proxy.example.com
login username
password secretpassword

# Limitiamo i diritti di accesso al file
chmod 600 ~/.netrc

# Utilizziamo in curl
curl -x http://proxy.example.com:3128 --proxy-netrc https://api.example.com/data

Metodo 4: Tramite variabili d'ambiente da un vault segreto — consigliato per CI/CD e ambienti di produzione:

# Nello script leggiamo le credenziali dalle variabili (impostate da CI/CD)
#!/bin/bash
PROXY_URL="http://${PROXY_USER}:${PROXY_PASS}@proxy.example.com:3128"
curl -x "${PROXY_URL}" https://api.example.com/data

Tabella di confronto dei metodi di autenticazione:

Metodo Comodità Sicurezza Adatto per
URL (user:pass@host) ⭐⭐⭐ Test
Flag --proxy-user ⭐⭐⭐ ⭐⭐ Comandi singoli
File .netrc ⭐⭐ ⭐⭐⭐ Script locali
Variabili d'ambiente da vault ⭐⭐ ⭐⭐⭐⭐⭐ CI/CD, produzione

7. Eccezioni e no_proxy: come aggirare il proxy per indirizzi locali

Negli ambienti aziendali e cloud, è spesso necessaria una configurazione fine: il traffico esterno — tramite proxy, interno — direttamente. La variabile no_proxy (o NO_PROXY) consente di specificare un elenco di eccezioni.

# Eccezioni di base
export no_proxy="localhost,127.0.0.1,::1"

# Eccezione per dominio (con punto — tutti i sottodomini)
export no_proxy="localhost,127.0.0.1,.internal.company.com,.corp.local"

# Eccezione per intervallo IP (la notazione CIDR non funziona ovunque!)
export no_proxy="localhost,127.0.0.1,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16"

# Per AWS: escludiamo l'endpoint dei metadati e gli indirizzi interni
export no_proxy="localhost,127.0.0.1,169.254.169.254,.amazonaws.com.internal"

⚠️ Importante caratteristica di no_proxy:

La notazione CIDR (10.0.0.0/8) non è supportata da tutti gli strumenti. curl la supporta a partire dalla versione 7.86.0. wget — non la supporta affatto. Per compatibilità, è meglio elencare IP specifici o maschere come 10. (tutto ciò che inizia con 10.).

Esempio pratico per un ambiente Kubernetes, dove è necessario escludere l'API server e i servizi interni:

export no_proxy="localhost,127.0.0.1,10.96.0.0/12,10.244.0.0/16,.cluster.local,.svc,.default"
export NO_PROXY="${no_proxy}"

8. Proxy in CI/CD: GitHub Actions, GitLab CI, Docker

Configurare il proxy nei pipeline CI/CD è uno dei compiti più comuni per gli ingegneri DevOps che lavorano in reti aziendali o con accesso limitato a Internet. Esaminiamo configurazioni specifiche per piattaforme popolari.

GitHub Actions

# .github/workflows/deploy.yml
name: Deploy

on: [push]

jobs:
  deploy:
    runs-on: ubuntu-latest
    env:
      http_proxy: ${{ secrets.PROXY_URL }}
      https_proxy: ${{ secrets.PROXY_URL }}
      no_proxy: "localhost,127.0.0.1,.github.com"
    
    steps:
      - uses: actions/checkout@v3
      
      - name: Download dependencies
        run: |
          curl -x "${http_proxy}" https://external-api.example.com/config.json -o config.json
          wget -e use_proxy=yes -e http_proxy="${http_proxy}" https://releases.example.com/app-v1.0.tar.gz

GitLab CI

# .gitlab-ci.yml
variables:
  http_proxy: "http://proxy.company.com:3128"
  https_proxy: "http://proxy.company.com:3128"
  no_proxy: "localhost,127.0.0.1,.gitlab.company.com"

build:
  stage: build
  script:
    - curl -x "${http_proxy}" https://registry.npmjs.org/package -o package.json
    - wget -e use_proxy=yes -e http_proxy="${http_proxy}" https://example.com/resource.tar.gz

Docker: proxy durante la costruzione delle immagini

# Passaggio del proxy tramite argomenti di build
docker build \
  --build-arg http_proxy=http://proxy.example.com:3128 \
  --build-arg https_proxy=http://proxy.example.com:3128 \
  --build-arg no_proxy=localhost,127.0.0.1 \
  -t myapp:latest .

# Nel Dockerfile utilizziamo ARG per ottenere le variabili
# Dockerfile
FROM ubuntu:22.04

ARG http_proxy
ARG https_proxy
ARG no_proxy

ENV http_proxy=${http_proxy}
ENV https_proxy=${https_proxy}
ENV no_proxy=${no_proxy}

RUN apt-get update && apt-get install -y curl wget

RUN curl -x "${http_proxy}" https://example.com/setup.sh | bash

# Pulisci le variabili proxy nell'immagine finale (opzionale)
ENV http_proxy=""
ENV https_proxy=""

Impostazione globale del proxy per il daemon Docker (per docker pull tramite proxy):

# /etc/systemd/system/docker.service.d/proxy.conf
[Service]
Environment="HTTP_PROXY=http://proxy.example.com:3128"
Environment="HTTPS_PROXY=http://proxy.example.com:3128"
Environment="NO_PROXY=localhost,127.0.0.1,.internal.registry.com"

# Riavvia Docker
systemctl daemon-reload
systemctl restart docker

9. Rotazione dei proxy negli script bash

Se hai bisogno di fare un gran numero di richieste a API o servizi esterni, la rotazione dei proxy consente di distribuire il carico e evitare blocchi per IP. Questo è particolarmente rilevante durante il monitoraggio dei prezzi, la raccolta di dati o il testing della disponibilità delle risorse da diverse regioni.

Per tali compiti, i proxy di data center sono molto adatti: offrono alta velocità e stabilità durante richieste massicce.

#!/bin/bash
# rotate_proxy.sh — rotazione dei proxy da una lista

PROXY_LIST=(
  "http://user:[email protected]:3128"
  "http://user:[email protected]:3128"
  "http://user:[email protected]:3128"
  "http://user:[email protected]:3128"
)

URLS_FILE="urls.txt"
OUTPUT_DIR="./results"
mkdir -p "${OUTPUT_DIR}"

PROXY_COUNT=${#PROXY_LIST[@]}
INDEX=0

while IFS= read -r url; do
  PROXY="${PROXY_LIST[$INDEX]}"
  FILENAME=$(echo "${url}" | md5sum | cut -d' ' -f1)
  
  echo "Richiesta: ${url} tramite proxy $((INDEX + 1))/${PROXY_COUNT}"
  
  curl -x "${PROXY}" \
       --max-time 30 \
       --retry 3 \
       --retry-delay 2 \
       --silent \
       --output "${OUTPUT_DIR}/${FILENAME}.html" \
       "${url}"
  
  if [ $? -eq 0 ]; then
    echo "  ✓ Successo"
  else
    echo "  ✗ Fallito, provando il prossimo proxy..."
    INDEX=$(( (INDEX + 1) % PROXY_COUNT ))
    curl -x "${PROXY_LIST[$INDEX]}" \
         --max-time 30 \
         --silent \
         --output "${OUTPUT_DIR}/${FILENAME}.html" \
         "${url}"
  fi
  
  # Passiamo al prossimo proxy
  INDEX=$(( (INDEX + 1) % PROXY_COUNT ))
  
  # Piccola pausa tra le richieste
  sleep 0.5
  
done < "${URLS_FILE}"

echo "Fatto! Risultati salvati in ${OUTPUT_DIR}"

Una versione più avanzata — controllare la funzionalità del proxy prima dell'uso:

#!/bin/bash
# check_proxy.sh — verifica la disponibilità del proxy

check_proxy() {
  local proxy_url="$1"
  local test_url="https://api.ipify.org"
  
  result=$(curl -x "${proxy_url}" \
                --max-time 10 \
                --silent \
                --write-out "%{http_code}" \
                --output /dev/null \
                "${test_url}")
  
  if [ "${result}" -eq 200 ]; then
    echo "VIVO"
  else
    echo "MORTO"
  fi
}

# Otteniamo l'IP esterno tramite il proxy
get_proxy_ip() {
  local proxy_url="$1"
  curl -x "${proxy_url}" --max-time 10 --silent https://api.ipify.org
}

PROXY="http://user:[email protected]:3128"
STATUS=$(check_proxy "${PROXY}")
echo "Stato del proxy: ${STATUS}"

if [ "${STATUS}" == "VIVO" ]; then
  EXTERNAL_IP=$(get_proxy_ip "${PROXY}")
  echo "IP esterno tramite proxy: ${EXTERNAL_IP}"
fi

10. Debugging e errori comuni

Lavorare con i proxy comporta inevitabilmente errori — soprattutto durante la configurazione iniziale. Esaminiamo i problemi più comuni e i modi per diagnosticarli.

Diagnostica tramite modalità verbose

# Output dettagliato di curl
curl -vvv -x http://proxy.example.com:3128 https://api.example.com/data 2>&1 | head -50

# Cosa osservare nell'output:
# * Connesso a proxy.example.com — connessione al proxy stabilita
# CONNECT api.example.com:443 — richiesta di tunnel
# HTTP/1.1 200 Connection established — tunnel aperto
# * SSL connection using TLS — TLS funziona

# Debugging wget
wget -d -e use_proxy=yes -e http_proxy=http://proxy.example.com:3128 https://api.example.com/data

Errori comuni e soluzioni

Errore Causa Soluzione
407 Proxy Authentication Required Credenziali non fornite Aggiungere user:pass nell'URL del proxy o flag --proxy-user
Connection refused Porta errata o proxy non disponibile Controllare la porta: nc -zv proxy.host 3128
SSL certificate error Proxy aziendale con ispezione SSL Aggiungere il CA aziendale: --cacert /path/to/ca.crt
Could not resolve proxy DNS non risolve il nome del proxy Utilizzare l'IP invece del nome o controllare il DNS
Timeout Proxy lento o sovraccarico Aumentare il timeout: --max-time 60
```