Для отладки HTTP-запросов может оказаться полезным перехват трафика и просмотр пакетов, которые отправляются туда и обратно между клиентом и сервером.
Это тривиально, если HTTP-запросы отправляются по незашифрованному каналу.
В этом случае достаточно просто использовать инструмент типа tcpdump для захвата пакетов и просмотреть их с помощью инструмента типа Wireshark.
Для демонстрации вместо Wireshark используется tshark.
Tshark – это версия Wireshark, основанная на CLI, и предоставляет примерно те же возможности для анализа сетевых пакетов.
Разумеется, показанная здесь отладка может быть выполнена и с помощью Wireshark с графическим интерфейсом.
Для начала давайте рассмотрим пример отладки HTTP-трафика с помощью tshark.
Сначала мы запустим простой httpd-сервер Apache, который принимает обычные текстовые соединения на порту 80 и шифрованные TLS-соединения на порту 443.
Для удобства мы запустим Apache httpd внутри контейнера Docker, но он будет работать и без контейнера, независимо от того, установлен ли Apache httpd из репозитория дистрибутива или скомпилирован самостоятельно.
Чтобы запустить контейнер Apache httpd, создайте файл Dockerfile со следующим содержимым.
Система установит веб-сервер Apache httpd, который по умолчанию принимает обычные текстовые соединения на порту 80.
Кроме того, мы включаем TLS-шифрованные соединения на порту 443 и для этого используем сертификаты, предоставляемые пакетом ssl-cert.
Это самоподписанные сертификаты, которые можно использовать для тестирования.
Поскольку они самоподписанные, они не будут распознаны как доверенные сертификаты большинством пользовательских агентов, но это не проблема.
FROM httpd:2.4 # install snakeoil certificates RUN apt update && apt install -y ssl-cert # enable https on port 443 with snakeoil certificates RUN sed -i \ -e 's/^#\(Include .*httpd-ssl.conf\)/\1/' \ -e 's/^#\(LoadModule .*mod_ssl.so\)/\1/' \ -e 's/^#\(LoadModule .*mod_socache_shmcb.so\)/\1/' \ conf/httpd.conf RUN sed -i \ -e 's|^\(SSLCertificateFile\).*|\1 /etc/ssl/certs/ssl-cert-snakeoil.pem|' \ -e 's|^\(SSLCertificateKeyFile\).*|\1 /etc/ssl/private/ssl-cert-snakeoil.key|' \ conf/extra/httpd-ssl.conf # additionally expose port 443 EXPOSE 443
Затем соберите его с помощью этой команды:
docker build -t simple-apache-httpd .
Теперь запустите httpd-сервер Apache в качестве контейнера:
docker run -it --rm --net="host" --name simple-apache-httpd simple-apache-httpd
В отдельном терминале запустите tcpdump для захвата трафика:
sudo tcpdump -v -i any "src localhost || dst localhost" -w dump.pcap
- 🖧 Как захватить и проанализировать сетевой трафик с помощью tcpdump?
- Как захватить сетевые пакеты и сохранить их в файл с помощью tcpdump
В другом терминале выполните команду curl для выполнения запроса к контейнеру в открытом виде:
$ curl -v http://localhost * Trying 127.0.0.1:80... * TCP_NODELAY set * Connected to localhost (127.0.0.1) port 80 (#0) > GET / HTTP/1.1 > Host: localhost > User-Agent: curl/7.68.0 > Accept: */* > * Mark bundle as not supporting multiuse < HTTP/1.1 200 OK < Date: Thu, 02 Dec 2021 12:55:40 GMT < Server: Apache/2.4.51 (Unix) OpenSSL/1.1.1k < Last-Modified: Mon, 11 Jun 2007 18:53:14 GMT < ETag: "2d-432a5e4a73a80" < Accept-Ranges: bytes < Content-Length: 45 < Content-Type: text/html < <html><body><h1>It works!</h1></body></html> * Connection #0 to host localhost left intact
Остановите tcpdump и просмотрите захват пакетов с помощью tshark:
$ tshark -r dump.pcap -Y http 48 11.912607 127.0.0.1 → 127.0.0.1 HTTP 141 GET / HTTP/1.1 50 11.919104 127.0.0.1 → 127.0.0.1 HTTP 353 HTTP/1.1 200 OK (text/html)
Мы можем четко увидеть HTTP-запрос, который мы только что выполнили с помощью curl.
🖧 В чем разница между curl и Wget?
С зашифрованными соединениями TLS это уже не так просто.
Мы вообще не увидим никакого HTTP-трафика, вместо этого мы увидим только рукопожатие TLS и зашифрованные пакеты данных.
Обратите внимание, что теперь нам нужно указать флаг -k для curl, поскольку сертификаты являются самоподписанными и поэтому не заслуживают доверия:
$ curl -v -k https://localhost * Trying 127.0.0.1:443... * TCP_NODELAY set * Connected to localhost (127.0.0.1) port 443 (#0) * ALPN, offering h2 * ALPN, offering http/1.1 * successfully set certificate verify locations: * CAfile: /etc/ssl/certs/ca-certificates.crt CApath: /etc/ssl/certs * TLSv1.3 (OUT), TLS handshake, Client hello (1): * TLSv1.3 (IN), TLS handshake, Server hello (2): * TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8): * TLSv1.3 (IN), TLS handshake, Certificate (11): * TLSv1.3 (IN), TLS handshake, CERT verify (15): * TLSv1.3 (IN), TLS handshake, Finished (20): * TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1): * TLSv1.3 (OUT), TLS handshake, Finished (20): * SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384 * ALPN, server accepted to use http/1.1 * Server certificate: * subject: CN=f31d50e8d088 * start date: Dec 2 10:39:24 2021 GMT * expire date: Nov 30 10:39:24 2031 GMT * issuer: CN=f31d50e8d088 * SSL certificate verify result: self signed certificate (18), continuing anyway. > GET / HTTP/1.1 > Host: localhost > User-Agent: curl/7.68.0 > Accept: */* > * TLSv1.3 (IN), TLS handshake, Newsession Ticket (4): * TLSv1.3 (IN), TLS handshake, Newsession Ticket (4): * old SSL session ID is stale, removing * Mark bundle as not supporting multiuse < HTTP/1.1 200 OK < Date: Thu, 02 Dec 2021 13:00:23 GMT < Server: Apache/2.4.51 (Unix) OpenSSL/1.1.1k < Last-Modified: Mon, 11 Jun 2007 18:53:14 GMT < ETag: "2d-432a5e4a73a80" < Accept-Ranges: bytes < Content-Length: 45 < Content-Type: text/html < <html><body><h1>It works!</h1></body></html> * Connection #0 to host localhost left intact
Мы больше не видим HTTP-запрос:
$ tshark -r dump.pcap -Y http
Мы можем видеть только зашифрованные пакеты TLS:
$ tshark -r dump.pcap -Y tls 13 1.492489 127.0.0.1 → 127.0.0.1 TLSv1 585 Client Hello 15 1.496532 127.0.0.1 → 127.0.0.1 TLSv1.3 1381 Server Hello, Change Cipher Spec, ... 17 1.497260 127.0.0.1 → 127.0.0.1 TLSv1.3 148 Change Cipher Spec, Application Data 19 1.497486 127.0.0.1 → 127.0.0.1 TLSv1.3 163 Application Data 21 1.497556 127.0.0.1 → 127.0.0.1 TLSv1.3 355 Application Data 23 1.497709 127.0.0.1 → 127.0.0.1 TLSv1.3 355 Application Data 25 1.498220 127.0.0.1 → 127.0.0.1 TLSv1.3 375 Application Data 27 1.498655 127.0.0.1 → 127.0.0.1 TLSv1.3 92 Application Data 29 1.498830 127.0.0.1 → 127.0.0.1 TLSv1.3 92 Application Data
Теперь трафик зашифрован, и нам потребуется расшифровать захваченные пакеты, чтобы проверить HTTP-трафик.
В целях проверки трафика TLS-соединения можно разделить на две группы.
Соединения, которые используют Perfect Forward Secrecy (PFS), и соединения, которые не используют.
Основное различие между этими двумя типами соединений заключается в том, что соединения без PFS могут быть расшифрованы постфактум с помощью долгоживущего закрытого ключа сервера.
Для соединений с PFS это невозможно, поскольку между клиентом и сервером согласовываются недолговечные, эфемерные ключи.
Обычно это достигается путем обмена ключами Диффи-Хеллмана или его производной. Эфемерные ключи, созданные во время обмена ключами, никогда не сохраняются и не используются повторно для других соединений.
Это предотвращает расшифровку трафика без участия в первоначальном рукопожатии соединения.
Сначала рассмотрим соединения без PFS. Здесь для расшифровки трафика достаточно передать Wireshark закрытый ключ сервера.
Для этого примера мы должны убедиться, что используем параметры TLS, которые не задействуют PFS. Для этого мы явно указываем curl использовать протокол TLSv1.2 и набор шифров CAMELLIA128-SHA.
Мы повторяем приведенный выше пример, перехватывая трафик:
$ curl -v -k --tlsv1.2 --tls-max 1.2 --ciphers CAMELLIA128-SHA https://localhost * Trying 127.0.0.1:443... * TCP_NODELAY set * Connected to localhost (127.0.0.1) port 443 (#0) * ALPN, offering h2 * ALPN, offering http/1.1 * Cipher selection: CAMELLIA128-SHA * successfully set certificate verify locations: * CAfile: /etc/ssl/certs/ca-certificates.crt CApath: /etc/ssl/certs * 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 finished (14): * TLSv1.2 (OUT), TLS handshake, Client key exchange (16): * TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1): * TLSv1.2 (OUT), TLS handshake, Finished (20): * TLSv1.2 (IN), TLS handshake, Finished (20): * SSL connection using TLSv1.2 / CAMELLIA128-SHA * ALPN, server accepted to use http/1.1 * Server certificate: * subject: CN=f31d50e8d088 * start date: Dec 2 10:39:24 2021 GMT * expire date: Nov 30 10:39:24 2031 GMT * issuer: CN=f31d50e8d088 * SSL certificate verify result: self signed certificate (18), continuing anyway. > GET / HTTP/1.1 > Host: localhost > User-Agent: curl/7.68.0 > Accept: */* > * Mark bundle as not supporting multiuse < HTTP/1.1 200 OK < Date: Thu, 02 Dec 2021 13:34:01 GMT < Server: Apache/2.4.51 (Unix) OpenSSL/1.1.1k < Last-Modified: Mon, 11 Jun 2007 18:53:14 GMT < ETag: "2d-432a5e4a73a80" < Accept-Ranges: bytes < Content-Length: 45 < Content-Type: text/html < <html><body><h1>It works!</h1></body></html> * Connection #0 to host localhost left intact
$ tshark -r dump.pcap -Y tls 6 0.420061 127.0.0.1 → 127.0.0.1 TLSv1 216 Client Hello 8 0.420403 127.0.0.1 → 127.0.0.1 TLSv1.2 943 Server Hello, Certificate, Server Hello Done 10 0.420756 127.0.0.1 → 127.0.0.1 TLSv1.2 414 Client Key Exchange, Change Cipher Spec, ... 12 0.421699 127.0.0.1 → 127.0.0.1 TLSv1.2 147 Change Cipher Spec, Encrypted Handshake Message 14 0.421923 127.0.0.1 → 127.0.0.1 TLSv1.2 189 Application Data 16 0.422142 127.0.0.1 → 127.0.0.1 TLSv1.2 397 Application Data 18 0.422378 127.0.0.1 → 127.0.0.1 TLSv1.2 125 Encrypted Alert 20 0.422497 127.0.0.1 → 127.0.0.1 TLSv1.2 125 Encrypted Alert
Теперь мы извлекаем закрытый TLS ключ сервера:
docker exec -it simple-apache-httpd cat /etc/ssl/private/ssl-cert-snakeoil.key > ssl-cert-snakeoil.key
Это позволит нам использовать закрытый ключ в tshark, указав его с помощью флага -o:
$ tshark -o tls.keys_list:,,,ssl-cert-snakeoil.key -r dump.pcap -Y tls 6 0.420061 127.0.0.1 → 127.0.0.1 TLSv1 216 Client Hello 8 0.420403 127.0.0.1 → 127.0.0.1 TLSv1.2 943 Server Hello, Certificate, Server Hello Done 10 0.420756 127.0.0.1 → 127.0.0.1 TLSv1.2 414 Client Key Exchange, Change Cipher Spec, Finished 12 0.421699 127.0.0.1 → 127.0.0.1 TLSv1.2 147 Change Cipher Spec, Finished 14 0.421923 127.0.0.1 → 127.0.0.1 HTTP 189 GET / HTTP/1.1 16 0.422142 127.0.0.1 → 127.0.0.1 HTTP 397 HTTP/1.1 200 OK (text/html) 18 0.422378 127.0.0.1 → 127.0.0.1 TLSv1.2 125 Alert (Level: Warning, Description: Close Notify) 20 0.422497 127.0.0.1 → 127.0.0.1 TLSv1.2 125 Alert (Level: Warning, Description: Close Notify)
Как было сказано выше, этот подход не будет работать с PFS.
Это означает, что если доступны только параметры TLS с PFS, то невозможно будет использовать описанный выше подход для расшифровки трафика для отладки.
Для TLSv1.3 это всегда так, потому что TLSv1.3 требует PFS.
Нам не нужно указывать это явно, так как curl будет автоматически использовать TLSv1.3.
Чтобы проиллюстрировать это, мы покажем пример, как и раньше.
$ curl -v -k https://localhost * Trying 127.0.0.1:443... * TCP_NODELAY set * Connected to localhost (127.0.0.1) port 443 (#0) * ALPN, offering h2 * ALPN, offering http/1.1 * successfully set certificate verify locations: * CAfile: /etc/ssl/certs/ca-certificates.crt CApath: /etc/ssl/certs * TLSv1.3 (OUT), TLS handshake, Client hello (1): * TLSv1.3 (IN), TLS handshake, Server hello (2): * TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8): * TLSv1.3 (IN), TLS handshake, Certificate (11): * TLSv1.3 (IN), TLS handshake, CERT verify (15): * TLSv1.3 (IN), TLS handshake, Finished (20): * TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1): * TLSv1.3 (OUT), TLS handshake, Finished (20): * SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384 * ALPN, server accepted to use http/1.1 * Server certificate: * subject: CN=f31d50e8d088 * start date: Dec 2 10:39:24 2021 GMT * expire date: Nov 30 10:39:24 2031 GMT * issuer: CN=f31d50e8d088 * SSL certificate verify result: self signed certificate (18), continuing anyway. > GET / HTTP/1.1 > Host: localhost > User-Agent: curl/7.68.0 > Accept: */* > * TLSv1.3 (IN), TLS handshake, Newsession Ticket (4): * TLSv1.3 (IN), TLS handshake, Newsession Ticket (4): * old SSL session ID is stale, removing * Mark bundle as not supporting multiuse < HTTP/1.1 200 OK < Date: Thu, 02 Dec 2021 14:06:14 GMT < Server: Apache/2.4.51 (Unix) OpenSSL/1.1.1k < Last-Modified: Mon, 11 Jun 2007 18:53:14 GMT < ETag: "2d-432a5e4a73a80" < Accept-Ranges: bytes < Content-Length: 45 < Content-Type: text/html < <html><body><h1>It works!</h1></body></html> * Connection #0 to host localhost left intact
При использовании PFS мы снова видим только рукопожатие TLS.
Несмотря на предоставление серверам закрытого ключа, как и раньше, пакеты остаются зашифрованными.
$ tshark -o tls.keys_list:,,,ssl-cert-snakeoil.key -r dump.pcap -Y tls 20 1.660863 127.0.0.1 → 127.0.0.1 TLSv1 585 Client Hello 22 1.676658 127.0.0.1 → 127.0.0.1 TLSv1.3 1381 Server Hello, Change Cipher Spec, ... 24 1.677228 127.0.0.1 → 127.0.0.1 TLSv1.3 148 Change Cipher Spec, Application Data 26 1.677406 127.0.0.1 → 127.0.0.1 TLSv1.3 355 Application Data 27 1.677415 127.0.0.1 → 127.0.0.1 TLSv1.3 163 Application Data 30 1.677504 127.0.0.1 → 127.0.0.1 TLSv1.3 355 Application Data 32 1.680826 127.0.0.1 → 127.0.0.1 TLSv1.3 375 Application Data 34 1.681131 127.0.0.1 → 127.0.0.1 TLSv1.3 92 Application Data 36 1.681262 127.0.0.1 → 127.0.0.1 TLSv1.3 92 Application Data
Чтобы расшифровать этот трафик, нам придется регистрировать эфемерные ключи либо на стороне клиента, либо на стороне сервера.
Все больше и больше технологий используют переменную окружения SSLKEYLOGFILE как способ указать файл журнала, в который могут записываться эфемерные ключи.
Эти журналы могут быть переданы в tshark для расшифровки трафика, аналогично тому, как мы использовали закрытый ключ сервера ранее.
Обратите внимание, что эфемерные ключи вообще не записываются в журнал, если эта переменная окружения не установлена.
Для проверки трафика переменная окружения SSLKEYLOGFILE должна быть установлена на стороне сервера или клиента во время генерации трафика.
После создания этого журнала перехват и расшифровка трафика работают точно так же, как и раньше.
Давайте сначала выполним пример, в котором мы установим переменную окружения SSLKEYLOGFILE на стороне клиента с помощью curl.
Убедитесь, что вы используете curl 7.58 или более новую версию, чтобы это работало.
$ SSLKEYLOGFILE=sslkeylogfile.log curl -v -k https://localhost * Trying 127.0.0.1:443... * TCP_NODELAY set * Connected to localhost (127.0.0.1) port 443 (#0) * ALPN, offering h2 * ALPN, offering http/1.1 * successfully set certificate verify locations: * CAfile: /etc/ssl/certs/ca-certificates.crt CApath: /etc/ssl/certs * TLSv1.3 (OUT), TLS handshake, Client hello (1): * TLSv1.3 (IN), TLS handshake, Server hello (2): * TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8): * TLSv1.3 (IN), TLS handshake, Certificate (11): * TLSv1.3 (IN), TLS handshake, CERT verify (15): * TLSv1.3 (IN), TLS handshake, Finished (20): * TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1): * TLSv1.3 (OUT), TLS handshake, Finished (20): * SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384 * ALPN, server accepted to use http/1.1 * Server certificate: * subject: CN=f31d50e8d088 * start date: Dec 2 10:39:24 2021 GMT * expire date: Nov 30 10:39:24 2031 GMT * issuer: CN=f31d50e8d088 * SSL certificate verify result: self signed certificate (18), continuing anyway. > GET / HTTP/1.1 > Host: localhost > User-Agent: curl/7.68.0 > Accept: */* > * TLSv1.3 (IN), TLS handshake, Newsession Ticket (4): * TLSv1.3 (IN), TLS handshake, Newsession Ticket (4): * old SSL session ID is stale, removing * Mark bundle as not supporting multiuse < HTTP/1.1 200 OK < Date: Thu, 02 Dec 2021 14:17:04 GMT < Server: Apache/2.4.51 (Unix) OpenSSL/1.1.1k < Last-Modified: Mon, 11 Jun 2007 18:53:14 GMT < ETag: "2d-432a5e4a73a80" < Accept-Ranges: bytes < Content-Length: 45 < Content-Type: text/html < <html><body><h1>It works!</h1></body></html> * Connection #0 to host localhost left intact
С помощью журнала ключей, записанного curl, мы можем снова расшифровать трафик.
Обратите внимание, что закрытый ключ сервера больше не требуется, нам нужен только файл журнала ключей.
$ tshark -o tls.keylog_file:sslkeylogfile.log -r dump.pcap -Y tls 4 0.007706 127.0.0.1 → 127.0.0.1 TLSv1 585 Client Hello 6 0.009024 127.0.0.1 → 127.0.0.1 TLSv1.3 1381 Server Hello, Change Cipher Spec, ... 8 0.009576 127.0.0.1 → 127.0.0.1 TLSv1.3 148 Change Cipher Spec, Finished 10 0.009790 127.0.0.1 → 127.0.0.1 HTTP 163 GET / HTTP/1.1 11 0.009796 127.0.0.1 → 127.0.0.1 TLSv1.3 355 New Session Ticket 14 0.009941 127.0.0.1 → 127.0.0.1 TLSv1.3 355 New Session Ticket 16 0.010132 127.0.0.1 → 127.0.0.1 HTTP 375 HTTP/1.1 200 OK (text/html) 18 0.010355 127.0.0.1 → 127.0.0.1 TLSv1.3 92 Alert (Level: Warning, Description: Close Notify) 20 0.010458 127.0.0.1 → 127.0.0.1 TLSv1.3 92 Alert (Level: Warning, Description: Close Notify)
Аналогичным образом мы можем установить переменную окружения SSLKEYLOGFILE на стороне сервера.
Для этого необходимо наличие Apache httpd 2.4.49 или более поздней версии.
Мы перезапускаем контейнер сервера и передаем переменную окружения SSLKEYLOGFILE.
docker run -it --rm --net="host" --name simple-apache-httpd -e SSLKEYLOGFILE="/usr/local/apache2/logs/sslkeylogfile.log" simple-apache-httpd
Следующая запись журнала сигнализирует о том, что файл журнала ключей будет записан:
[Tue Dec 21 20:03:20.441733 2021] [ssl:notice] [pid 1:tid 139780428569920] AH10227: Init: Logging SSL private key material to /usr/local/apache2/logs/sslkeylogfile.log
Мы готовы повторить запрос:
$ curl -v -k https://localhost * Trying 127.0.0.1:443... * TCP_NODELAY set * Connected to localhost (127.0.0.1) port 443 (#0) * ALPN, offering h2 * ALPN, offering http/1.1 * successfully set certificate verify locations: * CAfile: /etc/ssl/certs/ca-certificates.crt CApath: /etc/ssl/certs * TLSv1.3 (OUT), TLS handshake, Client hello (1): * TLSv1.3 (IN), TLS handshake, Server hello (2): * TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8): * TLSv1.3 (IN), TLS handshake, Certificate (11): * TLSv1.3 (IN), TLS handshake, CERT verify (15): * TLSv1.3 (IN), TLS handshake, Finished (20): * TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1): * TLSv1.3 (OUT), TLS handshake, Finished (20): * SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384 * ALPN, server accepted to use http/1.1 * Server certificate: * subject: CN=f31d50e8d088 * start date: Dec 2 10:39:24 2021 GMT * expire date: Nov 30 10:39:24 2031 GMT * issuer: CN=f31d50e8d088 * SSL certificate verify result: self signed certificate (18), continuing anyway. > GET / HTTP/1.1 > Host: localhost > User-Agent: curl/7.68.0 > Accept: */* > * TLSv1.3 (IN), TLS handshake, Newsession Ticket (4): * TLSv1.3 (IN), TLS handshake, Newsession Ticket (4): * old SSL session ID is stale, removing * Mark bundle as not supporting multiuse < HTTP/1.1 200 OK < Date: Thu, 02 Dec 2021 14:23:13 GMT < Server: Apache/2.4.51 (Unix) OpenSSL/1.1.1k < Last-Modified: Mon, 11 Jun 2007 18:53:14 GMT < ETag: "2d-432a5e4a73a80" < Accept-Ranges: bytes < Content-Length: 45 < Content-Type: text/html < <html><body><h1>It works!</h1></body></html> * Connection #0 to host localhost left intact
После выполнения и захвата запроса нам нужно получить файл журнала из контейнера, чтобы использовать его с помощью tshark.
docker exec -it simple-apache-httpd cat /usr/local/apache2/logs/sslkeylogfile.log > sslkeylogfile.log
Теперь мы можем расшифровать трафик, как и раньше, снова передав файл журнала ключей в tshark:
$ tshark -o tls.keylog_file:sslkeylogfile.log -r dump.pcap -Y tls 6 0.033156 127.0.0.1 → 127.0.0.1 TLSv1 585 Client Hello 8 0.035385 127.0.0.1 → 127.0.0.1 TLSv1.3 1381 Server Hello, Change Cipher Spec, ... 10 0.035890 127.0.0.1 → 127.0.0.1 TLSv1.3 148 Change Cipher Spec, Finished 12 0.036026 127.0.0.1 → 127.0.0.1 HTTP 163 GET / HTTP/1.1 14 0.036078 127.0.0.1 → 127.0.0.1 TLSv1.3 355 New Session Ticket 16 0.036194 127.0.0.1 → 127.0.0.1 TLSv1.3 355 New Session Ticket 18 0.036511 127.0.0.1 → 127.0.0.1 HTTP 375 HTTP/1.1 200 OK (text/html) 20 0.036814 127.0.0.1 → 127.0.0.1 TLSv1.3 92 Alert (Level: Warning, Description: Close Notify) 22 0.036932 127.0.0.1 → 127.0.0.1 TLSv1.3 92 Alert (Level: Warning, Description: Close Notify)
Этот подход с использованием переменной окружения SSLKEYLOGFILE работает и в некоторых браузерах.
Однако ее можно отключить с помощью переменной времени компиляции из-за риска, который она представляет.
Если злоумышленнику удастся установить эту переменную окружения для клиента или сервера и получить доступ к журналу ключей, он сможет легко взломать TLS-шифрование, как показано выше.
По этой причине хорошей идеей может быть мониторинг журналов на наличие записи, указывающей на использование переменной среды SSLKEYLOGFILE, как показано выше, или даже добавление отдельного журнала, в котором переменная SSLKEYLOGFILE будет регистрироваться, если она присутствует.
Это позволит вам определить постфактум, какие запросы были затронуты, если переменная окружения была установлена.
Кроме того, было бы неплохо просмотреть переменные окружения всех процессов, чтобы определить, установлена ли где-нибудь эта переменная.
Простым способом сделать это вручную является следующая команда.
Она показывает, что переменная окружения SSLKEYLOGFILE используется и куда записывается файл журнала ключей:
$ sudo cat /proc/*/environ | tr '\0' '\n' | grep SSLKEYLOGFILE SSLKEYLOGFILE=/usr/local/apache2/logs/sslkeylogfile.log SSLKEYLOGFILE=/usr/local/apache2/logs/sslkeylogfile.log SSLKEYLOGFILE=/usr/local/apache2/logs/sslkeylogfile.log SSLKEYLOGFILE=/usr/local/apache2/logs/sslkeylogfile.log
см. также:
- 👨⚕️️ Расшифровка трафика SSL / TLS с помощью Wireshark
- 🖧 Как установить Wireshark на Rocky Linux
- 🖧 Как отследить IP-адреса с помощью Wireshark
- 🖧 Поиск и устранение неисправностей сетевой задержки с помощью Wireshark