Диагностика времени ответа web-сервера по HTTPS с помощью curl если он защищен сервисом Cloudflare

Если Ваш web-сервер защищен с помощью сервиса Cloudflare и периодически при открытии сайта появляется ошибка Error 524: A timeout occurred, то для диагностики проблемы можно легко найти официальную статью Error 524: A timeout occurred в которой описывается причина этой ошибки и как тестировать время ответа Вашего web-сервера. Но статья описывает только вариант тестирования по HTTP и не затрагивает особенностей тестирования при HTTPS соединениях и как раз в этом случае могу возникать сложности.

В своей заметке я постараюсь быстро рассказать особенности тестирования времени ответа web-сервера с помощью curl при HTTPS соединениях.

Исходные данные: Debian 9.9 + nginx 1.15.5 + curl 7.52.1
Задача: Протестировать время ответа web-сервера по HTTPS с помощью curl если он защищен сервисом Cloudflare

В моем случае вся связь по цепочке «Браузер клиента» -> «Сервера Cloudflare» -> «Мой web-сервер» идет только с использованием HTTPS, то есть в панели dash.cloudflare.com на странице SSL режим «Modes of Operation» стоит «Full SSL», более детально о режимах читайте на этой странице, а если кратко, то картинка ниже все проиллюстрирует:

Cloudflare Full SSL

Итак, первым шагом мы должны убедиться, что у нас свежая версия консольной утилиты curl, нам нужна версия выше 7.18.1 т.к. именно с этой версии есть поддержка расширения SNI. Если Вы захотите тестировать кластер серверов, то Вам потребуется curl не ниже версии 7.49.0, т.к. именно с этой версии есть поддержка опции —connect-to (см. лог изменений curl).

Проверим версию curl:

# curl --version
curl 7.52.1 (x86_64-pc-linux-gnu) libcurl/7.52.1 OpenSSL/1.0.2r zlib/1.2.8 libidn2/0.16 libpsl/0.17.0 (+libidn2/0.16) libssh2/1.7.0 nghttp2/1.18.1 librtmp/2.3
Protocols: dict file ftp ftps gopher http https imap imaps ldap ldaps pop3 pop3s rtmp rtsp scp sftp smb smbs smtp smtps telnet tftp
Features: AsynchDNS IDN IPv6 Largefile GSS-API Kerberos SPNEGO NTLM NTLM_WB SSL libz TLS-SRP HTTP2 UnixSockets HTTPS-proxy PSL

Отлично, в нашем дистрибутиве Debian версия 7.52.1

Теперь первым шагом мы проверяем время ответа нашего web-сервера через Cloudflare, тут все просто:

MYDOMAIN="mysite.ru"; curl -vso /dev/null -A "Mozilla/5.0 (Windows; U; Windows NT 5.1; de; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3" -w "Connect: %{time_connect}\nTTFB: %{time_starttransfer}\nTotal time: %{time_total}\n" https://${MYDOMAIN}

В ответ нам будет выдано что-то подобное:

* Rebuilt URL to: https://mysite.ru/
*   Trying 104.27.189.205...
* TCP_NODELAY set
* Connected to mysite.ru (104.27.189.205) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH
* successfully set certificate verify locations:
*   CAfile: /etc/ssl/certs/ca-certificates.crt
  CApath: /etc/ssl/certs
* TLSv1.2 (OUT), TLS header, Certificate Status (22):
} [5 bytes data]
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
} [512 bytes data]
* TLSv1.2 (IN), TLS handshake, Server hello (2):
{ [96 bytes data]
* TLSv1.2 (IN), TLS handshake, Certificate (11):
{ [2209 bytes data]
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
{ [147 bytes data]
* TLSv1.2 (IN), TLS handshake, Server finished (14):
{ [4 bytes data]
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
} [70 bytes data]
* TLSv1.2 (OUT), TLS change cipher, Client hello (1):
} [1 bytes data]
* TLSv1.2 (OUT), TLS handshake, Finished (20):
} [16 bytes data]
* TLSv1.2 (IN), TLS change cipher, Client hello (1):
{ [1 bytes data]
* TLSv1.2 (IN), TLS handshake, Finished (20):
{ [16 bytes data]
* SSL connection using TLSv1.2 / ECDHE-ECDSA-AES128-GCM-SHA256
* ALPN, server accepted to use h2
* Server certificate:
*  subject: C=US; ST=CA; L=San Francisco; O=CloudFlare, Inc.; CN=sni.cloudflaressl.com
*  start date: Mar 31 00:00:00 2019 GMT
*  expire date: Mar 31 12:00:00 2020 GMT
*  subjectAltName: host "mysite.ru" matched cert's "*.mysite.ru"
*  issuer: C=US; ST=CA; L=San Francisco; O=CloudFlare, Inc.; CN=CloudFlare Inc ECC CA-2
*  SSL certificate verify ok.
* Using HTTP2, server supports multi-use
* Connection state changed (HTTP/2 confirmed)
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
} [5 bytes data]
* Using Stream ID: 1 (easy handle 0x55fc957fada0)
} [5 bytes data]
> GET / HTTP/1.1
> Host: mysite.ru
> User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; de; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3
> Accept: */*
>
{ [5 bytes data]
* Connection state changed (MAX_CONCURRENT_STREAMS updated)!
} [5 bytes data]
< HTTP/2 200
< date: Tue, 14 May 2019 16:51:24 GMT
< content-type: text/html; charset=UTF-8
< set-cookie: __cfduid=d13c3e9a1156e6edba1e2a13d0c30a8bd1557852684; expires=Wed, 13-May-20 16:51:24 GMT; path=/; domain=.mysite.ru; HttpOnly; Secure
< set-cookie: PHPSESSID=6a5ac8ff445b861b55e311c631e9226c; path=/; secure; HttpOnly
< expires: Thu, 19 Nov 1981 08:52:00 GMT
< cache-control: no-store, no-cache, must-revalidate
< pragma: no-cache
< x-content-type-options: nosniff
< x-xss-protection: 1; mode=block
< x-frame-options: SAMEORIGIN
< strict-transport-security: max-age=7776000; preload
< expect-ct: max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"
< server: cloudflare
< cf-ray: 4d6e606b9fd1bd9b-AMS
<
{ [888 bytes data]
* Curl_http_done: called premature == 0
* Connection #0 to host mysite.ru left intact
Connect: 0.068082
TTFB: 0.582591
Total time: 0.582884

Нас конечно же будет интересовать HTTP код ответа web-сервера, это строка с HTTP/2 200 — значит все хорошо.

Далее нас интересуют строки:

Connect: 0.068082
TTFB: 0.582591
Total time: 0.582884

Первая строка (Connect) — это время потраченное на соединение;

Вторая (TTFB — Time To First Byte или Время до первого байта) — время до получения первого байта (сетевого пакета) веб-страницы после отправки запроса со стороны клиента. Измерение включает DNS-запрос (разрешение имени), время подключения к web-серверу и время ожидания обработанного запроса (обработка, перепаковка, отправка страницы). Термин TTFB часто путают c временем отклика web-сервера — этот показатель дает возможность оценить скорость реакции на HTTP-запрос при отсутствии сетевой задержки. На TTFB влияет почти все: сетевые проблемы и задержки, объем входящего трафика, настройки web-сервера, объем и оптимизированность контента (качество графики, размер html/css/js), если например у вас сайт на php, то сюда же включается время ответа php-скриптов для формирования динамического контента, а если php-скрипты забирают данные из удаленной БД, то и время ответа БД так же будет участвовать в TTFB. В общем это довольно длинная цепочка зависимостей. Более детальный анализ всех стадий соединения и загрузки удобнее проводить с помощью специализированного сервиса, например webpagetest.org, но нам для наших целей сгодиться и curl

И третья строка (Total time) — это общее время.

Теперь нам нужно узнать TTFB в обход серверов Cloudflare и тут база знаний Cloudflare ответа не дает, поэтому вооружившись man curl мы найдем ответ сами, вот он:

MYDOMAIN="mysite.ru"; MYIP="185.125.231.XXX"; curl -vso /dev/null --insecure --resolve ${MYDOMAIN}:443:${MYIP} -A "Mozilla/5.0 (Windows; U; Windows NT 5.1; de; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3" -w "Connect: %{time_connect}\nTTFB: %{time_starttransfer}\nTotal time: %{time_total}\n" -H "Host: ${MYDOMAIN}" https://${MYIP}

,где переменная

MYDOMAIN=mysite.ru — это наш сайт

MYIP=185.125.231.XXX — это реальный IP адрес нашего web-сервера

В ответ нам будет выдано что-то подобное:

* Added mysite.ru:443:185.125.231.XXX to DNS cache
* Rebuilt URL to: https://185.125.231.XXX/
*   Trying 185.125.231.XXX...
* TCP_NODELAY set
* Connected to 185.125.231.XXX (185.125.231.XXX) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH
* successfully set certificate verify locations:
*   CAfile: /etc/ssl/certs/ca-certificates.crt
  CApath: /etc/ssl/certs
* TLSv1.2 (OUT), TLS header, Certificate Status (22):
} [5 bytes data]
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
} [512 bytes data]
* TLSv1.2 (IN), TLS handshake, Server hello (2):
{ [103 bytes data]
* TLSv1.2 (IN), TLS handshake, Certificate (11):
{ [808 bytes data]
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
{ [333 bytes data]
* TLSv1.2 (IN), TLS handshake, Server finished (14):
{ [4 bytes data]
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
} [70 bytes data]
* TLSv1.2 (OUT), TLS change cipher, Client hello (1):
} [1 bytes data]
* TLSv1.2 (OUT), TLS handshake, Finished (20):
} [16 bytes data]
* TLSv1.2 (IN), TLS change cipher, Client hello (1):
{ [1 bytes data]
* TLSv1.2 (IN), TLS handshake, Finished (20):
{ [16 bytes data]
* SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256
* ALPN, server accepted to use h2
* Server certificate:
*  subject: C=CA; ST=None; L=NB; O=None; CN=185.125.231.XXX
*  start date: Mar 27 19:17:02 2019 GMT
*  expire date: Mar 24 19:17:02 2029 GMT
*  issuer: C=CA; ST=None; L=NB; O=None; CN=185.125.231.XXX
*  SSL certificate verify result: self signed certificate (18), continuing anyway.
* Using HTTP2, server supports multi-use
* Connection state changed (HTTP/2 confirmed)
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
} [5 bytes data]
* Using Stream ID: 1 (easy handle 0x5580c7871da0)
} [5 bytes data]
> GET / HTTP/1.1
> Host: mysite.ru
> User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; de; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3
> Accept: */*
>
{ [5 bytes data]
* Connection state changed (MAX_CONCURRENT_STREAMS updated)!
} [5 bytes data]
< HTTP/2 200
< server: nginx
< date: Tue, 14 May 2019 16:53:18 GMT
< content-type: text/html; charset=UTF-8
< set-cookie: PHPSESSID=f1be30edfc7680d6680f0aaa2ac3725c; path=/; secure; HttpOnly
< expires: Thu, 19 Nov 1981 08:52:00 GMT
< cache-control: no-store, no-cache, must-revalidate
< pragma: no-cache
< x-content-type-options: nosniff
< x-xss-protection: 1; mode=block
< x-frame-options: SAMEORIGIN
< strict-transport-security: max-age=31557600
<
{ [3039 bytes data]
* Curl_http_done: called premature == 0
* Connection #0 to host 185.125.231.XXX left intact
Connect: 0.054492
TTFB: 0.492668
Total time: 0.493891

Время TTFB в случае прямого соединения с нашим web-сервером оказалось чуть ниже чем если соединение шло через Cloudflare, но иногда оно может быть и больше.

На этом все, до скорых встреч.

Если у Вас возникли вопросы или Вы хотите, чтобы я помог Вам, то Вы всегда можете связаться со мной разными доступными способами.


Оставить комментарий

avatar
1000

Этот сайт использует Akismet для борьбы со спамом. Узнайте, как обрабатываются ваши данные комментариев.

  Подписаться  
Уведомление о