Übersicht
Signale, die auf TCP/IP- und Transportebene sichtbar sind, vor jeder HTTP- oder JS-Ausführung.
1. TCP/IP-Stack-Fingerprint (JA4T / Satori / p0f)
Mechanismus
Passives OS-Fingerprinting liest das TCP-SYN-Paket, um das Betriebssystem zu identifizieren. Jeder OS-TCP/IP-Stack hat eine einzigartige Kombination aus:
- Initialer TTL: 64 (Linux/macOS), 128 (Windows), 255 (manche UNIX)
- Fenstergröße: 64240 (Chrome/Linux), 65535 (macOS), 8192 (ältere Systeme)
- MSS (Maximum Segment Size): Abgeleitet von der MTU
- TCP-Optionen: Reihenfolge und Auswahl von MSS, SACK_PERM, TIMESTAMP, NOP, WINDOW_SCALE
- IP-Flags: DF (Don't Fragment)-Bit-Verhalten
Formate
JA4T: 64240_2-4-8-1-3_1452_10
| Komponente | Bedeutung | Beispiel |
|---|---|---|
| 64240 | TCP-Fenstergröße | Windows-Standard |
| 2-4-8-1-3 | TCP-Optionsreihenfolge (MSS, SACK, TIMESTAMP, NOP, WINDOW) | Chrome/Linux-Reihenfolge |
| 1452 | MSS | Abgeleitet von MTU |
| 10 | Window-Scale-Shift-Zähler | 2^10 = 1024 Multiplikator |
Satori-Fingerprint: 64240:64:1:60:M1452,S,T,N,W10:.
OS-Erkennung
| OS | Fenster | TTL | MSS | Optionen |
|---|---|---|---|---|
| Linux | 29200-65535 | 64 | 1460 | M,S,T,N,W(7-8) |
| Windows 10/11 | 64240 | 128 | 1460 | M,S,T,N,W(10) |
| macOS | 65535 | 64 | 1460 | M,S,T,N,W(6-7) |
| Android | 29200-65535 | 64 | 1460 | M,S,T,N,W(7-8) |
Auswirkung auf Obscura
Client Obscura-Container (TCP-Terminierung) Internet
Client-TCP-Stack Container-TCP-Stack
(für Obscura sichtbar) (für Ziel sichtbar)
Der Zielserver sieht Obscuras TCP-Stack, nicht den des Clients. Dies ist unvermeidbar, da der Container die Client-TCP-Verbindung terminiert.
Abschwächung: Keine auf TCP-Ebene. Die meisten Fingerprinting-Dienste konzentrieren sich jedoch auf Anwendungsebene (TLS, HTTP) statt auf TCP-Ebene. Der TCP-Fingerprint allein identifiziert selten einen Benutzer.
2. TLS-Fingerprint (JA3 / JA4)
Siehe tls-fingerprinting.md für vollständige Details.
Wichtige Punkte für die Netzwerkschicht:
- Der TLS-Handshake ist das wichtigste Signal auf Netzwerkebene
- Vollständig kontrollierbar via
utls(Go) oder eigenem Rust-TLS - Kritisch für Obscura – muss gespooft werden, sonst wird der Proxy verraten
3. HTTP/2-Fingerprint
Mechanismus
Die HTTP/2-Verbindungspräambel und die ersten Frames variieren je nach Implementierung.
Signale:
- SETTINGS-Frame-Parameter (Reihenfolge ist wichtig):
SETTINGS_HEADER_TABLE_SIZESETTINGS_ENABLE_PUSHSETTINGS_MAX_CONCURRENT_STREAMSSETTINGS_INITIAL_WINDOW_SIZESETTINGS_MAX_FRAME_SIZESETTINGS_MAX_HEADER_LIST_SIZE
- WINDOW_UPDATE-Initial-Frame
- PING-Verhalten
- PRIORITY-Frame-Struktur
Browser-Beispiele
| Browser | Initial Window | Max Concurrent | Header Table Size |
|---|---|---|---|
| Chrome | 6291456 | 1000 | 65536 |
| Firefox | 131072 | 100 | 65536 |
| Safari | 1048576 | 100 | 65536 |
Auswirkung auf Obscura
Bei Verwendung von Go's net/http für HTTP/2 sieht der Server Go's HTTP/2-Fingerprint. Eigenes HTTP/2 muss implementiert oder eine Bibliothek verwendet werden, die SETTINGS-Überschreibung erlaubt.
4. QUIC / HTTP/3-Fingerprint
Problem
HTTP/3 läuft über QUIC (UDP). QUIC-Verbindungen sind Ende-zu-Ende verschlüsselt, einschließlich der Transportschicht:
Client QUIC (UDP 443) Server
Verschlüsselt Verschlüsselt
(kann nicht prüfen) (kann nicht prüfen)
QUIC-Transportparameter, Verbindungs-IDs und Versionsinformationen sind im initialen Handshake sichtbar, aber der Proxy kann sie nicht ändern.
Strategie
UDP 443 blockieren, um einen Fallback auf HTTP/2 oder HTTP/1.1 über TCP zu erzwingen:
iptables -A FORWARD -p udp --dport 443 -j DROP
Dies verhindert, dass QUIC-Verbindungen den Proxy umgehen.
Zielkonflikt: Etwas höhere Latenz (TCP vs. QUIC), kein 0-RTT, keine Verbindungsmigration.
5. Zeitbasierte Fingerprints
5.1 Performance-Timing
performance.now() // Hochauflösender Zeitstempel in ms (Sub-Millisekunden-Präzision)
performance.timeOrigin
performance.getEntriesByType('navigation')
Abschwächung: performance.now() auf 100 ms Auflösung runden per JS-Injection:
const originalNow = performance.now.bind(performance)
performance.now = () => Math.round(originalNow() / 100) * 100
5.2 Clock Skew
Server können den Clock Skew messen, indem sie Date.now()-Werte über mehrere Anfragen vergleichen.
Abschwächung: Date.now()-Auflösung runden.
5.3 Netzwerk-Timing via Ressourcenladung
Websites messen die Latenz, indem sie die Ladezeit von Ressourcen messen:
const start = performance.now()
fetch('/image.png').then(() => {
const rtt = performance.now() - start
})
Abschwächung: Kann nicht vollständig verhindert werden – der Proxy fügt seine eigene Latenz hinzu, aber das relative Timing gibt weiterhin Informationen preis.
6. WebRTC-IP-Leck
Mechanismus
WebRTC umgeht den Proxy, indem es STUN/TURN-Server verwendet, um die echte IP zu ermitteln.
const pc = new RTCPeerConnection({
iceServers: [{ urls: 'stun:stun.l.google.com:19302' }]
})
pc.createDataChannel('test')
pc.createOffer().then(d => pc.setLocalDescription(d))
pc.onicecandidate = e => {
if (e.candidate) {
// e.candidate.candidate enthält IP-Adresse
console.log(e.candidate.candidate)
}
}
Abschwächung per JS-Injection
// WebRTC vollständig blockieren
Object.defineProperty(window, 'RTCPeerConnection', { value: undefined })
Object.defineProperty(window, 'RTCDataChannel', { value: undefined })
Object.defineProperty(window, 'RTCSessionDescription', { value: undefined })
Wirkung
| Einstellung | WebRTC-Leck | Erkennung |
|---|---|---|
| WebRTC verfügbar | IP-Leck | Nicht erkannt |
| WebRTC blockiert | Kein Leck | Erkennbar (Feature-Abwesenheit) |
7. DNS-Fingerprint
Signale
- DNS-Resolver-IP (Cloudflare 1.1.1.1 vs. Google 8.8.8.8 vs. ISP)
- DNS over HTTPS vs. DNS over TLS vs. normales DNS
- EDNS0-Client-Subnetz (verrät ungefähren Netzwerkstandort)
- DNSSEC-Unterstützung
Abschwächung
Obscura kontrolliert DNS vollständig. Verwende einen konsistenten, datenschutzfreundlichen Upstream (Quad9 9.9.9.9 oder Cloudflare 1.1.1.1) und entferne EDNS0-Client-Subnetz.
Schlussfolgerungen für Obscura
| Vektor | Kontrollierbar | Priorität | Anmerkungen |
|---|---|---|---|
| TCP/IP-Fingerprint | Nein (vom Container geerbt) | Niedrig | Niedrige Entropie, selten allein verwendet |
| TLS-Fingerprint | Ja (via utls) | Kritisch | Muss gespooft werden, sonst wird Proxy verraten |
| HTTP/2-Fingerprint | Teilweise | Mittel | Erfordert eigene HTTP/2-Implementierung |
| QUIC/HTTP/3 | Blockieren oder erben | Mittel | UDP 443 blockieren |
| Timing-Angriffe | Teilweise | Niedrig | performance.now() runden |
| WebRTC-IP-Leck | Ja (per JS blockieren) | Hoch | Kritisch für VPN-Benutzer |
| DNS-Fingerprint | Ja | Hoch | Obscura kontrolliert DNS |