Cómo aceptar la conexión SSL en un proceso y reutilizar el mismo contexto SSL en otro proceso

6 minutos de lectura

Como aceptar la conexion SSL en un proceso y reutilizar
sentido

He pasado bastante tiempo investigando cómo abordar este problema, pero aún no he podido encontrar una solución que funcione.

Problema:
Estoy usando la biblioteca OpenSSL y Linux. Tengo un proceso de servidor P1 que acepta la conexión SSL del cliente SSL. P1 hace tcp_accept() y luego SSL_accept() e intercambia algunos datos de protocolo con el cliente con SSL_read/SSL_write(). Todo está bien hasta este punto. Ahora, por diseño, P1 necesita bifurcar un proceso secundario C1 para servir al cliente desde este punto en adelante. C1 usa la llamada execve para volver a crear una imagen de sí mismo y generar un binario diferente. C1 aún necesita comunicarse con el cliente SSL a través de la misma conexión SSL que se usó en P1. El problema es que, dado que C1 es un proceso completamente diferente, ¿cómo puede reutilizar la conexión SSL existente para ese cliente? Puedo pasar el descriptor de socket TCP subyacente de P1 a C1, ya que se mantiene en el núcleo, pero no puedo pasar el contexto SSL ya que se mantiene en la biblioteca Openssl.

Vi esta banda de rodadura en stackoverflow pero desafortunadamente no se menciona ninguna solución. OpenSSL: acepte la conexión TLS y luego transfiera a otro proceso

Solución posible:
No estoy seguro de si alguien ya ha resuelto este tipo de problema, pero traté de seguir.

  1. Pensé que podía crear un nuevo contexto SSL y renegociar SSL en el nuevo proceso secundario. Así que en C1 creé un nuevo contexto SSL sobre el mismo fd de socket tcp subyacente e intenté hacer una renegociación SSL. Esto es lo que hice (Omitiendo la parte de inicialización de SSL_ctx)

    ssl = SSL_new(ctx) // ctx se inicializa igual que en el servidor P1
    SSL_set_fd(ssl, fd); // fd es el socket tcp subyacente fd pasado de P1 a C1
    SSL_set_accept_state(ssl);
    SSL_set_verify(ssl, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, 0);
    SSL_renegociar(ssl);
    SSL_hacer_apretón de manos (ssl);
    ssl->estado=SSL_ST_ACCEPT;
    SSL_hacer_apretón de manos (ssl);

Pero la renegociación no tiene éxito y me devuelve un error interno de Openssl de la primera llamada SSL_do_handshake(). Ni siquiera estoy seguro de si esto realmente se puede hacer. La otra solución que se me ocurre es la siguiente.

  1. De alguna manera transfiera todo el contexto SSL para ese cliente de P1 a C1. ¿Qué tan eficientemente se puede hacer esto? Puedo pensar en la memoria compartida para esto, pero no estoy realmente seguro de qué estado interno mantiene OpenSSL que debe copiarse en la memoria compartida. Esta parece ser la solución más lógica, pero no tengo mucha información sobre el código OpenSSL para hacer esto.

¿Alguien se ha enfrentado a un problema similar y lo ha resuelto? Realmente apreciaré cualquier ayuda con respecto a esto.

Muchas gracias

  • ¿Tiene alguna solución para este problema?, en caso afirmativo, dígame la solución.

    – lucifer

    27 de mayo de 2016 a las 9:55


Una búsqueda en línea encuentra esta discusión:

Pasar sesiones TLS entre programas

Una vez que tenga SSL_SESSION, conviértalo a ASN1 (a través de i2d_SSL_SESSION) y descárguelo en un archivo. Lea ese archivo con su segundo programa y vuelva a convertirlo de ASN1 a SSL_SESSION (a través de d2i_SSL_SESSION) y agréguelo a la memoria caché SSL_SESSION de SSL_CTX (a través de SSL_CTX_add_session).

Encontré en doc/ssleay.txt:

[…]

PEM_write_SSL_SESSION(fp,x) y PEM_read_SSL_SESSION(fp,x,cb) escribirán en un puntero de archivo en codificación base64. Lo que puede hacer con esto es pasar información de sesión entre procesos separados.
[…]

Por lo tanto, debe serializar los datos de la sesión SSL de P1 y pasarlos a C1 para deserializarlos, junto con el descriptor de socket. A continuación, puede crear nuevos SSL y SSL_CTX objetos en C1 y asociarlos con el socket y los datos de sesión deserializados para que C1 pueda hacerse cargo de la conversación.

  • Gracias por los consejos. Hice esto, pero C1 no puede enviar los datos con la sesión reanudada. P1 hace SSL_accept(), SSL_get_session(), i2d_SSL_SESSION() y luego bifurca C1. C1 hace SSL_new(), SSL_set_fd(), d2i_SSL_SESSION(), SSL_CTX_add_session(), SSL_set_session(), SSL_set_accept_state(), SSL_write() en orden. Pero los datos no salen del sistema. ¿Me estoy perdiendo algo más?

    – ssen

    21 mayo 2014 a las 21:56

  • ¿OpenSSL informa algún error, especialmente en el SSL_write() ¿En particular?

    – Rémy Lebeau

    21 mayo 2014 a las 22:04

  • SSL_write() no informa ningún error. ¿Cuáles podrían ser otras posibilidades?

    – ssen

    21 mayo 2014 a las 22:24

  • ¿Está seguro de que el socket subyacente simplemente no está almacenando en búfer los datos salientes? ¿Qué tipo de datos estás enviando realmente? ¿Cómo está monitoreando que los datos no salen del sistema?

    – Rémy Lebeau

    21 mayo 2014 a las 22:41

  • Por lo que puedo ver, una SSL_SESSION es solo una especie de caché de aceleración de protocolo de enlace. La conexión real es el objeto SSL, que no es movible. Esta respuesta no responde a la pregunta.

    – Alcaro

    12 de febrero de 2017 a las 11:24

1646968510 776 Como aceptar la conexion SSL en un proceso y reutilizar
minghua

Hice una búsqueda de “modo kernel tls” y encontré un parche de kernel para dar un fd normal para una conexión TLS. Por lo tanto, el fd se puede pasar a otros procesos como un socket normal.

La página se titula “TLS en el núcleo” en lwn.net. Hacia el final hay discusiones interesantes al respecto. Espero que pueda llegar a la línea principal del kernel. O si no, desearía que alguien pudiera crear un conjunto de parches de calidad de producción para que la gente pueda hacer un uso real de él.

Si sabe que algunos productos reales lo están usando, probablemente sea una buena idea compartirlo aquí.

Actualizar: Este proyecto de código abierto “TLSe” como reemplazo de openssh está especialmente diseñado para exportar contexto a otro proceso.

  • Este es el tipo de cosas con las que un ingeniero de seguridad tiene pesadillas. Me recuerda un poco a las fuentes de representación en el kernel de Windows

    – Niklas B.

    18 de junio de 2016 a las 18:09


  • Me pregunto si existen otras formas de pasar una conexión TLS entre procesos. ¿Quizás algo así como un fd activo con el que el proceso puede ser una etapa en una canalización?

    – minghua

    19 de junio de 2016 a las 3:19

  • La memoria compartida parece la opción obvia

    – Niklas B.

    19 de junio de 2016 a las 10:14


  • La memoria compartida puede ser la parte de datos. ¿Qué tal el disparador de un proceso a otro? ¿Cuál sería el más económico y el más rápido?

    – minghua

    20 de junio de 2016 a las 4:35

  • ¿Pasando mensaje? No lo sé exactamente, pero Linux realmente tiene muchas opciones para IPC. Incluso puede enviar un descriptor de archivo a través de un socket Unix

    – Niklas B.

    20 de junio de 2016 a las 8:01


¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad