Как перехватить и расшифровать TLS-трафик curl

1 Как перехватить и расшифровать TLS-трафик curl?
1.1 Цель
Иногда в целях отладки хочется посмотреть содержимое https трафика.
Например, клиент с помощью cURL
взаимодействует с публичный API сервера.
Но иногда что-то идет не так. Клиент не получает ответ, хотя сервер залогировал, что запрос был успешно выполнен и ответ был отправлен. Выглядит что где-то среди различных проксей и различных подсетей что-то теряется.
В этом случае можно попробовать записать сетевую активность между клиентом и сервисом в разных местах, расшифровать данные, сопоставить запросы и ответы и проверить не потерялось ли что-то.
Для curl
команды есть переменная SSLKEYLOGFILE
, которая содержит имя в файла, в который будут записаны сессионные ключи TLS сессий.
1.2 Перехват и декодирование трафика
Для демонстрации рассмотрим небольшой пример.
Клиент с помощью curl выполнят запросы к произвольному web серверу, используя защищенное соединение.
Записывать сетевой трафик будем с помощью tcpdump
, а анализировать и расшифровывать с помощью wireshark
.
Напишем скрипт:
#!/bin/bash
export SSLKEYLOGFILE=./sslkeys.txt
TCPDUMP_FILE_PID=/tmp/tcpdump.pid
tcpdump -i any -w ./capture.pcap "tcp port 443" &
echo $! >$TCPDUMP_FILE_PID
sleep 1
curl -s "https://amyasnikov.com/posts/" >/dev/null
sleep 1
curl -s "https://amyasnikov.com/tags/" >/dev/null
sleep 1
kill -2 $(cat $TCPDUMP_FILE_PID)
Запускаем:
[amyasnikov@ubuntu:~]$ bash ./script.sh
tcpdump: data link type LINUX_SLL2
tcpdump: listening on any, link-type LINUX_SLL2 (Linux cooked v2), snapshot length 262144 bytes
82 packets captured
82 packets received by filter
0 packets dropped by kernel
Проверим, что в sslkeys.txt записались ключи:
SERVER_HANDSHAKE_TRAFFIC_SECRET 033cb348c1310701e54b6f7291058ccf07e41dce5010546f0080c068587bed37 84f676fcf546c4c12507885485d3841cf9705b158c39e7b90052bb255fcbd00b
EXPORTER_SECRET 033cb348c1310701e54b6f7291058ccf07e41dce5010546f0080c068587bed37 82bd785b4b1165dce6ed95629c01b1d7106f6eb3f612d3e272d015255bd1d88e
SERVER_TRAFFIC_SECRET_0 033cb348c1310701e54b6f7291058ccf07e41dce5010546f0080c068587bed37 61499a7a12af2e0d29b76fa825c1d0ed20bb83994b0bdfe05ea5529203d5ed97
CLIENT_HANDSHAKE_TRAFFIC_SECRET 033cb348c1310701e54b6f7291058ccf07e41dce5010546f0080c068587bed37 527cd45a5a780d5e9c46f3d502bc9bcd8f291041f3e5b8b27a98143d356dbaba
CLIENT_TRAFFIC_SECRET_0 033cb348c1310701e54b6f7291058ccf07e41dce5010546f0080c068587bed37 8b2e86dd8f587b1be03b0d44eae5e0ad9be3ca3fb4dc83501e749e7ce675f097
SERVER_HANDSHAKE_TRAFFIC_SECRET 7c3bbd5f515b905aadceeca189f9f1dcdd5eace6b9eff376ff6f2d250c95749a 2a47038b2e6a7fb39a92c3da9f33219ce3c97e4f2f8c6a6e20b4e12f5449a962
EXPORTER_SECRET 7c3bbd5f515b905aadceeca189f9f1dcdd5eace6b9eff376ff6f2d250c95749a 4d73ef515b8b2ab6806135c061f2b497e9abcccb3787be14e938da984a0ab41a
SERVER_TRAFFIC_SECRET_0 7c3bbd5f515b905aadceeca189f9f1dcdd5eace6b9eff376ff6f2d250c95749a 789f61f6234bbda5f0253a792343ed656355797eba609dcd117b94e5031a131f
CLIENT_HANDSHAKE_TRAFFIC_SECRET 7c3bbd5f515b905aadceeca189f9f1dcdd5eace6b9eff376ff6f2d250c95749a 618530661d160671244b112b319241786dea8a9d11ce572e8a69631c9a5a4f5a
CLIENT_TRAFFIC_SECRET_0 7c3bbd5f515b905aadceeca189f9f1dcdd5eace6b9eff376ff6f2d250c95749a 953d9d633f42bd42379ab6550de1aad45e4fda2dc04abed50fcb2719cee19bc5
Отлично. Все необходимые данные есть.
Теперь осталось открыть дамп в wireshark
и указать файл sslkeys.txt
в настройках Preferences -> Protocols -> TLS -> (Pre)-Master-Secret log filename
.
1.3 Как расшифрованный трафит выглядит в wireshark

Отображение всех пакетов

Декодирование запроса http запроса

Поток данных http трафика
1.4 Вывод
Для расшифровки curl запросов достаточно задать переменную SSLKEYLOGFILE
, никак явно не влияя на сам curl
запрос.
Метод не универсальный. На macOS не заработало, файл указанный в SSLKEYLOGFILE
создавался пустым.