Se você administra servidores, escreve scripts de automação ou faz o deploy de aplicativos na infraestrutura corporativa — cedo ou tarde você se deparará com a necessidade de enviar tráfego curl ou wget através de um proxy. Isso pode ser um proxy corporativo, contornar bloqueios geográficos ao baixar pacotes, ou rotação de IP ao fazer solicitações em massa a APIs externas. Neste artigo — apenas prática: comandos, configurações, exemplos de código sem enrolação.
1. Como curl e wget funcionam com proxy: mecanismos básicos
Antes de mexer nas configurações, é importante entender o que acontece por trás dos panos. Ambas as ferramentas suportam dois protocolos principais de proxy: HTTP/HTTPS e SOCKS5. A mecânica é diferente e isso influencia qual tipo de proxy escolher para uma tarefa específica.
Proxy HTTP funciona como um intermediário no nível do protocolo de aplicação. Quando o curl envia uma solicitação através de um proxy HTTP, ele literalmente diz ao servidor proxy: “faça uma solicitação GET para este URL em meu lugar”. Para tráfego HTTPS, o método CONNECT é utilizado — o curl pede ao proxy para estabelecer um túnel até o host de destino, após o qual o handshake TLS ocorre diretamente entre o cliente e o servidor de destino. Isso é importante: o proxy, nesse caso, não vê o conteúdo do tráfego HTTPS.
SOCKS5 opera em um nível mais baixo — ele proxy TCP/UDP sem estar vinculado ao protocolo de aplicação. Isso torna o SOCKS5 mais versátil: através dele, é possível passar não apenas HTTP/HTTPS, mas também outros protocolos. Além disso, o SOCKS5 suporta resolução DNS do lado do servidor proxy — isso é criticamente importante para evitar vazamentos de DNS.
💡 Diferença chave para a prática:
Se você precisa apenas baixar um arquivo ou fazer uma solicitação API — um proxy HTTP é suficiente. Se você precisa de total anonimato, contornar vazamentos de DNS ou trabalhar com protocolos não padrão — use SOCKS5.
O curl suporta ambos os protocolos nativamente desde versões muito antigas. O wget historicamente teve suporte mais limitado ao SOCKS5 — em versões antigas (até 1.19) não há suporte ao SOCKS5, apenas ao proxy HTTP. Isso deve ser considerado ao escrever scripts que devem funcionar em diferentes distribuições.
Para verificar a versão do wget, use o comando wget --version. Para o curl — curl --version, onde também será possível ver quais protocolos a biblioteca libcurl foi compilada.
2. Variáveis de ambiente: a maneira mais rápida de configurar
A maneira mais elegante de configurar um proxy para curl e wget é através de variáveis de ambiente. Isso funciona de forma sistêmica: não é necessário alterar cada script, basta definir as variáveis uma vez na sessão ou adicioná-las ao perfil do usuário.
Ambas as ferramentas leem as mesmas variáveis padrão:
# Para tráfego HTTP export http_proxy="http://proxy.example.com:3128" # Para tráfego HTTPS export https_proxy="http://proxy.example.com:3128" # Duplicamos em maiúsculas (alguns programas leem apenas elas) export HTTP_PROXY="http://proxy.example.com:3128" export HTTPS_PROXY="http://proxy.example.com:3128" # Para FTP (se necessário) export ftp_proxy="http://proxy.example.com:3128" # Exceções — endereços que NÃO passam pelo proxy export no_proxy="localhost,127.0.0.1,::1,192.168.0.0/16,.internal.company.com"
Um detalhe importante: o curl é sensível a maiúsculas e minúsculas nas variáveis dependendo da versão. Para evitar surpresas — sempre defina ambas as versões: em minúsculas e maiúsculas. Esta é uma prática padrão em DevOps.
Para que as configurações sejam aplicadas constantemente para um usuário específico, adicione as linhas em ~/.bashrc ou ~/.profile. Para scripts e serviços do sistema — em /etc/environment ou no arquivo de unidade systemd através da diretiva 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 o proxy exigir autenticação, o login e a senha são inseridos diretamente na URL da variável:
export http_proxy="http://username:[email protected]:3128" export https_proxy="http://username:[email protected]:3128"
⚠️ Segurança:
Não armazene senhas em texto claro em .bashrc ou em variáveis de ambiente em servidores de produção. Use soluções de cofre (HashiCorp Vault, AWS Secrets Manager) ou, no mínimo, restrinja as permissões do arquivo com as variáveis.
3. Flags curl para trabalhar com proxy: análise completa
O curl fornece um rico conjunto de flags para gerenciar proxies diretamente da linha de comando. Isso é conveniente quando você precisa fazer uma solicitação única através de um proxy, sem alterar as configurações do sistema.
A flag principal é -x ou --proxy:
# Proxy HTTP básico curl -x http://proxy.example.com:3128 https://api.example.com/data # Forma curta curl -x proxy.example.com:3128 https://api.example.com/data # Com especificação explícita do protocolo curl --proxy http://proxy.example.com:3128 https://api.example.com/data # Verificar IP externo através do proxy curl -x http://proxy.example.com:3128 https://api.ipify.org
Para ignorar variáveis de ambiente e fazer uma conexão direta (contornar o proxy configurado), use a flag --noproxy:
# Ignorar proxy para um host específico curl --noproxy "internal.company.com" https://internal.company.com/api # Ignorar proxy completamente (mesmo que as variáveis de ambiente estejam definidas) curl --noproxy "*" https://api.example.com/data
Flags úteis para depuração de conexões proxy:
# Modo verbose: vê todos os cabeçalhos, incluindo CONNECT ao proxy curl -v -x http://proxy.example.com:3128 https://api.example.com/data # Apenas cabeçalhos de resposta curl -I -x http://proxy.example.com:3128 https://api.example.com/data # Mostrar tempo de conexão através do 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
Configurar o proxy através do arquivo de configuração ~/.curlrc — é conveniente, se você não quer digitar as flags toda vez:
# ~/.curlrc
proxy = http://proxy.example.com:3128
proxy-user = username:password
noproxy = localhost,127.0.0.1,.internal.company.com
Para scripts do sistema, você pode criar um arquivo de configuração separado e especificá-lo explicitamente através de curl -K /path/to/config — isso permite ter diferentes perfis de proxy para diferentes tarefas.
4. Configuração de proxy no wget: flags e arquivo de configuração
O wget é menos flexível que o curl, mas para tarefas típicas — baixar arquivos, espelhar sites recursivamente — suas capacidades são mais que suficientes. O proxy no wget pode ser configurado de três maneiras: através de variáveis de ambiente (já discutidas acima), através de flags de linha de comando e através do arquivo de configuração ~/.wgetrc.
Flags de linha de comando do wget para proxy:
# Proxy HTTP através da flag wget -e use_proxy=yes \ -e http_proxy=http://proxy.example.com:3128 \ https://example.com/file.tar.gz # HTTPS através do proxy wget -e use_proxy=yes \ -e https_proxy=http://proxy.example.com:3128 \ https://example.com/file.tar.gz # Com autenticação wget -e use_proxy=yes \ -e http_proxy=http://username:[email protected]:3128 \ https://example.com/file.tar.gz # Desativar o proxy para um comando específico (se as variáveis de ambiente estiverem definidas) wget --no-proxy https://internal.company.com/file.tar.gz
O arquivo de configuração ~/.wgetrc — é a maneira preferida para configurações permanentes:
# ~/.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 o proxy exigir autenticação proxy_user = username proxy_password = secretpassword
Para aplicação em sistema (todos os usuários) utiliza-se /etc/wgetrc — o mesmo formato, mas aplicado globalmente. Conveniente para servidores onde todas as operações de download devem passar pelo proxy corporativo.
Exemplo prático: download recursivo de um site através do proxy com limitação de profundidade e velocidade:
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 em curl e wget: configuração e exemplos
SOCKS5 — é o protocolo mais preferido para tarefas onde a anonimidade é importante ou ao trabalhar com portas não padrão. Para administradores de sistemas e engenheiros DevOps, o SOCKS5 é frequentemente utilizado ao trabalhar através de túneis SSH, bem como ao conectar-se a proxies residenciais, que imitam o tráfego de usuários reais.
No curl, o SOCKS5 é suportado através de um prefixo especial na URL do proxy:
# SOCKS5 com resolução DNS do lado do cliente (pode haver vazamento de DNS!) curl --socks5 proxy.example.com:1080 https://api.example.com/data # SOCKS5 com resolução DNS do lado do proxy (recomendado!) curl --socks5-hostname proxy.example.com:1080 https://api.example.com/data # Através da flag -x com especificação explícita do protocolo curl -x socks5h://proxy.example.com:1080 https://api.example.com/data # Com autenticação curl -x socks5h://username:[email protected]:1080 https://api.example.com/data # SOCKS5 através de variável de ambiente export all_proxy="socks5h://proxy.example.com:1080" curl https://api.example.com/data
📌 socks5 vs socks5h — qual é a diferença?
socks5 — a consulta DNS é realizada localmente, através do proxy apenas a conexão TCP é feita por IP. Pode haver vazamento de DNS.socks5h (h = hostname) — a consulta DNS é realizada do lado do servidor proxy. Total anonimidade. Recomendado para a maioria das tarefas.
Um cenário popular em DevOps — usar SSH como proxy SOCKS5 para tunelamento de tráfego através de um host bastião:
# Abrindo um túnel SSH com SOCKS5 na porta local 1080 ssh -D 1080 -f -C -q -N [email protected] # Agora usamos esse túnel no curl curl -x socks5h://localhost:1080 https://internal-api.private.network/data # Ou através de variável de ambiente para todas as solicitações na sessão export all_proxy="socks5h://localhost:1080" wget https://internal-resource.private.network/file.tar.gz
O wget suporta SOCKS5 a partir da versão 1.19. Em versões mais antigas (CentOS 7, Ubuntu 16.04) será necessário usar soluções alternativas: proxychains, tsocks, ou mudar para curl para tarefas que exigem SOCKS5.
6. Autenticação em proxy: login e senha
A maioria dos proxies comerciais e servidores proxy corporativos exige autenticação. Existem várias maneiras de passar as credenciais — cada uma com seus prós e contras em termos de segurança.
Método 1: Credenciais na URL — simples, mas inseguro (a senha é visível na lista de processos):
curl -x http://user:p%[email protected]:3128 https://api.example.com/data # Caracteres especiais na senha precisam ser codificados em URL: @ → %40, : → %3A
Método 2: Flag --proxy-user no curl — a senha pode não ser especificada na linha de comando, o curl solicitará interativamente:
# Login e senha na flag (ainda visível em ps aux) curl -x http://proxy.example.com:3128 \ --proxy-user "username:password" \ https://api.example.com/data # Apenas o login — o curl perguntará a senha interativamente curl -x http://proxy.example.com:3128 \ --proxy-user "username" \ https://api.example.com/data
Método 3: Através do arquivo .netrc — o mais seguro para scripts:
# ~/.netrc machine proxy.example.com login username password secretpassword # Restringindo as permissões do arquivo chmod 600 ~/.netrc # Usando no curl curl -x http://proxy.example.com:3128 --proxy-netrc https://api.example.com/data
Método 4: Através de variáveis de ambiente de um cofre secreto — recomendado para CI/CD e ambientes de produção:
# No script, lemos as credenciais das variáveis (definidas pelo CI/CD)
#!/bin/bash
PROXY_URL="http://${PROXY_USER}:${PROXY_PASS}@proxy.example.com:3128"
curl -x "${PROXY_URL}" https://api.example.com/data
Tabela de comparação dos métodos de autenticação:
| Método | Conveniência | Segurança | Adequado para |
|---|---|---|---|
URL (user:pass@host) |
⭐⭐⭐ | ⭐ | Teste |
| Flag --proxy-user | ⭐⭐⭐ | ⭐⭐ | Comandos únicos |
| Arquivo .netrc | ⭐⭐ | ⭐⭐⭐ | Scripts locais |
| Variáveis de ambiente de vault | ⭐⭐ | ⭐⭐⭐⭐⭐ | CI/CD, produção |
7. Exceções e no_proxy: como contornar o proxy para endereços locais
Em ambientes corporativos e em nuvem, muitas vezes é necessária uma configuração fina: tráfego externo — através do proxy, interno — diretamente. A variável no_proxy (ou NO_PROXY) permite definir uma lista de exceções.
# Exceções básicas export no_proxy="localhost,127.0.0.1,::1" # Exceção por domínio (com ponto — todos os subdomínios) export no_proxy="localhost,127.0.0.1,.internal.company.com,.corp.local" # Exceção por intervalo de IP (notação CIDR nem sempre funciona!) export no_proxy="localhost,127.0.0.1,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16" # Para AWS: excluindo endpoint de metadados e endereços internos export no_proxy="localhost,127.0.0.1,169.254.169.254,.amazonaws.com.internal"
⚠️ Característica importante do no_proxy:
A notação CIDR (10.0.0.0/8) não é suportada por todas as ferramentas. O curl a suporta a partir da versão 7.86.0. O wget — não suporta de forma alguma. Para compatibilidade, é melhor listar IPs específicos ou máscaras como 10. (tudo que começa com 10.).
Exemplo prático para um ambiente Kubernetes, onde é necessário excluir o servidor API e serviços internos:
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 em CI/CD: GitHub Actions, GitLab CI, Docker
Configurar proxy em pipelines CI/CD — uma das tarefas mais comuns para engenheiros DevOps que trabalham em redes corporativas ou com acesso limitado à internet. Vamos analisar configurações específicas para plataformas populares.
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 ao construir imagens
# Passando proxy através de build args 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 . # No Dockerfile, usamos ARG para obter as variáveis
# 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 # Limpando as variáveis de proxy na imagem final (opcional) ENV http_proxy="" ENV https_proxy=""
Configuração global de proxy para o daemon Docker (para docker pull através do 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" # Reiniciando o docker systemctl daemon-reload systemctl restart docker
9. Rotação de proxy em scripts bash
Se você precisa fazer um grande número de solicitações a APIs externas ou serviços — a rotação de proxies permite distribuir a carga e evitar bloqueios por IP. Isso é especialmente relevante ao monitorar preços, coletar dados ou testar a disponibilidade de recursos de diferentes regiões.
Para essas tarefas, proxies de data center são uma boa escolha — eles oferecem alta velocidade e estabilidade em solicitações em massa.
#!/bin/bash # rotate_proxy.sh — rotação de proxies a partir de uma 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 "Solicitando: ${url} via 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 " ✓ Sucesso" else echo " ✗ Falhou, tentando o próximo proxy..." INDEX=$(( (INDEX + 1) % PROXY_COUNT )) curl -x "${PROXY_LIST[$INDEX]}" \ --max-time 30 \ --silent \ --output "${OUTPUT_DIR}/${FILENAME}.html" \ "${url}" fi # Passando para o próximo proxy INDEX=$(( (INDEX + 1) % PROXY_COUNT )) # Pequena pausa entre as solicitações sleep 0.5 done < "${URLS_FILE}" echo "Concluído! Resultados salvos em ${OUTPUT_DIR}"
Uma versão mais avançada — verificar a funcionalidade do proxy antes de usá-lo:
#!/bin/bash # check_proxy.sh — verificação de disponibilidade do 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 "ATIVO" else echo "MORTO" fi } # Obtendo IP externo através do 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 "Status do proxy: ${STATUS}" if [ "${STATUS}" == "ATIVO" ]; then EXTERNAL_IP=$(get_proxy_ip "${PROXY}") echo "IP externo via proxy: ${EXTERNAL_IP}" fi
10. Depuração e erros comuns
Trabalhar com proxies inevitavelmente envolve erros — especialmente durante a configuração inicial. Vamos analisar os problemas mais comuns e como diagnosticá-los.
Diagnóstico usando o modo verbose
# Saída mais detalhada do curl curl -vvv -x http://proxy.example.com:3128 https://api.example.com/data 2>&1 | head -50 # O que observar na saída: # * Conectado ao proxy.example.com — conexão com o proxy estabelecida # CONNECT api.example.com:443 — solicitação para túnel # HTTP/1.1 200 Connection established — túnel aberto # * SSL connection using TLS — TLS funcionando # Depuração do wget wget -d -e use_proxy=yes -e http_proxy=http://proxy.example.com:3128 https://api.example.com/data
Erros comuns e soluções
| Erro | Causa | Solução |
|---|---|---|
407 Proxy Authentication Required |
Credenciais não fornecidas | Adicionar user:pass na URL do proxy ou flag --proxy-user |
Connection refused |
Porta incorreta ou proxy indisponível | Verificar a porta: nc -zv proxy.host 3128 |
SSL certificate error |
Proxy corporativo com inspeção SSL | Adicionar CA corporativa: --cacert /path/to/ca.crt |
Could not resolve proxy |
DNS não resolve o nome do proxy | Usar IP em vez do nome ou verificar DNS |
Timeout |
Proxy lento ou sobrecarregado | Aumentar o timeout: --max-time |