netrc en Python: credenciales por host

Publicado el: 08/08/2026
Tempo de leitura: 7 minutos
Candado digital que representa credenciales por host con netrc en Python

Las herramientas de línea de comandos, clientes FTP, scripts de automatización y bibliotecas HTTP a menudo necesitan localizar credenciales sin pedir al usuario que escriba login y contraseña en cada ejecución. El formato .netrc nació en el ecosistema Unix para almacenar autenticación por host. netrc en Python analiza ese archivo, valida su sintaxis y ofrece una API pequeña para consultar login, cuenta y contraseña.

La comodidad implica responsabilidades importantes. Permisos abiertos, logs accidentales, copias inseguras y la selección del host equivocado pueden exponer secretos. Esta guía explica el parsing, la entrada default, los errores de diagnóstico, los permisos POSIX, las actualizaciones atómicas, los riesgos de redirección, las pruebas y cuándo conviene usar un gestor de secretos.

El contenido complementa nuestras guías sobre shlex, tempfile, atexit, zoneinfo y mimetypes.

Estructura básica

Una entrada habitual utiliza machine, el nombre del host y los campos de autenticación.

machine api.ejemplo.com
    login usuario
    password valor-secreto

El campo histórico account también puede aparecer, aunque muchos servicios modernos no lo utilizan.

Ubicación predeterminada

Si no se proporciona una ruta, netrc.netrc() lee .netrc en el directorio personal resuelto mediante os.path.expanduser().

from netrc import netrc

credenciales = netrc()

Si el archivo predeterminado no existe, se genera FileNotFoundError. La aplicación puede distinguir ausencia de configuración y error de sintaxis.

Leer un archivo explícito

from netrc import netrc

credenciales = netrc("/etc/mi-app/credenciales.netrc")

Una ruta explícita permite controlar propietario, permisos y montaje. Los servicios deben guardar el archivo en un directorio restringido, no en una ubicación compartida con escritura pública.

Consultar un host

authenticators() devuelve login, account y password.

auth = credenciales.authenticators("api.ejemplo.com")
if auth is None:
    raise RuntimeError("faltan credenciales")

login, account, password = auth

Las versiones modernas pueden devolver strings vacíos para campos omitidos. Valida todos los valores exigidos antes de abrir la conexión.

La entrada default

El formato admite una entrada especial de fallback.

default
    login invitado
    password secreto-compartido

authenticators() busca primero la máquina exacta y después default. Esto puede enviar una credencial genérica a un servidor incorrecto si existe un error de escritura o un host controlado externamente. Los sistemas sensibles deberían evitar el fallback o aplicar una lista explícita de destinos.

Permisos POSIX

Cuando el archivo predeterminado contiene contraseñas, Python comprueba propietario y permisos en plataformas con os.getuid(). Si otro usuario puede leer o escribir el archivo, se genera NetrcParseError.

chmod 600 ~/.netrc

El propietario debe ser la cuenta que ejecuta el proceso. En containers confirma el UID efectivo y el dueño del volumen montado.

Otros sistemas operativos

Las plataformas sin os.getuid() no aplican la misma comprobación automática. Eso no significa que el archivo pueda quedar abierto. Utiliza ACLs, protección del perfil, cifrado de disco y cuentas de servicio apropiadas.

Tratar errores de parsing

Los errores de sintaxis generan NetrcParseError, que incluye mensaje, archivo y línea.

from netrc import netrc, NetrcParseError

try:
    config = netrc()
except NetrcParseError as error:
    print(error.msg)
    print(error.filename)
    print(error.lineno)

Muestra información suficiente para reparar el archivo, pero no registres la línea completa porque puede contener una contraseña.

UTF-8 y caracteres especiales

Desde Python 3.10, el parser intenta UTF-8 antes del encoding de la configuración regional. Los tokens pueden contener caracteres no ASCII y whitespace. La compatibilidad con clientes externos antiguos puede variar.

Si varias herramientas comparten el archivo, prueba espacios, acentos y caracteres especiales en los sistemas reales.

Campos opcionales

Las versiones recientes ya no exigen todos los tokens. Los valores ausentes se convierten en string vacío.

machine solo-token.ejemplo
    password abc123

El parser puede aceptar la entrada aunque el cliente necesite login. La validación de la aplicación debe fallar antes de la conexión con un mensaje claro.

Inspeccionar hosts sin revelar secretos

La instancia expone el diccionario público hosts.

for host in credenciales.hosts:
    print(host)

Una herramienta de diagnóstico puede mostrar nombres de máquinas y presencia de campos, pero nunca los valores de las tuplas.

Macros

El formato histórico admite macros, disponibles en macros. Fueron diseñadas para clientes FTP y son poco comunes en aplicaciones actuales.

Si solo necesitas credenciales, ignóralas. No interpretes su texto como comandos de shell sin un sistema de ejecución separado y protegido.

repr contiene secretos

repr(config) produce una representación en formato netrc. Elimina comentarios y puede reordenar entradas, pero además incluye las credenciales.

No envíes esta salida a logs, sistemas de errores, telemetría o tickets de soporte.

Integración con un cliente HTTP

def credenciales_para(host: str):
    auth = config.authenticators(host)
    if auth is None:
        raise LookupError(f"faltan credenciales para {host}")
    login, _, password = auth
    if not login or not password:
        raise ValueError("login o contraseña vacío")
    return login, password

Valida el host antes de buscar. Una URL controlada por usuario no debe seleccionar credenciales internas de forma arbitraria.

Riesgo de redirecciones

Los clientes HTTP pueden seguir redirecciones a otro dominio. Asegura que la autorización no se reenvíe a un host diferente. La política debe comparar nombres normalizados y, cuando importe, puertos y esquemas.

Hosts y puertos

Una entrada netrc normalmente usa nombre de máquina, no URL completa. Define cómo representar servicios en puertos diferentes y verifica la estrategia de la biblioteca consumidora.

Normaliza correctamente: los nombres DNS no distinguen mayúsculas, pueden incluir un punto final y los nombres internacionales requieren IDNA consistente.

Variables de entorno frente a netrc

Las variables de entorno son cómodas en containers y CI, pero pueden aparecer en inspecciones, diagnósticos, procesos hijos o interfaces administrativas. Netrc organiza credenciales por host, aunque depende de protección del archivo.

Ningún método es universal. Evalúa amenazas, rotación, auditoría y plataforma.

Cuándo usar un gestor de secretos

  • Varios servidores o equipos comparten credenciales.
  • Se necesita rotación automática.
  • El acceso debe auditarse.
  • Las credenciales son temporales.
  • La infraestructura es compartida.
  • Las políticas exigen cifrado y revocación centralizados.

Netrc sigue siendo útil para herramientas locales y clientes compatibles.

No versionar el archivo

Añade .netrc y archivos privados al .gitignore. Revisa también historial, artifacts de CI, capas de container y backups. Eliminar un secreto del último commit no borra versiones anteriores.

Rotación y actualización atómica

Crea un archivo temporal con permisos restrictivos, escribe el nuevo contenido, sincroniza cuando sea necesario y reemplaza el destino. Así otro proceso no leerá un archivo parcialmente escrito.

Pruebas sin secretos reales

from pathlib import Path
from netrc import netrc

contenido = """machine prueba.local
login usuario-ejemplo
password secreto-ejemplo
"""

ruta = Path("credenciales-prueba.netrc")
ruta.write_text(contenido, encoding="utf-8")
config = netrc(str(ruta))

Usa directorios temporales y valores ficticios. En POSIX configura modos explícitos para probar el comportamiento de permisos.

Probar fallos de permisos

Crea un archivo seguro y otro legible por grupo u otros usuarios. La comprobación automática depende de la ruta predeterminada y de la disponibilidad del UID, por lo que las pruebas deben ser condicionales.

Mensajes de error seguros

Un mensaje útil identifica host, ruta y tipo de fallo. Excluye contraseñas, entradas completas y representaciones del objeto.

raise RuntimeError(
    f"no existen credenciales para {host!r}"
)

Errores frecuentes

  • Dejar el archivo legible por otros usuarios.
  • Registrar repr(config).
  • Confiar en default para cualquier host.
  • Reenviar credenciales después de una redirección.
  • Permitir que entrada externa elija el host.
  • Subir secretos al repositorio.
  • Ignorar campos vacíos.
  • Suponer que las comprobaciones POSIX existen en todas partes.

Buenas prácticas

  • Usa modo 600 y propietario correcto en POSIX.
  • Valida host, login y contraseña antes de conectar.
  • Nunca registres el contenido de credenciales.
  • Evita default en sistemas sensibles.
  • Actualiza archivos atómicamente.
  • Usa credenciales sintéticas en pruebas.
  • Bloquea el reenvío de autorización entre hosts.
  • Migra a un cofre cuando necesites rotación y auditoría.

Conclusión

netrc en Python ofrece una forma compatible y compacta de leer credenciales por host. Su API pequeña se integra fácilmente con clientes de red y herramientas de línea de comandos.

La seguridad depende del diseño completo: permisos, selección del host, logs, redirecciones, copias y gobierno de secretos. Utiliza netrc para configuración local controlada y adopta un gestor de secretos cuando el entorno exija rotación, auditoría o distribución. Consulta la documentación oficial de netrc y la documentación del formato netrc.

Compartilhe:

Facebook
WhatsApp
Twitter
LinkedIn

Contenido del artículo

    Artículos relacionados

    Documento y bandeja de entrada que representan buzones de correo con mailbox en Python
    Bibliotecas y Módulos
    Foto de perfil de Leandro Hirt da Academify

    mailbox en Python: buzones de correo

    Aprende mailbox en Python para leer, crear y migrar Maildir, mbox y MH con locking, flags, mensajes y manejo seguro

    Ler mais

    Tempo de leitura: 5 minutos
    12/08/2026
    Editor de texto que representa formato con textwrap en Python
    Bibliotecas y Módulos
    Foto de perfil de Leandro Hirt da Academify

    textwrap en Python: formatea textos

    Aprende textwrap en Python para dividir, rellenar, acortar, indentar y quitar sangrías con control de ancho, espacios y palabras largas.

    Ler mais

    Tempo de leitura: 5 minutos
    10/08/2026
    Carpeta y lupa que representan filtros de nombres con fnmatch en Python
    Bibliotecas y Módulos
    Foto de perfil de Leandro Hirt da Academify

    fnmatch en Python: filtra nombres de archivos

    Aprende fnmatch en Python para filtrar nombres de archivos con comodines, controlar mayúsculas, excluir patrones y distinguir glob de regex.

    Ler mais

    Tempo de leitura: 5 minutos
    10/08/2026
    Monitor con datos binarios que representa arrays numéricos compactos en Python
    Bibliotecas y Módulos
    Foto de perfil de Leandro Hirt da Academify

    array en Python: números compactos

    Aprende array en Python para almacenar números compactos, usar archivos binarios, byte order, memoryview y buffers seguros.

    Ler mais

    Tempo de leitura: 5 minutos
    10/08/2026
    Círculo cromático que representa conversiones RGB, HSV y HLS con colorsys en Python
    Bibliotecas y Módulos
    Foto de perfil de Leandro Hirt da Academify

    colorsys en Python: RGB, HSV y HLS

    Aprende colorsys en Python para convertir colores entre RGB, HSV, HLS y YIQ, crear paletas y evitar errores de escala

    Ler mais

    Tempo de leitura: 5 minutos
    09/08/2026
    Icono de configuración que representa archivos plist con plistlib en Python
    Bibliotecas y Módulos
    Foto de perfil de Leandro Hirt da Academify

    plistlib: lee y escribe archivos plist

    Aprende plistlib en Python para leer y escribir archivos plist XML y binarios, validar datos y manejar fechas, bytes y

    Ler mais

    Tempo de leitura: 6 minutos
    08/08/2026