Ferramentas de linha de comando, clientes FTP, scripts de automação e bibliotecas HTTP frequentemente precisam localizar credenciais sem exigir que o usuário digite login e senha a cada execução. O formato .netrc surgiu no ecossistema Unix para armazenar autenticação por host. O módulo netrc no Python lê esse arquivo, valida sua sintaxe e oferece uma API simples para consultar login, conta e senha.
Apesar da conveniência, um arquivo de credenciais exige cuidados rigorosos. Permissões abertas, logs acidentais, backups inseguros e uso do host errado podem expor segredos. Este guia mostra como analisar o arquivo, lidar com a entrada default, interpretar erros, proteger permissões e decidir quando usar um cofre de segredos em vez de um arquivo local.
O conteúdo complementa nossos guias sobre shlex, tempfile, atexit, zoneinfo e mimetypes.
Estrutura básica do arquivo
Uma entrada comum possui a palavra machine, o nome do host e os campos de autenticação.
machine api.exemplo.com
login usuario
password senha-secretaO campo account também pode existir, embora muitos serviços modernos não o utilizem.
Localização padrão
Quando nenhum caminho é informado, netrc.netrc() procura .netrc no diretório pessoal determinado por os.path.expanduser().
from netrc import netrc
credenciais = netrc()Se o arquivo padrão não existir, a inicialização gera FileNotFoundError. Isso permite distinguir claramente a ausência da configuração de um erro de sintaxe.
Ler um arquivo específico
from netrc import netrc
credenciais = netrc("/etc/minha-app/credenciais.netrc")Ao fornecer um caminho explícito, você controla onde a configuração fica armazenada. Em serviços, prefira um diretório com permissões restritas e proprietário definido durante o deploy.
Consultar um host
authenticators() retorna uma tupla com login, account e password.
auth = credenciais.authenticators("api.exemplo.com")
if auth is None:
raise RuntimeError("host sem credenciais")
login, account, password = authO retorno pode conter strings vazias quando campos foram omitidos. Valide os valores exigidos pelo seu cliente antes de iniciar a conexão.
A entrada default
O formato permite uma entrada especial usada quando o host solicitado não possui configuração própria.
default
login convidado
password senha-padraoauthenticators() consulta primeiro o host exato e depois default. Esse fallback é conveniente, mas pode enviar uma credencial genérica ao destino errado. Em sistemas sensíveis, evite default ou imponha uma lista explícita de hosts autorizados.
Permissões em sistemas POSIX
Quando o arquivo padrão contém senhas, o Python verifica proprietário e permissões em plataformas com os.getuid(). Se outro usuário puder ler ou escrever o arquivo, uma NetrcParseError será gerada.
chmod 600 ~/.netrcO arquivo deve pertencer ao usuário que executa o processo. Em containers, confirme o UID efetivo e o proprietário do volume montado.
Limitações em outras plataformas
Sistemas sem suporte a os.getuid() não aplicam a mesma verificação automática. Isso não significa que permissões sejam irrelevantes. Use ACLs, proteção do perfil, criptografia de disco e políticas de acesso adequadas ao sistema operacional.
Tratar erros de sintaxe
Erros de parsing geram NetrcParseError, que contém mensagem, arquivo e número da linha.
from netrc import netrc, NetrcParseError
try:
config = netrc()
except NetrcParseError as erro:
print(erro.msg)
print(erro.filename)
print(erro.lineno)Mostre informações suficientes para o operador corrigir o arquivo, mas nunca registre o conteúdo da linha se ela puder conter senha.
UTF-8 e caracteres especiais
Desde Python 3.10, o parser tenta UTF-8 antes do encoding específico da localidade. Campos podem conter caracteres não ASCII e whitespace. Mesmo assim, interoperabilidade com ferramentas antigas pode variar.
Quando o arquivo será compartilhado com clientes externos, teste acentos, espaços e caracteres especiais no ambiente real.
Campos opcionais
Versões modernas não exigem todos os tokens. Campos ausentes recebem string vazia.
machine somente-token.exemplo
password abc123Uma biblioteca pode aceitar esse resultado, mas sua aplicação deve declarar quais campos são obrigatórios. Falhar cedo produz diagnósticos melhores do que um erro remoto de autenticação.
Inspecionar o dicionário hosts
A instância expõe hosts, um dicionário de host para tupla de autenticação.
for host in credenciais.hosts:
print(host)Não imprima os valores completos. Ferramentas de diagnóstico devem mostrar apenas nomes de hosts e a presença dos campos, nunca as senhas.
Macros
O formato histórico permite macros, disponíveis no atributo macros. Elas foram criadas para clientes FTP e são raras em aplicações modernas.
Se você apenas precisa de credenciais, ignore macros e não execute seu conteúdo como comandos. O parser devolve texto; interpretá-lo como shell ampliaria muito a superfície de ataque.
Representação com repr
repr(config) gera uma representação no formato netrc, descartando comentários e podendo reordenar entradas.
Como essa saída contém segredos, não a envie a logs, mensagens de erro ou ferramentas de monitoramento. Também não a use para editar o arquivo preservando comentários.
Integração com um cliente HTTP
def credencial_para(host: str):
auth = config.authenticators(host)
if auth is None:
raise LookupError(f"credencial ausente para {host}")
login, _, password = auth
if not login or not password:
raise ValueError("login ou senha vazio")
return login, passwordValide o host antes da consulta. Não permita que uma URL fornecida por usuário selecione arbitrariamente credenciais internas.
Risco de redirecionamento
Clientes HTTP podem seguir redirecionamentos para outro domínio. Garanta que o cabeçalho de autorização não seja reenviado a um host diferente. A política deve comparar nomes normalizados e, quando necessário, portas e esquemas.
Host e porta
Uma entrada netrc normalmente usa nome de máquina, não uma URL completa. Defina uma convenção para serviços em portas diferentes e confirme como a biblioteca consumidora procura a entrada.
Não concatene dados sem normalização. Hosts são case-insensitive, podem possuir ponto final e nomes internacionais exigem tratamento adequado.
Variáveis de ambiente versus netrc
Variáveis de ambiente são simples em containers e CI, mas podem aparecer em dumps, interfaces administrativas e processos filhos. .netrc centraliza credenciais por host, porém depende de proteção do arquivo.
Nenhuma opção é universalmente segura. Avalie modelo de ameaça, rotação, auditoria e experiência operacional.
Quando usar um cofre de segredos
Prefira um secret manager quando:
- há vários servidores ou equipes;
- segredos precisam de rotação automática;
- é necessária auditoria de acesso;
- credenciais têm vida curta;
- o serviço roda em infraestrutura compartilhada;
- políticas exigem criptografia centralizada.
O netrc funciona bem para ferramentas locais e integração com clientes compatíveis, mas não substitui governança corporativa.
Não versionar o arquivo
Adicione .netrc e variações privadas ao .gitignore. Verifique também históricos, artifacts de CI, imagens de container e backups. Remover o arquivo do commit atual não elimina versões antigas.
Rotação de credenciais
Ao trocar uma senha, atualize o arquivo de forma atômica. Crie um temporário com permissões restritas, grave, faça fsync quando necessário e substitua o destino.
Evite janelas em que um processo leia conteúdo parcialmente escrito.
Testes sem segredos reais
from pathlib import Path
from netrc import netrc
conteudo = """machine teste.local
login usuario
password exemplo
"""
arquivo = Path("credenciais-teste.netrc")
arquivo.write_text(conteudo, encoding="utf-8")
config = netrc(str(arquivo))Use diretórios temporários e valores fictícios. Em POSIX, ajuste permissões para reproduzir o comportamento do arquivo padrão.
Validação de permissões em testes
Teste um arquivo com modo seguro e outro acessível por grupo ou outros usuários. A verificação automática depende de o caminho padrão ser usado e da plataforma oferecer UID; portanto, escreva testes condicionais e documente diferenças.
Mensagens de erro seguras
Uma boa mensagem informa o host, o caminho de configuração e o tipo do problema. Ela não inclui senha, conteúdo integral nem objeto netrc.
raise RuntimeError(
f"credencial para {host!r} não encontrada no arquivo configurado"
)Erros frequentes
- Usar permissões abertas no arquivo.
- Registrar
repr(config). - Confiar indiscriminadamente na entrada
default. - Enviar credenciais após redirecionamento de domínio.
- Permitir que entrada externa escolha o host.
- Versionar segredos por engano.
- Ignorar campos vazios.
- Presumir que a verificação POSIX existe em todas as plataformas.
Boas práticas
- Use modo 600 e proprietário correto em POSIX.
- Valide host, login e senha antes da conexão.
- Não registre conteúdo de credenciais.
- Evite fallback
defaultem sistemas sensíveis. - Atualize arquivos de forma atômica.
- Use segredos fictícios em testes.
- Impeça reenvio de autorização em redirecionamentos.
- Migre para um cofre quando precisar de rotação e auditoria.
Conclusão
O módulo netrc no Python fornece uma forma compatível e simples de ler credenciais por host. Sua API pequena facilita integrações com clientes de rede e ferramentas de linha de comando.
A segurança depende do entorno: permissões, escolha de host, logs, redirecionamentos e governança de segredos. Use o formato para configurações locais controladas e adote um secret manager quando o ambiente exigir rotação, auditoria ou distribuição. Consulte a documentação oficial de netrc e a documentação do formato netrc para detalhes de interoperabilidade.







