TLS 1.3 досі надсилає ім’я сервера відкритим текстом
TLS 1.3 шифрує рукостискання, але не SNI. Прочитайте ClientHello, перевірте справжнє прийняття ECH і зафіксуйте, що спостерігач усе ще може бачити.
Оновлення слухача до TLS 1.3 змінює те, що спостерігач може прочитати, але не настільки, наскільки припускає номер версії. ClientHello, як і раніше, передається до узгодження будь-якого шифрування, і у звичайному з’єднанні запитане ім’я сервера лежить там відкритим текстом. Encrypted Client Hello — це механізм, що його приховує, і це окреме розгортання з власними передумовами. Виконайте ці чотири кроки, перш ніж писати політику, що припускає одну з двох поведінок.
Що рукостискання насправді розкриває
TLS 1.3 шифрує сертифікат сервера та більшу частину рукостискання, що йде після ServerHello. Усе, що клієнт надсилає першим, залишається поза цим захистом, бо ключів ще не існує. Зазначення імені сервера є частиною цього першого польоту, тому пасивний спостерігач усе ще може його прочитати, нічого не зламуючи.
Специфікація ECH, RFC 9849, змінює це, шифруючи внутрішній ClientHello для сервера, що співпрацює. Зовнішнє рукостискання зберігається і несе публічне ім’я, яке бачить мережа, тому розгортанню все ще потрібна зовнішня ідентичність, зрозуміла посередникам. Це зовнішнє ім’я — та частина, яку люди пропускають, очікуючи, що з’єднання стане анонімним. Це прикривне ім’я, а не приховане, і воно має розв’язуватися та автентифікуватися, як будь-яке інше.
Ніщо з цього не приховує шлях доставки. Адреси джерела й призначення, порти, розміри пакетів і таймінги залишаються спостережуваними, і вони часто говорять про те, хто говорить, більше, ніж ім’я. Розв’язання імен і зв’язки на рівні застосунків — ще один шар, кожен зі своєю видимістю.
Читайте ClientHello замість припущень
Версія в ServerHello не каже, що надіслав клієнт. Подивіться на перший політ безпосередньо, з позиції, що представляє спостерігача, який вас цікавить.
openssl s_client -connect app.plant.example:443 -servername app.plant.example -tls1_3 </dev/null> 2>/dev/null | head -20 sudo tcpdump -ni eth0 -c 40 'tcp port 443' -w /tmp/tls.pcap tshark -r /tmp/tls.pcap -Y 'tls.handshake.extensions_server_name' -T fields -e tls.handshake.extensions_server_name
Перша команда виконує рукостискання і показує узгоджені параметри, включно з версією протоколу та запитаним вами ім’ям. Друга захоплює перші пакети реального з’єднання, а третя витягує поле SNI із цього захоплення. Якщо поле заповнене, емульований вами спостерігач може його прочитати.
Захоплюйте окремо на боці клієнта і на шляху, коли ці два не збігаються, бо локальне захоплення може показати ім’я, яке проміжний пристрій згодом перепише або відкине. Захоплюйте також із хоста, який сам не завершує TLS, оскільки завершальний проксі бачить відкритий текст за своєю конструкцією і нічого не доводить про те, що бачить мережа.
Ставтеся до розширення ECH як до твердження, а не доказу
Побачити розширення ECH у ClientHello не означає, що з’єднання використало ECH. Клієнти надсилають GREASE ECH, коли не мають придатної конфігурації, саме для того, щоб їхні рукостискання виглядали однаково. Розширення присутнє, внутрішній hello — приманка, а справжнє ім’я все ще читається.
dig +short HTTPS app.plant.example openssl s_client -connect app.plant.example:443 -tls1_3 -status </dev/null> 2>/dev/null | grep -i -E 'ech|status_request'
Перша команда показує, чи публікує джерело запис ресурсу HTTPS із параметром конфігурації ECH, і саме так клієнти дізнаються ключ. Друга шукає відомості про стан рукостискання, хоча повідомлення про успіх клієнта — сильніший доказ. Важливе прийняття: сервер без відповідного ключа не може розшифрувати внутрішній hello, і з’єднання відкочується.
Перевірте й клієнт, оскільки підтримка браузерів і конфігурація різняться за версією та платформою. Політика, побудована на „сучасні браузери використовують ECH“, — це здогад про парк, а не факт про ваш парк. Проведіть інвентаризацію версій, які справді підключаються, і протестуйте по одній із кожної. Та сама сторінка, що працює з актуального настільного браузера, може нічого не приховати від старішого клієнта в тій самій мережі.
Запишіть область спостерігача в політику
Укажіть, де перебуває спостерігач і що видно в цій точці, перш ніж вирішувати, на що може спиратися контроль. З’єднання браузера із сайтом, зовнішній транспорт VPN і проксі, що завершує TLS, розкривають кожен свій набір фактів, і правило, написане для однієї позиції, рідко переноситься чисто на іншу.
Якщо контроль залежить від читання SNI, перевірте, як поводяться розгорнуті клієнти, коли ECH доступний і коли ні. Потім зафіксуйте наслідок для сумісності, бо фільтр, який мовчки перестає збігатися, гірший за той, що ніколи не розгортався.
Нарешті, зберігайте невизначеність у записі. Заміна старого універсального твердження новішим залишає ту саму прогалину під іншим ім’ям протоколу, і наступний рецензент повірить у нього так само твердо.