Фильтр TLS на домены youtube

Фильтр убран. Что это такое было — непонятно, у меня нет даже предположений.

Я тут на днях поизучал последнюю версию приложения Навальный. Okhttp обнаружить не смог. Более того, оно максимуи, что пытается сделать, так это обратится к DnS.GooGle и, вроде как, не использует домены youtube. Блокировки пытается обойти через newnode, а это битторенты и прочие данные по udp протоколу. Соответственно, эта приложуха тут не причем.
При всем при этом, очевидно, это не случайный фильтр и для чего-то он тестировался. Осталось понять, зачем? Другой вопрос, что фильтр убрали, когда гугл согласился сотрудничать и удалить видео с канала Навального, только причем тут newpipe, который, так и так, мало кто использует, а те, кто используют, знают про VPN?

У меня два предположения, высосанных из пальца:

  1. Проводилась демонстрация возможности блокировки конкретной программы, а не сервиса: «Смотрите, в браузере работает, в официальной программе работает, а в NewPipe — не работает».
  2. Перепутали NewNode и NewPipe.

I had a quick look at an APK I found at https://www.apkmonk.com/download-app/com.navalny.blog/4_com.navalny.blog_2021-08-15.apk/ (version 2.0, dated 2021-08-14).

  1. There are many references to “OkHttp” in the code. I see okhttp3. which matches the major version reported earlier; however there is also okhttp/4.6.0. (Well, looking at the changelog, it seems these numbers do not have to match and okhttp3 is the correct package name even for later versions.)
  2. In the disassembled code (smali/s/k.smali), there is a list of 4 strings:
    {"dns.google", "1.1.1.1", "1.0.0.1", "doh.opendns.com"}
    
  3. The string youtube does not appear.
$ apktool d com.navalny.blog_2021-08-15.apk
$ cd com.navalny.blog_2021-08-15

$ grep -ir okhttp
smali/io/ktor/client/engine/okhttp/OkHttpEngineContainer.smali:.class public final Lio/ktor/client/engine/okhttp/OkHttpEngineContainer;
smali/io/ktor/client/engine/okhttp/OkHttpEngineContainer.smali:    const-string v0, "OkHttp"
smali/n/b/k/a.smali:    const-string v4, "OkHttp"
smali/o/y.smali:    const-string v0, "null cannot be cast to non-null type kotlin.collections.List<okhttp3.Interceptor?>"
smali/o/y.smali:    const-string v1, "okHttpClient"
smali/o/i0/c.smali:    const-string v2, "OkHttpClient::class.java.name"
smali/o/i0/c.smali:    const-string v2, "okhttp3."
smali/o/i0/h/e.smali:    sget-object v2, Lokhttp3/internal/publicsuffix/PublicSuffixDatabase;->d:Lokhttp3/internal/publicsuffix/PublicSuffixDatabase$a;
smali/o/i0/h/e.smali:    sget-object v2, Lokhttp3/internal/publicsuffix/PublicSuffixDatabase;->c:Lokhttp3/internal/publicsuffix/PublicSuffixDatabase;
smali/o/i0/h/e.smali:    invoke-virtual {v2, v5}, Lokhttp3/internal/publicsuffix/PublicSuffixDatabase;->a(Ljava/lang/String;)Ljava/lang/String;
smali/o/i0/h/a.smali:    const-string v11, "okhttp/4.6.0"
... many more ...

$ grep -ir -F -A 32 dns.google
smali/s/k.smali:    const-string v7, "dns.google"
smali/s/k.smali-
smali/s/k.smali-    invoke-direct {v6, v7, v4}, Li/g;-><init>(Ljava/lang/String;Lb/a/a/e;)V
smali/s/k.smali-
smali/s/k.smali-    aput-object v6, v5, v21
smali/s/k.smali-
smali/s/k.smali-    new-instance v6, Li/g;
smali/s/k.smali-
smali/s/k.smali-    const-string v7, "1.1.1.1"
smali/s/k.smali-
smali/s/k.smali-    invoke-direct {v6, v7, v4}, Li/g;-><init>(Ljava/lang/String;Lb/a/a/e;)V
smali/s/k.smali-
smali/s/k.smali-    aput-object v6, v5, v20
smali/s/k.smali-
smali/s/k.smali-    new-instance v6, Li/g;
smali/s/k.smali-
smali/s/k.smali-    const-string v7, "1.0.0.1"
smali/s/k.smali-
smali/s/k.smali-    invoke-direct {v6, v7, v4}, Li/g;-><init>(Ljava/lang/String;Lb/a/a/e;)V
smali/s/k.smali-
smali/s/k.smali-    const/4 v7, 0x2
smali/s/k.smali-
smali/s/k.smali-    aput-object v6, v5, v7
smali/s/k.smali-
smali/s/k.smali-    new-instance v6, Li/g;
smali/s/k.smali-
smali/s/k.smali-    const-string v7, "doh.opendns.com"
smali/s/k.smali-
smali/s/k.smali-    invoke-direct {v6, v7, v4}, Li/g;-><init>(Ljava/lang/String;Lb/a/a/e;)V
smali/s/k.smali-
smali/s/k.smali-    const/4 v4, 0x3
smali/s/k.smali-
smali/s/k.smali-    aput-object v6, v5, v4

$ grep -ir youtube

The filter was configured for SNI check. It wasn’t IP-bound.
I also edited SNI in the captured packet to docs.google.com, and it was delivered successfully. Haven’t tried other SNIs.

Проблема с NewPipe встречалась мне только один раз.

Регулярно встречаю ошибки буферизации при воспроизведении Ютуба с помощью mpv + youtube-dl со следующими ошибками в командной строке:

    ffmpeg: tls: Error in the pull function.
    ffmpeg: https: Will reconnect at 262144 in 0 second(s), error=Input/output error.

Получается, ffmpeg тоже блокируют.

А патченная версия NewPipe от ValdikSS’a не пишет ли куда-либо обширные логи ? Смущает слово"debug" в названии. Отладка в данном вопросе дело конечно нужное, но для меня этот фикс проблему решил и хотелось бы обойтись без лишних логов, которые будут захламлять память.

The APK at GitHub claims to be v2.2 and it mentions www.youtube.com. But the TLS fingerprint of the traffic produced by that APK is slightly different from NewPipe’s fingerprint as well. I take NewPipe’s fingerprint from the aforeposted pcaps.

v2.2 from apkmonk also mentions youtube, but the binary differs from GitHub release.

Thanks, great find. I confirm that I find “www.youtube.com” in the 2.2 APK.

smali/s/k.smali:    const-string v11, "www.youtube.com"

Also, the list of DNS resolver names removes “1.1.1.1”.

{"dns.google", "1.0.0.1", "doh.opendns.com"}

v2.2 from apkmonk also mentions youtube, but the binary differs from GitHub release.

For me, the two binaries are the same.

$ sha256sum *.apk
58913378ea52b6effa28117f201ae73f4ae473fd2aa965627f7b1c07b4350c20  androidApp-release-69_2-2.apk
58913378ea52b6effa28117f201ae73f4ae473fd2aa965627f7b1c07b4350c20  com.navalny.blog_2021-09-14.apk

Indeed, my bad. Seems, I’ve confused the apk from apkmonk with the v2.2 apk from apkcombo.com having sha256 3a2dc36dcaac20e8d52ac91b6290508a3c3209dc4bd81f91b86924304122c699.