GNU/Linux >> Tutoriales Linux >  >> Linux

Cómo solucionar el problema del protocolo Curl TLS SSL desde CLI y código PHP

P: En uno de nuestros servidores, el servidor web no está configurado para admitir SSLv2 o SSLv3. Ambos están deshabilitados en el lado del servidor. Solo es compatible con TLSv1. ¿Cómo puedo hacer que curl funcione tanto desde la línea de comandos como desde dentro de mi código PHP?

R: En la mayoría de los casos, curl elegirá automáticamente el protocolo correcto y se conectará a él. Pero también puede especificar un protocolo específico para usar con el comando curl. En este ejemplo, debe indicarle a CURL que use TLSv1, como se explica en este tutorial.

Especifique el protocolo en la línea de comandos Curl

Las siguientes son las diversas opciones de protocolo admitidas en la línea de comando por curl:

  • -0 (o) –http1.0 para HTTP 1.0 (H)
  • -1 (o) –tlsv1 para TLSv1 (SSL)
  • -2 (o) –sslv2 para SSLv2 (SSL)
  • -3 (o) –sslv3 para SSLv3 (SSL)

En este ejemplo, este servidor en particular funciona en HTTP normal. No hay problemas aquí.

$ curl http://192.168.101.1
<html><body><h1>It works!</h1></body></html>

Consulte esto:15 ejemplos prácticos de comandos cURL de Linux

Pero, si usa SSLv3, usando la opción -3, devuelve el mensaje de error "falla de protocolo de enlace de alerta sslv3".

$ curl -3 https://192.168.101.1
curl: (35) error:14094410:SSL routines:SSL3_READ_BYTES:sslv3 alert handshake failure

Si usa SSLv2, usando la opción -2, devuelve el mensaje de error "Protocolo SSL desconocido".

$ curl -2 https://192.168.101.1
curl: (35) Unknown SSL protocol error in connection to 192.168.101.1:443 

En este caso, en este servidor en particular, solo admite TLS. Entonces, use la opción -1 como se muestra a continuación.

$ curl -1 https://192.168.101.1
curl: (60) SSL certificate problem, verify that the CA cert is OK. Details:
error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed

En este caso, dado que estamos utilizando la dirección IP, que no coincide con el certificado SSL que está instalado en el servidor web. Por lo tanto, recibimos el mensaje de error anterior "SSL3_GET_SERVER_CERTIFICATE:verificación de certificado fallida".

Curl por defecto realiza la verificación del certificado SSL. Si utiliza un paquete de autoridad de CA, el nombre del paquete predeterminado es curl-ca-bundle.crt. Puede especificar un paquete diferente usando la opción –cacert.

Pero, en nuestro caso, queremos usar el protocolo TLSv1, pero sin la verificación del certificado SSL. Para ello, utilice la opción -k (o la opción –insecure), que no realizará la verificación del certificado SSL.

El siguiente es un uso de la opción -k.

$ curl -k https://192.168.101.1
curl: (35) Unknown SSL protocol error in connection to 192.168.101.1:443 

Si desea conocer más detalles sobre el error arrojado por el comando CURL, use la opción -v. Como ves a continuación. Incluso cuando no pasamos la opción de protocolo, desde el resultado del comando, podemos ver que está tratando de usar SSLv2 para esto.

$ curl -k -v https://192.168.101.1
* About to connect() to 192.168.101.1 port 443
*   Trying 192.168.101.1... connected
* Connected to 192.168.101.1 (192.168.101.1) port 443
* successfully set certificate verify locations:
*   CAfile: /etc/pki/tls/certs/ca-bundle.crt
  CApath: none
* SSLv2, Client hello (1):
Unknown SSL protocol error in connection to 192.168.101.1:443 
* Closing connection #0
curl: (35) Unknown SSL protocol error in connection to 192.168.101.1:443 

Solución desde la línea de comandos

Consulte esto:wget vs curl:Cómo descargar archivos usando wget y curl

Entonces, en nuestro caso, dado que SSLv2 y SSLv3 están deshabilitados en el lado del servidor, y por alguna razón si curl no configura automáticamente el protocolo correcto, lo siguiente funciona cuando queremos usar solo el protocolo TLSv1 con curl desde la línea de comando como se muestra a continuación.

$ curl -k -1 https://192.168.101.1
<html><body><h1>It works!</h1></body></html>

Si desea ver los detalles de lo que hace exactamente, pase la opción -v como se muestra a continuación.

$ curl -k -1 -v https://192.168.101.1

Lo anterior también se puede hacer usando las siguientes opciones alternativas

$ curl --insecure --tlsv1 --verbose https://192.168.101.1

Nuevamente, en el comando anterior:

  • -1 (o) –tlsv1 para TLSv1 (SSL)
  • -k (o) –insecure para permitir conexiones a sitios SSL sin certificados (H)
  • -v (o) –verbose para hacer que la operación sea más comunicativa (v minúscula)

Solución desde PHP

Desde su código PHP, si está utilizando las funciones cURL y desea configurar las opciones de protocolo, debe usar la función curl_setopt o curl_setopt_array.

Use curl_setopt si desea establecer solo una opción.

curl_setopt($c, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1);

En lo anterior:

  • $c es la variable curl que obtuvo de la función curl_init(), cuando creó un nuevo recurso cURL desde su programa PHP.
  • CURLOPT_SSLVERSION es un nombre de opción curl.
  • CURL_SSLVERSION_TLSv1 es un valor curl para la opción correspondiente en el parámetro #2

También puede usar un número en lugar de "CURL_SSLVERSION_TLSv1". En este ejemplo, esto es equivalente a 1.

curl_setopt($c, CURLOPT_SSLVERSION, 1);

Los siguientes son posibles valores CURLOPT_SSLVERSION que puede establecer. Puede usar la constante descriptiva o el número correspondiente que se muestra a continuación.

  • CURL_SSLVERSION_DEFAULT (0)
  • CURL_SSLVERSION_TLSv1 (1)
  • CURL_SSLVERSION_SSLv2 (2)
  • CURL_SSLVERSION_SSLv3 (3)
  • CURL_SSLVERSION_TLSv1_0 (4)
  • CURL_SSLVERSION_TLSv1_1 (5)
  • CURL_SSLVERSION_TLSv1_2 (6)

Cuando desee configurar la opción CURL múltiple, use curl_setopt_array como se muestra a continuación. Aquí, además de configurar CURLOPT_SSLVERSION, también configura algunas otras opciones de curl.

En este caso, el segundo parámetro será una matriz que contendrá múltiples opciones de CURL como se muestra a continuación.

curl_setopt_array($c, array
(
  CURLOPT_SSL_VERIFYHOST => 0,
  CURLOPT_SSL_VERIFYPEER => 0,
  CURLOPT_SSLVERSION => 1
));

Linux
  1. ¿Qué es un comando cURL y cómo usarlo?

  2. Emita certificados SSL gratuitos y firmados por CA para servidores web de LetsEncrypt

  3. ¿Cómo degradar Php de 5.3.x a 5.2.x?

  4. ¿Cómo habilitar menús globales y arreglar Hud (después de actualizar a 12.04 desde 10.04)?

  5. Cómo verificar si existe un comando de shell desde PHP

Cómo instalar Drupal 8 con Apache, MySQL y SSL en Ubuntu 15.10

Cómo instalar Drupal 8.1 con Nginx, PHP-FPM y SSL en Ubuntu 16.04

Cómo comprobar la fecha de caducidad de SSL en Plesk

Cómo arreglar las desconexiones automáticas de WHM y cPanel

Cómo instalar y configurar Memcached en CentOS 8

Cómo instalar y configurar PHP OPcache en Ubuntu 18.04