cURL com proxy: como configurar proxy HTTP e SOCKS5

Publicado:

16 min de leitura

Atualizado:

PXNET
Autor: PXNET
Sobre linhas de IP apagadas, moldura de cantos em cruz com o logotipo da Proxynet, um X, o do cURL e INTEGRATION

Você recebeu o endereço de um proxy do seu provedor e quer saber se ele funciona antes de colocá-lo em um scraper, em uma tarefa do cron ou em um pipeline de CI. O cURL é o teste mais rápido: um único comando envia uma requisição pelo proxy e mostra o endereço IP que o site de destino enxerga, e depois esse mesmo comando entra direto em um script de shell.

Este artigo cobre a opção -x, usuário e senha, SOCKS5, o proxy para todos os comandos, um script de download com novas tentativas e as mensagens de erro exatas. Todos os comandos foram executados com o curl 8.21 contra um proxy de teste local; as opções estão documentadas na página de manual do curl.

O que é o cURL?

O cURL (pronuncia-se "kurl") é uma ferramenta de linha de comando para transferir dados de e para servidores por meio de URLs: ele baixa páginas e arquivos, envia formulários e requisições de API e mostra ou grava a resposta. Quem faz o trabalho por baixo é a libcurl, uma biblioteca de transferência que o PHP e outras linguagens também usam.

Como todo comando, o cURL segue uma sintaxe fixa:

bash
curl [options] [URL]

A parte das "opções" diz o que o comando deve fazer, e existem mais de 250 delas. Uma das mais conhecidas é -o page.html, que grava a resposta em um arquivo; -I busca só os cabeçalhos, -L segue redirecionamentos e -x usa um proxy. As opções diferenciam maiúsculas de minúsculas: -x define um proxy, enquanto -X define o método HTTP. Do mesmo jeito, -f faz o cURL falhar em silêncio nos erros HTTP, e -F envia um formulário.

O cURL vem instalado no macOS, no Windows 10 e 11 (como curl.exe) e na maioria das distribuições Linux; em imagens mínimas de contêiner ele pode não vir, e aí é preciso instalá-lo (apt install curl no Debian e no Ubuntu). Rode curl --version: se a linha Features: trouxer HTTPS-proxy, a sua versão também consegue se conectar a um proxy por TLS.

Quais protocolos o cURL aceita?

O cURL só trabalha com protocolos que podem ser escritos como URL; protocolos de rede que não são endereçados por URL ficam de fora. A versão atual lista DICT, FILE, FTP, FTPS, GOPHER, GOPHERS, HTTP, HTTPS, IMAP, IMAPS, LDAP, LDAPS, MQTT, MQTTS, POP3, POP3S, RTSP, SCP, SFTP, SMB, SMBS, SMTP, SMTPS, TELNET, TFTP, WS e WSS. O curl --version mostra o que a sua compilação suporta; o RTMP, que aparece em listas antigas, saiu da lista.

Sem esquema na URL, o cURL deduz o protocolo pelo nome do host (ftp.example.com vira FTP, a maioria dos nomes vira HTTP) e não passa para outro protocolo se aquele falhar. Para proxies, o protocolo importa de uma forma: um proxy HTTP transporta HTTP e HTTPS; os outros protocolos só passam por um túnel CONNECT (-p), e apenas se o proxy liberar aquela porta. O SOCKS5 transporta qualquer conexão TCP, então FTP ou SMTP por proxy normalmente significa SOCKS5.

Por que usar o cURL com proxy?

  • Cada etapa à vista. O -v mostra a conexão com o proxy, a requisição CONNECT e as duas respostas, então você vê em que ponto a requisição falha. É uma saída detalhada do que foi enviado e recebido, valiosa para depurar.
  • Todos os tipos de proxy em uma opção. HTTP, HTTPS, SOCKS4, SOCKS4a, SOCKS5 e SOCKS5h passam todos pelo -x.
  • Scripts. Códigos de saída, --retry, tempos limite e --write-out permitem que um script de shell trate as falhas, e as funções curl_* do PHP aceitam as mesmas opções.
  • Várias URLs em um comando. Com colchetes e chaves (o chamado URL globbing), como page[1-20].html ou {a,b,c}, um único comando vira várias requisições, todas pelo mesmo proxy.

Usos típicos: conferir o país de um IP de saída antes de uma rodada de extração de dados, testar alvos de monitoramento de preços a partir de outro mercado e fazer downloads em tarefas agendadas. Os equivalentes em Node.js estão em cURL em JavaScript, e os de PHP em Web scraping com PHP.

Como o cURL envia uma requisição pelo proxy?

  1. O cURL se conecta ao proxy, não ao destino.
  2. Destino HTTP, proxy HTTP: o cURL envia a requisição com a URL completa (GET http://example.com/ HTTP/1.1). O proxy consegue ler o conteúdo.
  3. Destino HTTPS, proxy HTTP: o cURL envia CONNECT example.com:443, com um cabeçalho Proxy-Authorization se você informou credenciais. Depois que o proxy responde 200, o TLS com o destino roda dentro desse túnel, e o proxy vê apenas o host e a porta. O método CONNECT é definido na RFC 9110.
  4. Proxy SOCKS5: o cURL faz login (com usuário e senha, se informados) e pede ao proxy que se conecte ao destino (RFC 1928). Com socks5://, ele envia um IP que resolveu por conta própria; com socks5h://, envia o nome do host.
  5. O destino responde ao IP do proxy. O seu IP não chega até ele, mas, se o cURL resolver os nomes localmente, as consultas DNS saem pela sua própria conexão.

Como configurar um proxy no cURL: a opção -x

Abra um terminal: curl --help proxy lista todas as opções de proxy. A principal é esta:

text
 -x, --proxy <[protocol://]host[:port]>  Use this proxy

O x é minúsculo. Os dados do proxy são passados com -x ou com --proxy; as duas formas significam a mesma coisa:

bash
curl -x "http://user:pass@pr.proxynet.io:8000" https://httpbin.org/ip

Para testar, serve bem um serviço que devolva o IP de origem da requisição. O httpbin.org/ip faz exatamente isso: com o proxy funcionando, você vê o IP de saída dele, e não o seu.

  • Sem esquema, vale HTTP. O protocolo de proxy padrão é o HTTP, então -x "user:pass@pr.proxynet.io:8000" se comporta como a forma com http://.
  • Escreva sempre a porta. Sem ela, o cURL escolhe uma porta padrão: no nosso teste com o curl 8.21, 80 para http://, 443 para https:// e 1080 para SOCKS (o manual ainda fala em 1080). Dificilmente alguma delas é a porta do seu provedor, então a conexão falha ou estoura o tempo limite.
  • Coloque o endereço entre aspas para que o shell não interprete caracteres especiais como &, ? ou !.
  • O -x vale por comando e tem prioridade sobre as variáveis de ambiente de proxy. O comando seguinte volta a sair direto, sem proxy.

Nos produtos residencial e móvel da Proxynet, um único gateway atende HTTP e SOCKS5 em portas separadas, e o Gerador de endpoints do painel monta o nome de usuário com o país, a cidade e a sessão que você escolher.

Como usar o cURL com proxy HTTP ou HTTPS?

Um proxy HTTP transporta os dois tipos de destino:

bash
# Destino HTTPS: túnel CONNECT, a página continua criptografada
curl -x "http://user:pass@pr.proxynet.io:8000" https://httpbin.org/ip

# Destino HTTP: o proxy repassa a requisição em texto aberto
curl -x "http://user:pass@pr.proxynet.io:8000" http://httpbin.org/ip

Um proxy HTTPS (https://) também criptografa a conexão com o próprio proxy. Use esse formato só se a porta falar TLS; https:// apontado para uma porta HTTP comum falha no handshake (SEC_E_INVALID_TOKEN no Windows, normalmente wrong version number com OpenSSL).

As opções de certificado se dividem entre as duas conexões:

  • -k (--insecure) desativa a verificação de certificado apenas do site de destino. Com um destino http://, não faz nada.
  • --proxy-insecure desativa a verificação do certificado de um proxy HTTPS. --proxy-cacert file.pem é mais seguro: confia na CA do proxy da empresa sem desligar as verificações.

Deixe o -k para testes rápidos, nunca em scripts que enviam tokens. Para protocolos que não são HTTP através de um proxy HTTP, adicione -p (--proxytunnel). A página Proxies HTTPS mostra como o tráfego criptografado passa por um proxy.

Como informar usuário e senha do proxy?

As duas formas enviam o mesmo cabeçalho Proxy-Authorization:

bash
curl -x "http://user:pass@pr.proxynet.io:8000" https://httpbin.org/ip
curl -x "http://pr.proxynet.io:8000" -U "user:pass" https://httpbin.org/ip

Dentro do endereço, os caracteres especiais da senha precisam de codificação percentual: @ vira %40, : vira %3A e # vira %23. O cURL decodifica tudo antes de enviar; no nosso teste, p%40ss chegou ao proxy como p@ss. Com -U (--proxy-user), não é preciso codificar nada. A autenticação Basic é o padrão; proxies corporativos podem exigir --proxy-ntlm, --proxy-digest ou --proxy-anyauth.

Senhas digitadas na linha de comando ficam gravadas no histórico do shell. Em scripts, leia-as de um arquivo de configuração privado (-K file) ou use uma whitelist de IP no lugar delas (a Proxynet aceita até 10 IPs). O artigo Autenticação de proxy: user:pass ou whitelist de IP compara os dois métodos e explica o erro 407.

Como usar o cURL com proxy SOCKS5?

Conforme a versão do SOCKS, você escreve socks4://, socks4a://, socks5:// ou socks5h:// como esquema:

bash
curl -x "socks5h://user:pass@pr.proxynet.io:1080" https://httpbin.org/ip
EsquemaQuem resolve o nome do hostUsuário e senhaUse para
http://O proxySimWeb scraping, APIs, a maioria das ferramentas
https://O proxySimUma porta de proxy que fala TLS
socks5h://O proxySimSOCKS5 com DNS coerente com a localização
socks5://A sua máquinaSimDestinos que só o seu DNS consegue resolver
socks4a://O proxySó um ID de usuárioServidores SOCKS4 antigos
socks4://A sua máquinaSó um ID de usuárioServidores SOCKS4 antigos

Com socks5h://, quem resolve o nome do host é o proxy, e não a sua máquina. Com socks5://, o seu servidor DNS vê cada host que você visita, e os sites que levam a localização em conta respondem para a sua região; o socks5h:// evita os dois problemas (Vazamentos de WebRTC e DNS explica por que isso importa). A opção mais antiga --socks5-hostname host:port equivale a socks5h://, com as credenciais em -U; já --socks5 equivale a socks5://, com o DNS resolvido na sua máquina.

Para as diferenças entre os protocolos, veja Diferença entre SOCKS e HTTP proxy e Proxies SOCKS5: como funcionam. O Proxies SOCKS5 da Proxynet roda em uma porta própria, ao lado da porta HTTP.

Como definir um proxy para todos os comandos do cURL?

MétodoAlcanceExemplo
-xUm comandocurl -x "http://user:pass@host:port" URL
Variável de ambienteA sessão do shellexport https_proxy="http://user:pass@host:port"
.curlrcTodas as execuções daquele usuárioproxy = "http://host:port"

Variáveis de ambiente. O cURL lê http_proxy para destinos HTTP, https_proxy ou HTTPS_PROXY para HTTPS e ALL_PROXY como reserva para o resto. O http_proxy só funciona em minúsculas (uma proteção para programas CGI), então HTTP_PROXY é ignorado no Linux e no macOS. No PowerShell, o comando é $env:HTTPS_PROXY = "http://user:pass@host:port". O wget, o pip e o git leem as mesmas variáveis; veja Uso de proxy com o wget e a página do everything curl sobre variáveis de proxy.

O arquivo de configuração. O cURL lê o ~/.curlrc (no Windows, %USERPROFILE%\.curlrc ou _curlrc) antes de cada execução:

text
proxy = "http://pr.proxynet.io:8000"
proxy-user = "user:pass"

Para ignorar o arquivo em uma execução, use curl -q URL; o -q precisa ser a primeira opção do comando.

Exceções. --noproxy "localhost,.internal.example" ou a variável NO_PROXY mandam esses hosts direto, sem proxy. Um nome também vale para os subdomínios dele, faixas CIDR como 192.168.0.0/16 funcionam e o único curinga aceito é um * sozinho. O NO_PROXY vale mesmo com -x.

O cURL não tem motor de JavaScript, então não executa arquivos PAC. Se a sua rede usa um, leia o arquivo (O que é um arquivo PAC?) e passe com -x o proxy que ele devolve.

Como verificar se o cURL está usando o proxy?

Rode curl https://api.ipify.org sem e com -x: um endereço diferente, no país esperado, significa que o proxy funciona. Uma requisição HTTPS saudável por um proxy HTTP mostra estas linhas no -v:

text
* Establishing HTTP proxy tunnel to httpbin.org:443
> CONNECT httpbin.org:443 HTTP/1.1
> Proxy-Authorization: Basic dXNlcjpwYXNz
< HTTP/1.1 200 Connection Established
* CONNECT tunnel established, response 200

O valor de Proxy-Authorization é só Base64, que qualquer pessoa decodifica; apague-o antes de compartilhar a saída. Em scripts, o -w mostra o resultado em uma linha:

bash
curl -s -o /dev/null -x "http://user:pass@pr.proxynet.io:8000" \
  -w "%{http_code} connect=%{http_connect} proxy_used=%{proxy_used}\n" https://httpbin.org/ip

http_connect é a resposta do proxy ao CONNECT; proxy_used (curl 8.7 ou mais recente) vale 1 quando um proxy foi usado. Para testes de localização, velocidade e vazamentos, veja Como testar um proxy.

Exemplo: baixar uma lista de URLs pelo proxy com novas tentativas

Este script baixa as URLs de urls.txt quatro de cada vez pelo proxy, tenta de novo as falhas temporárias e mostra o status e a duração de cada uma. Ele precisa do cURL e de um shell POSIX (Linux, macOS ou Git Bash):

bash
#!/usr/bin/env bash
# fetch.sh: baixa cada URL de urls.txt pelo proxy, 4 de cada vez
set -u
PROXY="${PROXY:-http://user:pass@pr.proxynet.io:8000}"

sed 's/^/url = /' urls.txt | curl \
  --parallel --parallel-max 4 \
  --proxy "$PROXY" \
  --connect-timeout 10 --max-time 30 \
  --retry 3 --retry-connrefused \
  --fail --silent --show-error \
  --create-dirs --output-dir pages --remote-name-all \
  --write-out "%{http_code} %{time_total}s %{url}\n" \
  --config -
  • --config - lê as linhas url = … que vêm do sed e precisa ficar por último, porque --remote-name-all só vale para as URLs adicionadas depois dele.
  • --retry 3 repete a requisição em caso de tempo esgotado e de HTTP 408, 429, 500, 502, 503, 504, 522 e 524, esperando 1, 2 e 4 segundos e respeitando o cabeçalho Retry-After.
  • --max-time interrompe uma transferência travada; --fail transforma os erros HTTP no código de saída 22.
  • Mantenha o --parallel-max baixo quando todas as URLs são do mesmo site; requisições paralelas demais podem trazer respostas 429.

No nosso teste, quatro páginas foram salvas e uma URL que devolvia 503 foi tentada de novo três vezes antes de o script terminar com o código 22.

Repita uma requisição para o api.ipify.org e veja se o seu gateway faz rotação: um gateway rotativo devolve um IP novo a cada vez, e uma sessão fixa mantém o mesmo IP por 1 a 60 minutos na Proxynet. O que é rotação de IP explica quando usar cada um; o Proxies residenciais oferece os dois modos.

Erros comuns de proxy no cURL e como resolver

As mensagens abaixo são as que o curl 8.21 mostrou nos nossos testes. Elas aparecem sempre em inglês:

  • curl: (5) Could not resolve proxy: … O nome do host do proxy está errado: confira a grafia e procure aspas sobrando.
  • curl: (7) Failed to connect to … over proxy … Nada responde naquela porta (ou o cURL recorreu a uma porta padrão porque nenhuma foi informada), ou um firewall bloqueia a conexão.
  • curl: (7) CONNECT tunnel failed, response 407 Credenciais erradas, caracteres especiais sem codificação ou um IP que não está na whitelist. Versões mais antigas mostram curl: (56) Received HTTP code 407 from proxy after CONNECT; com destinos http://, você simplesmente recebe o status 407. Veja Códigos de status HTTP no web scraping.
  • curl: (56) Proxy CONNECT aborted O proxy fechou a conexão; no nosso teste, um endereço http:// apontava para uma porta SOCKS5.
  • curl: (97) Received invalid version in initial SOCKS5 response. Um endereço socks5:// aponta para uma porta HTTP. Já User was rejected by the SOCKS5 server significa credenciais SOCKS erradas.
  • curl: (28) Connection timed out after … milliseconds Nenhuma resposta chegou a tempo; veja Servidor proxy não está respondendo.
  • curl: (35) … ou SSL_ERROR_SYSCALL O handshake TLS falhou: https:// em uma porta de proxy comum, ou um equipamento na rede que corta conexões TLS.
  • curl: (60) SSL certificate problem: unable to get local issuer certificate Muitas vezes é um proxy corporativo que inspeciona o TLS. Instale o certificado da CA dele em vez de usar -k.
  • O proxy é ignorado. Procure NO_PROXY, HTTP_PROXY em maiúsculas ou outro .curlrc; o -v mostra qual endereço o cURL tenta primeiro. A versão em Python dessas falhas está em Max Retries Exceeded With URL.

Guia de decisão

NecessidadeRecomendação
Testar um proxy novo uma vezcurl -x "http://user:pass@host:port" https://httpbin.org/ip
A senha tem @, : ou #-U "user:pass" ou codificação percentual
DNS resolvido no proxysocks5h://, não socks5://
FTP, SMTP ou outro protocolo que não é HTTPSOCKS5, ou -p com um proxy HTTP
Proxy para uma sessão do shellexport https_proxy=… e http_proxy em minúsculas
Proxy para todas as execuçõesproxy = "…" no ~/.curlrc
Nenhuma senha nos scriptsWhitelist de IP no painel
O mesmo IP em um fluxo de loginSessão fixa pelo Gerador de endpoints

Perguntas frequentes

O cURL usa as configurações de proxy do sistema no Windows ou no macOS?

Não. O cURL só pega um proxy do -x, das variáveis de ambiente e do .curlrc. Um proxy definido nas Configurações do Windows ou nos Ajustes do Sistema do macOS não tem efeito sobre ele.

Como fazer o cURL ignorar o proxy em uma requisição?

Adicione --noproxy "*" ou -x "". Qualquer uma das duas opções manda aquele comando direto, mesmo quando https_proxy ou o .curlrc definem um proxy.

Por que o comando de proxy do cURL falha no PowerShell?

No Windows PowerShell 5.1, curl é um alias de Invoke-WebRequest, que não conhece o -x. Digite curl.exe para rodar o cURL de verdade. O PowerShell 7 não tem mais esse alias.

Qual é a diferença entre socks5 e socks5h no cURL?

Com socks5://, a sua máquina resolve o nome do host; com socks5h://, quem resolve é o proxy, e assim o DNS corresponde à localização do proxy.

Dá para usar proxy com o cURL no PHP?

Sim. As funções de cURL do PHP usam a libcurl: CURLOPT_PROXY define o endereço, CURLOPT_PROXYUSERPWD as credenciais e CURLOPT_PROXYTYPE o tipo de SOCKS. Há exemplos em Web scraping com PHP.

O cURL consegue trocar de proxy a cada requisição?

O cURL usa um proxy por comando. Um gateway rotativo atribui um novo IP de saída a cada conexão, então um laço de comandos recebe um IP diferente a cada vez. Várias URLs em um único comando costumam reaproveitar a mesma conexão e dividem o mesmo IP.

Em resumo

Para usar o cURL com proxy, adicione -x com o endereço completo: esquema, credenciais, host e porta. Use http:// na maioria dos trabalhos e socks5h:// para SOCKS5 com DNS remoto, coloque o proxy em https_proxy ou no .curlrc quando todos os comandos precisarem dele e deixe o -k para testes. Quando um comando falha, o código de saída e a saída do -v mostram se o problema está no endereço, nas credenciais ou no destino. Para endpoints residenciais, móveis e SOCKS5 que funcionam com esses comandos, veja os proxies da Proxynet.