Autenticación de proxy y buenas prácticas con credenciales
Separa las credenciales del proxy de los inicios de sesión del sitio, mantenlas fuera de registros y código, codifícalas bien en la URL y lee los errores 407 y SOCKS.
Quieres la documentación estructurada de Red?
Este artículo forma parte de la biblioteca editorial. Para pasos de configuración, material de referencia y actualizaciones continuas, entra en la sección de docs.
Por qué las credenciales del proxy requieren un tratamiento aparte
Un navegador que trabaja a través de un proxy autenticado maneja dos conjuntos de credenciales que no tienen relación entre sí. La credencial del proxy demuestra que tu organización puede usar la ruta. El inicio de sesión del destino demuestra que una persona puede usar una cuenta en un sitio web. Las emiten partes distintas, caducan en calendarios distintos, y la filtración de una exige una respuesta diferente a la de la otra. Tratarlas como un único "inicio de sesión" es el primer error de muchas revisiones de credenciales.
La distinción es práctica y no solo conceptual. La credencial del proxy suele pertenecer a una cuenta de servicio o a un panel del proveedor y la comparten los trabajos que usan la ruta. El inicio de sesión del destino pertenece a un usuario o a una cuenta de prueba y viaja dentro del tráfico de la página. Si ambos conviven en un mismo archivo de configuración o en un mismo secreto, rotar la credencial del proxy puede bloquear una cuenta de prueba, y un cambio de contraseña en el destino puede parecer una caída del proxy. Guárdalos en secretos separados, con responsables distintos y registros de rotación distintos.
Estas recomendaciones se refieren a proxies que tu organización está autorizada a usar, según las condiciones del proveedor que emitió las credenciales. No abarcan buscar, adivinar, compartir ni revender credenciales, ni describen formas de saltarse los controles de acceso de un proveedor. Si una credencial no es tuya para usarla, ninguna práctica de manejo hace aceptable la ruta.
Los nombres de los protocolos también fijan expectativas. La autenticación HTTP Basic y el método de usuario y contraseña de SOCKS5 son formas de presentar un nombre de usuario y una contraseña. Ninguno protege la confidencialidad del secreto por sí solo: Basic usa una codificación que cualquiera puede revertir, y el método de SOCKS5 envía los valores tal cual salvo que otra cosa proteja la conexión. La confidencialidad depende del transporte entre el navegador y el proxy, de lo que registre el proveedor y de cómo trate el valor tu propio sistema. Esas piezas cambian de un despliegue a otro, así que una revisión debe nombrarlas en lugar de darlas por supuestas.
Los lugares por donde puede filtrarse una credencial son más numerosos de lo que parece. Un secreto puede acabar en el control de versiones, en una línea de comandos visible en la lista de procesos, en el registro de un trabajo que repite sus argumentos de lanzamiento, en un mensaje de error que cita la dirección del proxy, en una captura de un terminal, en una incidencia de soporte o en un archivo de configuración compartido. La higiene de credenciales consiste en decidir, para cada uno de estos lugares, si el secreto puede aparecer en él, y comprobar después que no aparece.
La configuración de rutas se explica en Configuración de proxy, y el modo en que los navegadores usan túneles CONNECT y cabeceras de proxy se describe en Semántica del proxy HTTP y solicitudes del navegador. Aquí el foco es la credencial misma: cómo se presenta, se escribe, se almacena, se rota y se mantiene fuera de los lugares que no le corresponden.
Cómo interpretar los fallos de autenticación 407, 401 y SOCKS
Cuando un proxy exige autenticación, responde a la solicitud con el estado 407 Proxy Authentication Required y una cabecera Proxy-Authenticate que indica el esquema que acepta. El cliente reintenta entonces con una cabecera Proxy-Authorization. RFC 9110 define ambas cabeceras y el estado, y las páginas de MDN sobre Proxy-Authorization y 407 los resumen para quienes desarrollan web. Lo importante es quién es el dueño del desafío: un 407 lo emite un proxy, así que identifica el tramo del proxy dentro de la ruta.
Una respuesta 401 Unauthorized es el desafío propio del destino. Lleva una cabecera WWW-Authenticate y se contesta con una cabecera Authorization. Los dos intercambios pueden darse durante una misma carga de página, y cada uno usa su propia credencial. Un 407 significa que el proxy no aceptó la credencial del proxy. Un 401 significa que el proxy aceptó la ruta y que el destino no aceptó el inicio de sesión. Confundirlos lleva la investigación al responsable equivocado y al secreto equivocado.
Los destinos HTTPS añaden un detalle más. El navegador pide primero al proxy que abra un túnel con una solicitud CONNECT, y la autenticación del proxy ocurre en esa solicitud. La sesión TLS del destino y cualquier desafío 401 aparecen solo cuando el túnel ya existe. Por eso un fallo de autenticación del proxy en una página HTTPS se manifiesta como un fallo al establecer el túnel, a menudo antes de cualquier contenido de la página, y no como una respuesta del sitio. Además, Proxy-Authorization está dirigida al proxy que la pidió y no se transmite al destino.
HTTP Basic se define en RFC 7617. El cliente une el nombre de usuario y la contraseña con dos puntos y aplica Base64. Base64 es una codificación reversible y no aporta secreto; la RFC indica que Basic no ofrece confidencialidad por sí solo y que debe usarse sobre una conexión protegida. Como los dos puntos son el separador, el nombre de usuario no puede contenerlos, mientras que la contraseña sí puede. Cuando una credencial contiene caracteres así, importa cómo se escriben en una URL.
SOCKS5 usa un intercambio distinto. Después de que el cliente y el servidor acuerdan el método de usuario y contraseña definido en RFC 1929, el cliente envía el nombre de usuario y la contraseña, cada uno de hasta 255 bytes, y el servidor responde con un estado. Un estado cero significa éxito. Cualquier otro valor es un fallo y el servidor cierra la conexión. El navegador no recibe una página 407, porque SOCKS no tiene códigos de estado HTTP. Un fallo de autenticación en una ruta SOCKS5 se manifiesta como una conexión rechazada o cerrada durante el establecimiento, por lo que el texto del error suele ser menos específico que una respuesta HTTP. El método no cifra los valores por sí mismo.
Un informe acotado de un fallo de autenticación nombra el tramo y la categoría, y nada más. Por ejemplo: "autenticación del proxy rechazada para la ruta R, desafío recibido, túnel no abierto". No incluye el valor de Proxy-Authorization, el nombre de usuario, la URL completa del proxy ni el cuerpo de la respuesta del proveedor. Informar del resultado como un error de autenticación, y no como un tiempo de espera agotado o un fallo de red genérico, mantiene correcta la acción siguiente: revisar la credencial y su caducidad, no la configuración de DNS ni el destino.
Los reintentos repetidos necesitan un límite. Una ruta que devuelve 407 tras recibir una credencial correcta suele seguir haciéndolo, y muchos reintentos rápidos pueden bloquear la cuenta o activar protecciones del lado del proveedor. Detente tras un número pequeño de intentos definido por tu propia política, marca la ruta como fallida con una categoría de autenticación y pásala al responsable que puede renovar o rotar la credencial. No pruebes otras credenciales que no se asignaron a la ruta con la esperanza de encontrar una que funcione.
Cómo escribir credenciales en una URL de proxy
Una URL de proxy sigue la sintaxis genérica de RFC 3986. Las credenciales van en el componente userinfo, antes del host: el esquema, después el nombre de usuario, dos puntos, la contraseña, una arroba, el host y el puerto. La misma RFC marca como obsoleta la forma de usuario y contraseña en userinfo porque pasar información de autenticación en texto claro ha demostrado ser un riesgo de seguridad. Eso es un motivo para tratar la cadena con cuidado, no para escribirla de otra manera, ya que muchas interfaces de lanzamiento esperan exactamente esta forma.
Varios caracteres tienen un significado dentro de una URL y deben codificarse con porcentaje cuando aparecen en un nombre de usuario o en una contraseña. La arroba cierra el userinfo, así que una arroba literal en una contraseña se leería como el inicio del host. La barra, el signo de interrogación y la almohadilla terminan la parte de autoridad. El signo de porcentaje inicia un valor codificado, así que uno literal debe codificarse también. Los dos puntos separan el nombre de usuario de la contraseña. Codificar un carácter significa sustituirlo por un signo de porcentaje y su código hexadecimal de dos dígitos.
Por ejemplo, la contraseña p@ss:word se escribe p%40ss%3Aword en la URL, y el valor completo podría ser http://svc_user:p%40ss%3Aword@proxy.example.com:8080. El host de ese ejemplo es un marcador de posición de documentación. Codifica por separado el nombre de usuario y la contraseña y solo después monta la URL, porque codificar la URL ya terminada cambiaría también sus separadores. Un auxiliar probado de la biblioteca estándar de tu lenguaje es más seguro que los reemplazos escritos a mano, como encodeURIComponent en JavaScript o urllib.parse.quote con un conjunto seguro vacío en Python.
Las herramientas interpretan el userinfo de formas ligeramente distintas, de modo que un valor que funciona en un cliente puede fallar en otro. Tras codificar, prueba la cadena exacta en la herramienta que la usará y trata un error de análisis como un problema de configuración. No debilites la codificación para que una cadena fallida pase. Una contraseña que incluya un signo más, un espacio o texto no ASCII merece su propia prueba, porque los codificadores no coinciden en esos caracteres; en una URL el espacio se escribe como %20, y el signo más pertenece a la codificación de formularios.
Una codificación incorrecta produce un fallo engañoso. Si una arroba sin codificar divide el userinfo en el lugar equivocado, la herramienta puede enviar al proxy una contraseña truncada y recibir un 407, o intentar resolver un host que no existe y notificar un error de red. En ambos casos la credencial estaba bien. Cuando un fallo aparece justo después de cambiar una contraseña, compara la cadena codificada antes de sospechar del proveedor.
Si un proveedor admite otro método de autenticación, como aceptar solicitudes desde una dirección de origen aprobada, quizá puedas lanzar con una URL sin userinfo. Eso retira el secreto de la línea de comandos, pero traslada la confianza a la dirección y a su responsable, así que regístralo como un método distinto, con su propio responsable y su propia revisión. Algunos proveedores no lo ofrecen, y las condiciones del proveedor deciden si puedes usarlo.
Mantén la URL literal fuera de los lugares que perduran. Los archivos de código, las imágenes de contenedor, el historial del shell y los comentarios de incidencias conservan los valores mucho después de que cambie una credencial. En esos lugares debe ir una referencia al secreto en lugar del valor.
Almacenar, rotar y ocultar credenciales
Guarda cada credencial de proxy en un gestor de secretos o en un almacén equivalente que tu organización ya controle, y refiérete a ella por su nombre. Entonces el registro de lanzamiento contiene una etiqueta de ruta, por ejemplo "regional-checks-eu", y una referencia al secreto, como el nombre de la entrada almacenada, y no la URL literal del proxy. Quien lea el registro puede saber qué ruta se usó y quién es su responsable sin poder utilizarla.
Resuelve la referencia lo más tarde posible. El lanzador obtiene el valor, codifica el nombre de usuario y la contraseña, construye la URL, inicia el navegador y no conserva el valor en su propio estado ni en sus registros. Construye la URL en el ámbito más reducido que puedas y no la escribas en un archivo que sobreviva al lanzamiento. Así la misma definición de trabajo sigue siendo válida tras una rotación, porque solo cambia el valor almacenado.
Sé claro sobre lo que expone un argumento de línea de comandos. Un argumento de lanzamiento es visible para otras cuentas del mismo host que pueden listar procesos, y puede ser capturado por agentes de monitorización, informes de fallos o la salida de inspección de un entorno de contenedores. Incrustar la credencial en el argumento no la hace privada en ese host. Restringe quién puede iniciar sesión en la máquina y leer la información de sus procesos, y prefiere credenciales limitadas a una ruta, con permisos acotados y de corta duración cuando el proveedor lo admita.
El ocultamiento es un control aparte y hay que probarlo en lugar de darlo por hecho. Los registros de trabajos, los scripts envoltorio, los gestores de errores y los informes de pruebas suelen imprimir los argumentos de lanzamiento cuando algo falla. Enmascara el userinfo antes de escribir una línea, sustituye la contraseña por un marcador fijo y enmascara también la forma codificada, porque un registro puede contener cualquiera de las dos. Después de un lanzamiento fallido, lee los archivos de salida reales y la lista de procesos, y busca en ellos el nombre de usuario y la contraseña, tanto en su forma original como codificada.
La rotación necesita un responsable y un plan. Decide con qué frecuencia se sustituye cada credencial, quién puede hacerlo y cómo llega el valor nuevo al lanzador. Sustituye el valor almacenado, vuelve a lanzar los contextos que usan esa ruta y confirma que el valor antiguo ya no funciona. Una rotación provocada por una sospecha de filtración exige además revisar dónde se escribió el valor antiguo, porque los registros y las incidencias pueden conservarlo después de que el proveedor lo revoque.
Da a cada ruta su propia credencial y su propia referencia. Cuando una credencial compartida sirve a muchas rutas y contextos, una sola rotación interrumpe esas rutas a la vez y una sola filtración expone a cada una de ellas. Las referencias separadas permiten sustituir la credencial de una ruta mientras las demás siguen funcionando con las suyas. Si el proveedor asocia las credenciales a un plan o a una subcuenta, refleja esa estructura en tu propia nomenclatura.
Los datos del lado del proveedor se quedan con el proveedor. Cuánto tiempo conserva un proveedor los registros de solicitudes, si registra el nombre de usuario, si la conexión con el proxy está protegida con TLS y cómo caducan las credenciales son aspectos propios de cada proveedor. Pídelos por escrito y guarda las respuestas junto a la ruta. No supongas que un esquema de apariencia segura en una URL significa que el primer tramo está cifrado: un proxy HTTPS protege la conexión con el proxy, un proxy HTTP no la protege, y una ruta SOCKS5 necesita su propia evaluación.
Mantén los inicios de sesión del destino fuera de este almacén. La contraseña de una cuenta del destino pertenece al titular de la cuenta y a la aplicación que inicia sesión, con su propio almacenamiento y su propia rotación. Colocarla junto a la credencial del proxy amplía quién puede leer cada una y ata dos rotaciones que no tienen relación.
Revisión operativa
Trata el manejo de credenciales como una propiedad que se verifica tras los cambios, no como un paso de configuración que se termina una sola vez. Repite la revisión tras un cambio de proveedor, un cambio de plan, una rotación de credencial, una actualización del lanzador, un cambio en el registro, una actualización mayor del navegador o la incorporación de una ruta nueva. Anota qué comprobaste, la etiqueta de ruta, la referencia al secreto y el resultado, sin copiar ningún secreto en el registro.
Asigna los roles igual que asignas las rutas. El responsable de la ruta decide qué credencial sirve a qué contexto y aprueba las rotaciones. El responsable de la plataforma controla el almacén de secretos y el flujo de registros. El responsable de la aplicación define lo que ve el usuario cuando una ruta no está disponible. Un traspaso breve entre estos tres responsables es una evidencia más sólida que un documento compartido con las credenciales pegadas dentro.
Define el resultado visible de un fallo de autenticación antes de que ocurra. Un trabajo puede detenerse con un mensaje claro de que la ruta requiere atención, una función puede mostrar un estado no disponible, o una ruta alternativa aprobada puede asumir el tráfico cuando tu política lo permita. Una conexión directa que casualmente carga la página no es una alternativa implícita. Cambia el límite de red y el origen del tráfico sin una decisión, de modo que no debe ser el resultado silencioso de una credencial fallida.
BotBrowser soporta credenciales de proxy incrustadas en la URL de --proxy-server para rutas HTTP, HTTPS, SOCKS5, SOCKS5H y QUIC, con codificación porcentual de los caracteres especiales, de modo que un operador puede aportar al lanzar las credenciales de una ruta aprobada sin page.authenticate(). BotBrowser no puede ofrecer almacenamiento de secretos, rotación ni ocultamiento en registros, y no hace que las credenciales incrustadas sean privadas frente a la lista de procesos o a los registros del proveedor; esos controles siguen en manos de tus herramientas de despliegue y del proveedor del proxy.
El enrutamiento por contexto ayuda a mantener separadas las referencias. Cuando un mismo despliegue de navegador atiende varios flujos aprobados, cada contexto puede usar su propia ruta y, por tanto, su propia credencial, como se describe en Proxy por contexto. Esa opción elige entre rutas que tu despliegue ya ha calificado; no emite ninguna credencial y no cambia lo que el proveedor permite.
Cuando una ruta falla la autenticación, las acciones responsables son renovar o rotar la credencial a través de su responsable, elegir otra ruta aprobada o detener el flujo. Buscar credenciales en otro lugar, tomar prestadas las de otro equipo o cambiar a otra cuenta de proveedor sin aprobación no se cuentan entre ellas. El registro debe mostrar qué acción se tomó y quién la tomó.
Los mensajes de estado y las respuestas de soporte deben usar el mismo vocabulario que el registro. "Autenticación del proxy rechazada" es más acotado y más útil que "error de red", y "se requiere inicio de sesión en el destino" indica que debe actuar otro responsable. Una redacción precisa evita que una incidencia se envíe al equipo equivocado y mantiene los secretos fuera de incidencias que muchas personas pueden leer.
Ejecuta las comprobaciones de higiene de credenciales
Aplica estas comprobaciones a cada ruta y anota aprobado o fallido en cada una, sin copiar ningún secreto en el registro.
- Sigue una solicitud fallida hasta su tramo. Aprobado si un 407 con un desafío Proxy-Authenticate se atribuye al tramo del proxy, un 401 con un desafío WWW-Authenticate se atribuye al destino, y ni el valor de Proxy-Authorization ni el de Authorization aparecen en el registro. Fallido si ambos se funden en una sola categoría de "inicio de sesión fallido".
- Lee el registro de lanzamiento. Aprobado si muestra una etiqueta de ruta y una referencia al secreto. Fallido si contiene una URL de proxy literal, un nombre de usuario o una contraseña.
- Busca el nombre de usuario y la contraseña, en forma original y codificada con porcentaje, en los registros de trabajos, la salida de errores y la lista de procesos de un lanzamiento normal y de uno fallido a propósito. Aprobado si los registros y la salida de errores no contienen coincidencias y la lista de procesos no tiene coincidencias o solo la pueden leer cuentas que aprobaste. Fallido si la credencial aparece en un registro, en la salida de errores o en una lista de procesos que otras cuentas pueden leer.
- Lanza con una contraseña de prueba que contenga caracteres reservados, como una arroba, dos puntos, una barra y un signo de porcentaje. Aprobado si la contraseña está codificada con porcentaje en la URL y la ruta se autentica. Fallido si la conexión funciona solo después de debilitar la codificación.
- Aporta una credencial incorrecta o caducada a propósito. Aprobado si la ejecución se detiene dentro de tu límite de reintentos y notifica un error de autenticación para la ruta indicada. Fallido si notifica un tiempo de espera agotado, un error de DNS o un fallo de red genérico, o si reintenta sin límite.
- Rota la credencial de una ruta. Aprobado si esa ruta se autentica con el valor nuevo, el valor antiguo es rechazado y las demás rutas y contextos siguen funcionando con sus propias referencias. Fallido si rotar una ruta cambia el resultado de otra.
- Repite las comprobaciones 1 a 6 tras un cambio de proveedor, un cambio de plan, una actualización del lanzador o una actualización mayor del navegador. Conserva el último registro aceptado hasta que la repetición se apruebe.
Fuentes
Artículos Relacionados
Lleva BotBrowser de la investigación a producción
Usa estas guías para entender el modelo y después avanzar hacia validación multiplataforma, contextos aislados y despliegue de navegador preparado para escalar.