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

    Mensaje digital que representa codificación quoted-printable con quopri en Python
    Bibliotecas y Módulos
    Foto de perfil de Leandro Hirt da Academify

    quopri en Python: quoted-printable

    Aprende quopri en Python para codificar y decodificar quoted-printable en correo, archivos e integraciones MIME de forma segura.

    Ler mais

    Tempo de leitura: 6 minutos
    08/08/2026
    Icono de archivo digital que representa tipos MIME con mimetypes en Python
    Bibliotecas y Módulos
    Foto de perfil de Leandro Hirt da Academify

    mimetypes en Python: tipos MIME

    Aprende mimetypes en Python para identificar tipos MIME, extensiones y encodings de forma segura en cargas, descargas, correo y APIs

    Ler mais

    Tempo de leitura: 6 minutos
    08/08/2026
    Búsqueda binaria y listas ordenadas con bisect en Python
    Bibliotecas y Módulos
    Foto de perfil de Leandro Hirt da Academify

    bisect en Python: listas ordenadas

    Aprende bisect en Python para búsqueda binaria, inserción ordenada, duplicados, rangos y diseño seguro de listas.

    Ler mais

    Tempo de leitura: 5 minutos
    08/08/2026
    Código y archivos empaquetados con importlib.resources en Python
    Bibliotecas y Módulos
    Foto de perfil de Leandro Hirt da Academify

    importlib.resources en Python: guía práctica

    Aprende importlib.resources en Python para acceder a archivos empaquetados con seguridad en wheels y aplicaciones instaladas.

    Ler mais

    Tempo de leitura: 5 minutos
    07/08/2026
    Teclado y flujo de datos que representa el procesamiento de varios archivos con fileinput en Python
    Bibliotecas y Módulos
    Foto de perfil de Leandro Hirt da Academify

    fileinput en Python: lee varios archivos

    Aprende fileinput en Python para leer varios archivos o stdin, rastrear líneas, abrir archivos comprimidos y reescribir contenido con backups.

    Ler mais

    Tempo de leitura: 7 minutos
    07/08/2026
    Editor de código con líneas numeradas que representa el módulo linecache en Python
    Bibliotecas y Módulos
    Foto de perfil de Leandro Hirt da Academify

    linecache en Python: lee líneas por número

    Aprende linecache en Python para leer líneas por número, administrar la caché, actualizar archivos modificados e integrar traceback y loaders.

    Ler mais

    Tempo de leitura: 7 minutos
    07/08/2026