Almacenamiento y transmisión de credenciales de proxy en CI/CD sin fugas: guía paso a paso
Contenido del artículo
- Introducción: cómo se filtran las credenciales de proxy en los registros y el historial
- Preparación preliminar: qué necesitará
- Conceptos básicos: términos en lenguaje sencillo
- Paso 1: entender la trampa principal: la contraseña en la url
- Paso 2: la forma correcta: variables de entorno y archivos de credenciales
- Paso 3: secretos en ci populares: github actions, gitlab ci, jenkins
- Paso 4: registros: desactivamos los modos que imprimen proxy-authorization
- Paso 5: rotación de la contraseña del proxy sin tiempo de inactividad en las compilaciones
- Paso 6: verificación de fugas: script de auditoría listo para usar
- Paso 7: lista de verificación antes de implementar el pipeline
- Verificación del resultado: cómo asegurarse de que todo funciona
- Errores típicos y soluciones
- Opciones adicionales: protección avanzada
- Faq: preguntas frecuentes
- Conclusión
Las credenciales de proxy terminan en los registros públicos de compilación más a menudo de lo que parece. Un simple curl -v descuidado, una variable expuesta, una contraseña dentro de la URL — y su usuario y contraseña ya están en el historial del pipeline, accesibles para todo el equipo. En esta guía, analizaremos cómo evitar que esto suceda.
Introducción: cómo se filtran las credenciales de proxy en los registros y el historial
Imagine una situación típica. Está configurando una compilación que usa el proxy Proxeon para acceder a recursos externos. Para verificar rápidamente la conexión, escribe un comando con la contraseña directamente en la URL: http://user:pass@host:port. La compilación funciona y usted se alegra. Pero una semana después, descubre que la contraseña es visible en el registro de cada ejecución, en el historial de shell del runner e incluso en la salida de depuración del cliente.
Esto no es una rareza, sino una tendencia. Las credenciales de proxy tienen una desagradable particularidad: se necesitan en casi cada llamada de red, por lo que es fácil que se filtren en docenas de lugares a la vez.
Qué obtendrá al final
Después de completar la guía, podrá configurar su CI/CD para que las credenciales de proxy no aparezcan en ningún registro, ni en el historial de comandos ni en el repositorio. Aprenderá a usar los secretos de los sistemas populares, desactivar modos de depuración peligrosos, cambiar la contraseña de forma segura sin detener las compilaciones y verificar todo con un script listo para usar.
Para quién es esta guía
El material está dirigido a ingenieros de nivel medio: DevOps, desarrolladores backend, automatizadores de QA. Si ya sabe cómo ejecutar un pipeline y sabe qué es una variable de entorno, se sentirá cómodo. Los lectores avanzados encontrarán secciones sobre rotación y auditoría.
Qué debe saber de antemano
Aquí no repasaremos la configuración básica de las variables http_proxy y no_proxy; eso se cubre en un material aparte. Se asume que la conexión al proxy ya funciona y que la tarea ahora es hacer que el almacenamiento de credenciales sea seguro.
Cuánto tiempo tomará
La lectura y comprensión tomará unos 40 minutos. La implementación en un solo pipeline puede tomar de 30 minutos a una hora y media, dependiendo del sistema de CI. La rotación y la verificación de fugas se pueden agregar después; cada una toma entre 15 y 20 minutos.
Preparación preliminar: qué necesitará
Antes de comenzar, reúna todo lo necesario. Esto le ahorrará tiempo y evitará interrupciones en medio del trabajo.
Herramientas y accesos
- Acceso a su proyecto en CI/CD con permisos para editar configuraciones y secretos.
- Una suscripción de proxy Proxeon activa con usuario, contraseña, host y puerto.
- Una máquina local con curl y git instalados, así como intérpretes de Python 3 y Node.js si planea usar esos ejemplos.
- Un editor de texto para modificar los archivos de configuración del pipeline.
Requisitos del sistema
No hay requisitos especiales. Todo funciona en Linux, macOS y Windows. Los runners de CI suelen usar Linux, por lo que la mayoría de los ejemplos se dan en sintaxis bash. Mencionaremos las diferencias para runners de Windows por separado.
Qué preparar con antelación
Guarde sus credenciales de proxy actuales en un administrador de contraseñas confiable. Las necesitará al configurar los secretos. No las guarde en un archivo de texto plano en su escritorio.
Consejo: Cree una cuenta de proxy separada solo para CI si su plan de Proxeon lo permite. Así, una posible fuga de las credenciales de compilación no afectará sus credenciales personales y viceversa.
Copia de seguridad de la configuración
Antes de modificar el pipeline, haga una copia de su archivo de configuración actual. Simplemente copie .gitlab-ci.yml, el archivo de workflow o Jenkinsfile en una carpeta separada fuera del repositorio.
⚠️ Atención: Nunca haga una copia de seguridad commiteándola en el mismo repositorio con la contraseña dentro. Incluso en una rama temporal, las credenciales quedarán en el historial de git para siempre.
Conceptos básicos: términos en lenguaje sencillo
Repasemos las palabras clave para no confundirnos más adelante.
Credenciales de proxy
Son el usuario y la contraseña con los que su cliente confirma su derecho a usar el proxy Proxeon. A veces se usa la vinculación por IP en lugar de usuario y contraseña, pero aquí hablamos específicamente del par usuario-contraseña.
Secreto en CI
Un secreto es un almacenamiento especial dentro del sistema de CI donde se coloca un valor sensible. El sistema lo cifra y lo inyecta en la compilación como una variable de entorno, ocultándolo automáticamente en los registros.
Enmascaramiento
El enmascaramiento es cuando el CI reemplaza el valor del secreto en la salida con asteriscos. Si la contraseña se imprime accidentalmente, verá algo como [MASKED] en su lugar. No siempre funciona perfectamente, por lo que combinaremos varias protecciones.
Encabezado Proxy-Authorization
Cuando el cliente se autentica en el proxy, envía el encabezado HTTP Proxy-Authorization con las credenciales codificadas. En el modo de depuración detallado, muchos clientes imprimen este encabezado completo. Decodificarlo es trivial, por lo que esa salida se considera una fuga.
Ámbito de visibilidad
El ámbito de visibilidad determina qué compilaciones pueden acceder al secreto. Un secreto limitado correctamente es visible solo para ramas protegidas y no llega a forks o pull requests externos.
Consejo: Recuerde el principio principal: el secreto debe existir en la memoria del proceso solo el tiempo necesario y no debe dejar rastros en el disco ni en la salida.
Paso 1: Entender la trampa principal: la contraseña en la URL
Objetivo de la etapa: aprender a reconocer la fuente de fugas más común y abandonarla para siempre.
El error más común es escribir las credenciales directamente en la dirección del proxy: http://user:pass@host:port. Es conveniente, por lo que casi todos los principiantes lo hacen. El problema es que esa URL aparece en lugares inesperados.
Dónde aparece exactamente la contraseña de la URL
- Lista de procesos. El comando ps en el runner mostrará la línea de comando completa, incluida la contraseña. Cualquier proceso en la misma máquina puede leerla.
- Registros del propio proxy. Algunos registros de servidor capturan la cadena de conexión. Si la URL contiene la contraseña, esta termina en el registro.
- Historial de comandos de shell. El archivo .bash_history guarda todo lo que escribió, incluida la contraseña en la URL.
- Salida de depuración del cliente. Cuando se ejecuta con el modo detallado, el cliente imprime la dirección de destino junto con las credenciales.
- Registros de CI. Si la variable con la URL no está marcada como secreta, se imprime en texto plano en la etapa de echo o al producirse un error.
Compruébelo ahora mismo. Ejecute un comando inofensivo en cualquier máquina y observe la lista de procesos.
curl -x http://myuser:mypass@proxy.proxeon.net:8080 https://example.com & ps aux | grep curlVerá su contraseña en texto plano en la salida de ps. Esta es la fuga que vamos a eliminar.
⚠️ Atención: Incluso si la compilación es privada, otro proceso, otro job en un runner compartido o una herramienta de monitoreo pueden tener acceso a la lista de procesos del runner. Considere la contraseña en la URL como pública.
Resultado esperado: comprende los cinco lugares de fuga y nunca más escribirá la contraseña dentro de la dirección del proxy.
✅ Verificación: ejecute el comando de prueba anterior y asegúrese de ver la contraseña en la salida de ps. Si la ve, ha reproducido el problema correctamente y está listo para resolverlo.
Paso 2: La forma correcta: variables de entorno y archivos de credenciales
Objetivo de la etapa: trasladar las credenciales de la URL a almacenamientos seguros: variables de entorno y archivos especiales.
La idea es simple. El usuario y la contraseña se guardan por separado de la dirección. El cliente los lee del entorno o de un archivo con permisos restringidos, no de la línea de comandos. Así no terminan en la lista de procesos ni en el historial.
Opción A: variables de entorno
Muchos clientes pueden leer las credenciales de proxy del entorno. Veamos ejemplos.
curl mediante variable de entorno
Establezca la dirección del proxy sin credenciales y pase el usuario y la contraseña con una bandera separada, cuyo valor tome de una variable.
- Exporte la variable con las credenciales al entorno (en CI lo hará un secreto; localmente, una fuente segura).
- Pase su valor mediante la bandera -U, no en la URL.
export PROXY_CREDS="$PROXEON_USER:$PROXEON_PASS"; curl -x http://proxy.proxeon.net:8080 -U "$PROXY_CREDS" https://example.comIncluso la bandera -U con una variable es mejor que la contraseña en la URL, pero también es visible en ps. Por eso, es preferible un archivo de credenciales, como se explica a continuación.
Python requests
En Python, lea las credenciales del entorno con os.environ y construya el diccionario de proxies en memoria. No imprima nada.
import os, requests; user=os.environ['PROXEON_USER']; pwd=os.environ['PROXEON_PASS']; proxy=f'http://{user}:{pwd}@proxy.proxeon.net:8080'; r=requests.get('https://example.com', proxies={'http':proxy,'https':proxy}); print(r.status_code)Aquí, la contraseña permanece en la variable dentro del proceso de Python y no se expone en la línea de comandos. Lo principal es no registrar la variable proxy completa.
Node.js
En Node, también tome las credenciales de process.env y construya el agente de proxy en el código.
const user=process.env.PROXEON_USER; const pass=process.env.PROXEON_PASS; const proxyUrl=`http://${user}:${pass}@proxy.proxeon.net:8080`; const {HttpsProxyAgent}=require('https-proxy-agent'); const agent=new HttpsProxyAgent(proxyUrl); fetch('https://example.com',{agent}).then(r=>console.log(r.status));Consejo: En cualquier lenguaje, registre solo el estado de la respuesta y, si es necesario, el host de destino. Nunca imprima el objeto de configuración del proxy completo: contiene la contraseña.
Opción B: archivo .netrc
El archivo .netrc es la forma clásica de guardar credenciales por separado de los comandos. curl puede leerlo automáticamente.
- Cree el archivo .netrc en el directorio de inicio del runner sobre la marcha, a partir del secreto de CI.
- Escriba una línea con la máquina, el usuario y la contraseña.
- Establezca los permisos 600 para que solo el propietario pueda leerlo.
- Ejecute curl con la bandera para usar netrc.
printf 'machine proxy.proxeon.net login %s password %s' "$PROXEON_USER" "$PROXEON_PASS" > ~/.netrc; chmod 600 ~/.netrc; curl --netrc -x http://proxy.proxeon.net:8080 https://example.comAhora la contraseña no aparece ni en la línea de comandos ni en la lista de procesos. Está en un archivo con permisos 600, que eliminará al final de la compilación.
⚠️ Atención: Los permisos 600 son obligatorios. Sin ellos, curl puede negarse a leer el archivo y este quedará accesible para otros usuarios de la máquina.
Opción C: archivo de configuración de curl
curl puede leer las banderas de un archivo de configuración. Coloque allí el proxy y las credenciales, y establezca permisos 600.
printf 'proxy = http://proxy.proxeon.net:8080\nproxy-user = "%s:%s"\n' "$PROXEON_USER" "$PROXEON_PASS" > ~/.curlrc; chmod 600 ~/.curlrc; curl https://example.comCon un .curlrc con permisos 600, las credenciales no son visibles en el proceso ni se escriben en el historial.
Opción D: archivo de configuración del cliente de la aplicación
Si tiene una aplicación propia que lee la configuración, guarde las credenciales de proxy en un archivo de configuración fuera del repositorio. En el repositorio, mantenga solo una plantilla con marcadores de posición, y los valores reales se inyectan en el runner desde los secretos.
Resultado esperado: en ningún ejemplo la contraseña aparece en la línea de comandos ni en la lista de procesos. Vive en la variable dentro del proceso o en un archivo con permisos 600.
✅ Verificación: ejecute cualquier ejemplo y, en paralelo, ejecute ps aux | grep curl. No debe haber contraseña en la salida. Si usa netrc, verifique los permisos con ls -l ~/.netrc: debe ser -rw-------.
Paso 3: Secretos en CI populares: GitHub Actions, GitLab CI, Jenkins
Objetivo de la etapa: colocar las credenciales de proxy en el almacenamiento protegido de su sistema de CI e inyectarlas sin fugas.
GitHub Actions
En GitHub, los secretos se almacenan a nivel de repositorio u organización.
- Abra el repositorio y vaya a la sección de configuración Settings.
- A la izquierda, encuentre el elemento Secrets and variables y luego Actions.
- Haga clic en el botón New repository secret.
- Ingrese el nombre, por ejemplo PROXEON_USER, y el valor: su usuario. Guarde.
- Repita para PROXEON_PASS con la contraseña.
En el workflow, acceda a los secretos mediante el contexto secrets y pase los valores al paso como variables de entorno.
steps: - name: request env: PROXEON_USER: ${{ secrets.PROXEON_USER }} PROXEON_PASS: ${{ secrets.PROXEON_PASS }} run: printf 'machine proxy.proxeon.net login %s password %s' "$PROXEON_USER" "$PROXEON_PASS" > ~/.netrc; chmod 600 ~/.netrc; curl --netrc -x http://proxy.proxeon.net:8080 https://example.comGitHub enmascara automáticamente los valores de los secretos en los registros. Si la contraseña se imprime accidentalmente, verá tres asteriscos.
⚠️ Atención: De forma predeterminada, los secretos no están disponibles en los workflows que se ejecutan desde forks mediante pull_request. No cambie este comportamiento a pull_request_target sin una necesidad muy justificada; así, un colaborador externo podría obtener sus credenciales.
GitLab CI
En GitLab, los secretos se denominan variables de CI/CD y se configuran en el proyecto.
- Abra el proyecto, vaya a Settings y luego a CI/CD.
- Expanda la sección Variables y haga clic en Add variable.
- Ingrese la clave PROXEON_USER y el valor.
- Marque la casilla Masked para que el valor se oculte en los registros.
- Marque la casilla Protected para que la variable esté disponible solo para ramas y etiquetas protegidas.
- Repita para PROXEON_PASS.
En .gitlab-ci.yml, las variables están disponibles automáticamente como entorno.
request: script: - printf 'machine proxy.proxeon.net login %s password %s' "$PROXEON_USER" "$PROXEON_PASS" > ~/.netrc - chmod 600 ~/.netrc - curl --netrc -x http://proxy.proxeon.net:8080 https://example.comConsejo: La casilla Masked en GitLab solo funciona para valores que cumplen ciertas reglas: longitud mínima, sin saltos de línea y un conjunto de caracteres compatible con base64. Si la contraseña no se enmascara, GitLab mostrará una advertencia al guardarla. En ese caso, cambie la contraseña para que cumpla los requisitos.
Jenkins
En Jenkins, las credenciales se almacenan en la sección Credentials y se inyectan mediante el plugin Credentials Binding.
- Abra Manage Jenkins y luego Credentials.
- Elija el ámbito apropiado, por ejemplo System y Global credentials.
- Haga clic en Add Credentials.
- Elija el tipo Username with password.
- Ingrese el usuario y la contraseña del proxy, y asigne un ID claro, por ejemplo proxeon-creds.
En el Jenkinsfile, envuelva el uso en el bloque withCredentials. Jenkins enmascara los valores en la consola.
withCredentials([usernamePassword(credentialsId: 'proxeon-creds', usernameVariable: 'PROXEON_USER', passwordVariable: 'PROXEON_PASS')]) { sh 'printf "machine proxy.proxeon.net login %s password %s" "$PROXEON_USER" "$PROXEON_PASS" > ~/.netrc; chmod 600 ~/.netrc; curl --netrc -x http://proxy.proxeon.net:8080 https://example.com' }⚠️ Atención: Jenkins enmascara solo los valores proporcionados mediante Credentials Binding. Si construye la contraseña con una cadena en Groovy y la imprime, el enmascaramiento no funcionará. Trabaje con las credenciales solo dentro del bloque withCredentials y solo en pasos sh.
Resultado esperado: las credenciales están en el almacenamiento protegido de su sistema de CI, se inyectan en la compilación como entorno y se enmascaran en los registros.
✅ Verificación: ejecute la compilación y abra el registro. Asegúrese de ver asteriscos o un marcador de enmascaramiento en lugar de la contraseña. Intente imprimir deliberadamente la variable con echo: el sistema debería ocultarla.
Paso 4: Registros: desactivamos los modos que imprimen Proxy-Authorization
Objetivo de la etapa: eliminar la salida detallada donde se revela el encabezado de autorización, y mantener un nivel de registro seguro.
El enmascaramiento de CI no es una panacea. Si el cliente imprime el encabezado Proxy-Authorization en base64 y el sistema no conoce la contraseña original palabra por palabra, el enmascaramiento puede fallar. Por eso, desactivamos los modos peligrosos en el origen.
curl
La bandera -v y especialmente --trace imprimen los encabezados, incluida la autorización del proxy. En CI, use el modo silencioso.
- Quite -v, --verbose, --trace y --trace-ascii de los comandos de compilación.
- Para controlar errores, use -sS: silencioso, pero muestra errores.
- Si necesita depuración, aplique --trace solo localmente y nunca en CI.
curl -sS --netrc -x http://proxy.proxeon.net:8080 https://example.com -o /dev/null -w '%{http_code}'Así obtendrá solo el código de respuesta sin ningún encabezado en la salida.
Python requests
La biblioteca requests no imprime credenciales por sí sola, pero el registro de urllib3 habilitado en nivel DEBUG muestra los encabezados de las solicitudes. Mantenga el nivel de registro en WARNING o INFO.
import logging; logging.getLogger('urllib3').setLevel(logging.WARNING)Consejo: Si para diagnosticar necesita DEBUG, agregue un filtro de registro que recorte el encabezado Proxy-Authorization de los mensajes. Pero es más fácil diagnosticar localmente y mantener WARNING en CI.
Node.js
En Node, evite establecer la variable NODE_DEBUG=http en CI: imprime los encabezados. Tampoco imprima el objeto del agente ni el objeto de la solicitud completos.
- Quite NODE_DEBUG del entorno del runner.
- En los manejadores de errores, imprima solo error.message, no el objeto completo.
- No use bibliotecas de registro de solicitudes HTTP en compilaciones de producción.
⚠️ Atención: El stack trace de una excepción no controlada también puede contener la URL del proxy con credenciales si construyó la URL con la contraseña. Esta es otra razón para no poner la contraseña en la URL, sino usar netrc o campos separados.
Resultado esperado: ninguna herramienta en CI imprime el encabezado de autorización ni la URL completa del proxy.
✅ Verificación: ejecute la compilación y busque en el registro las líneas Proxy-Authorization, Basic y su nombre de usuario. No debe haber ninguna coincidencia.
Paso 5: Rotación de la contraseña del proxy sin tiempo de inactividad en las compilaciones
Objetivo de la etapa: aprender a cambiar la contraseña para que las compilaciones no fallen y la contraseña anterior deje de funcionar.
La contraseña del proxy se debe cambiar periódicamente y, obligatoriamente, ante cualquier sospecha de fuga. La tarea es hacerlo sin ventana de inactividad.
Estrategia de solapamiento
La opción ideal es que durante un tiempo funcionen tanto la contraseña antigua como la nueva. Si su plan de Proxeon permite crear una segunda cuenta o un conjunto adicional de credenciales, use esta opción.
- Cree nuevas credenciales de proxy en el panel de control de Proxeon sin eliminar las antiguas.
- Agregue los nuevos valores a los secretos de CI con nombres temporales, por ejemplo PROXEON_USER_NEW.
- Cambie el pipeline a los nuevos nombres en una rama separada y ejecute la compilación.
- Asegúrese de que la compilación funcione con las nuevas credenciales.
- Reemplace los valores de los secretos principales PROXEON_USER y PROXEON_PASS por los nuevos.
- Elimine los secretos temporales.
- Revogue las credenciales antiguas en el panel de Proxeon.
Así, en todo momento hay un conjunto de credenciales funcional y las compilaciones no fallan.
Si el solapamiento no está disponible
Cuando solo hay un par de credenciales, actúe en una ventana de baja actividad.
- Elija un momento con mínima actividad de compilaciones.
- Pause el lanzamiento de nuevos pipelines por unos minutos.
- Cambie la contraseña en el panel de Proxeon.
- Actualice inmediatamente el valor del secreto en CI.
- Ejecute una compilación de verificación.
- Reanude la actividad normal.
Consejo: Prepare un procedimiento corto de rotación y guárdelo junto con la descripción del pipeline. En una situación de estrés tras una fuga, una lista de pasos ya preparada le ahorra nervios y tiempo.
⚠️ Atención: Después de cambiar la contraseña, elimine siempre el archivo netrc o curlrc antiguo del runner si se almacena en caché entre compilaciones. De lo contrario, el cliente seguirá usando las credenciales antiguas.
Resultado esperado: la contraseña se cambió, las nuevas compilaciones usan las nuevas credenciales y la contraseña antigua ya no funciona.
✅ Verificación: intente realizar una solicitud con la contraseña antigua: debe devolver un error de autorización del proxy. La nueva compilación debe completarse con éxito.
Paso 6: Verificación de fugas: script de auditoría listo para usar
Objetivo de la etapa: asegurarse de que no haya credenciales en los artefactos, registros y el repositorio, y automatizar esta verificación.
Dónde buscar
- Artefactos de compilación: archivos compilados, informes, volcados.
- Registros del pipeline, incluidos los antiguos.
- Historial del repositorio git.
- Cachés y archivos temporales del runner.
Búsqueda en artefactos y registros
Descargue los artefactos y registros en una carpeta local y busque marcadores característicos: nombre de usuario, parte de la contraseña, la palabra Basic y el encabezado de autorización.
grep -RniE 'proxy-authorization|Basic [A-Za-z0-9+/=]{8,}|proxeon.*login|:[^@/]+@proxy' ./artifacts ./logsEl script busca el encabezado de autorización, cadenas base64 después de la palabra Basic, el patrón de inicio de sesión en netrc y el indicio de contraseña en la URL antes del símbolo de arroba. Cualquier coincidencia es motivo de investigación.
Búsqueda en el historial de git
La contraseña podría haber entrado en un commit antiguo. Verifique todo el historial.
git log -p -S 'proxy.proxeon.net' --all | grep -nE ':[^@/]+@proxy|password [^ ]+'⚠️ Atención: Si la contraseña se encuentra en el historial de git, eliminar el archivo no es suficiente: permanecerá en los commits antiguos. Es necesario reescribir el historial con herramientas especiales y, lo más importante, cambiar la contraseña de inmediato. Considere que esa contraseña está comprometida.
Automatización en el pipeline
Agregue un job separado que escanee los artefactos compilados antes de publicarlos y falle si encuentra algo. Este protector detecta la fuga antes de que salga al exterior.
leak_check: script: - if grep -RniE 'proxy-authorization|Basic [A-Za-z0-9+/=]{8,}' ./artifacts; then echo 'LEAK DETECTED'; exit 1; fiConsejo: Adicionalmente, conecte escáneres de secretos listos para usar en la etapa pre-commit localmente. Capturan las credenciales antes de que lleguen al commit y evitan que entren al repositorio.
Resultado esperado: la auditoría manual y el job automático confirman que no hay credenciales en ningún lugar.
✅ Verificación: ejecute el script de auditoría: debe terminar sin coincidencias. Luego, coloque deliberadamente una línea de prueba con el marcador Basic en un artefacto y asegúrese de que el script la encuentre y falle.
Paso 7: Lista de verificación antes de implementar el pipeline
Objetivo de la etapa: realizar la verificación final antes de poner el pipeline en funcionamiento.
Recorra la lista y marque cada elemento. Si falta alguno, no implemente el pipeline.
- La contraseña del proxy no está escrita en ninguna URL del tipo user:pass@host.
- El usuario y la contraseña se almacenan solo en los secretos de CI, no en archivos del repositorio.
- Los secretos están marcados como enmascarables y protegidos.
- Los secretos no están disponibles para compilaciones de forks ni pull requests externos.
- De los comandos se eliminaron las banderas de modo detallado y de traza.
- El nivel de registro de las bibliotecas HTTP no es DEBUG.
- Las variables de depuración como NODE_DEBUG no están en el entorno del runner.
- Los archivos netrc y curlrc se crean sobre la marcha y tienen permisos 600.
- Los archivos de credenciales se eliminan al final de la compilación o están en un runner efímero.
- El pipeline tiene un job de verificación de fugas.
- El historial de git está verificado y no contiene credenciales.
- Existe un procedimiento de rotación de contraseñas.
Consejo: Guarde esta lista como plantilla y adjúntela a cada nuevo pipeline que use un proxy. La uniformidad reduce la cantidad de errores.
✅ Verificación: los doce elementos están marcados. Solo entonces el pipeline está listo para implementarse.
Verificación del resultado: cómo asegurarse de que todo funciona
Recopilemos la verificación final en un escenario único.
Lista de verificación de funcionamiento
- La compilación accede con éxito al proxy Proxeon y obtiene las respuestas esperadas.
- En el registro de la compilación no hay contraseña, usuario, cadenas base64 de autorización ni URL completa del proxy.
- En la lista de procesos del runner durante la solicitud no aparece la contraseña.
- Los artefactos están limpios; el script de auditoría no encuentra coincidencias.
- Los secretos se enmascaran incluso con un echo intencional.
Cómo probarlo
- Ejecute el pipeline completo de principio a fin.
- Abra el registro y busque el nombre de usuario: no debe haber coincidencias.
- Descargue los artefactos y ejecute el script de auditoría sobre ellos.
- Verifique el job de verificación de fugas: debe pasar en verde.
Indicadores de éxito
El éxito se ve así: la compilación es verde, las solicitudes a través del proxy funcionan y la búsqueda en todos los lugares posibles no encuentra ningún fragmento de credenciales. Si es así, ha logrado el objetivo de la guía.
Errores típicos y soluciones
Analicemos los problemas comunes con el esquema problema, causa, solución.
Problema 1: la contraseña sigue siendo visible en el registro
Causa: la variable se creó como normal, no como secreto, o no se marcó como enmascarable.
Solución: mueva el valor a la sección de secretos, active el enmascaramiento y verifique que el nombre de la variable coincida en la configuración y en el almacenamiento.
Problema 2: el enmascaramiento no funciona en GitLab
Causa: la contraseña contiene caracteres o saltos de línea no permitidos para el enmascaramiento.
Solución: cambie la contraseña por una cadena de letras, números y caracteres permitidos con la longitud suficiente, que cumpla los requisitos de enmascaramiento.
Problema 3: curl no lee netrc
Causa: el archivo tiene permisos incorrectos o no está en el directorio de inicio.
Solución: establezca permisos 600 con chmod y asegúrese de que la ruta al archivo coincida con la esperada, o especifique la ruta con la bandera netrc-file.
Problema 4: contraseña en el stack trace al producirse un error
Causa: la URL del proxy se construyó con credenciales y el cliente la imprime en la excepción.
Solución: cambie a netrc o a campos separados de usuario y contraseña para que la URL no contenga credenciales, e imprima solo el mensaje de error.
Problema 5: la contraseña antigua sigue usándose después de la rotación
Causa: el archivo netrc o curlrc en caché permaneció en el runner.
Solución: elimine los archivos de credenciales al final de cada compilación y use runners efímeros donde el sistema de archivos se limpia entre ejecuciones.
Problema 6: el secreto se filtró en un pull request de un fork
Causa: se activó un modo que otorga acceso a los secretos a PR externos.
Solución: desactive ese modo, ejecute las compilaciones con secretos solo para ramas de confianza y realice la verificación de PR externos sin acceso al proxy.
Problema 7: la contraseña se encontró en el historial de git
Causa: alguna vez se confirmaron credenciales en un archivo de configuración.
Solución: cambie la contraseña de inmediato y luego reescriba el historial del repositorio para eliminar los datos sensibles de todos los commits.
Opciones adicionales: protección avanzada
Cuando la protección básica esté configurada, puede reforzarla.
Administrador de secretos externo
En lugar de almacenar las credenciales en el propio sistema de CI, conecte un administrador de secretos externo. El pipeline obtiene las credenciales mediante un token de corta duración solo durante la compilación. Así, los secretos no permanecen en la configuración del proyecto de forma constante.
Tokens de corta duración en lugar de contraseña
Si la infraestructura de Proxeon y su esquema de acceso lo permiten, prefiera tokens temporales con vida útil limitada. Incluso con una fuga, un token así se vuelve inútil rápidamente.
Separación de credenciales por entornos
Use credenciales diferentes para las compilaciones de prueba y las de producción. El compromiso de las credenciales de prueba no afectará los procesos de producción.
Consejo: Configure alertas sobre actividad anómala en la cuenta de proxy. Un aumento brusco de solicitudes o conexiones desde fuentes inesperadas es una señal de posible fuga que requiere rotación inmediata.
Rotación automática
Los equipos avanzados automatizan la rotación con un programador: un script crea nuevas credenciales, actualiza el secreto y revoca las antiguas sin intervención humana. Comience con un procedimiento manual y agregue la automatización cuando el proceso esté pulido.
FAQ: Preguntas frecuentes
¿Puedo simplemente confiar en el enmascaramiento de CI y no preocuparme?
No. El enmascaramiento solo detecta coincidencias exactas de un valor conocido. Un encabezado en base64 o una salida parcial puede pasarlo por alto. Combine el enmascaramiento con la eliminación de la contraseña en la URL y la desactivación de los registros detallados.
¿Qué es más seguro: variable de entorno o archivo netrc?
El archivo netrc con permisos 600 es preferible para curl porque el valor ni siquiera aparece en la lista de procesos. Para código en Python y Node, las variables de entorno leídas dentro del proceso son más convenientes. Ambas opciones son seguras con un manejo cuidadoso.
¿Es necesario eliminar el archivo de credenciales después de la compilación?
Sí, si el runner se reutiliza. En runners efímeros, donde la máquina se destruye después de la compilación, es menos crítico, pero eliminar el archivo al final es un buen hábito en cualquier caso.
¿Qué hago si la contraseña del proxy contiene caracteres especiales?
En netrc y en campos separados, los caracteres especiales no suelen ser un problema. Los problemas surgen precisamente al insertarla en una URL, donde caracteres como el arroba y los dos puntos rompen el análisis. Este es otro argumento para no poner la contraseña en la URL.
¿Imprime requests las credenciales por sí solo?
De forma predeterminada, no. La fuga ocurre cuando está habilitado el registro DEBUG de urllib3 o al imprimir el objeto de configuración del proxy. Mantenga el registro en WARNING y no imprima la configuración completa.
¿Es visible la contraseña en la lista de procesos cuando uso la bandera proxy-user?
Sí, la bandera en la línea de comandos es visible en ps. Por eso, para curl es preferible netrc o curlrc, donde las credenciales no se pasan como argumento.
¿Con qué frecuencia debo cambiar la contraseña del proxy?
La rotación planificada es razonable hacerla de forma periódica, por ejemplo trimestralmente, y de inmediato ante cualquier sospecha de fuga. El procedimiento de rotación del paso 5 le ayudará a hacerlo rápido.
¿Puedo almacenar las credenciales en un archivo cifrado en el repositorio?
Técnicamente sí, pero complica el proceso y crea el riesgo de fuga de la clave de cifrado. Los secretos de CI y los administradores de secretos externos resuelven el problema de forma más simple y segura. No invente su propio almacenamiento sin necesidad.
¿Qué hago si la fuga ya ocurrió?
Actúe en orden: cambie la contraseña del proxy de inmediato, revoque las credenciales antiguas, encuentre todos los lugares de fuga con el script de auditoría, reescriba el historial de git si es necesario y analice la causa para que no se repita.
¿Estas recomendaciones funcionan para runners de Windows?
Sí, los principios son los mismos. Cambia la sintaxis: en lugar de export, use la forma de establecer variables para su shell, y en lugar de chmod use la configuración de permisos a través de las propiedades del archivo. La lógica de almacenamiento y desactivación de registros es idéntica.
Conclusión
Ha recorrido el camino desde el hábito inseguro de escribir la contraseña en la URL hasta la protección completa de las credenciales de proxy en CI/CD. Recordemos lo que se ha hecho.
Aprendió a reconocer los cinco lugares de fuga y abandonó la contraseña en la dirección del proxy. Trasladó las credenciales a variables de entorno y a archivos netrc, curlrc y configuraciones de cliente con permisos 600. Configuró secretos en GitHub Actions, GitLab CI y Jenkins con enmascaramiento y ámbito de visibilidad limitado. Desactivó los registros detallados que imprimen el encabezado de autorización en curl, Python requests y Node. Dominó la rotación de contraseña sin tiempo de inactividad en las compilaciones y creó un script de auditoría de fugas listo para usar. Finalmente, completó la lista de verificación final antes de implementar.
Qué hacer a continuación. Implemente la lista de verificación como etapa obligatoria de revisión en todos los pipelines que usen el proxy Proxeon. Agregue el job de verificación de fugas a todos los proyectos. Gradualmente, pase al administrador de secretos externo y a tokens de corta duración cuando el proceso básico se vuelva un hábito.
Hacia dónde avanzar. Estudie las prácticas de gestión de secretos a escala de organización, rotación automática y monitoreo de anomalías en la cuenta de proxy. La seguridad de las credenciales no es una configuración única, sino una disciplina de ingeniería constante. Pero ahora tiene una base sólida sobre la que construir todo lo demás. Compilaciones exitosas y seguras.