Uso de cURL para la solución de problemas con Cloudflare

Información general

cURL es una herramienta de línea de comando que se utiliza para enviar o recibir solicitudes HTTP/HTTPS con la sintaxis de direcciones URL.

Esta herramienta resulta útil para la investigación de fallas:

  • Rendimiento HTTP/HTTPS
  • Respuestas de error HTTP 
  • Encabezados HTTP
  • API
  • Comparación de respuestas de servidor o proxy
  • Certificados SSL

Instalación de cURL (Windows)

En el caso de que el sistema local que se utilice para la prueba o solución de problemas no sea un sistema basado en Linux o UNIX, es probable que la cURL no se instale de forma predeterminada para su uso en la línea de comando de Windows.

La comunidad de código abierto en curl.haxx.se ofrece un asistente de instalación que los usuarios de Windows pueden utilizar. Siga estas instrucciones si utiliza el método de instalación de cURL:

  1. Seleccione el tipo de paquete: curl ejecutable
  2. Seleccione el sistema operativo: Windows/Win32 o Win64
  3. Seleccione el tipo: Genérico
  4. Seleccione la versión Win32 (solo si se ha seleccionado Windows/Win32 en el paso 2): Sin especificar

Si utiliza sistemas basados en x64, consulte los 64 bits ejecutables de curl.haxx.se.

Uso general

Un simple comando de envío de una solicitud estándar HTTP GET sería el siguiente:

curl -svo /dev/null http://example.com/

Este comando devolverá un resultado detallando la respuesta HTTP y los encabezados de solicitud, mientras se descarga el cuerpo de la página en el dispositivo nulo local (que descarta cualquier información que se escriba de inmediato). 

Trying 104.16.39.188...
* Connected to whiskytango.us (127.0.0.1) port 80 (#0)
> GET / HTTP/1.1
> Host: whiskytango.us
> Agente de usuario: curl/7.43.0
> Aceptar: */*
>
< HTTP/1.1 200 OK
< Date: Sat, 09 Jul 2016 11:53:37 GMT
< Content-Type: text/html
< Transfer-Encoding: chunked
< Connection: keep-alive
< Set-Cookie: __cfduid=d1f3639ea02e3abff666d; expires=Sun, 09-Jul-17 11:53:37 GMT; path=/; domain=.whiskytango.us; HttpOnly
< Cf-Railgun: direct (waiting for pending WAN connection)
< Last-Modified: Tue, 18 Aug 2015 09:05:34 GMT
< Server: cloudflare
< CF-RAY: 2bfb939a0a57440e-SFO-DOG
<
{ [2291 bytes data]
* Connection #0 to host whiskytango.us left intact]]>

El resultado anterior es generalmente útil para confirmar la respuesta HTTP y si Cloudflare redirige o no actualmente el tráfico mediante proxy para el sitio (evidente en este caso por el servidor y los encabezados CF-RAY).

Manipulación de los resultados de cURL

En algunos casos, es posible que solo deba revisar un valor de encabezado específico o un poco de información, en lugar de todo el resultado o respuesta de cURL.

En estos casos, la cURL se puede combinar con comandos como grep/egrep y manipular la stdout (respuesta estándar) con 2>&1:

curl -svo /dev/null http://whiskytango.us/img/sg50/IMG_0190.jpg 2>&1 | grep "CF-"
< CF-Cache-Status: HIT
< CF-RAY: 2c07be0acb1d440e-SFO-DOG

En el ejemplo anterior, se ha utilizado esta cURL para analizar los encabezados CF-Cache-Status y CF-RAY (método útil para revisar o solucionar los problemas de almacenamiento en la memoria caché).

Si fuera necesario especificar varias variables para analizar el resultado de cURL estándar, se puede utilizar egrep:

curl -svo /dev/null http://whiskytango.us/img/sg50/IMG_0190.jpg 2>&1 | egrep "Date|CF-|HTTP/"
> GET /img/sg50/IMG_0190.jpg HTTP/1.1
< HTTP/1.1 200 OK
< Date: Sun, 10 Jul 2016 23:35:54 GMT
< CF-Cache-Status: HIT
< CF-RAY: 2c07d5b6bed7440e-SFO-DOG'

2>&1 es una construcción que indica cómo debe redirigirse stderr (error estándar) (y, por lo tanto, incluirse) en stdout (resultado estándar). Esto resulta útil para ofrecer información más detallada y analizar el resultado de cURL en otro comando (como grep).

Indicadores utilizados con frecuencia

-svo /dev/null

Esta serie de indicadores especifica una respuesta detallada, mientras se descarga el resultado o el cuerpo de la página en el elemento local, desarrollado o nulo, que descarta la información inmediatamente y no la guarda. Esto se utiliza para facilitar una visualización clara de la información, como los encabezados de solicitud o respuesta. A continuación, se incluye un desglose de estas opciones:

  • -s: modo Silencio. Elimina la visualización del medidor de progreso o de los mensajes de error.
  • -v: habilita un resultado detallado. 
  • -o /dev/null: configura el resultado en un archivo. En este caso, enviamos el cuerpo de la página a /dev/null.
--header «ENCABEZADO: VALOR»

La opción de --header anterior resulta útil para enviar encabezados de solicitud específicos, como el host, configurar cookies, o incluso un encabezado personalizado que se utilice en una plataforma o aplicación de cliente única. 

--user-agent "USERAGENTSTRING"

En algunos casos, los servidores o las aplicaciones web tienen reglas para bloquear la cadena de agente de usuario de cURL predeterminada, por lo que resulta útil el envío de una cadena de agente de usuario legítima desde un navegador conocido o actual. También puede haber casos en los que se necesiten pruebas de un agente de usuario específico. Si fuera necesario, puede encontrar una base de datos de cadenas de agente de usuario aquí.

--resolve hostname:port:DESTINATIONIPADDRESS http(s)://hostname/URL]]>

La opción de resolución configura una dirección personalizada para un host y puerto específicos. Esto ofrece la capacidad de enviar solicitudes de curl mediante una dirección especifica y evitar que se utilice la dirección generalmente resuelta (la línea de comando alternativa a la modificación del archivo local/host/etc). Esta opción resulta extremadamente útil para comparar las repuestas del servidor de origen y con respecto a las solicitudes que Cloudflare redirige mediante proxy.

Depuración de errores HTTP

Cuando utilice la solución de problemas de los errores HTTP, intente redirigir la cURL con respecto al origen para confirmar la repuesta sin redirigirla a Cloudflare mediante proxy.

Esto se puede realizar de dos maneras, ya sea mediante la especificación del encabezado del alojamientoo y la dirección de cURL con respecto a la dirección IP de origen del sitio, o mediante la opción de resolución

curl -svo /dev/null --header "Host: example.com" http://123.123.123.123/
curl -svo /dev/null --resolve example.com:80:123.123.123.123 http://example.com/

A continuación, se incluye un ejemplo en el que se observa un error 520 para las solicitudes redirigidas mediante proxy.

curl -svo /dev/null http://whiskytango.us/
*   Trying 104.16.40.188...
* Connected to whiskytango.us (127.0.0.1) port 80 (#0)
> GET / HTTP/1.1
> Host: whiskytango.us
> User-Agent: curl/7.43.0
> Accept: */*
>
< HTTP/1.1 520 Unknown Origin-Error
< Date: Sun, 10 Jul 2016 19:55:33 GMT
< Content-Type: text/html; charset=UTF-8
< Transfer-Encoding: chunked
< Connection: keep-alive
< Set-Cookie: __cfduid=d5a459e3960ee3254; expires=Mon, 10-Jul-17 19:55:18 GMT; path=/; domain=.whiskytango.us; HttpOnly
< Pragma: no-cache
< X-Frame-Options: SAMEORIGIN
< Server: cloudflare
< CF-RAY: 2c069292c8e3440e-SFO-DOG
<
{ [3685 bytes data]
* Connection #0 to host whiskytango.us left intact]]>

La ejecución de una cURL en el origen muestra ahora el envío de respuestas vacías, lo que confirmaría la causa raíz del error 520:

curl -svo /dev/null --resolve whiskytango.us:80:123.123.123.123 http://whiskytango.us/
* Added whiskytango.us:80:123.123.123.123 to DNS cache
* Hostname whiskytango.us was found in DNS cache
*   Trying 123.123.123.123...
* Connected to whiskytango.us (127.0.0.1) port 80 (#0)
> GET / HTTP/1.1
> Host: whiskytango.us
> User-Agent: curl/7.43.0
> Accept: */*
>
* Empty reply from server
* Connection #0 to host whiskytango.us left intact]]>

Solución de problemas de rendimiento

La utilización de una cURL puede ser útil para medir la latencia o la degradación del rendimiento de las solicitudes HTTP/HTTPS. Un método rápido y sencillo consiste en utilizar los comandos de tiempo y de cURL:

time curl -svo /dev/null http://example.com/

Se muestra el tiempo total para completar la solicitud:

* Trying 104.16.43.188...
* Connected to whiskytango.us (127.0.0.1) port 80 (#0)
> GET / HTTP/1.1
> Host: whiskytango.us
> User-Agent: curl/7.43.0
> Accept: */*
>
< HTTP/1.1 200 OK
< Date: Sun, 10 Jul 2016 19:10:28 GMT
< Content-Type: text/html
< Transfer-Encoding: chunked
< Connection: keep-alive
< Set-Cookie: __cfduid=de980d61f2dc09; expires=Mon, 10-Jul-17 19:10:28 GMT; path=/; domain=.whiskytango.us; HttpOnly
< Cf-Railgun: direct (waiting for pending WAN connection)
< Last-Modified: Tue, 18 Aug 2015 09:05:34 GMT
< Server: cloudflare
< CF-RAY: 2c0650e4f76c4408-SFO-DOG
<
{ [925 bytes data]
* Connection #0 to host whiskytango.us left intact
real	0m0.079s
user	0m0.007s
sys	0m0.006s]]>

Un método más completo y exhaustivo para probar el rendimiento sería utilizar las opciones -w --write out, que permiten la especificación de variables para la comparación de rendimiento que la cURL imprimirá en el resultado. Se puede encontrar una lista completa de variables para esta opción ejecutando man curl en la lista de comandos o visitando el manual en curl.haxx.se. Puede encontrar una explicación más detallada de lo que significan estos tiempos en este artículo sobre los tiempos con cURL.

A continuación, se muestra un ejemplo de una ejecución de cURL que mide varios vectores de rendimiento en la transacción de solicitud:

curl -svo /dev/null https://example.com/ -w "\nContent Type: %{content_type} \
\nHTTP Code: %{http_code} \
\nHTTP Connect:%{http_connect} \
\nNumber Connects: %{num_connects} \
\nNumber Redirects: %{num_redirects} \
\nRedirect URL: %{redirect_url} \
\nSize Download: %{size_download} \
\nSize Upload: %{size_upload} \
\nSSL Verify: %{ssl_verify_result} \
\nTime Handshake: %{time_appconnect} \
\nTime Connect: %{time_connect} \
\nName Lookup Time: %{time_namelookup} \
\nTime Pretransfer: %{time_pretransfer} \
\nTime Redirect: %{time_redirect} \
\nTime Start Transfer: %{time_starttransfer} \
\nTime Total: %{time_total} \
\nEffective URL: %{url_effective}\n" 2>&1

Conforme al resultado de cURL, se mostrarán los valores de las variables. A continuación, se muestra un ejemplo de la cURL anterior:

 > GET / HTTP/1.1
> Host: whiskytango.us
> User-Agent: curl/7.43.0
> Accept: */*
>
{ [5 bytes data]
< HTTP/1.1 200 OK
< Date: Sun, 10 Jul 2016 19:25:06 GMT
< Content-Type: text/html
< Transfer-Encoding: chunked
< Connection: keep-alive
< Set-Cookie: __cfduid=dcfcff083c6e553dc6750134395b8bf711468178706; expires=Mon, 10-Jul-17 19:25:06 GMT; path=/; domain=.whiskytango.us; HttpOnly
< Cf-Railgun: direct (starting new WAN connection)
< Last-Modified: Tue, 18 Aug 2015 09:05:34 GMT
< Server: cloudflare
< CF-RAY: 2c0666564631440e-SFO-DOG
<
{ [935 bytes data]
* Connection #0 to host whiskytango.us left intact
Content Type: text/html
HTTP Code: 200
HTTP Connect:000
Number Connects: 1
Number Redirects: 0
Redirect URL:
Size Download: 14166
Size Upload: 0
SSL Verify: 0
Time Handshake: 0.076
Time Connect: 0.018
Name Lookup Time: 0.002
Time Pretransfer: 0.076
Time Redirect: 0.000
Time Start Transfer: 0.111
Time Total: 0.129
Effective URL: https://whiskytango.us/

En el resultado, se puede ver información de rendimiento útil que puede afectar a los tiempos de carga, como el protocolo de enlace TLS, el tiempo de búsqueda de DNS, redireccionamientos, transferencias, descargas o cargas de tamaño, etc. 

Cuando se utilizan las opciones -w o --write-out, se puede lograr un resultado más claro de los resultados al denotar una nueva línea con \n antes de cada variable. Esto imprimirá cada variable en una nueva línea en lugar de mostrar todas las métricas en una única línea.

Almacenamiento en memoria caché

La cURL también resulta útil para revisar los comportamientos de almacenamiento en la memoria caché cuando se revisan los encabezados de respuesta HTTP. Se deben tener en cuenta prácticamente siempre los siguientes encabezados HTTP al solucionar problemas de almacenamiento en la memoria caché con Cloudflare:

  • CF-Cache-Status
  • Cache-control/Pragma
  • Expires
  • Last-Modified
  • S-Maxage

Los detalles sobre el comportamiento de almacenamiento en la memoria caché de Cloudflare se pueden encontrar en el artículo de la base de conocimientos:¿Cómo indico a Cloudflare qué debe almacenar en la memoria caché?

Al utilizar una cURL, la utilización de los mismos métodos que se describen en la sección Depuración de errores HTTP de este artículo, resulta útil para comparar los encabezados de respuestas de almacenamiento en la memoria caché desde el origen y cuando Cloudflare redirige las solicitudes mediante proxy.

A continuación, se muestra un ejemplo en el que se utiliza la manipulación de resultados para mostrar que el origen del sitio gestiona tres versiones distintas del mismo archivo (al observar el encabezado Last-Modified) y al confirmar por qué la memoria caché obsoleta se habría gestionado de forma intermitente en las solicitudes:

curl -vso /dev/null -H "Host: example.com" http://162.242.199.20/courses 2>&1 | egrep "< Date|< Last-Modified|< ETag"
< Last-Modified: Sun, 23 Mar 2014 01:07:13 GMT
< ETag: "4147-4f53bbd33b240"
< Date: Thu, 03 Apr 2014 22:52:58 GMT

curl -vso /dev/null -H "Host: example.com" http://162.242.199.20/courses 2>&1 | egrep "< Date|< Last-Modified|< ETag"
< Last-Modified: Sun, 23 Mar 2014 01:07:26 GMT
< ETag: "4149-4f53bbdfa0f80"
< Date: Thu, 03 Apr 2014 22:53:00 GMT

curl -vso /dev/null -H "Host: example.com" http://162.242.199.20/courses 2>&1 | egrep "< Date|< Last-Modified|< ETag"
< Last-Modified: Sun, 23 Mar 2014 01:03:02 GMT
< ETag: "413d-4f53bae3dbd80"
< Date: Thu, 03 Apr 2014 22:53:43 GMT

Depuración de SSL/TLS

Revisión de certificados con cURL

Además de utilizar openSSL para revisar la información de certificado de un sitio y la solución de problemas, la cURL es otra herramienta que puede utilizarse para revisar el certificado gestionado en la solicitud HTTPS:

curl -svo /dev/null https://whiskytango.us/ 2>&1 | egrep -v "^{.*$|^}.*$|^\* http.*$"

Con el comando anterior, los resultados mostrarán información útil, como el protocolo de enlace TLS y la información del certificado que se ha devuelto a la solicitud (en este caso, la solicitud que se ha redirigido mediante proxy ofrecerá un certificado compartido emitido por Comodo):

*  Trying 104.16.43.188...
* Connected to whiskytango.us (104.16.43.188) port 443 (#0)
* ALPN, offering http/1.1
* Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH
* successfully set certificate verify locations:
*   CAfile: /usr/local/etc/openssl/cert.pem
  CApath: none
* TLSv1.2 (OUT), TLS header, Certificate Status (22):
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
* TLSv1.2 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS change cipher, Client hello (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS change cipher, Client hello (1):
* TLSv1.2 (IN), TLS handshake, Finished (20):
* SSL connection using TLSv1.2 / ECDHE-ECDSA-AES128-GCM-SHA256
* ALPN, server accepted to use http/1.1
* Server certificate:
* 	 subject: OU=Domain Control Validated; OU=PositiveSSL Multi-Domain; CN=ssl329925.cloudflaressl.com
* 	 start date: 2016-01-04 00:00:00 GMT
* 	 expire date: 2016-12-31 23:59:59 GMT
* 	 subjectAltName: whiskytango.us matched
* 	 issuer: C=GB; ST=Greater Manchester; L=Salford; O=COMODO CA Limited; CN=COMODO ECC Domain Validation Secure Server CA 2
* 	 SSL certificate verify ok.
> GET / HTTP/1.1
> Host: whiskytango.us
> User-Agent: curl/7.43.0
> Accept: */*
>
< HTTP/1.1 200 OK
< Date: Sun, 10 Jul 2016 21:41:04 GMT
< Content-Type: text/html
< Transfer-Encoding: chunked
< Connection: keep-alive
< Set-Cookie: __cfduid=dde6e686bb3fffe36d57863a78828beb11468186864; expires=Mon, 10-Jul-17 21:41:04 GMT; path=/; domain=.whiskytango.us; HttpOnly
< Cf-Railgun: direct (starting new WAN connection)
< Last-Modified: Tue, 18 Aug 2015 09:05:34 GMT
< Server: cloudflare
< CF-RAY: 2c072d7e8be6440e-SFO-DOG
<
* Connection #0 to host whiskytango.us left intact

La cadena, 2>&1 | egrep -v "^{.*$|^}.*$|^\* http.*$" se puede utilizar para limpiar y analizar los resultados de cURL con el fin de ofrecer una visualización menos ruidosa de la información de certificado o del protocolo de enlace TLS.

La revisión del certificado de origen (suponiendo que se haya instalado uno) puede realizarse mediante el indicador --resolve:

curl -svo /dev/null --resolve www.example.com:443:ORIGINIPHERE https://www.example.com/

Prueba de versiones TLS

Es posible que se deban realizar pruebas con respecto a una versión específica de TLS (en el caso de solucionar problemas con navegadores antiguos o confirmar que el origen del sitio admite TLS). 

A continuación se incluyen las opciones de envío de una solicitud TLS mediante una versión específica para negociar con:

  • --tlsv1.0
  • --tlsv1.1
  • --tlsv1.2
  • --tlsv1.3

A continuación se incluye un ejemplo de cURL en el que se envía una solicitud HTTPS mediante un protocolo TLS, versión 1.2:

curl -svo /dev/null --tlsv1.1 https://whiskytango.us/ 2>&1 | egrep -v "^{.*$|^}.*$|^\* http.*$"
*   Trying 104.16.40.188...
* Connected to whiskytango.us (104.16.40.188) port 443 (#0)
* ALPN, offering http/1.1
* Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH
* successfully set certificate verify locations:
*   CAfile: /usr/local/etc/openssl/cert.pem
  CApath: none
* TLSv1.1 (OUT), TLS header, Certificate Status (22):
* TLSv1.1 (OUT), TLS handshake, Client hello (1):
* TLSv1.1 (IN), TLS handshake, Server hello (2):
* TLSv1.1 (IN), TLS handshake, Certificate (11):
* TLSv1.1 (IN), TLS handshake, Server key exchange (12):
* TLSv1.1 (IN), TLS handshake, Server finished (14):
* TLSv1.1 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.1 (OUT), TLS change cipher, Client hello (1):
* TLSv1.1 (OUT), TLS handshake, Finished (20):
* TLSv1.1 (IN), TLS change cipher, Client hello (1):
* TLSv1.1 (IN), TLS handshake, Finished (20):
* SSL connection using TLSv1.1 / ECDHE-RSA-AES128-SHA
* ALPN, server accepted to use http/1.1
* Server certificate:
* 	 subject: OU=Domain Control Validated; OU=PositiveSSL Multi-Domain; CN=ssl329924.cloudflaressl.com
* 	 start date: 2016-01-03 00:00:00 GMT
* 	 expire date: 2016-12-31 23:59:59 GMT
* 	 subjectAltName: whiskytango.us matched
* 	 issuer: C=GB; ST=Greater Manchester; L=Salford; O=COMODO CA Limited; CN=COMODO RSA Domain Validation Secure Server CA 2
* 	 SSL certificate verify ok.
> GET / HTTP/1.1
> Host: whiskytango.us
> User-Agent: curl/7.43.0
> Accept: */*
>
< HTTP/1.1 200 OK
< Date: Mon, 18 Jul 2016 20:48:41 GMT
< Content-Type: text/html
< Transfer-Encoding: chunked
< Connection: keep-alive
< Set-Cookie: __cfduid=dfdfe3bd6aec2927ab36d3748cd6a30a31468874921; expires=Tue, 18-Jul-17 20:48:41 GMT; path=/; domain=.whiskytango.us; HttpOnly
< Cf-Railgun: direct (starting new WAN connection)
< Last-Modified: Tue, 18 Aug 2015 09:05:34 GMT
< Server: cloudflare
< CF-RAY: 2c48cbc21031440e-SFO-DOG
<
* Connection #0 to host whiskytango.us left intact

Referencias

curl.haxx.se

¿No has encontrado una respuesta satisfactoria?

Nuestra herramienta de búsqueda puede contestar el 95% de las preguntas más comunes y es la mejor manera de conseguir una respuesta rápida.

Tecnología de Zendesk