Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ESNI #80

Open
4ndv opened this issue Jan 16, 2019 · 20 comments
Open

ESNI #80

4ndv opened this issue Jan 16, 2019 · 20 comments
Assignees

Comments

@4ndv
Copy link

4ndv commented Jan 16, 2019

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

@ValdikSS
Copy link
Owner

Думаю, проблема не в наличии ESNI, а в отсутствии SNI в пакетах с ESNI. DPI не может определить, к какому домену производится доступ, и блокирует соединение.

@4ndv
Copy link
Author

4ndv commented Jan 16, 2019

Да, думаю, в этом и есть причина на самом деле. Но было бы интересно видеть и такую проверку (на реакцию при отсутствующем SNI), если оно не сильно трудозатратно. ESNI пока все равно рано реализовывать, он еще не готов толком.

@ValdikSS
Copy link
Owner

ValdikSS commented Sep 7, 2019

Думаю, нужно переделывать Blockcheck на использование низкоуровневых библиотек работы с сетью и шифрованием.

@ValdikSS ValdikSS self-assigned this Sep 7, 2019
@ValdikSS
Copy link
Owner

@4ndv
см. #84
Попробуйте, пожалуйста. Теста ESNI там нет, зато есть тест запроса без SNI, что даст некоторое представление о работе разных DPI с ESNI.

@4ndv
Copy link
Author

4ndv commented Sep 23, 2019

Спс, попробую вечером, как доберусь до виндовой машины

@4ndv
Copy link
Author

4ndv commented Sep 23, 2019

Результаты для моего провайдера:

[O] Тестируем обход DPI (HTTPS)
	 Пробуем Обычный запрос на dailymotion.com
[☠] Ошибка (TLS): ConnectionResetError(10054, 'Удаленный хост принудительно разорвал существующее подключение', None, 10054, None)
	 Пробуем ClientHello без SNI на dailymotion.com
[☠] Ошибка (TLS): ConnectionResetError(10054, 'Удаленный хост принудительно разорвал существующее подключение', None, 10054, None)
	 Пробуем ClientHello с большим padding на dailymotion.com
[☠] Ошибка (TLS): ConnectionResetError(10054, 'Удаленный хост принудительно разорвал существующее подключение', None, 10054, None)
	 Пробуем ClientHello с большим padding и SNI только в конце padding на dailymotion.com
[☠] Ошибка (TLS): ConnectionResetError(10054, 'Удаленный хост принудительно разорвал существующее подключение', None, 10054, None)
	 Пробуем ClientHello с большим padding, поддельным SNI в начале и правильным до padding на dailymotion.com
[✓] Сайт открывается
	 Пробуем ClientHello с большим padding, поддельным SNI в начале и правильным после padding на dailymotion.com
[✓] Сайт открывается
	 Пробуем Обычный запрос на danbooru.donmai.us
[☠] Ошибка (TLS): ConnectionResetError(10054, 'Удаленный хост принудительно разорвал существующее подключение', None, 10054, None)
	 Пробуем ClientHello без SNI на danbooru.donmai.us
[☠] Ошибка (TLS): ConnectionResetError(10054, 'Удаленный хост принудительно разорвал существующее подключение', None, 10054, None)
	 Пробуем ClientHello с большим padding на danbooru.donmai.us
[☠] Ошибка (TLS): ConnectionResetError(10054, 'Удаленный хост принудительно разорвал существующее подключение', None, 10054, None)
	 Пробуем ClientHello с большим padding и SNI только в конце padding на danbooru.donmai.us
[☠] Ошибка (TLS): ConnectionResetError(10054, 'Удаленный хост принудительно разорвал существующее подключение', None, 10054, None)
	 Пробуем ClientHello с большим padding, поддельным SNI в начале и правильным до padding на danbooru.donmai.us
[☠] Ошибка (TLS): SSLError(1, '[SSL: TLSV1_ALERT_DECODE_ERROR] tlsv1 alert decode error (_ssl.c:1076)')
	 Пробуем ClientHello с большим padding, поддельным SNI в начале и правильным после padding на danbooru.donmai.us
[☠] Ошибка (TLS): SSLError(1, '[SSL: TLSV1_ALERT_DECODE_ERROR] tlsv1 alert decode error (_ssl.c:1076)')
	 Пробуем Обычный запрос на e621.net
[☠] Ошибка (TLS): ConnectionResetError(10054, 'Удаленный хост принудительно разорвал существующее подключение', None, 10054, None)
	 Пробуем ClientHello без SNI на e621.net
[☠] Ошибка (TLS): ConnectionResetError(10054, 'Удаленный хост принудительно разорвал существующее подключение', None, 10054, None)
	 Пробуем ClientHello с большим padding на e621.net
[☠] Ошибка (TLS): ConnectionResetError(10054, 'Удаленный хост принудительно разорвал существующее подключение', None, 10054, None)
	 Пробуем ClientHello с большим padding и SNI только в конце padding на e621.net
[☠] Ошибка (TLS): ConnectionResetError(10054, 'Удаленный хост принудительно разорвал существующее подключение', None, 10054, None)
	 Пробуем ClientHello с большим padding, поддельным SNI в начале и правильным до padding на e621.net
[☠] Ошибка (TLS): SSLError(1, '[SSL: TLSV1_ALERT_DECODE_ERROR] tlsv1 alert decode error (_ssl.c:1076)')
	 Пробуем ClientHello с большим padding, поддельным SNI в начале и правильным после padding на e621.net
[☠] Ошибка (TLS): SSLError(1, '[SSL: TLSV1_ALERT_DECODE_ERROR] tlsv1 alert decode error (_ssl.c:1076)')
	 Пробуем Обычный запрос на gelbooru.com
[☠] Ошибка (TLS): ConnectionResetError(10054, 'Удаленный хост принудительно разорвал существующее подключение', None, 10054, None)
	 Пробуем ClientHello без SNI на gelbooru.com
[☠] Ошибка (TLS): ConnectionResetError(10054, 'Удаленный хост принудительно разорвал существующее подключение', None, 10054, None)
	 Пробуем ClientHello с большим padding на gelbooru.com
[☠] Ошибка (TLS): ConnectionResetError(10054, 'Удаленный хост принудительно разорвал существующее подключение', None, 10054, None)
	 Пробуем ClientHello с большим padding и SNI только в конце padding на gelbooru.com
[☠] Ошибка (TLS): ConnectionResetError(10054, 'Удаленный хост принудительно разорвал существующее подключение', None, 10054, None)
	 Пробуем ClientHello с большим padding, поддельным SNI в начале и правильным до padding на gelbooru.com
[☠] Ошибка (TLS): SSLError(1, '[SSL: TLSV1_ALERT_DECODE_ERROR] tlsv1 alert decode error (_ssl.c:1076)')
	 Пробуем ClientHello с большим padding, поддельным SNI в начале и правильным после padding на gelbooru.com
[☠] Ошибка (TLS): SSLError(1, '[SSL: TLSV1_ALERT_DECODE_ERROR] tlsv1 alert decode error (_ssl.c:1076)')
	 Пробуем Обычный запрос на rutracker.org
[☠] Ошибка (TLS): ConnectionResetError(10054, 'Удаленный хост принудительно разорвал существующее подключение', None, 10054, None)
	 Пробуем ClientHello без SNI на rutracker.org
[☠] Ошибка (TLS): ConnectionResetError(10054, 'Удаленный хост принудительно разорвал существующее подключение', None, 10054, None)
	 Пробуем ClientHello с большим padding на rutracker.org
[☠] Ошибка (TLS): ConnectionResetError(10054, 'Удаленный хост принудительно разорвал существующее подключение', None, 10054, None)
	 Пробуем ClientHello с большим padding и SNI только в конце padding на rutracker.org
[☠] Ошибка (TLS): ConnectionResetError(10054, 'Удаленный хост принудительно разорвал существующее подключение', None, 10054, None)
	 Пробуем ClientHello с большим padding, поддельным SNI в начале и правильным до padding на rutracker.org
[✓] Сайт открывается
	 Пробуем ClientHello с большим padding, поддельным SNI в начале и правильным после padding на rutracker.org
[✓] Сайт открывается
	 Пробуем Обычный запрос на zello.com
[☠] Ошибка (TLS): ConnectionResetError(10054, 'Удаленный хост принудительно разорвал существующее подключение', None, 10054, None)
	 Пробуем ClientHello без SNI на zello.com
[☠] Ошибка (TLS): ConnectionResetError(10054, 'Удаленный хост принудительно разорвал существующее подключение', None, 10054, None)
	 Пробуем ClientHello с большим padding на zello.com
[☠] Ошибка (TLS): ConnectionResetError(10054, 'Удаленный хост принудительно разорвал существующее подключение', None, 10054, None)
	 Пробуем ClientHello с большим padding и SNI только в конце padding на zello.com
[☠] Ошибка (TLS): ConnectionResetError(10054, 'Удаленный хост принудительно разорвал существующее подключение', None, 10054, None)
	 Пробуем ClientHello с большим padding, поддельным SNI в начале и правильным до padding на zello.com
[☠] Ошибка (TLS): SSLError(1, '[SSL: TLSV1_ALERT_DECODE_ERROR] tlsv1 alert decode error (_ssl.c:1076)')
	 Пробуем ClientHello с большим padding, поддельным SNI в начале и правильным после padding на zello.com
[☠] Ошибка (TLS): SSLError(1, '[SSL: TLSV1_ALERT_DECODE_ERROR] tlsv1 alert decode error (_ssl.c:1076)')

@ValdikSS
Copy link
Owner

Ваш провайдер блокирует пакеты без SNI. Включение ESNI приведет к недоступности части сайтов, которые были доступны без ESNI.

@4ndv
Copy link
Author

4ndv commented Sep 23, 2019

А проверяется ли, провайдер блокирует вообще все сайты без SNI, или только на заблокированных айпишниках?

@ValdikSS
Copy link
Owner

Это не проверяется. Можно проверить самостоятельно, скачав OpenSSL и запустив, например:
openssl s_client -host yandex.ru -port 443 -noservername

@4ndv
Copy link
Author

4ndv commented Sep 23, 2019

Судя по всему, в отсутствие SNI мой провайдер блокирует по IP:

  1. openssl s_client -host yandex.ru -port 443 - ок (на моей версии openssl он не понимал опцию -noservername, но судя по всему, ей нужно наоборот принудительно передавать -servername, проверял по вайршарку)
▲ ~ openssl s_client -host e621.net -port 443
CONNECTED(00000006)
write:errno=54
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 0 bytes and written 0 bytes
---
New, (NONE), Cipher is (NONE)
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
    Protocol  : TLSv1.2
    Cipher    : 0000
    Session-ID:
    Session-ID-ctx:
    Master-Key:
    Start Time: 1569272449
    Timeout   : 7200 (sec)
    Verify return code: 0 (ok)
---

То же самое, соответственно, и с openssl s_client -host e621.net -port 443 -servername e621.net

  1. openssl s_client -host e621.net -port 443 -servername cloudflare.com - ок

А дальше - лучше.

В голову приходит следующее:

  1. openssl s_client -host cloudflare.com -port 443 -servername e621.net

Ииии... оно успешно соединяется о_О

dig a cloudflare.com + 198.41.214.162 e621.net в /etc/hosts => успешно открывающийся глутамат в хроме (причем, ff игнорировал hosts, видимо, по причине включенного doh, или потому что я его не перезапустил, или хрен его знает почему)

И это все при том, что blockcheck выдает "у вашего провайдера полный DPI"

@ValdikSS
Copy link
Owner

Ииии... оно успешно соединяется о_О

Да, такая особенность у CloudFlare. Он не позволяет делать полноценный Domain Fronting, зато можно подключаться к любому IP-адресу CloudFlare.

@4ndv
Copy link
Author

4ndv commented Sep 23, 2019

Да, но разве глутамат (e621.net) не заблокирован по домену?

@4ndv
Copy link
Author

4ndv commented Sep 23, 2019

То есть, я беру ip от cloudflare.com, и, совершенно не стеснясь и не скрывая, по SNI запрашиваю e621.net, который успешно открывается в хроме.

изображение

изображение

Соответственно, как только я в хостах комментирую эту запись и перезапускаю хром, открываться он перестаёт

@ValdikSS
Copy link
Owner

И это все при том, что blockcheck выдает "у вашего провайдера полный DPI"

Это означает, что ваш провайдер обнаруживает HTTP-запрос на любом IP-адресе и порту, а не только на 80.

[O] Тестируем HTTP
	Открываем  http://a.putinhuylo.com/
[✓] Сайт открывается
	Открываем  http://furry.booru.org/
[✓] Сайт открывается
	Открываем  http://furry.booru.org/index.php?page=post&s=view&id=111173
[☠] Сайт не открывается, пробуем через прокси
[☠] Сайт не открывается через прокси
	Проверяем доступность через isup.me
[☠] Сайт доступен, проблемы только у нас
	Открываем  http://pbooru.com/
[✓] Сайт открывается
	Открываем  http://pbooru.com/index.php?page=post&s=view&id=303026
[☠] Сайт не открывается, пробуем через прокси
[☠] Сайт не открывается через прокси
	Проверяем доступность через isup.me
[☠] Сайт доступен, проблемы только у нас
	Открываем  http://rutracker.org/forum/index.php
[☠] Сайт не открывается, пробуем через прокси
[☠] Сайт не открывается через прокси
	Проверяем доступность через isup.me
[☠] Сайт доступен, проблемы только у нас

Сайт не открылся даже через прокси антизапрета. DPI обнаружил попытку доступа к заблокированному URL даже через незаблокированный IP-адрес и порт 3128 прокси-сервера, и перенаправил на заглушку. Это я называю полным DPI.

@ValdikSS
Copy link
Owner

То есть, я беру ip от cloudflare.com, и, совершенно не стеснясь и не скрывая, по SNI запрашиваю e621.net, который успешно открывается в хроме.

Да, всё верно. Скорее всего, анализу SNI в DPI подвергаются только IP-адреса из реестра, а те, которых нет в реестре, не проходят через DPI, поэтому сайт открывается.

Что, вообще говоря, странно, раз это «полный DPI», выполняющий HTTP-обнаружение независимо от IP-адреса. Возможно, на пути следования пакета есть ещё и DPI вышестоящего провайдера, и блокирует именно он.

@l29ah
Copy link

l29ah commented Sep 24, 2019

Интересно, насколько работоспособным вариантом будет запихивание пустоты в SNI и корректного хостнейма в HTTP?

@4ndv
Copy link
Author

4ndv commented Sep 24, 2019

Интересно, насколько работоспособным вариантом будет запихивание пустоты в SNI и корректного хостнейма в HTTP?

SNI там не от хорошей жизни, это сработает только если у всех сайтов на этом айпишнике один сертификат

@fox0
Copy link

fox0 commented Nov 1, 2019

Небольшое пожелание: добавьте в программу (или в её следующую версию) следующую проверку:
openssl s_client -host derpibooru.org -port 443 (не работает, провайдер блокирует по SNI)
openssl s_client -host derpibooru.org -port 443 -noservername (работает, можно подключиться, если использовать ESNI)

@ValdikSS
Copy link
Owner

ValdikSS commented Nov 1, 2019

@fox0, такая проверка уже есть в экспериментальной версии. Тест обхода DPI HTTPS включает в том числе отправку ClientHello без SNI.

@fox0
Copy link

fox0 commented Nov 1, 2019

Ты крут! Тогда ждём патченый openSSL и/или инструкций как собрать и запустить экспериментальную версию кода,

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants