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

gen_fake_sni errors #17

Closed
zabbius opened this issue Aug 1, 2024 · 27 comments
Closed

gen_fake_sni errors #17

zabbius opened this issue Aug 1, 2024 · 27 comments

Comments

@zabbius
Copy link
Contributor

zabbius commented Aug 1, 2024

Checked out last version and it does not work. Got

root@OpenWrt:/tmp$ ./youtubeUnblock 537
Using TCP segmentation
Fake SNI will be sent before each googlevideo request
GSO is enabled
gen_fake_sni: ip header is null: No error information
gen_fake_sni: ip header is null: No error information
gen_fake_sni: ip header is null: No error information
gen_fake_sni: ip header is null: No error information
gen_fake_sni: ip header is null: No error information
gen_fake_sni: ip header is null: No error information
...

13e78bd works perfectly with POSTROUTING rule

I can help you with testing on OpenWRT if you want.

@Waujito
Copy link
Owner

Waujito commented Aug 2, 2024

Ouch, that is strange. I will playaround with it, thank you. Btw if you know how can you please dump iph from gen_fake_sni? iph is an argument of a function. Just print it(as hex) on each function call.

for(size_t i=0;i<sizeof(struct iphdr);i++)
printf("%02x ",((uint8_t *)iph)[i]);
printf(”\n");

I think the reason may be in ip extensions, but no sure.

@Waujito Waujito closed this as completed in a96d621 Aug 2, 2024
@Waujito Waujito reopened this Aug 2, 2024
@Waujito
Copy link
Owner

Waujito commented Aug 2, 2024

a96d621 is just a temporary solution. It allows to entirely disable fake sni with -DNO_FAKE_SNI I had to do it earlier but I'm too lazy. The issue itself needs in further research.

@Waujito Waujito changed the title Broken for me after last merge gen_fake_sni errors Aug 2, 2024
@zabbius
Copy link
Contributor Author

zabbius commented Aug 2, 2024

Here goes iph

root@OpenWrt:/tmp$ ./youtubeUnblock 537
Using TCP segmentation
Fake SNI will be sent before each googlevideo request
GSO is enabled
45 00 07 fc c2 60 40 00 3f 06 6e d1 c0 a8 17 02 05 08 26 18 
gen_fake_sni: ip header is null: No error information
45 00 07 fc 42 21 40 00 3f 06 ef 10 c0 a8 17 02 05 08 26 18 
gen_fake_sni: ip header is null: No error information
45 00 07 49 f1 aa 40 00 3f 06 40 39 c0 a8 17 02 05 08 26 19 
gen_fake_sni: ip header is null: No error information
45 00 08 16 35 1f 40 00 3f 06 ec 0c c0 a8 17 02 ad c2 8d 49 
gen_fake_sni: ip header is null: No error information
45 00 07 d6 ab 77 40 00 3f 06 75 f4 c0 a8 17 02 ad c2 8d 49 
gen_fake_sni: ip header is null: No error information
45 00 07 d6 4a da 40 00 3f 06 d6 91 c0 a8 17 02 ad c2 8d 49 
gen_fake_sni: ip header is null: No error information
45 00 08 16 a7 02 40 00 3f 06 7a 29 c0 a8 17 02 ad c2 8d 49 
gen_fake_sni: ip header is null: No error information
45 00 07 23 7e fe 40 00 3f 06 14 04 c0 a8 17 02 ad c2 1c 66 

@Waujito
Copy link
Owner

Waujito commented Aug 2, 2024

Here goes iph

45 00 07 fc c2 60 40 00 3f 06 6e d1 c0 a8 17 02 05 08 26 18

Thank you for dumps.
Are you using Google Chrome? I have noticed that total length in IP is too big. Try with Firefox or yt-dlp.

@Waujito
Copy link
Owner

Waujito commented Aug 2, 2024

Oh yeah, we love chrome fat packets. I was able to reproduce.

At very start I also put a debug (displayed in -DDEBUG) message WARNING! Google video packet is too big and may cause issues! for this.

@Waujito Waujito closed this as completed in 709fc4c Aug 2, 2024
@Waujito
Copy link
Owner

Waujito commented Aug 2, 2024

Please, reopen the issue if you get the error again.

@zabbius
Copy link
Contributor Author

zabbius commented Aug 2, 2024

Last version works good. Built dev variant and got this:

root@OpenWrt:/tmp$ ./youtubeUnblock 537
Using TCP segmentation
Fake SNI will be sent before each googlevideo request
GSO is enabled
Google video!
WARNING! Google video packet is too big and may cause issues!
send fake sni
: Operation not permitted

it reports error but it works. Something is not permitted, but we don't know what. =)

@zabbius
Copy link
Contributor Author

zabbius commented Aug 2, 2024

My bad, fresh version does not work. It was browser's cache.

@Waujito
Copy link
Owner

Waujito commented Aug 2, 2024

Last version works good. Built dev variant and got this:

root@OpenWrt:/tmp$ ./youtubeUnblock 537
Using TCP segmentation
Fake SNI will be sent before each googlevideo request
GSO is enabled
Google video!
WARNING! Google video packet is too big and may cause issues!
send fake sni
: Operation not permitted

it reports error but it works. Something is not permitted, but we don't know what. =)

3rd undocumented EPERM, Let's go!
And I have already discovered this and am working on it.

So, I haven't got this error on my machine but have on router. May be something in firewall drops the packet or idk what happening.

@Waujito
Copy link
Owner

Waujito commented Aug 2, 2024

Interesting. I think it may relate to RELATED,ESTABLISHED in conntrack iptables settings. May be RELATED flag will drop fake sni packets since them are out-of-ack and out-of-seq

@Waujito
Copy link
Owner

Waujito commented Aug 2, 2024

The solution will be

root@OpenWrt:/# nft --handle --numeric list chain inet fw4 accept_to_wan
table inet fw4 {
        chain accept_to_wan { # handle 16
                meta nfproto 2 oifname { "eth0.2", "pppoe-wan" } ct state 0x1 counter packets 651 bytes 281273 drop comment "!fw4: Prevent NAT leakage" # handle 289
                oifname { "eth0.2", "pppoe-wan" } counter packets 25994 bytes 3185475 accept comment "!fw4: accept wan IPv4/IPv6 traffic" # handle 291
        }
}
root@OpenWrt:/# nft delete rule inet fw4 accept_to_wan handle 289

@zabbius
Copy link
Contributor Author

zabbius commented Aug 2, 2024

Haven't understood what to do =(

@zabbius
Copy link
Contributor Author

zabbius commented Aug 2, 2024

Am I right that you propose to switch off 'Prevent NAT leakage' rule? Do you know is there any chance to get same conntrack mark for two new packets?

@Waujito
Copy link
Owner

Waujito commented Aug 2, 2024

Am I right that you propose to switch off 'Prevent NAT leakage' rule? Do you know is there any chance to get same conntrack mark for two new packets?

Yes, but better solution is just to immediately (as early as possible for filter output chain) accept any packet marked with youtubeUnblock's mark (I will change it in next versions according to #15 ).

I cannot say anything about connmark. It needs in manual testing.

Note that even if you set nfqueue to forward chain. All the traffic from raw socket (fake client hello and two original client hello segments) will go through the output chain. So you should always put the netfilter rule to accept by mark to the output chain.

You can find the mark defined somewhere in the code :)

@Waujito
Copy link
Owner

Waujito commented Aug 2, 2024

Next step is to update readme

@Waujito Waujito closed this as completed in 571692b Aug 2, 2024
@Waujito
Copy link
Owner

Waujito commented Aug 2, 2024

Updated the documentation. I hope this is finally fixed.

@Waujito
Copy link
Owner

Waujito commented Aug 2, 2024

That's funny but thanks to this issue I was able to fix degraded performance for my router. I was never used nftables before but now I see that this is a very powerful tool. I don't know is it possible to filter conntrack by sent packets in iptables but nftables makes it too easy :)

@ku4in
Copy link

ku4in commented Aug 3, 2024

I don't know is it possible to filter conntrack by sent packets in iptables but nftables makes it too easy :)

I am currently testing on a router with an old version of OpenWRT that uses iptables. To send the first 20 packets to the queue, I use this rule:
iptables -t mangle -A FORWARD -p tcp -m tcp --dport 443 --src 192.168.10.109 -m connbytes --connbytes-dir original --connbytes-mode packets --connbytes 0:19 -j NFQUEUE --queue-num 1984 --queue-bypass

@Waujito
Copy link
Owner

Waujito commented Aug 3, 2024

I don't know is it possible to filter conntrack by sent packets in iptables but nftables makes it too easy :)

I am currently testing on a router with an old version of OpenWRT that uses iptables. To send the first 20 packets to the queue, I use this rule: iptables -t mangle -A FORWARD -p tcp -m tcp --dport 443 --src 192.168.10.109 -m connbytes --connbytes-dir original --connbytes-mode packets --connbytes 0:19 -j NFQUEUE --queue-num 1984 --queue-bypass

Thank you!

@aospiridonov
Copy link

So cool! Everything worked for me.
Thanks!

Waujito added a commit that referenced this issue Aug 3, 2024
Add iptables connbytes counter thanks to this comment #17 (comment)
@ku4in
Copy link

ku4in commented Aug 3, 2024

iptables -t mangle -A FORWARD -p tcp -m tcp --dport 443 --src 192.168.10.109 -m connbytes --connbytes-dir original --connbytes-mode packets --connbytes 0:19 -j NFQUEUE --queue-num 1984 --queue-bypass

I see that you added this rule to the README. It would be helpful to mention that in OpenWRT for -m connbytes in you need install the additional package: opkg install iptables-mod-conntrack-extra.

@Waujito
Copy link
Owner

Waujito commented Aug 3, 2024

iptables -t mangle -A FORWARD -p tcp -m tcp --dport 443 --src 192.168.10.109 -m connbytes --connbytes-dir original --connbytes-mode packets --connbytes 0:19 -j NFQUEUE --queue-num 1984 --queue-bypass

I see that you added this rule to the README. It would be helpful to mention that in OpenWRT for -m connbytes in you need install the additional package: opkg install iptables-mod-conntrack-extra.

Updated. Thanks

@cu6apum
Copy link

cu6apum commented Aug 3, 2024

The solution will be

root@OpenWrt:/# nft --handle --numeric list chain inet fw4 accept_to_wan
table inet fw4 {
        chain accept_to_wan { # handle 16
                meta nfproto 2 oifname { "eth0.2", "pppoe-wan" } ct state 0x1 counter packets 651 bytes 281273 drop comment "!fw4: Prevent NAT leakage" # handle 289
                oifname { "eth0.2", "pppoe-wan" } counter packets 25994 bytes 3185475 accept comment "!fw4: accept wan IPv4/IPv6 traffic" # handle 291
        }
}
root@OpenWrt:/# nft delete rule inet fw4 accept_to_wan handle 289

It worked. Yessss. Thank you for this piece of art!
We'll be FREE.

@zabbius
Copy link
Contributor Author

zabbius commented Aug 4, 2024

I confirm that deleting output rule helps. But Step 3 from readme does not work for me.
Here is my rules:

        chain youtube_postrouting {
                type filter hook postrouting priority filter - 1; policy accept;
                meta nfproto ipv4 oifname { "lan3", "lan4" } tcp dport 443 ct original packets < 20 counter packets 1405 bytes 626065 queue flags bypass to 537
        }

        chain youtube_output {
                type filter hook output priority filter - 1; policy accept;
                meta nfproto ipv4 oifname { "lan3", "lan4" } meta mark & 0x00008000 == 0x00008000 counter packets 28 bytes 36064 accept
        }
...
        chain accept_to_internet {
                meta nfproto ipv4 oifname { "lan3", "lan4" } ct state invalid counter packets 38 bytes 36476 drop comment "!fw4: Prevent NAT leakage"
                meta nfproto ipv4 oifname { "lan3", "lan4" } counter packets 2454 bytes 222722 accept comment "!fw4: accept internet IPv4 traffic"
        }

and I'm still getting send fake sni: Operation not permitted. Btw counter in youtube_output is not zero. Something strange is happening.

@Waujito
Copy link
Owner

Waujito commented Aug 4, 2024

@zabbius Why do you create separate chain for just one rule? Use config for firewall from owrt/537-youtubeUnblock.nft

@zabbius
Copy link
Contributor Author

zabbius commented Aug 4, 2024

@zabbius Why do you create separate chain for just one rule? Use config for firewall from owrt/537-youtubeUnblock.nft

Because it is default way for last OpenWRT to add custom fw4 rules. See /etc/nftables.d/README.

Tried you file - it works good.
Now it's getting more interesting. I want to find the difference between dedicated output chain with priority filter-1 and the begin of default output chain.

@zabbius
Copy link
Contributor Author

zabbius commented Aug 4, 2024

Found the difference. accept verdict in my chain does not prevent next chain output and it drops the packet. In you case accept verdict stops current output chain and packet is not dropped.

I think the best solution for the future is to provide default drop-in includes in chain-pre mode.
See https://openwrt.org/docs/guide-user/firewall/firewall_configuration#drop-in_includes_for_package_authors

Current script adds rules correctly but I'm not sure that your rules will remain alive after firewall reload.

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

5 participants