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-secretoEl 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 = authLas 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-compartidoauthenticators() 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 ~/.netrcEl 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 abc123El 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, passwordValida 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
defaultpara 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
defaulten 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.







