Você definiu o proxy em um servidor Linux, o curl funciona e, mesmo assim, o sudo apt update continua indo para o endereço antigo, o git clone trava e o docker build não chega à rede. Isso não quer dizer que você configurou algo errado. No Linux não existe uma "chave de proxy" central: as variáveis de ambiente do seu shell são uma camada, o arquivo de configuração de cada ferramenta é a segunda e os serviços que rodam sob o systemd são uma terceira camada, completamente separada.
Este artigo percorre essas três camadas em ordem. Primeiro a configuração temporária e permanente por variáveis de ambiente, a diferença entre maiúsculas e minúsculas, as regras de escrita do no_proxy e por que o sudo não leva o seu ambiente adiante. Depois a configuração de apt, git, pip, npm e Docker uma a uma, por que o ajuste da área de trabalho não afeta o terminal, os passos de verificação e a linha para desfazer cada ajuste.
Por que o proxy no Linux não se configura em um lugar só?
No Windows e no macOS o sistema operacional mantém um registro de proxy do sistema e a maioria dos programas o lê. No Linux esse registro não existe. Em vez dele há uma convenção que vem dos anos 1990: ao rodar, um programa olha as variáveis de ambiente http_proxy, https_proxy, all_proxy e no_proxy e as usa se estiverem definidas. Isso não é um padrão, é um hábito difundido. Você precisa saber, ferramenta por ferramenta, qual delas segue esse hábito.
Separar as três camadas resolve a maior parte dos problemas:
- O ambiente do shell. As variáveis que você define com
exportsão herdadas pelos processos iniciados a partir daquele shell. Ao fechar o terminal, acabam. - A configuração da própria ferramenta. apt, git, pip, npm e Docker têm arquivos próprios. Esses arquivos funcionam de forma independente das variáveis de ambiente e em geral têm prioridade sobre elas.
- O ambiente do serviço. Um serviço iniciado pelo systemd não nasce do seu shell, então nunca enxerga as suas variáveis. Ele lê do próprio arquivo de unidade.
Para entender por que um ajuste "não funciona", primeiro é preciso perguntar para qual camada aquela ferramenta olha.
Em que formato o endereço do proxy é escrito?
Em todos os métodos a seguir o endereço é escrito da mesma forma:
http://user:pass@pr.proxynet.io:8000O esquema http:// é o protocolo da conexão feita com o proxy e permanece o mesmo mesmo quando você vai para endereços HTTPS. A parte user:pass@ só é necessária se você se autentica com usuário e senha; se autorizou o IP do seu servidor no painel, pode deixar essa parte de fora por completo. Explicamos a diferença entre os dois métodos em Autenticação de proxy: user:pass ou whitelist de IP.
Se a sua senha tiver @, :, # ou /, escreva esses caracteres no endereço com codificação percentual: %40 para @ e %23 para #. Um @ não codificado divide o endereço no lugar errado e o resultado costuma ser um 407 Proxy Authentication Required. Os detalhes da codificação e as diferenças entre as bibliotecas estão na seção de credenciais de Como usar proxy no Node.js: Axios e node-fetch.
Configuração temporária com variáveis de ambiente
O caminho mais rápido é definir as variáveis para a sessão atual:
export http_proxy="http://user:pass@pr.proxynet.io:8000"
export https_proxy="$http_proxy"
export no_proxy="localhost,127.0.0.1,.suaempresa.local"
curl -s https://api.ipify.org; echoSe a saída mostrar o IP do proxy em vez do seu, o ajuste está funcionando. Para remover as variáveis, basta unset http_proxy https_proxy no_proxy.
O que são essas variáveis, quais ferramentas as leem e como elas se relacionam com arquivos próprios como o .wgetrc explicamos em detalhe em Uso de proxy com o wget: comandos e exemplos, e não repetimos aqui. Para as opções do lado do cURL e o uso de SOCKS5, veja Como usar cURL com proxy: comandos e exemplos.
Duas observações práticas: sem o export, a variável fica apenas no shell e não passa para os programas que você executa. Se quiser um ajuste temporário para um único comando, escreva a variável antes do comando e só ele será afetado:
https_proxy="http://user:pass@pr.proxynet.io:8000" curl -s https://api.ipify.orghttp_proxy e HTTP_PROXY: por que as maiúsculas importam?
No Linux os nomes das variáveis de ambiente diferenciam maiúsculas de minúsculas: http_proxy e HTTP_PROXY são duas variáveis distintas. As ferramentas não tratam as duas da mesma forma.
O cURL e tudo o que usa a libcurl aceitam as variáveis de proxy tanto em minúsculas quanto em maiúsculas e dão prioridade à versão em minúsculas. A única exceção é o http_proxy: o cURL o lê apenas em minúsculas. O motivo é segurança. Quando um script CGI roda, o servidor converte os cabeçalhos da requisição recebida em variáveis de ambiente com o prefixo HTTP_, ou seja, um cabeçalho Proxy: enviado remotamente pode preencher a variável HTTP_PROXY. Os problemas de segurança que esse comportamento causou no passado estão descritos na documentação do cURL.
Na prática, duas regras resolvem:
- Tome as minúsculas como base. Escreva
http_proxy,https_proxy,no_proxy. - Defina as duas. Algumas ferramentas em Java e em Go procuram apenas a versão em maiúsculas. Colocar os dois grupos no mesmo valor é o caminho com menos surpresas.
export http_proxy="http://user:pass@pr.proxynet.io:8000"
export https_proxy="$http_proxy"
export no_proxy="localhost,127.0.0.1"
# defina tambem os gemeos em maiusculas
export HTTP_PROXY="$http_proxy" HTTPS_PROXY="$https_proxy" NO_PROXY="$no_proxy"Já o all_proxy é o padrão independente de protocolo; se existir uma variável específica do protocolo, ela vem na frente. Se for usar SOCKS5, prefira a forma all_proxy="socks5h://user:pass@pr.proxynet.io:1080". No esquema socks5h a resolução do nome de domínio é feita do lado do proxy. As diferenças estão na nossa página de Proxies SOCKS5 e em Diferença entre SOCKS e HTTP proxy: qual escolher?.
Como o no_proxy é escrito?
O no_proxy é uma lista separada por vírgulas de endereços que não devem passar pelo proxy. Ele não tem um padrão, por isso você vê pequenas diferenças entre as ferramentas. Nos nossos testes com o cURL 8.21 o comportamento é este:
| Escrita | Resultado |
|---|---|
example.com | example.com e www.example.com vão sem proxy, qualquer que seja a porta |
.example.com | cobre os subdomínios e o próprio domínio |
sub.example.com | apenas aquele subdomínio; o example.com acima dele continua passando pelo proxy |
EXAMPLE.COM | não diferencia maiúsculas, dá match |
example.com:80 | não dá match, indicar a porta não é suportado |
10.0.0.0/8 | a notação CIDR funciona a partir do cURL 7.86 |
* | um único asterisco deixa todos os endereços fora do proxy |
Há duas armadilhas. A primeira é indicar a porta: o no_proxy é uma lista de hosts, então se você escrever servidor:porta aquela linha não corresponde a nada e a requisição vai silenciosamente para o proxy. A segunda é que o CIDR não funciona em todo lugar; o módulo urllib do Python não reconhece a entrada 10.0.0.0/8 na mesma lista e manda o endereço 10.1.2.3 para o proxy. Se quiser manter a rede interna de fora no lado do Python, escreva os endereços um a um ou pelo nome de domínio.
Coloque na lista pelo menos o seguinte: localhost, 127.0.0.1, o domínio da sua rede interna, se houver, e a rede de contêineres. Caso contrário, a requisição para o seu servidor de desenvolvimento local também dá a volta pelo proxy e estoura o tempo limite.
Tornar o ajuste permanente: ~/.bashrc e /etc/environment
Quando você fecha o terminal, as linhas export se perdem. Para a permanência há dois lugares e o alcance deles é diferente.
~/.bashrc para um único usuário. Acrescente as mesmas linhas export ao fim do arquivo e depois releia com source ~/.bashrc. Esse arquivo roda em shells interativos, ou seja, vale quando você entra por SSH e digita comandos. Se usa Zsh, o equivalente é o ~/.zshrc e as linhas valem do mesmo jeito; se usa fish, o arquivo é ~/.config/fish/config.fish e a escrita passa a ser set -gx http_proxy "…".
/etc/environment para todo o sistema. Esse arquivo não é lido pelo shell, e sim pelo módulo pam_env do PAM. As variáveis são definidas para cada usuário que abre uma sessão. O formato é rígido: um CHAVE=VALOR por linha, e a palavra-chave export é aceita por compatibilidade, como diz a documentação, mas ignorada, sem expansão do shell. Ou seja, uma referência como $http_proxy não funciona aqui, é preciso escrever o valor de forma explícita:
# conteudo de /etc/environment, sem aspas e em texto simples
http_proxy=http://user:pass@pr.proxynet.io:8000
https_proxy=http://user:pass@pr.proxynet.io:8000
no_proxy=localhost,127.0.0.1A mudança vale para as sessões novas; para vê-la na sua sessão SSH aberta, saia e entre de novo. Para desfazer, basta apagar as linhas e renovar a sessão.
Nos dois arquivos a senha fica em texto puro. Se o servidor tem mais de um usuário, prefira o arquivo do usuário em vez do /etc/environment, ou autorize o IP do servidor no painel e passe ao uso sem senha. Para esse cenário, que exige endereço de saída fixo, os pacotes Proxies ISP e Proxies de datacenter são adequados.
Por que o sudo não enxerga o seu ajuste de proxy?
Se o sudo apt update ignora o proxy, o motivo em geral é este: por segurança, o sudo troca a maior parte das variáveis de ambiente do usuário que o chamou por um ambiente limpo. Você avisa que quer preservar o ambiente do usuário com a opção -E; como indica o manual do sudo, a política de segurança pode recusar esse pedido.
sudo -E apt updateSe o comando ainda assim não usar o proxy, restam duas possibilidades: ou a configuração do sudoers não permite a passagem dessas variáveis, ou a ferramenta já não olha para a variável de ambiente e sim para o próprio arquivo. Para o apt a segunda é a solução mais sólida e é o assunto da próxima seção.
Configuração de proxy no apt
O apt também lê as variáveis de ambiente, mas o lugar de verdade dele é o diretório /etc/apt/apt.conf.d/. Um arquivo de fragmento deixado ali resolve tanto o problema do sudo quanto as atualizações que rodam por cron.
// /etc/apt/apt.conf.d/95proxy
Acquire::http::Proxy "http://user:pass@pr.proxynet.io:8000";
Acquire::https::Proxy "http://user:pass@pr.proxynet.io:8000";O ponto e vírgula no fim da linha é obrigatório. Para deixar um servidor específico fora do proxy, você escreve a linha própria daquele host com a palavra-chave DIRECT:
Acquire::http::Proxy::repo.suaempresa.local "DIRECT";Há um ponto de atenção no nome do arquivo: segundo o manual do apt.conf, dos fragmentos daquele diretório só são lidos os que não têm extensão ou têm a extensão conf e cujo nome contém apenas letras, algarismos, hifens, sublinhados e pontos. Ou seja, 95proxy e 95proxy.conf valem; 95proxy.bak é ignorado e o apt avisa isso com uma nota. Para desfazer o ajuste, apague o arquivo ou tire-o do diretório, nenhum comando extra é necessário.
Configuração de proxy no git
O git usa a libcurl para endereços HTTP e HTTPS, portanto já lê as variáveis http_proxy e https_proxy. Se quiser um ajuste permanente e explícito, escreva na configuração dele:
git config --global http.proxy "http://user:pass@pr.proxynet.io:8000"
git config --global --get http.proxy # verifique
git config --global --unset http.proxy # desfacaSe quiser que valha só para um servidor específico, dá para condicionar ao endereço. Assim você vai direto ao seu servidor git interno e pelo proxy para fora:
git config --global http.https://github.com.proxy "http://user:pass@pr.proxynet.io:8000"Um detalhe que apareceu no nosso teste causa problema com frequência. O padrão do ajuste http.proxyAuthMethod do git é anyauth e, segundo a documentação do git-config, esse modo pressupõe que o proxy responda a uma requisição sem credenciais com um 407 e um cabeçalho Proxy-Authenticate. Em proxies que não completam essa rodada de descoberta, o git para com o erro Proxy CONNECT aborted. O mesmo comando passa de primeira com basic:
git config --global http.proxyAuthMethod basicSe quiser testar o ajuste para um único comando, a flag -c não toca na configuração: git -c http.proxy=... ls-remote <endereço>. Se você faz os fetches por SSH, nenhum desses ajustes tem efeito; para SSH é preciso a linha ProxyCommand no ~/.ssh/config.
Configuração de proxy no pip
O pip tem três caminhos e a ordem de prioridade está escrita na documentação do pip: as opções de linha de comando têm prioridade sobre as variáveis de ambiente, e estas sobre o arquivo de configuração.
# 1) uso pontual
pip install --proxy "http://user:pass@pr.proxynet.io:8000" requests
# 2) variavel de ambiente; o padrao PIP_<OPCAO> vale para cada opcao
export PIP_PROXY="http://user:pass@pr.proxynet.io:8000"Para um ajuste permanente use o arquivo ~/.config/pip/pip.conf. O /etc/pip.conf para todo o sistema e o $VIRTUAL_ENV/pip.conf para um único ambiente virtual aceitam o mesmo formato:
[global]
proxy = http://user:pass@pr.proxynet.io:8000Se não tiver certeza de qual arquivo está sendo lido, pip config debug lista todos os caminhos e os valores válidos naquele momento. Para desfazer, escreva pip config unset global.proxy ou apague a linha do arquivo.
Configuração de proxy no npm
O npm lê os arquivos .npmrc na ordem projeto, usuário, global e embutido; o da frente tem prioridade sobre o de trás. Segundo a documentação do npm, as variáveis de ambiente HTTP_PROXY e HTTPS_PROXY também são respeitadas, e o padrão da opção noproxy é a variável NO_PROXY.
npm config set proxy "http://user:pass@pr.proxynet.io:8000"
npm config set https-proxy "http://user:pass@pr.proxynet.io:8000"
npm config set noproxy "localhost,127.0.0.1,registry.suaempresa.local"
npm config delete proxy && npm config delete https-proxy # desfacaPara que o ajuste valha apenas em um repositório, acrescente --location=project aos comandos; o npm então escreve os valores no arquivo .npmrc da raiz do projeto. Não envie esse arquivo para o controle de versão, ele contém uma senha.
Uma pequena surpresa: o comando npm config get https-proxy não mostra o valor, ele emite o aviso "protected". As opções que contêm credenciais ficam fechadas para leitura. Para ver o valor, abra o arquivo .npmrc diretamente.
Configuração de proxy no Docker
No Docker não existe um ajuste único: o processo em segundo plano e os contêineres leem o ajuste de dois lugares independentes e, além disso, há a clássica armadilha do endereço. É daí que vem a maior parte da confusão.
1. O processo em segundo plano (baixar imagens). O docker pull e o docker push são feitos pelo dockerd, não pelo seu shell. Segundo a documentação do Docker, o ajuste é escrito na chave proxies do arquivo /etc/docker/daemon.json:
{
"proxies": {
"http-proxy": "http://user:pass@pr.proxynet.io:8000",
"https-proxy": "http://user:pass@pr.proxynet.io:8000",
"no-proxy": "localhost,127.0.0.1,.suaempresa.local"
}
}O mesmo trabalho também é feito com um arquivo de fragmento do lado do systemd. No arquivo /etc/systemd/system/docker.service.d/http-proxy.conf escrevem-se estas linhas:
[Service]
Environment="HTTP_PROXY=http://user:pass@pr.proxynet.io:8000"
Environment="HTTPS_PROXY=http://user:pass@pr.proxynet.io:8000"
Environment="NO_PROXY=localhost,127.0.0.1,.suaempresa.local"Nos dois métodos o ajuste passa a valer depois dos comandos sudo systemctl daemon-reload e sudo systemctl restart docker. Esse padrão não é exclusivo do Docker: todo serviço que roda sob o systemd recebe o proxy dessa maneira, porque o serviço não nasce do seu shell e nunca lê o seu ~/.bashrc.
2. Contêineres e builds. Fazer a aplicação dentro do contêiner sair para a rede é outro assunto. Como descrito na documentação própria dele, a CLI do Docker lê o bloco proxies.default do arquivo ~/.docker/config.json e repassa esses valores como variáveis de ambiente para novos contêineres e builds:
{
"proxies": {
"default": {
"httpProxy": "http://user:pass@pr.proxynet.io:8000",
"httpsProxy": "http://user:pass@pr.proxynet.io:8000",
"noProxy": "localhost,127.0.0.1"
}
}
}Os ajustes desse arquivo não afetam o processo em segundo plano; eles passam apenas para o ambiente de contêiner e de build, e só para os criados depois. Para uso pontual, docker run --env HTTP_PROXY=... e docker build --build-arg HTTP_PROXY=... fazem o mesmo serviço.
3. A armadilha do endereço. Se o proxy roda na própria máquina, não escreva http://127.0.0.1:8000 dentro do contêiner. O contêiner tem o próprio espaço de rede, e o 127.0.0.1 de lá é o próprio contêiner. Para alcançar a máquina anfitriã, use o endereço de rede dela.
Por que o ajuste da área de trabalho não afeta o terminal?
No Ubuntu, a definição que você faz em Configurações > Rede > Proxy de rede é gravada no repositório de ajustes do próprio GNOME e afeta os aplicativos que leem esses valores: o navegador do GNOME, a central de programas, a maioria dos aplicativos de área de trabalho. O shell que você abre no terminal não lê esse repositório, portanto curl e git não são afetados. Se quiser fazer o mesmo ajuste pela linha de comando, usam-se gsettings set org.gnome.system.proxy mode 'manual' e as chaves host e port correspondentes, mas do lado do terminal a variável de ambiente continua sendo necessária.
O resultado prático é este: se o servidor não tem área de trabalho, pule esta seção inteira. Se você trabalha em uma área de trabalho, precisa fazer os dois ajustes. Para os equivalentes em outros sistemas operacionais, veja Configuração de proxy no Windows e no Chrome, Como configurar proxy no Mac e no Safari e Como configurar proxy no celular Android.
Tabela de ferramenta, arquivo e desfazer
| Ferramenta | Onde fica o ajuste | Como desfazer |
|---|---|---|
| Shell (temporário) | export http_proxy=… | unset http_proxy https_proxy no_proxy |
| Shell (usuário) | ~/.bashrc, ~/.zshrc | Apague a linha e recarregue com source |
| Todo o sistema | /etc/environment | Apague a linha e renove a sessão |
| Serviço systemd | /etc/systemd/system/<nome>.service.d/*.conf | Apague o arquivo, daemon-reload |
| apt | /etc/apt/apt.conf.d/95proxy | Tire o arquivo do diretório |
| git | git config --global http.proxy | git config --global --unset http.proxy |
| pip | ~/.config/pip/pip.conf, --proxy | pip config unset global.proxy |
| npm | .npmrc (npm config set proxy) | npm config delete proxy |
| Processo do Docker | /etc/docker/daemon.json | Apague a chave e reinicie o serviço |
| Contêineres do Docker | ~/.docker/config.json | Apague o bloco proxies |
| Área de trabalho GNOME | Configurações > Rede > Proxy de rede | Ponha o modo em "Desativado" |
Como você confirma que o ajuste funciona?
Quatro passos, em ordem:
- Veja as variáveis. A saída de
env | grep -i proxydeve mostrar os valores esperados e os gêmeos em maiúsculas. - Veja o endereço de saída. O endereço devolvido por
curl -s https://api.ipify.orgdeve ser o do proxy. - Acompanhe a conexão. Na saída de
curl -v, procure a linhaUses proxy env variablee uma linhaTryingindo para o endereço do proxy em vez do destino. Se essas duas linhas não aparecem, a requisição não está indo ao proxy. - Teste cada ferramenta em separado. Os comandos
sudo apt update,git ls-remote <endereço>,pip download --no-deps sixenpm view express versionusam a própria configuração e cada um precisa ser verificado por conta própria.
Reunimos os passos detalhados de medição e de verificação de localização em Seu proxy está funcionando? Como testar um proxy.
Erros comuns
- Esquecer o
export. Sozinho,http_proxy=...deixa a variável apenas no shell e não a repassa ao programa que você executa. - Definir só o
http_proxy. As requisições para endereços HTTPS olham a variávelhttps_proxy; se ela falta, tentam sair direto. - Começar o valor de
https_proxycomhttps://. Se o seu proxy não termina TLS, o valor começa comhttp://. - Escrever a senha sem codificar. O
@de dentro dela divide o endereço e o resultado é um407. Listamos as outras causas do407em Códigos de status HTTP no web scraping: 403, 407, 429, 503. - Escrever uma porta na lista
no_proxy. A entradaservidor:8080não corresponde a nada. - Esperar que um serviço siga o ajuste do shell. Um serviço do systemd não lê o
~/.bashrc; é preciso um arquivo de unidade ou de fragmento. - Esquecer o arquivo de configuração e culpar a variável de ambiente.
git config --get http.proxy,pip config debugenpm config listrevelam um valor antigo. - Escrever
127.0.0.1dentro do contêiner. O contêiner tem o próprio espaço de rede.
O diagnóstico dos casos em que a conexão nem chega a ser estabelecida tratamos um a um em Servidor proxy não está respondendo: como resolver o erro.
Guia de decisão
| Necessidade | Ajuste recomendado |
|---|---|
| Passar um único comando pelo proxy | Escreva a variável antes do comando |
| Trabalhar no terminal durante a sessão | Linhas export |
| Permanente no servidor, um único usuário | ~/.bashrc |
| Permanente no servidor, todos os usuários | /etc/environment |
| Deixar as atualizações de pacotes passarem | /etc/apt/apt.conf.d/95proxy |
| Só o tráfego do git para repositórios externos | http.<endereço>.proxy |
| Só um passo em um fluxo de CI | PIP_PROXY ou npm_config_proxy |
| Um build de contêiner | ~/.docker/config.json ou --build-arg |
| Um serviço em segundo plano (dockerd, cron) | Um arquivo de fragmento do systemd |
| Manter a rede interna de fora | no_proxy e Acquire::…::DIRECT |
Perguntas frequentes
Fiz os ajustes, mas alguns programas continuam saindo direto, por quê?
Ler as variáveis de ambiente é um hábito, não uma obrigação. Algumas ferramentas escritas em Go procuram apenas a versão em maiúsculas, e alguns aplicativos Java esperam o próprio parâmetro -Dhttp.proxyHost. Veja o item sobre proxy na documentação do programa; se ele tem ajuste próprio, a variável de ambiente não o substitui.
Dá para usar proxy sem escrever a senha em um arquivo?
Dá. Se você autorizar o IP de saída do seu servidor no painel do proxy, o endereço se reduz a http://pr.proxynet.io:8000 e nenhuma senha fica em arquivo algum. Em servidores com IP fixo esse é o caminho mais limpo.
Dá para usar mais de um proxy ao mesmo tempo?
As variáveis de ambiente guardam um único endereço. A distinção você faz por protocolo (http_proxy e https_proxy com valores diferentes) ou por ferramenta (http.<endereço>.proxy no git, uma linha específica por host no apt). Se precisa de um endereço de saída diferente a cada requisição, um pacote Proxies rotativos de endereço único faz esse trabalho por você.
Minhas conexões SSH também passam pelo proxy?
Não. O http_proxy e as variáveis irmãs não afetam o cliente SSH. Para passar o SSH por um proxy, define-se a linha ProxyCommand no arquivo ~/.ssh/config. É por isso que endereços do tipo git clone git@... também ignoram o ajuste http.proxy.
Por que os meus jobs de cron não enxergam o proxy?
O cron não inicia os jobs a partir do seu shell de login e não lê o seu ~/.bashrc. Defina as variáveis no começo do arquivo crontab ou ajuste-as com export nas primeiras linhas do script.
O apt ficou lento pelo proxy, é normal?
Os repositórios de pacotes são distribuídos geograficamente e o proxy pode levar o tráfego para outro país. Usar o proxy só para as fontes externas e deixar os espelhos locais de fora com a linha Acquire::http::Proxy::<host> "DIRECT"; costuma ser suficiente.
Em resumo
A configuração de proxy no Linux tem três camadas: o ambiente do shell, o arquivo de configuração da própria ferramenta e a unidade de serviço. Comece com export no terminal, use ~/.bashrc ou /etc/environment para a permanência e depois configure apt, git, pip, npm e Docker separadamente pelos arquivos de cada um. Verifique a cada passo com curl -s https://api.ipify.org e não deixe de incluir a sua rede interna na lista no_proxy. Para trabalhos fixos e de alto volume rodando em servidor, dê uma olhada nas nossas soluções de extração de dados ou vá direto à nossa página de Proxies HTTPS.




