Aperçu
Signaux visibles au niveau TCP/IP et de la couche transport, avant toute exécution HTTP ou JS.
1. Empreinte de Pile TCP/IP (JA4T / Satori / p0f)
Mécanisme
L'empreinte OS passive lit le paquet SYN TCP pour identifier le système d'exploitation. Chaque pile TCP/IP d'OS a une combinaison unique de :
- TTL initial : 64 (Linux/macOS), 128 (Windows), 255 (Certains UNIX)
- Taille de fenêtre : 64240 (Chrome/Linux), 65535 (macOS), 8192 (systèmes plus anciens)
- MSS (Taille Maximale de Segment) : Dérivé du MTU
- Options TCP : Ordre et sélection de MSS, SACK_PERM, TIMESTAMP, NOP, WINDOW_SCALE
- Drapeaux IP : Comportement du bit DF (Ne Pas Fragmenter)
Formats
JA4T : 64240_2-4-8-1-3_1452_10
| Composant | Signification | Exemple |
|---|---|---|
| 64240 | Taille de Fenêtre TCP | Défaut Windows |
| 2-4-8-1-3 | Ordre des options TCP (MSS, SACK, TIMESTAMP, NOP, WINDOW) | Ordre Chrome/Linux |
| 1452 | MSS | Dérivé du MTU |
| 10 | Compteur de décalage de fenêtre | Multiplicateur 2^10 = 1024 |
Empreinte Satori : 64240:64:1:60:M1452,S,T,N,W10:.
Détection OS
| OS | Fenêtre | TTL | MSS | Options |
|---|---|---|---|---|
| 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) |
Impact sur Obscura
Client Conteneur Obscura (terminaison TCP) Internet
Pile TCP client Pile TCP du conteneur
(visible par Obscura) (visible par la destination)
Le serveur de destination voit la pile TCP d'Obscura, pas celle du client. C'est inévitable car le conteneur termine la connexion TCP du client.
Atténuation : Aucune au niveau TCP. Cependant, la plupart des services d'empreinte se concentrent sur les empreintes au niveau application (TLS, HTTP) plutôt qu'au niveau TCP. L'empreinte TCP seule identifie rarement un utilisateur.
2. Empreinte TLS (JA3 / JA4)
Voir tls-fingerprinting.md pour tous les détails.
Points clés pour la couche réseau :
- La poignée de main TLS est le signal réseau le plus important
- Entièrement contrôlable via
utls(Go) ou Rust TLS personnalisé - Critique pour Obscura — doit usurper ou le proxy est révélé
3. Empreinte HTTP/2
Mécanisme
La préface de connexion HTTP/2 et les trames initiales varient selon l'implémentation.
Signaux :
- Paramètres de trame SETTINGS (l'ordre compte) :
SETTINGS_HEADER_TABLE_SIZESETTINGS_ENABLE_PUSHSETTINGS_MAX_CONCURRENT_STREAMSSETTINGS_INITIAL_WINDOW_SIZESETTINGS_MAX_FRAME_SIZESETTINGS_MAX_HEADER_LIST_SIZE
- Trame initiale WINDOW_UPDATE
- Comportement PING
- Structure des trames PRIORITY
Exemples par Navigateur
| Navigateur | Fenêtre Initiale | Max Concurrents | Taille Table d'En-têtes |
|---|---|---|---|
| Chrome | 6291456 | 1000 | 65536 |
| Firefox | 131072 | 100 | 65536 |
| Safari | 1048576 | 100 | 65536 |
Impact sur Obscura
Si Go net/http est utilisé pour HTTP/2, le serveur voit l'empreinte HTTP/2 de Go. Doit implémenter HTTP/2 personnalisé ou utiliser une bibliothèque qui permet la surcharge des SETTINGS.
4. Empreinte QUIC / HTTP/3
Problème
HTTP/3 fonctionne sur QUIC (UDP). Les connexions QUIC sont chiffrées de bout en bout, y compris la couche transport :
Client QUIC (UDP 443) Serveur
Chiffré Chiffré
(ne peut inspecter) (ne peut inspecter)
Les paramètres de transport QUIC, les ID de connexion et les informations de version sont visibles dans la poignée de main initiale, mais le proxy ne peut pas les modifier.
Stratégie
Bloquer UDP 443 pour forcer le repli vers HTTP/2 ou HTTP/1.1 sur TCP :
iptables -A FORWARD -p udp --dport 443 -j DROP
Cela empêche les connexions QUIC de contourner le proxy.
Compromis : Latence légèrement plus élevée (TCP vs QUIC), pas de 0-RTT, pas de migration de connexion.
5. Empreintes Basées sur le Temps
5.1 Chronométrage de Performance
performance.now() // Horodatage haute résolution en ms (précision sub-milliseconde)
performance.timeOrigin
performance.getEntriesByType('navigation')
Atténuation : Arrondir performance.now() à une résolution de 100ms via injection JS :
const originalNow = performance.now.bind(performance)
performance.now = () => Math.round(originalNow() / 100) * 100
5.2 Dérive d'Horloge
Les serveurs peuvent mesurer la dérive d'horloge en comparant les valeurs Date.now() entre les requêtes.
Atténuation : Arrondir la résolution de Date.now().
5.3 Chronométrage Réseau via Chargement de Ressources
Les sites mesurent la latence en chronométrant le temps de chargement des ressources :
const start = performance.now()
fetch('/image.png').then(() => {
const rtt = performance.now() - start
})
Atténuation : Ne peut pas être totalement empêché — le proxy ajoute sa propre latence mais le timing relatif fuit encore des informations.
6. Fuite IP WebRTC
Mécanisme
WebRTC contourne le proxy en utilisant des serveurs STUN/TURN pour découvrir la véritable IP.
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 contient l'adresse IP
console.log(e.candidate.candidate)
}
}
Atténuation via Injection JS
// Bloquer WebRTC complètement
Object.defineProperty(window, 'RTCPeerConnection', { value: undefined })
Object.defineProperty(window, 'RTCDataChannel', { value: undefined })
Object.defineProperty(window, 'RTCSessionDescription', { value: undefined })
Effet
| Paramètre | Fuite WebRTC | Détection |
|---|---|---|
| WebRTC disponible | IP fuit | Non détecté |
| WebRTC bloqué | Pas de fuite | Détectable (absence de fonctionnalité) |
7. Empreinte DNS
Signaux
- IP du résolveur DNS (Cloudflare 1.1.1.1 vs Google 8.8.8.8 vs FAI)
- DNS sur HTTPS vs DNS sur TLS vs DNS standard
- Sous-réseau client EDNS0 (révèle l'emplacement réseau approximatif)
- Support DNSSEC
Atténuation
Obscura contrôle complètement le DNS. Utiliser un amont cohérent et axé sur la confidentialité (Quad9 9.9.9.9 ou Cloudflare 1.1.1.1) et supprimer le sous-réseau client EDNS0.
Conclusions pour Obscura
| Vecteur | Contrôlable | Priorité | Notes |
|---|---|---|---|
| Empreinte TCP/IP | Non (héritée du conteneur) | Faible | Faible entropie, rarement utilisé seul |
| Empreinte TLS | Oui (via utls) | Critique | Doit usurper ou le proxy est révélé |
| Empreinte HTTP/2 | Partiel | Moyenne | Nécessite implémentation HTTP/2 personnalisée |
| QUIC/HTTP/3 | Bloque ou hérite | Moyenne | Bloquer UDP 443 |
| Attaques temporelles | Partiel | Faible | Arrondir performance.now() |
| Fuite IP WebRTC | Oui (bloquer via JS) | Élevée | Critique pour les utilisateurs VPN |
| Empreinte DNS | Oui | Élevée | Obscura contrôle le DNS |