Soporte de registro de TIBCO BW ECS

Soporte de registro de TIBCO BW ECS

El soporte de registro de TIBCO BW ECS se está convirtiendo en una característica demandada debido al uso creciente del Esquema Común de Elastic para la solución de agregación de registros basada en la pila de Elastic (anteriormente conocida como pila ELK)

Ya hemos comentado mucho sobre la importancia de las soluciones de agregación de registros y sus beneficios, especialmente al discutir la arquitectura de contenedores. Debido a eso, hoy nos centraremos en cómo podemos adaptar nuestras aplicaciones BW para soportar este nuevo formato de registro.

Porque lo primero que necesitamos saber es la siguiente afirmación: Sí, esto se puede hacer. Y se puede hacer independientemente de su modelo de implementación. Por lo tanto, la solución proporcionada aquí funciona tanto para soluciones locales como para implementaciones en contenedores utilizando BWCE.

Antecedentes del Registro de TIBCO BW

TIBCO BusinessWorks (contenedor o no) se basa en sus capacidades de registro en la biblioteca logback, y esta biblioteca se configura utilizando un archivo llamado logback.xml que podría tener la configuración que necesita, como puede ver en la imagen a continuación:

BW ECS Logging: Ejemplo de configuración predeterminada de Logback.xml

Logback es una biblioteca bien conocida para desarrollos basados en Java y tiene una arquitectura basada en una solución central y complementos que extienden sus capacidades actuales. Es este enfoque de complemento el que vamos a utilizar para soportar ECS.

Incluso en la documentación oficial de ECS se cubre la configuración para habilitar esta configuración de registro cuando se utiliza la solución Logback, como puede ver en la imagen a continuación y en este enlace oficial:

BW ECS Logging: Información de Dependencia de ECS Java

En nuestro caso, no necesitamos agregar la dependencia en ningún lugar, sino simplemente descargar la dependencia, ya que necesitaremos incluirla en los paquetes OSGI existentes para la instalación de TIBCO BW. Solo necesitaremos dos archivos que son los siguientes:

  • ecs-logging-core-1.5.0.jar
  • logback-ecs-encoder-1.5.0.jar

En el momento de escribir este artículo, las versiones actuales son 1.5.0 para cada uno de ellos, pero manténgase atento para asegurarse de que está utilizando una versión reciente de este software para evitar problemas con el soporte y las vulnerabilidades.

Una vez que tengamos estas bibliotecas, necesitamos agregarlas a la instalación del sistema BW, y necesitamos hacerlo de manera diferente si estamos utilizando una instalación local de TIBCO o una instalación base de TIBCO BW. Para ser honesto, las cosas que necesitamos hacer son las mismas; el proceso de hacerlo es diferente.

Porque, al final, lo que necesitamos hacer es solo una tarea simple. Incluir estos archivos JAR como parte del paquete OSGI actual de logback que carga TIBCO BW. Así que, veamos cómo podemos hacer eso y comenzar con una instalación local. Usaremos la versión TIBCO BWCE 2.8.2 como ejemplo, pero se requerirán pasos similares para otras versiones.

La instalación local es la forma más fácil de hacerlo, pero solo porque tiene menos pasos que cuando lo hacemos en una imagen base de TIBCO BWCE. Así que, en este caso, iremos a la siguiente ubicación: <TIBCO_HOME>/bwce/2.8/system/shared/com.tibco.tpcl.logback_1.2.1600.002/

  • Colocaremos los JARs descargados en esa carpeta
BW ECS Logging: Ubicación del JAR
  • Abriremos el META-INF/MANIFEST.MF y haremos las siguientes modificaciones:
    • Agregar esos JARs a la sección Bundle-Classpath:
BW ECS Logging: Cambios en Bundle-Classpath
  • Incluir el siguiente paquete (co.elastic.logging.logback) como parte de los paquetes exportados agregándolo a la sección Exported-package:
BW ECS Logging: Cambios en Export-Package

Una vez hecho esto, nuestra instalación de TIBCO BW soporta el formato ECS. y solo necesitamos configurar el logback.xml para usarlo, y podemos hacerlo confiando en la documentación oficial en la página de ECS. Necesitamos incluir el siguiente codificador, como se muestra a continuación:

 <encoder class="co.elastic.logging.logback.EcsEncoder">
    <serviceName>mi-aplicación</serviceName>
    <serviceVersion>mi-versión-de-aplicación</serviceVersion>
    <serviceEnvironment>mi-entorno-de-aplicación</serviceEnvironment>
    <serviceNodeName>mi-nodo-de-clúster-de-aplicación</serviceNodeName>
</encoder>

Por ejemplo, si modificamos el archivo de configuración predeterminado logback.xml con esta información, tendremos algo como esto:

<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true">
  
  <!-- *=============================================================* -->
  <!-- *  APPENDER: Console Appender                                 * -->
  <!-- *=============================================================* -->  
  <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
    <encoder class="co.elastic.logging.logback.EcsEncoder">
      <serviceName>a</serviceName>
      <serviceVersion>b</serviceVersion>
      <serviceEnvironment>c</serviceEnvironment>
      <serviceNodeName>d</serviceNodeName>
  </encoder>
  </appender>



  <!-- *=============================================================* -->
  <!-- * LOGGER: Thor Framework loggers                              * -->
  <!-- *=============================================================* -->
  <logger name="com.tibco.thor.frwk">
    <level value="INFO"/>
  </logger>
  
  
  
  <!-- *=============================================================* -->
  <!-- * LOGGER: BusinessWorks Framework loggers                     * -->
  <!-- *=============================================================* -->
  <logger name="com.tibco.bw.frwk">
    <level value="WARN"/>
  </logger>  
  
  <logger name="com.tibco.bw.frwk.engine">
    <level value="INFO"/>
  </logger>   
  
  
  <!-- *=============================================================* -->
  <!-- * LOGGER: BusinessWorks Engine loggers                        * -->
  <!-- *=============================================================* --> 
  <logger name="com.tibco.bw.core">
    <level value="WARN"/>
  </logger>
  
  <logger name="com.tibco.bx">
    <level value="ERROR"/>
  </logger>

  <logger name="com.tibco.pvm">
    <level value="ERROR"/>
  </logger>
  
  <logger name="configuration.management.logger">
    <level value="INFO"/>
  </logger>
  
  
  <!-- *=============================================================* -->
  <!-- * LOGGER: BusinessWorks Palette and Activity loggers          * -->
  <!-- *=============================================================* -->
  
  <!-- Default Log activity logger -->
  <logger name="com.tibco.bw.palette.generalactivities.Log">
    <level value="DEBUG"/>
  </logger>
  
  <logger name="com.tibco.bw.palette">
    <level value="ERROR"/>
  </logger>

  
  
  <!-- *=============================================================* -->
  <!-- * LOGGER: BusinessWorks Binding loggers                       * -->
  <!-- *=============================================================* -->
  
  <!-- SOAP Binding logger -->
  <logger name="com.tibco.bw.binding.soap">
    <level value="ERROR"/>
  </logger>
  
  <!-- REST Binding logger -->
  <logger name="com.tibco.bw.binding.rest">
    <level value="ERROR"/>
  </logger>
  
  
  
  <!-- *=============================================================* -->
  <!-- * LOGGER: BusinessWorks Shared Resource loggers               * -->
  <!-- *=============================================================* --> 
  <logger name="com.tibco.bw.sharedresource">
    <level value="ERROR"/>
  </logger>
  
  
   
  <!-- *=============================================================* -->
  <!-- * LOGGER: BusinessWorks Schema Cache loggers                  * -->
  <!-- *=============================================================* -->
  <logger name="com.tibco.bw.cache.runtime.xsd">
    <level value="ERROR"/>
  </logger> 
  
  <logger name="com.tibco.bw.cache.runtime.wsdl">
    <level value="ERROR"/>
  </logger> 
  
    
  
  <!-- *=============================================================* -->
  <!-- * LOGGER: BusinessWorks Governance loggers                    * -->
  <!-- *=============================================================* -->  
  <!-- Governance: Policy Director logger1 --> 
  <logger name="com.tibco.governance">
    <level value="ERROR"/>
  </logger>
   
  <logger name="com.tibco.amx.governance">
    <level value="WARN"/>
  </logger>
   
  <!-- Governance: Policy Director logger2 -->
  <logger name="com.tibco.governance.pa.action.runtime.PolicyProperties">
    <level value="ERROR"/>
  </logger>
  
  <!-- Governance: SPM logger1 -->
  <logger name="com.tibco.governance.spm">
    <level value="ERROR"/>
  </logger>
  
  <!-- Governance: SPM logger2 -->
  <logger name="rta.client">
    <level value="ERROR"/>
  </logger>
  
  
    
  <!-- *=============================================================* -->
  <!-- * LOGGER: BusinessWorks Miscellaneous Loggers                 * -->
  <!-- *=============================================================* --> 
  <logger name="com.tibco.bw.platformservices">
    <level value="INFO"/>
  </logger>
  
  <logger name="com.tibco.bw.core.runtime.statistics">
    <level value="ERROR"/>
  </logger>
  

  
  <!-- *=============================================================* -->
  <!-- * LOGGER: Other loggers                                       * -->
  <!-- *=============================================================* -->  
  <logger name="org.apache.axis2">
    <level value="ERROR"/>
  </logger>

  <logger name="org.eclipse">
    <level value="ERROR"/>
  </logger>
  
  <logger name="org.quartz">
    <level value="ERROR"/>
  </logger>
  
  <logger name="org.apache.commons.httpclient.util.IdleConnectionHandler">
    <level value="ERROR"/>
  </logger>
  
  
  
  <!-- *=============================================================* -->
  <!-- * LOGGER: User loggers.  User's custom loggers should be      * -->
  <!-- *         configured in this section.                         * -->
  <!-- *=============================================================* -->

  <!-- *=============================================================* -->
  <!-- * ROOT                                                        * -->
  <!-- *=============================================================* --> 
  <root level="ERROR">
   <appender-ref ref="STDOUT" />
  </root>
  
</configuration>

También puede hacer configuraciones más personalizadas basadas en la información disponible en la página de configuración del codificador ECS aquí.

¿Cómo habilitar el soporte de registro de TIBCO BW ECS?

Para BWCE, los pasos son similares, pero debemos tener en cuenta que todos los componentes de tiempo de ejecución están empaquetados dentro del base-runtime-version.zip que descargamos de nuestro sitio de eDelivery de TIBCO, por lo que necesitaremos usar una herramienta para abrir ese ZIP y hacer las siguientes modificaciones:

  • Colocaremos los JARs descargados en esa carpeta /tibco.home/bwce/2.8/system/shared/com.tibco.tpcl.logback_1.2.1600.004
BW ECS Logging: Ubicación del JAR
  • Abriremos el META-INF/MANIFEST.MF y haremos las siguientes modificaciones:
    • Agregar esos JARs a la sección Bundle-Classpath:
BW ECS Logging: Cambios en Bundle-Classpath
  • Incluir el siguiente paquete (co.elastic.logging.logback) como parte de los paquetes exportados agregándolo a la sección Exported-package:
BW ECS Logging: Cambios en Export-package
  • Además, necesitaremos modificar el bwappnode en la ubicación /tibco.home/bwce/2.8/bin para agregar los archivos JAR también al classpath que la imagen base de BWCE usa para ejecutar y asegurar que esto se esté cargando:
BW ECS Logging: cambio en bwappnode

Ahora podemos construir nuestra imagen base de BWCE como de costumbre y modificar el logback.xml como se explicó anteriormente. Aquí puede ver una aplicación de ejemplo utilizando esta configuración:

{"@timestamp":"2023-08-28T12:49:08.524Z","log.level": "INFO","message":"TIBCO BusinessWorks version 2.8.2, build V17, 2023-05-19","ecs.version": "1.2.0","service.name":"a","service.version":"b","service.environment":"c","service.node.name":"d","event.dataset":"a","process.thread.name":"main","log.logger":"com.tibco.thor.frwk"}

<>@BWEclipseAppNode> {"@timestamp":"2023-08-28T12:49:25.435Z","log.level": "INFO","message":"Started by BusinessStudio.","ecs.version": "1.2.0","service.name":"a","service.version":"b","service.environment":"c","service.node.name":"d","event.dataset":"a","process.thread.name":"main","log.logger":"com.tibco.thor.frwk.Deployer"}
{"@timestamp":"2023-08-28T12:49:32.795Z","log.level": "INFO","message":"TIBCO-BW-FRWK-300002: BW Engine [Main] started successfully.","ecs.version": "1.2.0","service.name":"a","service.version":"b","service.environment":"c","service.node.name":"d","event.dataset":"a","process.thread.name":"main","log.logger":"com.tibco.bw.frwk.engine.BWEngine"}
{"@timestamp":"2023-08-28T12:49:34.338Z","log.level": "INFO","message":"TIBCO-THOR-FRWK-300001: Started OSGi Framework of AppNode [BWEclipseAppNode] in AppSpace [BWEclipseAppSpace] of Domain [BWEclipseDomain]","ecs.version": "1.2.0","service.name":"a","service.version":"b","service.environment":"c","service.node.name":"d","event.dataset":"a","process.thread.name":"Framework Event Dispatcher: Equinox Container: 1395256a-27a2-4e91-b774-310e85b0b87c","log.logger":"com.tibco.thor.frwk.Deployer"}
{"@timestamp":"2023-08-28T12:49:34.456Z","log.level": "INFO","message":"TIBCO-THOR-FRWK-300018: Deploying BW Application [t3:1.0].","ecs.version": "1.2.0","service.name":"a","service.version":"b","service.environment":"c","service.node.name":"d","event.dataset":"a","process.thread.name":"Framework Event Dispatcher: Equinox Container: 1395256a-27a2-4e91-b774-310e85b0b87c","log.logger":"com.tibco.thor.frwk.Application"}
{"@timestamp":"2023-08-28T12:49:34.524Z","log.level": "INFO","message":"TIBCO-THOR-FRWK-300021: All Application dependencies are resolved for Application [t3:1.0]","ecs.version": "1.2.0","service.name":"a","service.version":"b","service.environment":"c","service.node.name":"d","event.dataset":"a","process.thread.name":"Framework Event Dispatcher: Equinox Container: 1395256a-27a2-4e91-b774-310e85b0b87c","log.logger":"com.tibco.thor.frwk.Application"}
{"@timestamp":"2023-08-28T12:49:34.541Z","log.level": "INFO","message":"Started by BusinessStudio, ignoring .enabled settings.","ecs.version": "1.2.0","service.name":"a","service.version":"b","service.environment":"c","service.node.name":"d","event.dataset":"a","process.thread.name":"Framework Event Dispatcher: Equinox Container: 1395256a-27a2-4e91-b774-310e85b0b87c","log.logger":"com.tibco.thor.frwk.Application"}
{"@timestamp":"2023-08-28T12:49:35.842Z","log.level": "INFO","message":"TIBCO-THOR-FRWK-300006: Started BW Application [t3:1.0]","ecs.version": "1.2.0","service.name":"a","service.version":"b","service.environment":"c","service.node.name":"d","event.dataset":"a","process.thread.name":"EventAdminThread #1","log.logger":"com.tibco.thor.frwk.Application"}
{"@timestamp":"2023-08-28T12:49:35.954Z","log.level": "INFO","message":"aaaaaaa
","ecs.version": "1.2.0","service.name":"a","service.version":"b","service.environment":"c","service.node.name":"d","event.dataset":"a","process.thread.name":"bwEngThread:In-Memory Process Worker-1","log.logger":"com.tibco.bw.palette.generalactivities.Log.t3.module.Log"}
gosh: stopping shell

Si quieres profundizar más en el ecosistema TIBCO, consulta nuestra Guía completa de la plataforma de integración TIBCO donde cubrimos patrones, mejores prácticas y guía de producción.

Impulsando la seguridad de Kubernetes: Explorando KubeSec – Una herramienta imprescindible para proteger tu clúster

Impulsando la seguridad de Kubernetes: Explorando KubeSec - Una herramienta imprescindible para proteger tu clúster

KubeSec es otra herramienta para ayudar a mejorar la seguridad de nuestro clúster de Kubernetes. Y estamos viendo a muchas agencias centrarse en la seguridad para resaltar la importancia de este tema en arquitecturas y despliegues modernos. La seguridad es ahora un componente clave, probablemente el más crucial. Todos necesitamos mejorar nuestro desempeño en ese tema, y por eso es esencial tener herramientas en nuestro conjunto de herramientas que nos ayuden en esa tarea sin ser expertos en seguridad en cada una de las tecnologías, como Kubernetes en este caso.

KubeSec es una herramienta de código abierto desarrollada por una consultoría de seguridad nativa de la nube y de código abierto llamada ControlPlane que nos ayuda a realizar un análisis de riesgo de seguridad en los recursos de Kubernetes.

¿Cómo Funciona KubeSec?

KubeSec funciona basado en los Archivos de Manifiesto de Kubernetes que usas para desplegar los diferentes recursos, por lo que necesitas proporcionar el archivo YAML a una de las formas de ejecución que esta herramienta soporta. Este es un tema importante, «una de las formas de ejecución», porque KubeSec soporta muchos modos de ejecución diferentes que nos ayudan a cubrir otros casos de uso.

Puedes ejecutar KubeSec en los siguientes modos:

  • Modo HTTP: KubeSec estará escuchando solicitudes HTTP con el contenido del YAML y proporcionará un informe basado en eso. Esto es útil en casos que necesitan ejecución en modo servidor, como las canalizaciones CICD, o simplemente servidores de seguridad para ser utilizados por algunos equipos, como DevOps o Ingeniería de Plataforma. Además, otro caso de uso crítico de este modo es ser parte de un Controlador de Admisión de Kubernetes en tu Clúster de Kubernetes para que puedas hacer cumplir esto cuando los desarrolladores estén desplegando recursos en la plataforma misma.
  • Modo SaaS: Similar al modo HTTP pero sin necesidad de alojarlo tú mismo, todo disponible detrás de kubesec.io cuando el modo SaaS es de tu preferencia, y no estás manejando información sensible en esos componentes.
  • Modo CLI: Solo para ejecutarlo tú mismo como parte de tus pruebas locales, tendrás disponible otro comando CLI aquí: kubesec scan k8s-deployment.yaml
  • Modo Docker: Similar al modo CLI pero como parte de una imagen de docker, también puede ser compatible con las canalizaciones CICD basadas en cargas de trabajo contenedorizadas.

Informe de Salida de KubeScan

Lo que obtendrás de la ejecución de KubeScan en cualquiera de sus formas es un informe JSON que puedes usar para mejorar y calificar el nivel de seguridad de tus recursos de Kubernetes y algunas formas de mejorarlo. La razón detrás de usar JSON como salida también simplifica el uso de la herramienta en cargas de trabajo automatizadas como las canalizaciones CICD. Aquí puedes ver un ejemplo del informe de salida que obtendrás:

kubesec sample output

Lo importante sobre la salida es el tipo de información que recibirás de ella. Como puedes ver en la imagen de arriba, está separada en dos secciones diferentes por objeto. La primera es el «puntaje», que son las cosas implementadas relacionadas con la seguridad que proporcionan algún puntaje para la seguridad del objeto. Pero también tendrás una sección de consejos que proporciona algunas cosas y configuraciones que puedes hacer para mejorar ese puntaje, y debido a eso, también la seguridad global del objeto de Kubernetes en sí.

Kubescan también aprovecha otra herramienta que hemos comentado no hace mucho en este sitio, Kubeconform, por lo que también puedes especificar la versión de Kubernetes objetivo a la que estás apuntando para tener un informe mucho más preciso de tu Manifiesto de Kubernetes específico. Para hacer eso, puedes especificar el argumento --kubernetes-version cuando estés lanzando el comando, como puedes ver en la imagen a continuación:

kubesec command with kubernetes-version option

 ¿Cómo Instalar KubeScan?

La instalación también proporciona diferentes formas y sabores para ver qué es lo mejor para ti. Aquí hay algunas de las opciones disponibles en el momento de escribir este artículo:

Conclusión

Enfatizando la importancia primordial de la seguridad en las arquitecturas intrincadas de hoy en día, KubeSec emerge como un activo vital para fortalecer la protección de los clústeres de Kubernetes. Desarrollada por ControlPlane, esta herramienta de código abierto facilita evaluaciones de riesgo de seguridad exhaustivas de los recursos de Kubernetes. Ofreciendo versatilidad a través de múltiples modos operativos—como HTTP, SaaS, CLI y Docker—KubeSec proporciona soporte adaptado para diversos escenarios. Su salida basada en JSON simplifica la integración en flujos de trabajo automatizados, mientras que su sinergia con Kubeconform asegura un análisis preciso de los Manifiestos de Kubernetes. El enfoque amigable de KubeSec empodera tanto a expertos en seguridad como a novatos, catalizando un estándar elevado de seguridad en Kubernetes en todos los ámbitos.

📚 Want to dive deeper into Kubernetes? This article is part of our comprehensive Kubernetes Architecture Patterns guide, where you’ll find all fundamental and advanced concepts explained step by step.

Cómo habilitar SwaggerUI TIBCO BusinessWorks al descargar el certificado SSL

Cómo habilitar SwaggerUI TIBCO BusinessWorks al descargar el certificado SSL

SwaggerUI TIBCO BusinessWorks es una de las características disponibles por defecto para todos los servicios REST de TIBCO BusinessWorks desarrollados. Como probablemente sepas, SwaggerUI es solo una página HTML con una representación gráfica del archivo de definición de Swagger (o especificación OpenAPI para ser más precisos con la versión actual de los estándares en uso) que ayuda a entender la operación y capacidades expuestas por el servicio y también proporciona una manera fácil de probar el servicio como puedes ver en la imagen a continuación:

Cómo habilitar SwaggerUI TIBCO BusinessWorks al descargar el certificado SSL: vista de SwaggerUI desde la aplicación TIBCO BWCE

Esta interfaz se proporciona de manera predeterminada para cualquier servicio REST desarrollado usando TIBCO BusinessWorks que utiliza un puerto diferente (7777 por defecto) en caso de que estemos hablando de una implementación local o en el endpoint /swagger en caso de que estemos hablando de una edición de contenedor de TIBCO BusinessWorks.

¿Cómo funciona SwaggerUI para cargar la especificación de Swagger?

SwaggerUI funciona de una manera particular. Cuando llegas a la URL de SwaggerUI, hay otra URL que generalmente es parte de un campo de texto dentro de la página web que contiene el enlace al documento JSON o YAML que almacena la especificación real, como puedes ver en la imagen a continuación:

Cómo habilitar SwaggerUI TIBCO BusinessWorks al descargar el certificado SSL: SwaggerUI destacando las 2 URL cargadas en el proceso

Entonces, puedes pensar que este es un proceso de 2 llamadas:

  • La primera llamada carga SwaggerUI como un contenedor gráfico
  • Luego, basado en la URL interna proporcionada allí, realiza una segunda llamada para recuperar la especificación del documento
  • Y con esa información, renderiza la información en el formato de SwaggerUI.

El problema surge cuando SwaggerUI se expone detrás de un balanceador de carga porque la segunda URL necesita usar la URL anunciada ya que el servidor backend no es alcanzado directamente por el cliente que navega por SwaggerUI. Esto se resuelve de manera predeterminada con las capacidades de Kubernetes en el caso de TIBCO BWCE, y para la implementación local, ofrece dos propiedades para manejar eso de la siguiente manera:

# ------------------------------------------------------------------------------
# Sección: Configuración de Swagger REST de BW. Las propiedades en esta sección
# son aplicables al marco de Swagger que es utilizado por el enlace REST de BW.
#
# Nota: Hay propiedades adicionales de configuración de Swagger REST de BW que
# se pueden especificar en el archivo de configuración de BW AppNode "config.ini". Consulta
# la sección "Configuración de Swagger REST de BW" del archivo de configuración de BW AppNode
# para más detalles.
# ------------------------------------------------------------------------------
# Nombre de host del proxy inverso del marco de Swagger. Esta propiedad es opcional y
# especifica el nombre de host del proxy inverso en el que el marco de Swagger sirve
# los API's, el endpoint de documentación, api-docs, etc.
bw.rest.docApi.reverseProxy.hostName=localhost

# Puerto del marco de Swagger. Esta propiedad es opcional y especifica el
# puerto del proxy inverso en el que el marco de Swagger sirve los API's, el endpoint de documentación,
# api-docs, etc.
bw.rest.docApi.reverseProxy.port=0000

Puedes navegar por la página de documentación oficial para obtener información más detallada.

Eso resuelve el problema principal con respecto al nombre de host y el puerto que debe ser alcanzado como lo requiere el usuario final. Aún así, hay un componente pendiente en la URL que podría generar un problema, y ese es el protocolo, así que, en resumen, si esto se expone usando HTTP o HTTPS.

¿Cómo manejar la URL de Swagger al descargar SSL?

Hasta el lanzamiento de TIBCO BWCE 2.8.3, el protocolo dependía de la configuración del conector HTTP que usabas para exponer el componente swagger. Entonces, si usas un conector HTTP sin configuración SSL, intentará alcanzar el endpoint usando una conexión HTTP. En el otro caso, si usas un conector HTTP con una conexión SSL, intentará usar una conexión HTTPS. Eso parece bien, pero algunos casos de uso podrían generar un problema:

Certificado SSL descargado en el balanceador de carga: Si descargamos la configuración SSL en el balanceador de carga como se usa en implementaciones tradicionales locales y algunas de las configuraciones de Kubernetes, el consumidor establecerá una conexión HTTPS con el balanceador de carga, pero internamente la comunicación con el BWCE se realizará usando HTTP, por lo que, en este caso, generará una discrepancia, porque en la segunda llamada de las solicitudes adivinará que como el conector HTTP de BWCE no está usando HTTPS, la URL debería ser alcanzada usando HTTP pero ese no es el caso ya que la comunicación pasa por el balanceador de carga que maneja la seguridad.

Exposición de servicio de malla de servicios: Similar al caso anterior, pero en ese caso, cerca de la implementación de Kubernetes. Supongamos que estamos usando malla de servicios como Istio u otros. En ese caso, la seguridad es una de las cosas que necesita ser manejada. Por lo tanto, la situación es la misma que el escenario anterior porque el BWCE no conoce la configuración de seguridad pero está impactando el endpoint predeterminado generado.

¿Cómo habilitar SwaggerUI TIBCO BusinessWorks al descargar certificados SSL?

Desde BWCE 2.8.3, hay una nueva propiedad JVM que podemos usar para forzar que el endpoint generado sea HTTPS incluso si el conector HTTP utilizado por la aplicación BWCE no tiene ninguna configuración de seguridad que nos ayude a resolver este problema en los casos anteriores y en un escenario similar. La propiedad se puede agregar como cualquier otra propiedad JVM usando la propiedad de entorno BW_JAVA_OPTS, y el valor es este: bw.rest.enable.secure.swagger.url =true

Si quieres profundizar más en el ecosistema TIBCO, consulta nuestra Guía completa de la plataforma de integración TIBCO donde cubrimos patrones, mejores prácticas y guía de producción.

Aumentar los registros HTTP en TIBCO BusinessWorks en 5 minutos

Aumentar los registros HTTP en TIBCO BusinessWorks en 5 minutos

Aumentar los registros HTTP en TIBCO BusinessWorks cuando estás depurando o solucionando problemas en una integración basada en HTTP que podría estar relacionada con un servicio REST o SOAP es una de las cosas más utilizadas y útiles que puedes hacer al desarrollar con TIBCO BusinessWorks.

El propósito principal de aumentar los registros HTTP es obtener un conocimiento completo sobre qué información estás enviando y qué comunicación estás recibiendo de tu comunicador asociado para ayudar a entender un error o comportamiento inesperado.

¿Cuáles son los casos de uso principales para aumentar los registros HTTP?

Al final, todos los diferentes casos de uso son variaciones del caso de uso principal: “Obtener conocimiento completo sobre la comunicación de intercambio HTTP entre ambas partes.” Aún así, algunos más detallados se pueden listar a continuación:

  • Entender por qué un servidor backend está rechazando una llamada que podría estar relacionada con Autenticación o Autorización, y necesitas ver la respuesta detallada del servidor backend.
  • Verificar el valor de cada Encabezado HTTP que estás enviando y que podría afectar la compresión de la comunicación o el tipo de contenido aceptado.
  • Ver por qué estás rechazando una llamada de un consumidor

Dividiendo la comunicación según la fuente

Lo más importante a entender es que los registros usualmente dependen de la biblioteca que estás usando, y no es la misma biblioteca utilizada para exponer un servidor basado en HTTP que la biblioteca que usas para consumir un servicio basado en HTTP como REST o un servicio SOAP.

Comenzando por lo que expones, esto es lo más fácil porque esto será definido por los recursos del Conector HTTP que estás usando, como puedes ver en la imagen a continuación:

Conector de Recursos Compartidos HTTP en BW

Todos los Recursos del Conector HTTP que puedes usar para exponer servicios REST y SOAP están basados en la implementación del Servicio Jetty, y eso significa que los registradores que necesitas cambiar su configuración están relacionados con el servidor Jetty en sí.

Más complejos, en teoría, son los relacionados con la comunicación del cliente cuando nuestra aplicación TIBCO BusinessWorks consume un servicio basado en HTTP proporcionado por un backend porque cada una de estas comunicaciones tiene sus propios Recursos Compartidos del Cliente HTTP. La configuración de cada uno de ellos será diferente porque una de las configuraciones que podemos obtener aquí es la Biblioteca de Implementación, y eso tendrá un efecto directo en la forma de cambiar la configuración del registro:

Recurso del Cliente HTTP en BW que muestra las diferentes bibliotecas de implementación para detectar el registrador para Aumentar los Registros HTTP en TIBCO BusinessWorks

Tienes tres opciones cuando defines un Recurso del Cliente HTTP, como puedes ver en la imagen anterior:

  • Apache HttpComponents: El predeterminado que soporta servicios HTTP1, SOAP y REST.
  • Cliente HTTP Jetty: Este cliente solo soporta flujos HTTP como HTTP1 y HTTP2, y sería la opción principal cuando estás trabajando con flujos HTTP2.
  • Apache Commons: Similar al primero, pero actualmente está obsoleto, y para ser honesto, si tienes algún componente cliente usando esta configuración, deberías cambiarlo cuando puedas a Apache HttpComponents.

Entonces, si estamos consumiendo un servicio SOAP y REST, está claro que estaremos usando la biblioteca de implementación Apache HttpComponents, y eso nos dará el registrador que necesitamos usar.

Porque para Apache HttpComponents, podemos confiar en el siguiente registrador: “org.apache.http” y en caso de que queramos extender el lado del servidor, o estemos usando el cliente HTTP Jetty, podemos usar este: “org.eclipse.jetty.http”

Debemos ser conscientes de que no podemos extenderlo solo para un único recurso de Cliente HTTP porque la configuración se basará en la Biblioteca de Implementación, así que en caso de que establezcamos el nivel DEBUG para la biblioteca Apache HttpComponents, afectará a todos los Recursos Compartidos que usen esta Biblioteca de Implementación, y necesitarás diferenciar basado en los datos dentro del registro, por lo que eso será parte de tu análisis de datos.

¿Cómo configurar los Registros HTTP en TIBCO BusinessWorks?

Ahora que tenemos los registradores, debemos configurarlo a un nivel DEBUG (o TRACE). Necesitamos saber cómo hacerlo, y tenemos varias opciones dependiendo de cómo nos gustaría hacerlo y qué acceso tenemos. El alcance de este artículo es TIBCO BusinessWorks Container Edition, pero puedes extrapolar fácilmente parte de este conocimiento a una instalación de TIBCO BusinessWorks en las instalaciones.

TIBCO BusinessWorks (contenedor o no) se basa en sus capacidades de registro en la biblioteca log back, y esta biblioteca se configura usando un archivo llamado logback.xml que podría tener la configuración que necesitas, como puedes ver en la imagen a continuación:

configuración de logback.xml con la estructura predeterminada en TIBCO BW

Entonces, si queremos agregar una nueva configuración de registro, necesitamos agregar un nuevo elemento logger al archivo con la siguiente estructura:

  <logger name="%LOGGER_QUE_QUEREMOS_VER">
    <level value="%NIVEL_QUE_QUEREMOS_VER%"/>
  </logger>    

Entonces, el registrador fue preciso basado en la sección anterior, y el nivel dependerá de cuánta información quieras ver. Los niveles de registro son los siguientes: ERROR, WARN, INFO, DEBUG, TRACE. DEBUG y TRACE son los que muestran más información.

En nuestro caso, DEBUG debería ser suficiente para obtener la Solicitud HTTP completa y la Respuesta HTTP, pero también puedes aplicarlo a otras cosas donde podrías necesitar un nivel de registro diferente.

Ahora necesitas agregar eso al archivo logback.xml, y para hacerlo, tienes varias opciones, como se comentó:

  • Puedes encontrar el logback.xml dentro del contenedor BWCE (o la carpeta de configuración de AppNode) y modificar su contenido. La ubicación predeterminada de este archivo es esta: /tmp/tibco.home/bwce/<VERSION>/config/logback.xml Para hacer esto, necesitarás tener acceso para hacer un kubectl exec en el contenedor bwce, y si haces el cambio, el cambio será temporal y se perderá en el próximo reinicio. Eso podría ser algo bueno o malo, dependiendo de tu objetivo.
  • Si quieres que sea permanente o no tienes acceso al contenedor, tienes dos opciones. La primera es incluir una copia personalizada del logback.xml en la carpeta /resources/custom-logback/ en la imagen base de BWCE y establecer la variable de entorno CUSTOM_LOGBACK a valor TRUE, y eso sobrescribirá la configuración predeterminada de logback.xml con el contenido de este archivo. Como se comentó, esto será “permanente” y se aplicará desde el primer despliegue de la aplicación con esta configuración. Puedes encontrar más información en la documentación oficial aquí.
  • También hay una adicional desde BWCE 2.7.0 y superior que te permite cambiar el contenido de logback.xml sin una nueva copia o cambiar la imagen base, y eso se basa en el uso de la propiedad de entorno BW_LOGGER_OVERRIDES con el contenido de la siguiente manera (logger=value) así que en nuestro caso sería algo como esto org.apache.http=DEBUG y en el próximo despliegue obtendrás esta configuración. Similar a la anterior, esto será permanente pero no requiere agregar un archivo a la imagen base para ser alcanzable.

Entonces, como puedes ver, tienes diferentes opciones dependiendo de tus necesidades y niveles de acceso.

Conclusión

En conclusión, mejorar los registros HTTP dentro de TIBCO BusinessWorks durante la depuración y solución de problemas es una estrategia vital. Elevar los niveles de registro proporciona una comprensión completa del intercambio de información, ayudando en el análisis de errores y comportamientos inesperados. Ya sea discerniendo las causas de rechazo del backend, examinando los efectos de los encabezados HTTP, o aislando rechazos de llamadas de consumidores, los registros amplificados iluminan escenarios de integración complejos. Las adaptaciones varían según el uso de la biblioteca, abarcando la exposición del servidor y el consumo de servicios. La configuración a través de la biblioteca logback implica ajustes personalizados de registrador y nivel. Esta práctica empodera a los desarrolladores para desentrañar las complejidades de la integración de manera eficiente, asegurando interacciones robustas y fluidas basadas en HTTP a través de sistemas.

Si quieres profundizar más en el ecosistema TIBCO, consulta nuestra Guía completa de la plataforma de integración TIBCO donde cubrimos patrones, mejores prácticas y guía de producción.

Cómo crear una imagen de sistema de archivos de solo lectura para TIBCO BWCE

Cómo crear una imagen de sistema de archivos de solo lectura para TIBCO BWCE

Este artículo cubrirá cómo mejorar la seguridad de tus imágenes de TIBCO BWCE creando una Imagen de Sistema de Archivos de Solo Lectura para TIBCO BWCE. En artículos anteriores, hemos comentado los beneficios que este tipo de imagen proporciona varias ventajas en términos de seguridad, centrándonos en aspectos como la reducción de la superficie de ataque al limitar el tipo de cosas que cualquier usuario puede hacer, incluso si logran acceder a contenedores en ejecución.

Lo mismo se aplica en caso de que cualquier malware que pueda tener tu imagen haya limitado las posibles acciones que pueden hacer sin ningún acceso de escritura a la mayor parte del contenedor.

¿Cómo afecta ReadOnlyFileSystem a una imagen de TIBCO BWCE?

Esto tiene un impacto claro ya que la imagen de TIBCO BWCE es una imagen que necesita escribir en varias carpetas como parte del comportamiento esperado de la aplicación. Eso es obligatorio y no depende de los scripts que usaste para construir tu imagen.

Como probablemente sepas, TIBCO BWCE incluye dos conjuntos de scripts para construir la imagen base de Docker: los principales y los incluidos en la carpeta reducedStartupTime, como puedes ver en la página de GitHub pero también dentro de tu carpeta docker en el TIBCO-HOME después de la instalación, como puedes ver en la imagen a continuación.

Cómo crear una imagen de sistema de archivos de solo lectura para TIBCO BWCE

La principal diferencia entre ellos es dónde se realiza la descompresión del bwce-runtime. En el caso del script por defecto, la descompresión se realiza en el proceso de inicio de la imagen, y en el reducedStartupTime esto se hace en la construcción de la imagen misma. Así que, puedes empezar a pensar que los predeterminados necesitan algún acceso de escritura ya que necesitan descomprimir el archivo dentro del contenedor, y eso es cierto.

Pero también, el reducedStartupTime requiere acceso de escritura para ejecutar la aplicación; se realizan varias actividades relacionadas con la descompresión del archivo EAR, la gestión del archivo de propiedades y actividades internas adicionales. Así que, no importa qué tipo de scripts estés usando, debes proporcionar una carpeta con acceso de escritura para realizar esta actividad.

Por defecto, todas estas actividades están limitadas a una sola carpeta. Si mantienes todo por defecto, esta es la carpeta /tmp, por lo que debes proporcionar un volumen para esa carpeta.

¿Cómo desplegar una aplicación TIBCO BWCE con el

Ahora, está claro que necesitas un volumen para la carpeta /tmp, y ahora necesitas definir el tipo de volumen que deseas usar para este. Como sabes, hay varios tipos de volúmenes que puedes determinar dependiendo de los requisitos que tengas.

En este caso, el único requisito es el acceso de escritura, pero no hay necesidad en cuanto a almacenamiento y persistencia, por lo que, en ese caso, podemos usar un modo emptyDir. El contenido de emptyDir, que se borra cuando se elimina un pod, es similar al comportamiento predeterminado pero permite permiso de escritura en su contenido.

Para mostrar cómo sería el YAML, usaremos el predeterminado que tenemos disponible en la documentación aquí:

apiVersion: v1
kind: Pod
metadata:
  name: bookstore-demo
  labels:
    app: bookstore-demo
spec:
  containers:
  - name: bookstore-demo
    image: bookstore-demo:2.4.4
    imagePullPolicy: Never
    envFrom:
    - configMapRef:
      name: name 

Así que, cambiaremos eso para incluir el volumen, como puedes ver aquí:

apiVersion: v1
kind: Pod
metadata:
  name: bookstore-demo
  labels:
    app: bookstore-demo
spec:
  containers:
  - name: bookstore-demo
    image: bookstore-demo:2.4.4
    imagePullPolicy: Never
	securityContext:
		readOnlyRootFilesystem: true
    envFrom:
    - configMapRef:
      name: name
    volumeMounts:
    - name: tmp
      mountPath: /tmp
  volumes:
  - name: tmp
    emptyDir: {}

Los cambios son los siguientes:

  • Incluir la sección volumes con una única definición de volumen con el nombre de tmp con una definición de emptyDir.
  • Incluir una sección volumeMounts para el volumen tmp que se monta en la ruta /tmp para permitir escribir en esa ruta específica para habilitar también la descompresión del bwce-runtime así como todas las actividades adicionales que se requieren.
  • Para activar este comportamiento, incluye la bandera readOnlyRootFilesystem en la sección securityContext.

Conclusión

Incorporar un enfoque de ReadOnlyFileSystem en tus imágenes de TIBCO BWCE es una estrategia proactiva para fortalecer la postura de seguridad de tu aplicación. Al reducir el acceso de escritura innecesario y minimizar las posibles vías para acciones no autorizadas, estás dando un paso vital hacia la protección de tu entorno de contenedores.

Esta guía ha revelado los aspectos críticos de implementar tal medida de mejora de seguridad, guiándote a través del proceso con instrucciones claras y ejemplos prácticos. Con un enfoque en reducir vectores de ataque y reforzar el aislamiento, puedes desplegar con confianza tus aplicaciones TIBCO BWCE, sabiendo que has fortalecido su entorno de ejecución contra posibles amenazas.

Si quieres profundizar más en el ecosistema TIBCO, consulta nuestra Guía completa de la plataforma de integración TIBCO donde cubrimos patrones, mejores prácticas y guía de producción.

Mejorando la Seguridad de Contenedores: El Papel Vital de ReadOnlyRootFilesystem

Mejorando la Seguridad de Contenedores: El Papel Vital de ReadOnlyRootFilesystem

Introducción

Una característica de seguridad tan importante es el uso de ReadOnlyRootFilesystem, una herramienta poderosa que puede mejorar significativamente la postura de seguridad de tus contenedores.

En el panorama de desarrollo y despliegue de software en rápida evolución, los contenedores han surgido como una tecnología revolucionaria. Ofreciendo portabilidad, eficiencia y escalabilidad, los contenedores se han convertido en la solución preferida para empaquetar y entregar aplicaciones. Sin embargo, con estos beneficios vienen desafíos de seguridad específicos que deben abordarse para garantizar la integridad de tus aplicaciones en contenedores.

Un ReadOnlyRootFilesystem es precisamente lo que parece: un sistema de archivos que solo se puede leer, no escribir. En la contenedorización, el contenido del sistema de archivos de un contenedor está bloqueado en un estado de solo lectura, evitando cualquier modificación o alteración durante el tiempo de ejecución.

 Ventajas de Usar ReadOnlyRootFilesystem

  • Superficie de Ataque Reducida: Uno de los principios fundamentales de la ciberseguridad es reducir la superficie de ataque: los puntos de entrada potenciales para actores maliciosos. Aplicar un ReadOnlyRootFilesystem elimina la posibilidad de que un atacante obtenga acceso de escritura a tu contenedor. Esta medida simple pero efectiva limita significativamente su capacidad para inyectar código malicioso, manipular archivos críticos o instalar malware.
  • Infraestructura Inmutable: La infraestructura inmutable es un concepto donde los componentes nunca se cambian una vez desplegados. Este enfoque asegura consistencia y repetibilidad, ya que cualquier cambio se realiza desplegando una nueva instancia en lugar de modificar una existente. Al aplicar un ReadOnlyRootFilesystem, estás esencialmente adoptando los principios de infraestructura inmutable dentro de tus contenedores, haciéndolos más resistentes a modificaciones no autorizadas.
  • Mitigación de Malware: El malware a menudo depende de obtener acceso de escritura a un sistema para llevar a cabo sus actividades maliciosas. Al emplear un ReadOnlyRootFilesystem, eriges una barrera significativa contra el malware que intenta establecer persistencia o exfiltrar datos sensibles. Incluso si un atacante logra comprometer un contenedor, su capacidad para instalar y ejecutar código malicioso está severamente restringida.
  • Mejor Forense y Auditoría: En el desafortunado caso de una violación de seguridad, tener un ReadOnlyRootFilesystem en su lugar puede ayudar en el análisis forense. Dado que el sistema de archivos permanece inalterado, los investigadores pueden rastrear más precisamente el vector de ataque, determinar el alcance de la violación e identificar los puntos de entrada vulnerables.

Consideraciones de Implementación

Implementar un ReadOnlyRootFilesystem en tus aplicaciones en contenedores requiere un enfoque deliberado:

  • Diseño de Imagen: Construye tus imágenes de contenedor con el concepto de ReadOnlyRootFilesystem en mente. Asegúrate de separar las áreas de solo lectura y escritura del sistema de archivos. Esto podría implicar crear volúmenes para datos escribibles o usar variables de entorno para personalizar el comportamiento en tiempo de ejecución.
  • Configuración en Tiempo de Ejecución: Los contenedores a menudo requieren acceso de escritura para archivos temporales, registros u otras necesidades de tiempo de ejecución. Diseña cuidadosamente tu aplicación para usar directorios o volúmenes designados para estos propósitos mientras mantienes los componentes críticos de solo lectura.
  • Pruebas y Validación: Prueba exhaustivamente tu aplicación en contenedores con la configuración de ReadOnlyRootFilesystem para asegurar que funcione como se espera. Presta atención a cualquier error en tiempo de ejecución, problemas de permisos o comportamientos inesperados que puedan surgir.

¿Cómo Definir un Pod como ReadOnlyRootFilesystem?

Para definir un Pod como “ReadOnlyRootFilesystem”, esta es una de las banderas que pertenecen a la sección securityContext del pod, como puedes ver en el ejemplo a continuación:

apiVersion: v1
kind: Pod
metadata:
  name: <nombre del Pod>
spec:
  containers:
  - name: <nombre del contenedor>
    image: <imagen>
    securityContext:
      readOnlyRootFilesystem: true

Conclusión

A medida que la adopción de contenedores continúa aumentando, también lo hace la importancia de medidas de seguridad robustas. Incorporar un ReadOnlyRootFilesystem en tu estrategia de contenedores es un paso proactivo hacia la protección de tus aplicaciones y datos. Al reducir la superficie de ataque, fortalecer contra el malware y permitir un mejor análisis forense, estás mejorando la postura de seguridad general de tu entorno en contenedores.

A medida que adoptas infraestructura inmutable dentro de tus contenedores, estarás mejor preparado para enfrentar el panorama en constante evolución de las amenazas de ciberseguridad. Recuerda, cuando se trata de seguridad en contenedores, un ReadOnlyRootFilesystem puede ser el escudo que protege tus activos digitales de posibles daños.

📚 Want to dive deeper into Kubernetes? This article is part of our comprehensive Kubernetes Architecture Patterns guide, where you’ll find all fundamental and advanced concepts explained step by step.

Contenedores Efímeros en Kubernetes: Una Guía de Depuración Esencial

Contenedores Efímeros en Kubernetes: Una Guía de Depuración Esencial

En el mundo dinámico y en constante evolución de la orquestación de contenedores, Kubernetes sigue reinando como la elección definitiva para gestionar, desplegar y escalar aplicaciones en contenedores. A medida que Kubernetes evoluciona, también lo hacen sus características y capacidades, y una de esas fascinantes adiciones es el concepto de Contenedores Efímeros. En esta publicación de blog, profundizaremos en el mundo de los Contenedores Efímeros, entendiendo qué son, explorando sus casos de uso principales y aprendiendo cómo implementarlos, todo con la guía de la documentación oficial de Kubernetes.

 ¿Qué Son los Contenedores Efímeros?

Los Contenedores Efímeros, introducidos como una característica alfa en Kubernetes 1.16 y que alcanzaron un nivel estable en la versión 1.25 de Kubernetes, ofrecen un conjunto de herramientas poderoso para depurar, diagnosticar y solucionar problemas dentro de tus pods de Kubernetes sin requerir que alteres la configuración original de tu pod. A diferencia de los contenedores regulares que son parte de la definición central del pod, los contenedores efímeros se agregan dinámicamente a un pod en ejecución por una duración breve, proporcionándote un entorno temporal para ejecutar tareas de diagnóstico.

Lo bueno de los contenedores efímeros es que te permiten tener todas las herramientas necesarias para hacer el trabajo (depuración, recuperación de datos o cualquier otra cosa que pueda ser requerida) sin agregar más dispositivos a los contenedores base y aumentar el riesgo de seguridad basado en esa acción.

 Principales Casos de Uso de los Contenedores Efímeros

  • Solución de Problemas y Depuración: Los Contenedores Efímeros brillan más cuando se trata de solucionar problemas y depurar. Te permiten inyectar un nuevo contenedor en un pod problemático para recopilar registros, examinar archivos, ejecutar comandos o incluso instalar herramientas de diagnóstico sobre la marcha. Esto es particularmente valioso cuando se encuentran problemas que son difíciles de reproducir o diagnosticar en un entorno estático.
  • Recopilación y Análisis de Registros: Cuando un pod encuentra problemas, inspeccionar sus registros suele ser esencial. Los Contenedores Efímeros hacen que este proceso sea fluido al permitirte iniciar un contenedor temporal con herramientas de análisis de registros, dándote acceso instantáneo a los archivos de registro y ayudando a identificar la causa raíz de los problemas.
  • Recuperación y Reparación de Datos: Los Contenedores Efímeros también pueden usarse para escenarios de recuperación y reparación de datos. Imagina una situación donde un pod de base de datos enfrenta corrupción. Con un contenedor efímero, puedes montar el volumen de almacenamiento del pod, realizar operaciones de recuperación de datos y potencialmente reparar los datos sin comprometer el pod en ejecución.
  • Monitoreo y Análisis de Recursos: Los cuellos de botella de rendimiento o las restricciones de recursos a veces pueden afectar la funcionalidad de un pod. Los Contenedores Efímeros te permiten analizar la utilización de recursos, ejecutar diagnósticos y perfilar el entorno del pod, ayudándote a optimizar su rendimiento.

Implementación de Contenedores Efímeros

Gracias al enfoque amigable de Kubernetes, implementar contenedores efímeros es sencillo. Kubernetes proporciona el comando kubectl debug, que simplifica el proceso de adjuntar contenedores efímeros a los pods. Este comando te permite especificar el pod y el espacio de nombres e incluso elegir la imagen del contenedor de depuración a inyectar.

kubectl debug <nombre-del-pod> -n <espacio-de-nombres> --image=<imagen-del-contenedor-de-depuración>

Puedes ir incluso más allá, y en lugar de agregar los contenedores efímeros al pod en ejecución, puedes hacer lo mismo con una copia del pod, como puedes ver en el siguiente comando:

kubectl debug myapp -it --image=ubuntu --share-processes --copy-to=myapp-debug

Finalmente, una vez que hayas cumplido con tu deber, puedes eliminarlo permanentemente usando un comando kubectl delete, y eso es todo.

Es esencial notar que todas estas acciones requieren acceso directo al entorno. Incluso eso genera temporalmente una discrepancia en el despliegue de «infraestructura como código», ya que estamos manipulando el estado de ejecución temporalmente. Por lo tanto, este enfoque es mucho más desafiante de implementar si utilizas algunas prácticas de GitOps o herramientas como Rancher Fleet o ArgoCD.

Conclusión

Los Contenedores Efímeros, aunque actualmente son una característica estable desde el lanzamiento de Kubernetes 1.25, ofrecen capacidades impresionantes para depurar y diagnosticar problemas dentro de tus pods de Kubernetes. Al permitirte inyectar contenedores temporales en pods en ejecución de manera dinámica, te capacitan para solucionar problemas, recopilar registros, recuperar datos y optimizar el rendimiento sin interrumpir la funcionalidad central de tu aplicación. A medida que Kubernetes continúa evolucionando, agregar características como los Contenedores Efímeros demuestra su compromiso de proporcionar a los desarrolladores herramientas para simplificar la gestión y el mantenimiento de aplicaciones en contenedores. Así que, la próxima vez que encuentres un problema persistente dentro de tu entorno de Kubernetes, recuerda que los Contenedores Efímeros podrían ser el superhéroe de depuración que necesitas.

Para obtener información más detallada y ejemplos de uso, consulta la documentación oficial de Kubernetes sobre Contenedores Efímeros. ¡Feliz depuración!

📚 Want to dive deeper into Kubernetes? This article is part of our comprehensive Kubernetes Architecture Patterns guide, where you’ll find all fundamental and advanced concepts explained step by step.

Prevención de Divulgación de Información con Istio Service Mesh

Prevención de Divulgación de Información con Istio Service Mesh

En el panorama digital actual, donde las violaciones de datos y las amenazas cibernéticas se están volviendo cada vez más sofisticadas, garantizar la seguridad de sus servidores es primordial. Una de las preocupaciones críticas de seguridad que las organizaciones deben abordar es la «Divulgación de Información del Servidor». La Divulgación de Información del Servidor ocurre cuando información sensible sobre la configuración de un servidor, su pila tecnológica o estructura interna se expone inadvertidamente a partes no autorizadas. Los hackers pueden explotar esta vulnerabilidad para obtener información sobre posibles puntos débiles y lanzar ataques dirigidos. Tales violaciones pueden llevar al robo de datos, interrupción del servicio y daño a la reputación.

Divulgación de Información y Malla de Servicios Istio

Un ejemplo es el Encabezado HTTP del Servidor, que generalmente se incluye en la mayoría de las respuestas HTTP donde se encuentra el servidor que está proporcionando esta respuesta. Los valores pueden variar dependiendo de la pila, pero asuntos como Jetty, Tomcat o similares suelen verse. Pero también, si está utilizando una Malla de Servicios como Istio, verá el encabezado con un valor de istio-envoy, como puede ver aquí:

Divulgación de Información de Implementación del Servidor usando Malla de Servicios Istio

Como se comentó, esto es de tal importancia para varios niveles de seguridad, tales como:

  • Privacidad de Datos: La fuga de información del servidor puede exponer datos confidenciales, socavando la confianza del usuario y violando regulaciones de privacidad de datos como GDPR y HIPAA.
  • Reducción de la Superficie de Ataque: Al ocultar los detalles del servidor, minimiza la superficie de ataque disponible para posibles atacantes.
  • Seguridad por Oscuridad: Aunque no es un enfoque infalible, limitar la divulgación agrega una capa extra de seguridad, dificultando que los hackers recopilen información.

¿Cómo mitigar eso con la Malla de Servicios Istio?

Al usar Istio, podemos definir diferentes reglas para agregar y eliminar encabezados HTTP según nuestras necesidades, como puede ver en la siguiente documentación aquí: https://discuss.istio.io/t/remove-header-operation/1692 usando cláusulas simples para la definición de su VirtualService como puede ver aquí:

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: k8snode-virtual-service
spec:
  hosts:
  - "example.com"
  gateways:
  - k8snode-gateway
  http:
    headers:
      response:
        remove:
          - "x-my-fault-source"
  - route:
    - destination:
        host: k8snode-service
        subset: version-1 

Desafortunadamente, esto no es útil para todos los encabezados HTTP, especialmente los «principales», por lo que los que no son personalizados agregados por sus cargas de trabajo, sino los que son principalmente utilizados y definidos en el estándar HTTP W3C https://www.w3.org/Protocols/

Entonces, en el caso del encabezado HTTP del Servidor es un poco más complejo de hacer, y necesita usar un EnvoyFilter, uno de los objetos más sofisticados que forma parte de la Malla de Servicios Istio. Basado en las palabras de la documentación oficial de Istio, un EnvoyFilter proporciona un mecanismo para personalizar la configuración de Envoy generada por Istio Pilot. Por lo tanto, puede usar EnvoyFilter para modificar valores para ciertos campos, agregar filtros específicos o incluso agregar nuevos oyentes, clústeres, etc.

Implementación de EnvoyFilter para Eliminar Encabezado

Así que ahora que sabemos que necesitamos crear un EnvoyFilter personalizado, veamos cuál necesitamos usar para eliminar el encabezado del Servidor y cómo se hace esto para obtener más conocimiento sobre este componente. Aquí puede ver el EnvoyFilter para ese trabajo:

---
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
  name: gateway-response-remove-headers
  namespace: istio-system
spec:
  workloadSelector:
    labels:
      istio: ingressgateway
  configPatches:
  - applyTo: NETWORK_FILTER
    match:
      context: GATEWAY
      listener:
        filterChain:
          filter:
            name: "envoy.filters.network.http_connection_manager"
    patch:
      operation: MERGE
      value:
        typed_config:
          "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager"
          server_header_transformation: PASS_THROUGH
  - applyTo: ROUTE_CONFIGURATION
    match:
      context: GATEWAY
    patch:
      operation: MERGE
      value:
        response_headers_to_remove:
        - "server"

Así que centrémonos en las partes de la especificación del EnvoyFilter donde podemos obtener por un lado el usual workloadSelector, para saber dónde se aplicará este componente, que en este caso será el istio ingressgateway. Luego entramos en la sección configPatches, que son las secciones donde usamos la personalización que necesitamos hacer, y en nuestro caso, tenemos dos de ellas:

Ambas actúan en el contexto: GATEWAY y se aplican a dos objetos diferentes: NETWORK_FILTER Y ROUTE_CONFIGURATION. También puede usar filtros en sidecars para afectar su comportamiento. La primera parte lo que hace es incluir el filtro personalizado http_connection_manager que permite la manipulación del contexto HTTP, incluyendo para nuestro propósito principal también el encabezado HTTP, y luego tenemos la segunda parte que actúa en el ROUTE_CONFIGURATION eliminando el encabezado del servidor como podemos ver usando la opción response_header_to_remove

Conclusión

Como puede ver, esto no es fácil de implementar. Sin embargo, al mismo tiempo, es evidencia del poder y las capacidades de bajo nivel que tiene al usar una malla de servicios robusta como Istio para interactuar y modificar el comportamiento de cualquier pequeño detalle que desee para su beneficio y, en este caso, también para mejorar y aumentar la seguridad de sus cargas de trabajo desplegadas detrás del alcance de la Malla de Servicios.

En el panorama en constante evolución de las amenazas de ciberseguridad, proteger sus servidores contra la divulgación de información es crucial para proteger datos sensibles y mantener la integridad de su organización. Istio le permite fortalecer la seguridad de su servidor al proporcionar herramientas robustas para la gestión del tráfico, el cifrado y el control de acceso.

Recuerde, la clave para una seguridad adecuada del servidor es un enfoque proactivo que aborde las vulnerabilidades antes de que puedan ser explotadas. Tome la iniciativa de implementar Istio y eleve la protección de su servidor.

📚 Want to dive deeper into Kubernetes? This article is part of our comprehensive Kubernetes Architecture Patterns guide, where you’ll find all fundamental and advanced concepts explained step by step.

Mejorando la Resolución DNS del Service Mesh con la Capacidad de Proxy DNS de Istio: Beneficios y Casos de Uso

Mejorando la Resolución DNS del Service Mesh con la Capacidad de Proxy DNS de Istio: Beneficios y Casos de Uso

Istio es un popular service mesh de código abierto que proporciona una gama de potentes características para gestionar y asegurar arquitecturas basadas en microservicios. Hemos hablado mucho sobre sus capacidades y componentes, pero hoy hablaremos sobre cómo podemos usar Istio para ayudar con el mecanismo de resolución de DNS.

Como ya sabes, en una implementación típica de Istio, cada servicio está acompañado por un proxy sidecar, Envoy, que intercepta y gestiona el tráfico entre servicios. La capacidad de Proxy DNS de Istio aprovecha este proxy para manejar las solicitudes de resolución de DNS de manera más inteligente y eficiente.

Tradicionalmente, cuando un servicio dentro de una arquitectura de microservicios necesita comunicarse con otro servicio, depende de la resolución de DNS para descubrir la dirección IP del servicio objetivo. Sin embargo, la resolución de DNS tradicional puede ser difícil de gestionar en entornos complejos y dinámicos, como los que se encuentran en los clústeres de Kubernetes. Aquí es donde entra en juego la capacidad de Proxy DNS de Istio.

 Capacidades de Proxy DNS de Istio

Con Proxy DNS, Istio intercepta y controla las solicitudes de resolución de DNS de los servicios y realiza la resolución en su nombre. En lugar de depender de servidores DNS externos, los proxies sidecar manejan la resolución de DNS dentro del service mesh. Esto permite a Istio proporcionar varios beneficios valiosos:

  • Descubrimiento de servicios y balanceo de carga: El Proxy DNS de Istio permite mecanismos de descubrimiento de servicios más avanzados. Puede descubrir dinámicamente servicios y sus direcciones IP correspondientes dentro del mesh y realizar balanceo de carga entre instancias de un servicio en particular. Esto elimina la necesidad de que los servicios individuales gestionen la resolución de DNS y el balanceo de carga.
  • Seguridad y observabilidad: Istio obtiene visibilidad en el tráfico entre servicios al manejar la resolución de DNS dentro del mesh. Puede aplicar políticas de seguridad, como control de acceso y encriptación de tráfico, a nivel de DNS. Además, Istio puede recopilar datos de telemetría relacionados con DNS para monitoreo y observabilidad, proporcionando información sobre los patrones de comunicación entre servicios.
  • Gestión y control del tráfico: Proxy DNS permite a Istio implementar características avanzadas de gestión de tráfico, como reglas de enrutamiento e inyección de fallos, a nivel de resolución de DNS. Esto permite mecanismos sofisticados de control de tráfico dentro del service mesh, habilitando pruebas A/B, implementaciones canarias, ruptura de circuitos y otras estrategias de gestión de tráfico.

 Casos de Uso de Proxy DNS de Istio

Hay algunos momentos en los que no puedes o no quieres depender de la resolución normal de DNS. ¿Por qué es eso? Comenzando porque DNS es un gran protocolo pero carece de algunas capacidades, como el descubrimiento de ubicación. Si tienes el mismo DNS asignado a tres IPs, proporcionará cada una de ellas de manera circular y no puede depender de la ubicación.

O tienes varias IPs, y quieres bloquear algunas de ellas para algún servicio específico; estas son grandes cosas que puedes hacer con Istio Proxy DNS.

Habilitación de Proxy DNS de Istio

Debes saber que las capacidades de Proxy DNS de Istio no están habilitadas por defecto, por lo que debes ayudar si deseas usarlo. Lo bueno es que puedes permitirlo en diferentes niveles, desde el nivel completo del mesh hasta solo el nivel de un pod individual, por lo que puedes elegir lo que es mejor para ti en cada caso.

Por ejemplo, si queremos habilitarlo a nivel de pod, necesitamos inyectar la siguiente configuración en el proxy de Istio:

    proxy.istio.io/config: |
		proxyMetadata:   
         # Habilitar proxy DNS básico
         ISTIO_META_DNS_CAPTURE: "true" 
         # Habilitar asignación automática de direcciones, opcional
         ISTIO_META_DNS_AUTO_ALLOCATE: "true"

La misma configuración puede ser parte del nivel del Mesh como parte de la instalación del operador, como puedes encontrar la documentación aquí en la página oficial de Istio.

Conclusión

En resumen, la capacidad de Proxy DNS de Istio mejora el mecanismo de resolución de DNS dentro del entorno del service mesh, proporcionando descubrimiento de servicios avanzado, balanceo de carga, seguridad, observabilidad y características de gestión de tráfico. Istio centraliza y controla la resolución de DNS aprovechando los proxies sidecar, simplificando la gestión y optimización de la comunicación entre servicios en arquitecturas de microservicios complejas.

📚 Want to dive deeper into Kubernetes? This article is part of our comprehensive Kubernetes Architecture Patterns guide, where you’ll find all fundamental and advanced concepts explained step by step.

Preguntas frecuentes

¿Qué es ISTIO_META_DNS_CAPTURE?

Un ajuste del proxy que hace que el sidecar de Istio intercepte las consultas DNS del workload y las responda desde su caché local, en vez de reenviarlo todo a kube-dns. Reduce la carga de DNS, da respuestas consistentes para los hosts de ServiceEntry y habilita la resolución para VMs en la mesh.

¿Cuándo conviene activar el proxy DNS de Istio?

Tres detonantes: tráfico este-oeste que satura kube-dns/CoreDNS; ServiceEntries con resolution: DNS cuyos hosts deben resolverse igual en todos los pods; y escenarios de expansión de mesh con VMs sin DNS de clúster. Si no se da ninguno, la ruta por defecto es suficiente.

¿Cómo verifico que el sidecar está respondiendo el DNS?

Revisando la configuración del proxy: istioctl proxy-config dns <pod> lista los nombres que sirve el sidecar. En caliente, un nslookup desde el contenedor respondido por la dirección del sidecar confirma que la captura está activa.

¿Afecta la captura DNS a los dominios externos?

Las consultas de nombres desconocidos se reenvían a los resolvers originales, así que la resolución externa sigue funcionando. La caché solo responde con autoridad para los servicios y hosts de ServiceEntry que el proxy conoce.

Desbloqueando la Flexibilidad y Reutilización: Aprovechando el Poder de los Subgráficos de Múltiples Instancias de Helm

Desbloqueando la Flexibilidad y Reutilización: Aprovechando el Poder de los Subgráficos de Múltiples Instancias de Helm

El uso de subgráficos de múltiples instancias de Helm como parte de tu gráfico principal podría ser algo que, desde el principio, puede sonar extraño. Ya comentamos sobre los subgráficos y dependencias de los gráficos de helm en el blog porque el caso de uso habitual es así:

Tengo un gráfico que necesita otro componente, y lo «importo» como un subgráfico, lo que me da la posibilidad de desplegar el mismo componente y personalizar sus valores sin necesidad de crear otra copia del gráfico y, como puedes imaginar, simplificando mucho la gestión de los gráficos, un ejemplo puede ser así:

Descubre cómo múltiples subgráficos pueden revolucionar tus despliegues de Helm. Aprende a aprovechar el poder de la reutilización y personalización, permitiéndote desplegar componentes idénticos con configuraciones únicas. Mejora la flexibilidad y simplifica la gestión con esta avanzada característica de Helm. Desbloquea todo el potencial de tu arquitectura de microservicios y toma el control de despliegues de aplicaciones complejas. Sumérgete en el mundo de múltiples subgráficos y eleva tus gráficos de Helm al siguiente nivel.

Entonces, creo que eso está totalmente claro, pero ¿de qué estamos hablando ahora? El caso de uso es tener el mismo subgráfico definido dos veces. Así que, imagina este escenario, estamos hablando de eso en lugar de esto:

# Chart.yaml
dependencies:
- name: nginx
  version: "1.2.3"
  repository: "https://example.com/charts"
- name: memcached
  version: "3.2.1"
  repository: "https://another.example.com/charts"

Estamos teniendo algo como esto

# Chart.yaml
dependencies:
- name: nginx
  version: "1.2.3"
  repository: "https://example.com/charts"
- name: memcached-copy1
  version: "3.2.1"
  repository: "https://another.example.com/charts"
- name: memcached-copy2
  version: "3.2.1"
  repository: "https://another.example.com/charts"

Así que tenemos la opción de definir más de una «instancia» del mismo subgráfico. Y supongo que, en este momento, puedes empezar a preguntarte: «¿Cuáles son los casos de uso donde podría necesitar esto?»

Porque eso es bastante comprensible, a menos que lo necesites nunca te darás cuenta de eso. Es lo mismo que me pasa a mí. Así que hablemos un poco sobre posibles casos de uso para esto.

 Casos de Uso para Dependencia de Múltiples Instancias de Helm

Imagina que estás desplegando un gráfico de helm para un conjunto de microservicios que pertenecen al ámbito de la misma aplicación y cada uno de los microservicios tiene la misma base tecnológica, que puede ser TIBCO BusinessWorks Container Edition o pueden ser microservicios Golang. Así que todos ellos tienen la misma base por lo que pueden usar el mismo gráfico «bwce-microservice» o «golang-microservices» pero cada uno de ellos tiene su propia configuración, por ejemplo:

  • Cada uno de ellos tendrá su propio nombre de imagen que diferirá de uno a otro.
  • Cada uno de ellos tendrá su propia configuración que diferirá de uno a otro.
  • Cada uno de ellos tendrá sus propios puntos de conexión que diferirán y probablemente incluso se conectarán a diferentes fuentes como bases de datos o sistemas externos.

Así que, este enfoque nos ayudaría a reutilizar el mismo gráfico de helm tecnológico, «bwce» e instanciarlo varias veces, para que podamos tener cada uno de ellos con su propia configuración sin la necesidad de crear algo «personalizado» y manteniendo los mismos beneficios en términos de mantenibilidad que el enfoque de dependencia de helm nos proporciona.

 ¿Cómo podemos implementar esto?

Ahora que tenemos claro el caso de uso que vamos a soportar, el siguiente paso es sobre cómo podemos hacer esto una realidad. Y, para ser honesto, esto es mucho más simple de lo que puedes pensar desde el principio, comencemos con la situación normal cuando tenemos un gráfico principal, llamémoslo un «programa», que ha incluido una plantilla «bwce» como una dependencia como puedes ver aquí:

name: multi-bwce
description: Helm Chart para Desplegar una Aplicación TIBCO BusinessWorks Container Edition
apiVersion: v1
version: 0.2.0
icon: 
appVersion: 2.7.2

dependencies:
- name: bwce
  version: ~1.0.0
  repository: "file:///Users/avazquez/Data/Projects/DET/helm-charts/bwce"

Y ahora, vamos a movernos a un enfoque de múltiples instancias donde requeriremos dos microservicios diferentes, llamémoslos serviceA y serviceB, y ambos usarán el mismo gráfico de helm bwce.

Así que lo primero que modificaremos es el Chart.yaml de la siguiente manera:

name: multi-bwce
description: Helm Chart para Desplegar una Aplicación TIBCO BusinessWorks Container Edition
apiVersion: v1
version: 0.2.0
icon: 
appVersion: 2.7.2

dependencies:
- name: bwce
  alias: serviceA
  version: ~0.2.0
  repository: "file:///Users/avazquez/Data/Projects/DET/helm-charts/bwce"
- name: bwce
  alias: serviceB
  version: ~0.2.0
  repository: "file:///Users/avazquez/Data/Projects/DET/helm-charts/bwce"

La parte importante aquí es cómo declaramos la dependencia. Como puedes ver en el nombre seguimos manteniendo el mismo «nombre» pero tienen un campo adicional llamado «alias» y este alias es lo que nos ayudará a identificar más tarde las propiedades para cada una de las instancias según lo requiramos. Con eso, ya tenemos nuestra definición de instancia de serviceA y serviceB y podemos comenzar a usarlo en el values.yml de la siguiente manera:

# Este es un archivo con formato YAML.
# Declara variables para ser pasadas a tus plantillas.

serviceA:
  image: 
    imageName: 552846087011.dkr.ecr.eu-west-2.amazonaws.com/tibco/serviceA:2.5.2
    pullPolicy: Always
serviceB:  
  image: 
    imageName: 552846087011.dkr.ecr.eu-west-2.amazonaws.com/tibco/serviceB:2.5.2
    pullPolicy: Always
  

 Conclusión

El principal beneficio de esto es que mejora las opciones de usar gráficos de helm para aplicaciones «complejas» que requieren diferentes instancias del mismo tipo de componentes y al mismo tiempo.

Eso no significa que necesites un gráfico de helm enorme para tu proyecto porque esto iría en contra de todas las mejores prácticas del enfoque de contenedorización y microservicios, pero al menos te dará la opción de definir diferentes niveles de abstracción como desees, manteniendo todos los beneficios desde una perspectiva de gestión.