Configurare un proxy in curl: autenticazione, HTTPS CONNECT e controlli affidabili

15 minuti di lettura

Imposti un proxy esplicito in curl, tenga -U distinto da -u, faccia passare HTTPS con CONNECT senza -k e legga i codici di uscita rispetto al percorso usato davvero.

Questa guida è per chi ha già curl nel PATH e ha bisogno di un hop HTTP o SOCKS che possa dimostrare. I controlli sotto hanno usato un'origine loopback locale e proxy fittizi, non un account di un fornitore. Top Proxy non vende IP e qui non ci sono chiavi gratuite. Una pagina del browser Il mio IP mostra il percorso del browser, non questo processo curl.

01Esegua i controlli su un proxy vivo

I numeri di questo articolo arrivano da una misura loopback controllata su curl 8.7.1. Quella misura è metodologia. Non è un kit in questa pagina e non c'è un download pubblico.

Usi curl ordinario contro un proxy e un'origine che ha ancora in esecuzione. Il dummy lab-user:lab-pass è un'etichetta, non un account. Metta nel comando host, porta e CA live. Non riutilizzi le porte della famiglia 60585 del passaggio registrato. Quegli endpoint erano già spariti quando la misura è finita.

curl -q -sS --noproxy '' -x http://127.0.0.1:PROXY_PORT --proxy-user lab-user:lab-pass http://127.0.0.1:ORIGIN_PORT/identity

HTTPS attraverso lo stesso hop HTTP usa comunque CONNECT. Si fidi della CA che corrisponde all'origine con cui sta parlando adesso.

curl -q -sS --noproxy '' -x http://127.0.0.1:PROXY_PORT --proxy-user lab-user:lab-pass --cacert ca.pem https://localhost:ORIGIN_HTTPS_PORT/identity

02Imposti un proxy HTTP esplicito e verifichi il percorso

Parta curl con -q come prima opzione. Il man curl di 8.7.1 installato e la pagina man di curl dicono entrambi che -q in prima posizione salta curlrc. I manuali online possono descrivere flag più nuovi. Questa guida resta su 8.7.1. Se il file rc inietta un proxy, un bundle CA o --user, ogni flag successivo sta litigando con un fantasma. Non riscriva HOME per nascondere il file. -q è l'isolamento che il binario le dà già.

Punti all'hop con -x / --proxy. Senza schema, curl tratta l'host come proxy HTTP. I proxy HTTP in everything curl descrivono l'inoltro in forma assoluta per i target HTTP. Il proxy alpha del lab ha registrato GET http://127.0.0.1:60585/identity e poi ha restituito il JSON dell'origine. Lo status 200 da solo non è il percorso. L'origine ha riportato via_proxy_header: alpha. Un secondo proxy strumentato di nome beta è rimasto inattivo su quella chiamata.

  1. Esegua curl -q --version e tenga la riga libcurl. Questa guida ha usato curl 8.7.1, libcurl 8.7.1, SecureTransport più LibreSSL 3.3.6. Le feature elencavano HTTPS-proxy. Quel flag riguarda TLS verso un proxy. Non prova SOCKS e non prova CONNECT.
  2. Chiami l'origine una volta senza -x. HTTP diretto ha restituito exit 0, HTTP 200, id origine http-origin, e il proxy fittizio non ha ricevuto nulla. Questo è il controllo.
  3. Chiami lo stesso URL con -x, --noproxy '' e --proxy-user fittizio. --noproxy '' forza il proxy anche quando un NO_PROXY della shell salterebbe il loopback. Il corpo dell'origine ha nominato alpha. L'hop ha consumato Proxy-Authorization. L'origine non l'ha visto.
  4. Legga il log del proxy, non solo stdout. Credenziali assenti su questa fixture hanno restituito HTTP 407 con curl exit 0 perché --fail era spento.
curl -q -sS --noproxy '' -x http://127.0.0.1:PROXY_PORT --proxy-user lab-user:lab-pass http://127.0.0.1:ORIGIN_PORT/identity

PROXY_PORT e ORIGIN_PORT devono venire da una fixture ancora attiva. Non sono le porte scadute nei risultati salvati.

Controllo eseguito di un proxy HTTP esplicito, exit 0 e HTTP 200 attraverso alpha

Anche credenziali fittizie sbagliate hanno restituito 407 e exit 0. La fixture ha marcato auth: wrong. Le credenziali corrette hanno restituito origine 200 e auth: correct. I caratteri riservati nella password fittizia sono passati da --proxy-user, non da un URL incollato. La codifica URL componente per componente è l'altra via legale. Non metta password vere in argv se può evitarlo. I process listing vedono comunque l'argomento per un attimo. Il manuale 8.7.1 lo dice.

Se le serve solo sapere se un host risponde HTTP, usi il controllo proxy. È uno strumento di raggiungibilità. Non è questo processo curl.

03Tenga l'autenticazione del proxy distinta da quella dell'origine

-U / --proxy-user autentica verso il proxy. -u / --user autentica verso l'origine. L'autenticazione proxy in everything curl le tratta come indipendenti di proposito. Mescolarle è il modo in cui si fa trapelare una password del gateway in un login applicativo, o il contrario.

L'origine del lab serviva /origin-auth con una challenge Basic propria. Un comando ha inviato -U fittizio ad alpha e -u fittizio all'origine. Il JSON dell'origine diceva origin_authorized: true e proxy_authorization_present: false. L'hop ha consumato Proxy-Authorization. L'origine non l'ha mai visto.

  1. Metta le credenziali del proxy su -U o nello userinfo dell'URL del proxy, mai su -u.
  2. Metta le credenziali dell'origine su -u, su un netrc che ha davvero inteso, o sull'URL dell'origine. Questo lab ha usato un netrc privato vuoto e nessun --netrc, quindi un login a sorpresa sarebbe stato un bug.
  3. Confermi l'origine. Un 200 dal proxy con un 401 dall'origine è un fallimento diverso da un 407 dell'hop.
curl -q -sS --noproxy '' -x http://127.0.0.1:PROXY_PORT --proxy-user lab-user:lab-pass -u origin-user:origin-pass http://127.0.0.1:ORIGIN_PORT/origin-auth
Eseguiti -U per l'auth del proxy accanto a -u per l'auth dell'origine, origine autorizzata senza fuga dell'header del proxy

HTTP 407 senza --fail ha lasciato curl a exit 0 su questa build. Aggiungendo -f sulla stessa chiamata senza credenziali si è ottenuto HTTP 407 e exit 22. Il manuale installato avverte che 401 e 407 possono passare --fail. Su 8.7.1 in questa esecuzione non sono passati. Non generalizzi questo a ogni curl futuro. Registri status, status CONNECT e exit separatamente. --fail-with-body è il fratello che scrive comunque il documento. Qui non era il default.

Gli utenti fittizi in questo articolo sono etichette. Non sono account. Le tracce verbose nel lab avevano i valori Authorization e Proxy-Authorization sostituiti con [REDACTED] prima che qualsiasi file toccasse il disco.

04Raggiunga HTTPS tramite CONNECT senza disabilitare TLS

Un sito HTTPS davanti a un proxy HTTP è comunque un proxy HTTP. curl invia CONNECT host:port, il proxy apre TCP, poi TLS gira verso l'origine attraverso quel tunnel. Non le serve uno schema proxy https:// per questo. Lo schema proxy https:// è TLS verso il proxy stesso. everything curl sui proxy HTTP e il capitolo HTTPS proxy tengono quegli hop distinti. Questo lab non ha alzato un proxy HTTPS. --proxy-cacert è rimasto non misurato. --cacert ha verificato l'origine dopo CONNECT.

  1. Tenga -x su http://127.0.0.1:PORT anche quando l'URL è https://localhost:PORT/identity.
  2. Si fidi della CA del lab con --cacert. Non aggiunga -k.
  3. Pretenda una riga di log CONNECT prima di fidarsi del 200. Alpha ha registrato CONNECT localhost:60586 con auth: correct e status 200, poi il corpo dell'origine ha nominato https-origin.
  4. Ripeta una volta senza --cacert. CONNECT è comunque riuscito. curl è poi uscito 60, il fallimento del certificato peer TLS. Il tunnel andava. Il certificato no.
curl -q -sS --noproxy '' -x http://127.0.0.1:PROXY_PORT --proxy-user lab-user:lab-pass --cacert ca.pem https://localhost:ORIGIN_HTTPS_PORT/identity

--cacert deve essere la CA di una fixture ancora in esecuzione. Non la punti a un evidence/ca.pem avanzato dopo che il launcher one-shot è uscito, e non riutilizzi il path temporaneo cancellato dell'esecuzione registrata.

HTTPS CONNECT eseguito attraverso un proxy HTTP con una CA di lab fidata

Credenziali proxy assenti su CONNECT non assomigliavano al percorso HTTP 407 più exit 0. La fixture ha comunque risposto 407 su CONNECT. curl 8.7.1 è uscito 56 e il codice HTTP in write-out era 000. Credenziali sbagliate hanno fatto lo stesso. Tratti i fallimenti CONNECT come trasporto, non come un 407 HTML silenzioso da parsare dopo.

HTTPS diretto con la CA del lab ha restituito 200. HTTPS diretto senza di essa ha restituito exit 60. Quella coppia è la baseline TLS. È indipendente dal proxy.

Una scheda del browser Il mio IP non mostrerà comunque questo tunnel. Se voleva il browser, dovrebbe configurare il browser.

05Capisca i proxy d'ambiente e il bypass intenzionale

curl legge http_proxy, https_proxy, all_proxy e NO_PROXY. Le variabili d'ambiente dei proxy sono nette sulla trappola CGI. Gli header Proxy: in ingresso diventano HTTP_PROXY in maiuscolo. curl quindi accetta solo http_proxy in minuscolo per HTTP. HTTPS_PROXY e ALL_PROXY in maiuscolo restano validi per i loro schemi.

Il lab ha avviato ogni figlio da un ambiente pulito. Ha rimosso entrambi i casi delle variabili proxy, i resti CGI REQUEST_METHOD, CURL_CA_BUNDLE, SSL_CERT_FILE, SSL_CERT_DIR, SSLKEYLOGFILE e REQUESTS_CA_BUNDLE. Poi ha iniettato un dummy nominato alla volta. curl non ha uno switch trust_env=. Anche trust_env=False di Requests cambia la lookup di CA e netrc. Non copi quel flag su curl. -q più un env figlio pulito è l'isolamento equivalente.

  1. Imposti http_proxy minuscolo su alpha, passi --proxy-user e aggiunga --noproxy ''. L'origine ha nominato alpha. Questo è routing solo da ambiente.
  2. Imposti HTTP_PROXY maiuscolo sullo stesso URL alpha e ometta -x. L'origine è tornata diretta. Il conteggio eventi di alpha non si è mosso. Questa è la convenzione di sicurezza documentata, misurata su questo binario.
  3. Imposti http_proxy su alpha e passi -x esplicito su beta. L'origine ha nominato beta. Alpha non era l'hop selezionato. Due identità proxy valgono più di un 200 arrivato chissà da dove.
  4. Imposti http_proxy su alpha e NO_PROXY=127.0.0.1 senza --noproxy ''. L'origine era diretta e alpha è rimasto inattivo. Questo è il caso di bypass, eseguito di proposito.
  5. Tenga NO_PROXY=127.0.0.1 e aggiunga --noproxy ''. La lista vuota sovrascrive la variabile, come dice il manuale 8.7.1 da 7.53.0. L'origine ha di nuovo nominato alpha.
Eseguito -x esplicito su beta che batte http_proxy d'ambiente su alpha

Non inferisca mai l'hop da HTTP 200. Successo diretto e proxato sembrano uguali nel corpo, a meno che non abbia stampato il percorso. La fixture ha stampato X-Lab-Proxy sull'HTTP inoltrato. CONNECT non può stampare l'origine dentro TLS, quindi il log CONNECT è la prova.

06Confronti SOCKS5 e SOCKS5h con evidenza di handshake

SOCKS non è inoltro HTTP e non è CONNECT. Il capitolo SOCKS in everything curl tiene la tabella corta. SOCKS5 risolve in locale. SOCKS5h invia l'hostname al proxy. --socks5 e --socks5-hostname sono le forme a flag. socks5:// e socks5h:// su -x sono le forme URL.

Il curl 8.7.1 di Apple omette socks dalla lista dei protocolli e mette comunque a disposizione le opzioni proxy SOCKS. Una richiesta SOCKS riuscita non è prova di dove è successo il DNS. L'ATYP dell'handshake lo è.

  1. --socks5 127.0.0.1:PORT verso http://127.0.0.1:ORIGIN/identity è completato con HTTP 200. La fixture ha registrato ATYP ipv4 e indirizzo 127.0.0.1.
  2. --socks5-hostname 127.0.0.1:PORT verso http://lab.curl-fixture.test:ORIGIN/identity è completato con HTTP 200. La fixture ha registrato ATYP domain e indirizzo lab.curl-fixture.test. Il proxy ha mappato quell'hostname di lab su loopback. Quella mappatura è impianto interno della fixture, non una fuga misurata verso DNS pubblico.
  3. Si fermi lì. Questo articolo non pretende una cattura di resolver esterno.
curl -q -sS --noproxy '' --socks5-hostname 127.0.0.1:SOCKS_PORT http://lab.curl-fixture.test:ORIGIN_PORT/identity
Handshake SOCKS5h eseguito con ATYP domain per l'hostname di lab

La documentazione dei fornitori segue lo stesso spacco. I protocolli residenziali Oxylabs documentano socks5h://pr.oxylabs.io:7777 come passaggio dell'hostname, e socks5:// come passaggio di un IP risolto. I protocolli residenziali Decodo, ancora elencati nel catalogo come Smartproxy, documentano socks5h:// su gate.decodo.com:7000 e dicono che host di paese come us.decodo.com non funzionano per SOCKS5. Sono note di aderenza documentata. Non sono questa esecuzione loopback.

Il protocollo non è il tipo di IP. Le pagine mobili e residenziali descrivono i pool di uscita. SOCKS5 contro HTTP è l'handshake del client. Può avere un hop HTTP residenziale o un hop SOCKS datacenter. Non collassi quelle due impostazioni.

07Distingua un fallimento di connessione da un timeout di trasferimento

--connect-timeout limita DNS più TCP più, per TLS, l'handshake. --max-time limita l'intero trasferimento. I timeout in everything curl dicono che --max-time scatta comunque mentre i dati si muovono. Exit 28 è quel timer. Non è un read timeout in stile Requests.

Questo lab non ha misurato un connect timeout e non ha catturato pacchetti. Exit 7 è arrivato da un connect TCP a una porta loopback effimera posseduta da un socket UDP. curl ha stampato Couldn't connect to server con codice HTTP 000. È un errore di connessione. Non è exit 28.

Il percorso delayed-body è l'altra forma. /slow-body ha inviato gli header completi subito, ha flushato il primo byte del corpo H, poi ha aspettato oltre --max-time 1.5 prima del resto. curl ha riportato HTTP 200, non 000, e uscito 28. L'evento first-byte dell'origine era impostato. Alpha aveva inoltrato GET .../slow-body. È un timeout di trasferimento dopo che il corpo era partito.

  1. Per un hop morto, si aspetti un errore di connect. Qui era exit 7 contro una porta loopback posseduta.
  2. Per un corpo lento, pretenda header e un primo byte, poi --max-time, poi exit 28 con un HTTP 200 reale. Il codice 000 avrebbe fallito l'asserzione.
  3. Lasci --connect-timeout come documentato a meno che non stalli davvero l'handshake. Questa esecuzione non l'ha fatto.
curl -q -sS --noproxy '' -x http://127.0.0.1:PROXY_PORT --proxy-user lab-user:lab-pass --max-time 1.5 http://127.0.0.1:ORIGIN_PORT/slow-body
Timeout di trasferimento delayed-body eseguito, HTTP 200 poi curl exit 28

I retry sono uno switch a parte. --retry azzera il contatore --max-time per tentativo su 8.7.1. Limiti la finestra di retry con --retry-max-time se lo accende. Non tratti un flag di retry come idempotenza per POST.

08Scelga un endpoint usando protocollo e auth documentati

Scelga l'hop come lo documenta il fornitore, poi provi curl contro una fixture che possiede. I gateway a pagamento non sono stati chiamati. Targeting per paese, dicerie anti-bot e classifiche del «miglior servizio» sono fuori ambito.

I protocolli residenziali Oxylabs, recuperati il 14 ottobre 2026, mettono HTTP su pr.oxylabs.io:7777 con -U customer-USERNAME:PASSWORD. La stessa pagina aggiunge https://pr.oxylabs.io:7777 quando vuole TLS verso il gateway, e socks5h://pr.oxylabs.io:7777 quando il proxy deve vedere l'hostname. SOCKS5 non usa host di ingresso specifici per paese su quella pagina.

I protocolli residenziali Decodo, stesso giorno, mettono HTTP su gate.decodo.com:7000 e SOCKS5h sullo stesso host. Confronti quegli schemi documentati sulle schede inglesi live di Oxylabs e Smartproxy / Decodo. È aderenza al catalogo, non un test del gateway.

  1. Abbini lo schema al supporto del client. curl 8.7.1 qui parlava inoltro HTTP, CONNECT, SOCKS5 e SOCKS5h. TLS verso un proxy HTTPS resta una riga solo da documentazione.
  2. Abbini l'auth a -U, con i prefissi username che il fornitore documenta. L'-u dell'origine resta fuori da quella stringa.
  3. Controlli l'hop con il controllo proxy se le serve solo HTTP contro SOCKS su un host. Controlli l'IP di uscita in curl, non in una scheda del browser. Provi l'hop su un proxy vivo che possiede prima di puntare curl a un endpoint a pagamento.
Aderenza documentata degli endpoint curl Oxylabs e Decodo, non un test di performance del fornitore
Oxylabs — proxy residenziali e datacenter
Oxylabs — proxy residenziali e datacenter4.0771

Oxylabs vende proxy residenziali, mobile, ISP e datacenter sotto un unico abbonamento mensile da $30. Pagamenti: carte, bonifico, AliPay, PayPal.

10 paesi
0,45 USD
per 1 GB
Decodo (Smartproxy) — proxy residenziali e datacenter
Decodo (Smartproxy) — proxy residenziali e datacenter4.22118

Decodo (ex Smartproxy) vende proxy residenziali e datacenter. Residenziali: $4/GB senza piano mensile, o pacchetti mensili da $3.75/GB per 3 GB. Pagamenti: carte, PayPal, Alipay, Google/Apple Pay, crypto (con limiti).

83 paesi
0,38 USD
per 1 GB
Tabella compatta dei risultati eseguiti dal lab curl loopback
OsservazioneStatus HTTPStatus CONNECTExit curlChe cosa cambiare
Proxy HTTP, utente fittizio corretto200n/a0Il percorso è provato solo se l'identità del proxy coincide
Proxy HTTP, utente assente o sbagliato407n/a0 senza -f; 22 con -f su 8.7.1Corregga -U. Non assuma che ogni 407 diventi 22
HTTPS via proxy HTTP, CA fidata200200 Connection Established0Tenga --cacert sull'origine. Non aggiunga -k
HTTPS via proxy HTTP, utente proxy assente00040756CONNECT 407 è un fallimento di trasporto su questa build
HTTPS, CONNECT ok, origine non fidata00020060Corregga la CA. Il tunnel funzionava già
Solo HTTP_PROXY maiuscolo200 diretton/a0Usi http_proxy minuscolo o -x esplicito
Connect TCP rifiutato su porta posseduta000n/a7Errore di connessione. Non un timeout
Header e primo byte, poi --max-time200n/a28Budget di trasferimento. Non un fallimento di connect

Come si configura un proxy in curl?

Parta con curl -q, poi -x host:port, e aggiunga --proxy-user se l'hop richiede Basic auth. Per i test loopback aggiunga --noproxy '' così un NO_PROXY della shell non può saltare il proxy. Verifichi l'hop con un log o un marchio sull'origine, non con il solo HTTP 200.

HTTPS può usare un proxy HTTP?

Sì. curl invia CONNECT e poi esegue TLS verso l'origine attraverso il tunnel. Non le serve un URL proxy https:// per questo. Un URL proxy https:// è TLS verso il proxy, che questo lab non ha misurato.

In che cosa differiscono -U e -u?

-U autentica verso il proxy. -u autentica verso l'origine. Il proxy ha consumato Proxy-Authorization. L'origine ha accettato le proprie credenziali Authorization e non ha mai visto l'header del proxy. Mescolare le due credenziali è la fuga usuale.

Perché curl ignora HTTP_PROXY in maiuscolo?

I server CGI copiano gli header della richiesta in variabili HTTP_. Un header Proxy diventerebbe HTTP_PROXY. curl accetta solo http_proxy in minuscolo per HTTP, così uno script CGI non può essere trasformato in un client proxy aperto. HTTPS_PROXY in maiuscolo resta valido per HTTPS.

Dove risolve l'hostname socks5h?

Sul proxy. --socks5-hostname e socks5h:// inviano ATYP domain. --socks5 e socks5:// risolvono in locale e, in questo lab, hanno inviato ATYP ipv4 a 127.0.0.1. Un corpo SOCKS riuscito non è un localizzatore DNS.

Che cosa limitano --connect-timeout e --max-time?

--connect-timeout limita l'impostazione della connessione. --max-time limita l'intero trasferimento, anche dopo gli header. Il corpo ritardato di questa esecuzione ha restituito HTTP 200 e curl exit 28. Un connect TCP rifiutato ha restituito exit 7, non 28.