La importancia del connection pooling cuando usamos SSL/TLS sobre TDS

La importancia del connection pooling cuando usamos SSL/TLS sobre TDS

El uso de connection pooling es una técnica importante desde el punto de vista de rendimiento de SQL Server. Si cada petición que lanzáramos a la base de datos tuviera que pasar necesariamente por el proceso completo de conexión al servidor, con su autenticación, etc. el rendimiento sería muy pobre.

Desgraciadamente aún nos encontramos con aplicaciones, casi siempre heredadas, que no utilizan connection pooling y por tanto abren y cierran físicamente la conexión cada vez con la base de datos. Una buena forma de detectar si nuestras aplicaciones están utilizando o no connection pooling es analizando los contadores de rendimiento Login/sec y Logout/sec. Cuando estos valores sean elevados respecto al número de conexiones existentes entonces con una alta probabilidad estaremos teniendo este problema al menos en parte de las aplicaciones que conectan contra nuestro servidor.

En algunos casos extremos podemos tener valores elevados de estos valores si tenemos muchas aplicaciones que, aun utilizando pooling, generen picos de conexiones concurrentes elevadas. Esto hará que el tamaño del pool crezca para poder servir este número de conexiones que se necesitan de forma puntual, generando un pico de Login/sec. Pasado un tiempo de inactividad (por defecto suele ser 60 segundos) las conexiones se cerrarán por falta de uso generando un pico de Logout/sec. Si tenemos muchos clientes con este mismo comportamiento podemos llegar a tener, en todo momento, un número elevado de Login/sec y de Logout/sec causados por estas oscilaciones en los tamaños de los pools sin que realmente tengamos aplicaciones que no utilicen connection pooling. Este timeout de desconexión puede indicarse al proveedor vía cadena de conexión o también mediante configuración directa del proveedor.

En el caso de ODBC por ejemplo podemos controlar el pool timeout (CPTimeout) desde el administrador de Data Sources:

También tenemos casos en los que el mal uso del connection pooling es el problema de los problemas de rendimiento sufridos. Por ejemplo, imaginemos que para evitar el delay que ocurre cuando nos conectamos a un servidor a través de un pool y tenemos que abrir la conexión físicamente se decide configurar un mínimo de 100 conexiones abiertas en una aplicación cliente-servidor. Puede parecer excesiva esta medida, pero cuando la autenticación del usuario recae en Active Directory, tenemos muchos usuarios distintos y el AD se encuentra saturado o lejano geográficamente (y no tenemos AD secundarios locales) el proceso de login puede durar hasta varios segundos. Seguramente alguien se ha topado con este problema especialmente al intentar conectar con SQL Database desde el Microsoft SQL Management Studio. Por defecto el Microsoft SQL Management Studio utiliza 15 segundos como login timeout lo cual resulta insuficiente en ocasiones para completar el proceso de enrutado y login.

El problema de mantener un pool con un mínimo tan elevado de conexiones es que éstas no se cerrarán y si el número de usuarios de dicha aplicación cliente-servidor aumenta, el número de conexiones aumentará también de forma lineal. El límite de conexiones que una instancia de SQL Server puede aceptar es de 32767 por lo que con menos de 330 usuarios de la aplicación el servidor quedará saturado no aceptando más usuarios ni conexiones. Por tanto, la clave estará en configurar de forma equilibrada los valores mínimos para el pool de conexiones, el valor máximo y el tiempo que dichas conexiones permanecerán abiertas.

Una vez introducida la importancia del buen uso del connection pooling queremos mostrar otro escenario que puede amplificar más aún el impacto de no utilizar connection pooling. Concretamente un cliente nos contactó con problemas de rendimiento derivados de la activación de la encriptación SSL de las conexiones con SQL Server. No es habitual encontrarnos con este tipo de problemas ya que, aunque la encriptación SSL tiene un coste extra, en general es asumible y no supone más que un pequeño incremento en el consumo de CPU total del servidor. Sin embargo, en este caso el consumo de CPU no era excesivo y los tiempos de ejecución de las consultas similares, pero sin embargo lo que sí teníamos eran ralentizaciones durante el proceso de conexión. Por tanto, el problema de rendimiento era debido a esperas durante el proceso de conexión a la base de datos una vez se habilitaba y forzaba el uso de SSL.

Para verificar que efectivamente existe un impacto medible realizamos una prueba de concepto donde estresaríamos una máquina virtual para comprobar el impacto de forzar la encriptación SSL. El primer paso es configurar SQL Server con un certificado SSL apropiado para ello. Es importante que el certificado cumpla ciertas condiciones ya que en caso contrario no será aceptado. En la sección de troubleshooting de este artículo podemos encontrar más información: (https://support.microsoft.com/en-us/help/316898/how-to-enable-ssl-encryption-for-an-instance-of-sql-server-by-using-mi)

Aunque nos salgamos un poco de contexto es conveniente indicar que este certificado no tiene nada que ver con el que necesitaríamos por ejemplo para una encriptación TDE. Para poder encriptar con TDE necesitaríamos un certificado obtenido siguiendo el siguiente proceso: https://blogs.msdn.microsoft.com/sql_pfe_blog/2014/02/04/generating-a-trusted-tde-certificate-in-the-proper-format-from-a-certificate-authority/ Si tuviéramos que reutilizar un pfx existente habría que hacer una conversión con esta herramienta para adaptarlo al formato requerido: https://support.microsoft.com/en-ph/help/2914662/how-to-use-pfx-formatted-certificates-in-sql-server

Para la prueba de concepto crearemos un certificado autofirmado con este comando powershell:

Con este comando el certificado creado se cargará en el store “personal”:

 

Para que la validez del certificado pueda ser validada tendremos que exportar dicho certificado e importarlo dentro la carpeta con los certificados raíz de confianza. Normalmente este proceso no será necesario ya que el certificado que utilicemos vendrá de una fuente de certificación de confianza:

Antes de forzar el uso de encriptación realizaremos una prueba donde lanzaremos una consulta extremadamente sencilla con 50 threads y 100 iteraciones. Antes de lanzar la carga configuraremos la conexión a la base de datos sin connection pooling:

Podemos ver que sin encriptación SSL tenemos un tiempo total de ejecución de 14 segundos y un tiempo de respuesta medio de 9 milisegundos que nos servirá como línea base cuando comparemos con el entorno con SSL. Si monitorizamos el número de logins por segundo que alcanzamos podemos ver que llegamos a un pico de 450 por segundo:

Para configurar la encriptación SSL abriremos el Configuration Manager de SQL Server y en la sección “protocols” editaremos sus propiedades y activaremos el flag para forzar la encriptación de las conexiones:

En la pestaña “certificate” seleccionaremos el certificado que hemos creado previamente y reiniciaremos el servicio de SQL Server:

Antes de lanzar la carga comprobaremos que efectivamente las conexiones que realicemos contra el servidor están efectivamente encriptadas consultando la DMV sys.dm_exec_connections:

El siguiente paso será volver a lanzar la carga anterior contra el servidor:

Podemos ver que el tiempo total ha subido a casi 19 segundos (un 35% más) y el tiempo medio por ejecución de 9ms a 46ms. En lo que respecta al número de conexiones por segundo que podemos procesar vemos que se estancan en menos de 300 (vs las 450 que alcanzábamos sin SSL):

Queda por tanto claro que el número de conexiones por segundo que podemos abrir depende de forma importante de si habilitamos el SSL o no. En casos donde no tengamos paralelismo o éste sea más moderado las latencias por conexión pueden tener un impacto mucho mayor ya que el aumento de la latencia será más significativo. En el siguiente gráfico mostramos un caso real donde podemos ver que pasamos de tiempos de 10 segundos para un proceso serial sin SSL a más de 30 segundos con el SSL activado para el mismo proceso:

En conclusión, en condiciones normales, donde el connection pooling es utilizado de forma correcta, el uso de SSL no supone una sobrecarga relevante ni genera problemas. Sin embargo, donde ya teníamos una situación problemática previa (no uso de connection pooling y un proceso serial)  la activación de SSL sí puede empeorar la situación de forma notable. Recomendamos por tanto antes de habilitar a ciegas el SSL realizar una revisión previa del servidor para asegurarnos que no tenemos ya un problema previo que pudiera verse amplificado con su activación.

Auditoria de operaciones personalizada con Temporal Tables

Auditoria de operaciones personalizada con Temporal Tables

En no raras ocasiones nos vemos en la necesidad de mantener una auditoría de seguridad personalizada ante operaciones INSERT, UPDATE y DELETE. Se nos presenta entonces la problemática de querer añadir a la detección de la operación, determinados artefactos lógicos para nuestra trazabilidad interna. Imaginemos por ejemplo que queremos añadir el usuario lógico de nuestra aplicación, que le pasamos en una propiedad del Application Name de la cadena de conexión, es decir…algo digamos que requiera de cierta lógica por nuestra parte a la hora de guardar el dato.

(más…)

Ataque DoS a SQL Server para Dummies

Ataque DoS a SQL Server para Dummies

En muchas ocasiones nos encontramos con entornos de producción donde “demasiada gente” tiene acceso. En muchos casos son accesos de “solo lectura” aunque eso no los hace inofensivos de cara a la estabilidad del sistema. Pero podemos ir más allá, vamos a ver como con un login, con rol public, sin acceso a ninguna base de datos de usuario, se puede realizar fácilmente un ataque de denegación de servicio (DoS) contra SQL Server.

(más…)

Añadir miembros en roles de bases de datos en Analysis Services con Powershell

Añadir miembros en roles de bases de datos en Analysis Services con Powershell

Powershell es una magnífica herramienta para scripting y administración de servidores y es por esto que cada vez más productos van incorporando sus propios CMDLets para realizar las tareas más comunes. SQL Server no es una excepción y en la versión 2012 incorpora modulos con una buena variedad de comandos que nos permiten realizar tareas de administración sobre el motor de bases de datos, los servicios de análisis, de integración, etc.. En esta versión todavía existe el ejecutable sqlps.exe pero se verá depreciado en futuras versiones. (más…)
Powershell: Desactivando roles de Microsoft SQL Server Analysis Services dinámicamente

Powershell: Desactivando roles de Microsoft SQL Server Analysis Services dinámicamente

El control del acceso de los usuarios a nuestros cubos OLAP se convierte en una tarea importante si. Dentro de nuestras tareas diarias podemos tener diferentes procesos de actualización de los datos del data warehouse (por ejemplo, las últimas ventas de hoy) y su correspondiente proceso de actualización del cubo OLAP para reflejar estos nuevos datos y que se muestre en los informes de nuestros gerentes.
(más…)
Cómo establecer permisos a cada elemento de una lista

Cómo establecer permisos a cada elemento de una lista

El objetivo consiste en modificar los permisos de un elemento de una lista dinámicamente, desde un flujo de trabajo y sin tener que recurrir al modelo de objetos cliente por código.

Vamos a utilizar una lista de ejemplo llamada “Gastos diarios” a la que añadimos solamente dos columnas, “Importe” y “Contabilizado”. Lo que se busca es que el autor sea el único que pueda leer y editar cada elemento, y además, que solamente pueda editar aquellos elementos que no han sido contabilizados.

(más…)