Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Jan 28, 2026

Currently, tracker detection via TLS SNI opens a real socket to the tracker before extracting the hostname. Trackers see the connection attempt even when subsequently blocked.

Changes

netguard.h

  • Add SNI_PENDING state and sni_state field to tcp_session

tcp.c

  • For port 443 SYN: create session with socket=-1, send fake SYN-ACK, set sni_state=SNI_PENDING
  • When ClientHello arrives on SNI_PENDING session and is allowed: open real socket, queue data, clear state
  • Proper cleanup on write_syn_ack failure

ip.c

  • Send RST for blocked TLS sessions in SNI_PENDING state (tracker never receives any packets)

Flow

Before: SYN → connect to tracker → extract SNI → block (tracker saw connection)
After:  SYN → fake SYN-ACK → extract SNI → block (no connection to tracker)

The existing SNI extraction in ip.c calls is_address_allowed(). For blocked connections, the new code in ip.c sends RST to the app. For allowed connections, tcp.c opens the real socket and relays the queued ClientHello.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • dl.google.com
    • Triggering command: /usr/lib/jvm/temurin-17-jdk-amd64/bin/java /usr/lib/jvm/temurin-17-jdk-amd64/bin/java --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.lang.invoke=ALL-UNNAMED --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.prefs/java.util.prefs=ALL-UNNAMED --add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED --add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.prefs/java.util.prefs=ALL-UNNAMED --add-opens=java.base/java.nio.charset=ALL-UNNAMED --add-opens=java.base/java.net=ALL-UNNAMED --add-opens=java.base/java.util.concurrent.atomic=ALL-UNNAMED --add-opens=java.xml/javax.xml.namespace=ALL-UNNAMED -Xmx4608m -Dfile.encoding=UTF-8 -Duser.country -Duser.language=en -Duser.variant -cp /home/REDACTED/.gradle/wrapper/dists/gradle-8.13-bin/5xuhj0ry160q40clulazy9h7d/gradle-8.13/lib/gradle-daemon-main-8.13.jar (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

Original prompt

explore how to catch TLS SNI without connecting to remote server – and thereby have better tracking detection without contacting tracker hosts, by faking server response.


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

Copilot AI and others added 4 commits January 28, 2026 22:31
This change modifies the VPN packet handling to catch TLS SNI (Server
Name Indication) without actually connecting to tracker hosts, enabling
better tracking detection by faking the server response.

Key changes:
- Added SNI_PENDING state for TLS sessions awaiting SNI extraction
- tcp.c: For port 443 connections, delay real socket opening until SNI
  is checked. Send fake SYN-ACK immediately to receive ClientHello.
- ip.c: When SNI check fails (tracker detected), send RST to the app
  without ever making a connection to the tracker server.
- netguard.h: Added sni_state field to tcp_session structure and
  SNI_PENDING/SNI_RECEIVED constants.

Flow comparison:
Before: SYN → connect to tracker → get SNI → block (tracker sees connection)
After:  SYN → fake SYN-ACK → get SNI → block (no connection to tracker)

Co-authored-by: kasnder <5175206+kasnder@users.noreply.github.com>
- Handle write_syn_ack failure by cleaning up and returning early
- Don't update remote_seq in SNI handler - let check_tcp_socket handle it
- Remove redundant SNI_PENDING checks
- Remove unused SNI_RECEIVED constant
- Keep state as TCP_ESTABLISHED instead of resetting to TCP_LISTEN

Co-authored-by: kasnder <5175206+kasnder@users.noreply.github.com>
Co-authored-by: kasnder <5175206+kasnder@users.noreply.github.com>
Co-authored-by: kasnder <5175206+kasnder@users.noreply.github.com>
Copilot AI changed the title [WIP] Explore catching TLS SNI without connecting to remote server Intercept TLS SNI without connecting to remote server Jan 28, 2026
Copilot AI requested a review from kasnder January 28, 2026 22:50
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

Successfully merging this pull request may close these issues.

2 participants