klzgrad / naiveproxy

Make a fortune quietly
BSD 3-Clause "New" or "Revised" License
6.28k stars 866 forks source link

PostQuantumKyber breaks middleboxes after v124 #641

Closed hdid closed 1 week ago

hdid commented 3 weeks ago

Hi After updating both server and client to the v124; i have problem with client, it does not work anymore (both socks and redir mode). but with v123 everything is normal and working.

root@client:/opt/naiveproxy# ./naive config.json

[0427/085057.622121:INFO:naive_proxy_bin.cc(498)] Proxying via HTTPS server.com:443
[0427/085057.758080:INFO:naive_proxy_bin.cc(698)] Listening on socks://0.0.0.0:1080
[0427/085103.827213:INFO:naive_connection.cc(273)] Connection 1 to api.github.com:443
[0427/085103.834976:INFO:naive_connection.cc(273)] Connection 2 to collector.github.com:443
[0427/085104.125668:INFO:naive_connection.cc(273)] Connection 3 to api.github.com:443
[0427/085104.163995:INFO:naive_connection.cc(273)] Connection 4 to alive.github.com:443
[0427/085105.185023:INFO:naive_connection.cc(273)] Connection 5 to api.github.com:443
[0427/085105.252068:INFO:naive_connection.cc(273)] Connection 6 to collector.github.com:443
[0427/085107.080554:INFO:naive_connection.cc(273)] Connection 7 to witch.valdikss.org.ru:80
[0427/085134.121821:INFO:naive_proxy.cc(184)] Connection 5 closed: ERR_PROXY_CONNECTION_FAILED
[0427/085134.122036:INFO:naive_proxy.cc(184)] Connection 6 closed: ERR_PROXY_CONNECTION_FAILED
[0427/085134.133097:INFO:naive_connection.cc(273)] Connection 8 to api.github.com:443
[0427/085134.134542:INFO:naive_connection.cc(273)] Connection 9 to collector.github.com:443
[0427/085134.246392:INFO:naive_proxy.cc(184)] Connection 9 closed: ERR_PROXY_CONNECTION_FAILED
[0427/085134.253462:INFO:naive_proxy.cc(184)] Connection 8 closed: ERR_PROXY_CONNECTION_FAILED
[0427/085134.343275:INFO:naive_proxy.cc(184)] Connection 4 closed: ERR_PROXY_CONNECTION_FAILED
[0427/085135.358480:INFO:naive_proxy.cc(184)] Connection 3 closed: ERR_PROXY_CONNECTION_FAILED
[0427/085135.430652:INFO:naive_proxy.cc(184)] Connection 2 closed: ERR_PROXY_CONNECTION_FAILED
[0427/085137.507773:INFO:naive_proxy.cc(184)] Connection 7 closed: ERR_PROXY_CONNECTION_FAILED
[0427/085138.607908:INFO:naive_connection.cc(273)] Connection 10 to witch.valdikss.org.ru:80
[0427/085141.224345:INFO:naive_connection.cc(273)] Connection 11 to alive.github.com:443
[0427/085145.231536:INFO:naive_connection.cc(273)] Connection 12 to github.com:443
[0427/085154.906494:INFO:naive_connection.cc(273)] Connection 13 to optimizationguide-pa.googleapis.com:443

root@client:/opt/naiveproxy# cat config.json
{
  "listen": "socks://0.0.0.0:1080",
  "proxy": "https://uname:PaSs@server.com",
  "log": ""
}
Chilledheart commented 2 weeks ago

Maybe it is related to kyber768 algorirthm which changes TLS Hello. see https://www.ithome.com/0/765/151.htm (chineses)

Chilledheart commented 2 weeks ago

I sugguest you can use wireshsrk to capture naive's traffic (both 123 and 124)and upload the screenshot of tls section if possible. It matters.

Chilledheart commented 2 weeks ago

Checked with naiveproxy's source code. Kyber768 is enabled by default for desktop platfrom from v124 just like chrome v124 release:

https://github.com/klzgrad/naiveproxy/blob/master/src/net/base/features.cc#L154 https://github.com/search?q=repo%3Aklzgrad%2Fnaiveproxy%20kPostQuantumKyber&type=code https://chromestatus.com/feature/5257822742249472

image

Chilledheart commented 2 weeks ago

@klzgrad I suggest to add a feature switch to turn this option (aka PostQuantumKyber) off just like chrome does.

Edited: It should support something like

/opt/naiveproxy/naive --disable-features=PostQuantumKyber /etc/naiveproxy/config.json

I tried current binary but no luck.

Maybe you need to deal with command line with Switches

  if (base::CommandLine::ForCurrentProcess()->HasSwitch(
          switches::PostQuantumKyber)) {
    // Enable quantum kyber 768
    return;
  }
klzgrad commented 2 weeks ago

Cannot reproduce with v124 and https://github.com/klzgrad/forwardproxy/releases/tag/v2.7.6-naive2

Chilledheart commented 2 weeks ago

Cannot reproduce with v124 and https://github.com/klzgrad/forwardproxy/releases/tag/v2.7.6-naive2

See the article https://www.ithome.com/0/765/151.htm

It only affects some specific middlebox such as AWS.

Master-Hash commented 2 weeks ago

Cannot reproduce with v124 and https://github.com/klzgrad/forwardproxy/releases/tag/v2.7.6-naive2

See the article https://www.ithome.com/0/765/151.htm

It only affects some specific middlebox such as AWS.

Naiveproxy doesn't work with a load balancer that terminate TLS, and works well with l4 proxy that doesn't understand ClientHello. I wonder why AWS midbox should be blamed.

Chilledheart commented 2 weeks ago

By Google and Microsoft, Kyber768(PostQuantumKyber) is enabled only for desktop platform (Chrome and Edge 124) but not for mobile users such as iOS and Android. Why don't they turn it on for mobile users? It must be kind of experimental feature.

Chilledheart commented 2 weeks ago

Cannot reproduce with v124 and https://github.com/klzgrad/forwardproxy/releases/tag/v2.7.6-naive2

See the article https://www.ithome.com/0/765/151.htm It only affects some specific middlebox such as AWS.

Naiveproxy doesn't work with a load balancer that terminate TLS, and works well with l4 proxy that doesn't understand ClientHello. I wonder why AWS midbox should be blamed.

By some comments, Kyber768 doesn't work with middlebox which understands TLS but not TLS 1.2 with Kyber768 extension because Kyber768 adds kind of TLS 1.3 information in ClientHello even it is TLS 1.2.

klzgrad commented 2 weeks ago

https://issues.chromium.org/issues/336007383 https://issues.chromium.org/issues/336681980

Workaround: https://chromeenterprise.google/policies/#PostQuantumKeyAgreementEnabled

https://support.google.com/chrome/a/answer/9027408?hl=en

Chilledheart commented 2 weeks ago

You need additional efforts on chrome policy support https://source.chromium.org/chromium/chromium/src/+/main:components/policy/resources/templates/README.md if you want to avoid feature switches completely. And I didn't find a way to enable/disable feature switches without base::FeatureList::InitInstance call.

Still, there is no registry in Linux and macOS. You need load these options from command line or configuration files as described in #642. And abuse chrome policy might cause the confuse of chrome users.

I need to grab some sleep now.

klzgrad commented 2 weeks ago

https://github.com/klzgrad/naiveproxy/releases/tag/v124.0.6367.54-3

hdid commented 2 weeks ago

tested with new build. not resolved! https://github.com/klzgrad/naiveproxy/issues/641#issuecomment-2099869192

klzgrad commented 1 week ago

not resolved!

Cannot reproduce.

Chilledheart commented 1 week ago
➜  naiveproxy-v124.0.6367.54-3-linux-x64 ./naive --version
naive 124.0.6367.54

With kyber768:

image

With no-kyber768:

image

Chilledheart commented 1 week ago
➜  naiveproxy-v123.0.6312.40-1-linux-x64 ./naive --version
naive 123.0.6312.40

image

Chilledheart commented 1 week ago

What's changed?

Chilledheart commented 1 week ago
➜  naiveproxy-v124.0.6367.54-3-linux-x64 cat config.json
{
  "listen": "http://127.0.0.1:1081",
  "proxy": "https://goodurl",
  "log": ""
}
klzgrad commented 1 week ago

Read the fine release notes.

Chilledheart commented 1 week ago

For comparision with naiveproxy, let me show how yass behaves:

➜  ~ yass_cli --version
yass_cli 1.9.3
Last Change: 968722e9b6dd0b38a0d2879982e7eaa60e1c359f-refs/branch-heads/1.9.3{1}
Features: linux;arch: x86_64;release;clang 19.0.0;lto thin;linker lld;ldflags icf;libc++;abseil-cpp;tcmalloc_minimal;re2;googleurl;boringssl;mbedtls;builtin ca-bundle;asio;nlohmann json;protobuf;zlib;c-ares;nghttp2;quiche;balsa http parser

yass with kyber768 turned on, similar to naiveproxy 124:

image

yass without kyber768, similar to naiveproxy 123:

image

Look at the ClientHello packet's size. With kyber768, it is much larger and more than 1500 mtu, while without kyber768, it stays less than 600 bytes.

Chilledheart commented 1 week ago

@klzgrad please read the screenshots, your naiveproxy's switch fix doesn't work at all. yass 1.9.3 is based on chromium 125, containing all changes from 124.

klzgrad commented 1 week ago

@klzgrad please read the screenshots, your naiveproxy's switch fix doesn't work at all. yass 1.9.3 is based on chromium 125, containing all changes from 124.

Your statement is false, and your tests were not configured correctly.

These were produced by v124.0.6367.54-3 with the new option:

TLSv1.3 Record Layer: Handshake Protocol: Client Hello
    Content Type: Handshake (22)
    Version: TLS 1.0 (0x0301)
    Length: 604
    Handshake Protocol: Client Hello

TLSv1.3 Record Layer: Handshake Protocol: Client Hello
    Content Type: Handshake (22)
    Version: TLS 1.0 (0x0301)
    Length: 513
    Handshake Protocol: Client Hello
hdid commented 1 week ago

@Chilledheart i'm confused. what is the solution when --no-post-quantum option does not help?

Chilledheart commented 1 week ago

@hdid I got the same result with u. It is up to the author of this project to determine whether there is a switch for turning off post quantum kyber.

Chilledheart commented 1 week ago

@hdid anyway, you can try my project yass https://github.com/Chilledheart/yass?tab=readme-ov-file#prebuilt-binaries

klzgrad commented 1 week ago

I'm getting increasingly grumpy with this stuff. First it's not Chrome's responsibility to keep broken middleboxes working, and since naiveproxy is a verbatim downstream of Chromium, I can justifiably claim to not support this behavior without adding a line of code change. Then there is no established causal link that the reporter's issue has anything to do with post-quantum key agreement. Then I said ok, I add this flag, and there is still no information whatsoever about how to reproduce this issue.

This issue is closed as not reproducible. It's the job of the reporter to come up with a reproducer.

klzgrad commented 1 week ago

You are recommended to try other tools if they work for you. I'd be glad to see less users so there is less attention.

hdid commented 1 week ago

@klzgrad i like this tool and use it almost everyday but new version did not work for me. anyway i tested with another box that had ubuntu 22 and it seems working without changing config. just i do not know is it os limitation or cpu instruction set one. thank you both @klzgrad and @Chilledheart and sorry for the trouble.

Chilledheart commented 1 week ago

@hdid it depends on the middlebox (such as some router, old firewall, or something similar) where naive creates TLS connections, but not the OS nor CPU. And the failure case is very limited and this issue should not affect most of use cases.

Chilledheart commented 1 week ago

./naive

Yours is false-advertising. --no-post-quantum is not working at all.

I have new setup. And the TLS Client Hello is still too large.

    4   0.098745 192.168.2.117 → masked_ip TLSv1 1856 Client Hello

Full log attached:

Console 1:

➜  Downloads curl -L -O https://github.com/klzgrad/naiveproxy/releases/download/v124.0.6367.54-3/naiveproxy-v124.0.6367.54-3-linux-x64.tar.xz
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
100 2654k  100 2654k    0     0   658k      0  0:00:04  0:00:04 --:--:-- 1167k
➜  Downloads sha256sum naiveproxy-v124.0.6367.54-3-linux-x64.tar.xz
4d9d9f2f918b6b8b90f0094d485abdeadc8fd90ccccd07fed828ee2358959ecc  naiveproxy-v124.0.6367.54-3-linux-x64.tar.xz
➜  Downloads tar -xf naiveproxy-v124.0.6367.54-3-linux-x64.tar.xz
➜  Downloads cd naiveproxy-v124.0.6367.54-3-linux-x64
➜  naiveproxy-v124.0.6367.54-3-linux-x64 cat
➜  naiveproxy-v124.0.6367.54-3-linux-x64 cat > config.json
{
  "listen": "http://127.0.0.1:1080",
  "proxy": "https://goodurl",
  "log": ""
}
➜  naiveproxy-v124.0.6367.54-3-linux-x64 ./naive --no-post-quantum -log config.json
[0507/100312.403065:INFO:naive_proxy_bin.cc(194)] Proxying via HTTPS goodurl:443
[0507/100312.410599:INFO:naive_proxy_bin.cc(449)] Listening on http://127.0.0.1:1080
[0507/100314.170175:INFO:naive_connection.cc(273)] Connection 1 to www.google.com:80
[0507/100314.490472:INFO:naive_proxy_delegate.cc(137)] [goodurl:443] negotiated padding type: Variant1
[0507/100314.754081:INFO:naive_proxy.cc(184)] Connection 1 closed: OK

Console 2:

➜  Downloads sudo tcpdump host masked_ip -w recapped.pcap
dropped privs to pcap
tcpdump: listening on enp5s0, link-type EN10MB (Ethernet), snapshot length 262144 bytes
^C50 packets captured
50 packets received by filter
0 packets dropped by kernel
➜  Downloads tshark -r recapped.pcap
    1   0.000000 192.168.2.117 → masked_ip TCP 74 42270 → 443 [SYN] Seq=0 Win=32120 Len=0 MSS=1460 SACK_PERM TSval=1818049297 TSecr=0 WS=128
    2   0.097834 masked_ip → 192.168.2.117 TCP 74 443 → 42270 [SYN, ACK] Seq=0 Ack=1 Win=65160 Len=0 MSS=1440 SACK_PERM TSval=2576939398 TSecr=1818049297 WS=64
    3   0.097908 192.168.2.117 → masked_ip TCP 66 42270 → 443 [ACK] Seq=1 Ack=1 Win=32128 Len=0 TSval=1818049395 TSecr=2576939398
    4   0.098745 192.168.2.117 → masked_ip TLSv1 1856 Client Hello
    5   0.196416 masked_ip → 192.168.2.117 TCP 66 443 → 42270 [ACK] Seq=1 Ack=1791 Win=63936 Len=0 TSval=2576939497 TSecr=1818049396
    6   0.206275 masked_ip → 192.168.2.117 TLSv1.3 1514 Server Hello, Change Cipher Spec, Application Data
    7   0.206321 192.168.2.117 → masked_ip TCP 66 42270 → 443 [ACK] Seq=1791 Ack=1449 Win=31872 Len=0 TSval=1818049503 TSecr=2576939507
    8   0.206467 masked_ip → 192.168.2.117 TCP 1514 443 → 42270 [PSH, ACK] Seq=1449 Ack=1791 Win=64128 Len=1448 TSval=2576939507 TSecr=1818049396 [TCP segment of a reassembled PDU]
    9   0.206468 masked_ip → 192.168.2.117 TLSv1.3 561 Application Data, Application Data, Application Data, Application Data
   10   0.206506 192.168.2.117 → masked_ip TCP 66 42270 → 443 [ACK] Seq=1791 Ack=2897 Win=31872 Len=0 TSval=1818049504 TSecr=2576939507

Console 3:

➜  ~ ALL_PROXY=http://127.0.0.1:1080 curl http://www.google.com
Chilledheart commented 1 week ago

And remote caddy version (built with golang 1.22.2)

$ caddy --version
v2.7.6 h1:w0NymbG2m9PcvKWsrXO6EEkY9Ru4FJK8uQbYcev1p3A=
go version go1.22.2 linux/amd64
Chilledheart commented 1 week ago

For comparsion, some old versioned naiveproxy only created Client Hello with 583 bytes.

➜  Downloads tshark -r naive.pcap
    1   0.000000 192.168.2.22 → masked_ip TCP 74 47402 → 443 [SYN] Seq=0 Win=32120 Len=0 MSS=1460 SACK_PERM TSval=4184841450 TSecr=0 WS=128
    2   0.162247 masked_ip → 192.168.2.22 TCP 74 443 → 47402 [SYN, ACK] Seq=0 Ack=1 Win=43440 Len=0 MSS=1460 SACK_PERM TSval=3121284606 TSecr=4184841450 WS=1024
    3   0.162332 192.168.2.22 → masked_ip TCP 66 47402 → 443 [ACK] Seq=1 Ack=1 Win=32128 Len=0 TSval=4184841613 TSecr=3121284606
    4   0.162484 192.168.2.22 → masked_ip TLSv1 583 Client Hello
    5   0.325353 masked_ip → 192.168.2.22 TCP 66 443 → 47402 [ACK] Seq=1 Ack=518 Win=43008 Len=0 TSval=3121284769 TSecr=4184841613
    6   0.327746 masked_ip → 192.168.2.22 TLSv1.3 1514 Server Hello, Change Cipher Spec, Application Data
klzgrad commented 1 week ago

Wrong command line syntax:

./naive --no-post-quantum -log config.json

https://github.com/klzgrad/naiveproxy/blob/a08c4d354e5960c6c3c09d0ec8c1f87f00b3a43a/USAGE.txt#L1-L2

Either all command line or all config file. No mixing of config file and command line.

hdid commented 1 week ago

Either all command line or all config file. No mixing of config file and command line.

ahh this was my fault. just putted "no-post-quantum": "" in config file and it works now.