Resumen
Señales visibles en la capa TCP/IP y de transporte, antes de cualquier ejecución HTTP o JS.
1. Fingerprint de Pila TCP/IP (JA4T / Satori / p0f)
Mecanismo
El fingerprinting pasivo de SO lee el paquete TCP SYN para identificar el sistema operativo. Cada pila TCP/IP de SO tiene una combinación única de:
- TTL inicial: 64 (Linux/macOS), 128 (Windows), 255 (Algunos UNIX)
- Tamaño de ventana: 64240 (Chrome/Linux), 65535 (macOS), 8192 (sistemas antiguos)
- MSS (Maximum Segment Size): Derivado del MTU
- Opciones TCP: Orden y selección de MSS, SACK_PERM, TIMESTAMP, NOP, WINDOW_SCALE
- Flags IP: Comportamiento del bit DF (Don't Fragment)
Formatos
JA4T: 64240_2-4-8-1-3_1452_10
| Componente | Significado | Ejemplo |
|---|---|---|
| 64240 | Tamaño de ventana TCP | Windows por defecto |
| 2-4-8-1-3 | Orden de opciones TCP (MSS, SACK, TIMESTAMP, NOP, WINDOW) | Orden Chrome/Linux |
| 1452 | MSS | Derivado del MTU |
| 10 | Shift count de Window Scale | 2^10 = multiplicador 1024 |
Fingerprint Satori: 64240:64:1:60:M1452,S,T,N,W10:.
Detección de SO
| SO | Window | TTL | MSS | Opciones |
|---|---|---|---|---|
| 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) |
Impacto en Obscura
Cliente Contenedor Obscura (terminación TCP) Internet
Pila TCP del cliente Pila TCP del contenedor
(visible para Obscura) (visible para el destino)
El servidor destino ve la pila TCP de Obscura, no la del cliente. Esto es inevitable porque el contenedor termina la conexión TCP del cliente.
Mitigación: Ninguna a nivel TCP. Sin embargo, la mayoría de los servicios de fingerprinting se centran en fingerprints a nivel de aplicación (TLS, HTTP) en lugar de a nivel TCP. El fingerprint TCP solo rara vez identifica a un usuario.
2. Fingerprint TLS (JA3 / JA4)
Ver tls-fingerprinting.md para detalles completos.
Puntos clave para la capa de red:
- El handshake TLS es la señal más importante a nivel de red
- Totalmente controlable mediante
utls(Go) o Rust TLS personalizado - Crítico para Obscura — debe falsificarse o se revela el proxy
3. Fingerprint HTTP/2
Mecanismo
El prefacio de conexión HTTP/2 y las tramas iniciales varían según la implementación.
Señales:
- Parámetros de la trama SETTINGS (el orden importa):
SETTINGS_HEADER_TABLE_SIZESETTINGS_ENABLE_PUSHSETTINGS_MAX_CONCURRENT_STREAMSSETTINGS_INITIAL_WINDOW_SIZESETTINGS_MAX_FRAME_SIZESETTINGS_MAX_HEADER_LIST_SIZE
- Trama inicial WINDOW_UPDATE
- Comportamiento de PING
- Estructura de trama PRIORITY
Ejemplos por Navegador
| Navegador | Initial Window | Max Concurrent | Header Table Size |
|---|---|---|---|
| Chrome | 6291456 | 1000 | 65536 |
| Firefox | 131072 | 100 | 65536 |
| Safari | 1048576 | 100 | 65536 |
Impacto en Obscura
Si se usa net/http de Go para HTTP/2, el servidor ve el fingerprint HTTP/2 de Go. Debe implementar HTTP/2 personalizado o usar una librería que permita anular SETTINGS.
4. Fingerprint QUIC / HTTP/3
Problema
HTTP/3 se ejecuta sobre QUIC (UDP). Las conexiones QUIC están cifradas de extremo a extremo, incluyendo la capa de transporte:
Cliente QUIC (UDP 443) Servidor
Cifrado Cifrado
(no se puede inspeccionar) (no se puede inspeccionar)
Los parámetros de transporte QUIC, IDs de conexión e información de versión son visibles en el handshake inicial, pero el proxy no puede modificarlos.
Estrategia
Bloquear UDP 443 para forzar la caída a HTTP/2 o HTTP/1.1 sobre TCP:
iptables -A FORWARD -p udp --dport 443 -j DROP
Esto evita que las conexiones QUIC eviten el proxy.
Compensación: Latencia ligeramente mayor (TCP vs QUIC), sin 0-RTT, sin migración de conexión.
5. Fingerprints Basados en Temporización
5.1 Rendimiento de Temporización
performance.now() // Marca de tiempo de alta resolución en ms (precisión sub-milisegundo)
performance.timeOrigin
performance.getEntriesByType('navigation')
Mitigación: Redondear performance.now() a resolución de 100ms mediante inyección JS:
const originalNow = performance.now.bind(performance)
performance.now = () => Math.round(originalNow() / 100) * 100
5.2 Clock Skew
Los servidores pueden medir la desviación del reloj comparando valores de Date.now() entre peticiones.
Mitigación: Redondear la resolución de Date.now().
5.3 Temporización de Red mediante Carga de Recursos
Los sitios miden la latencia midiendo cuánto tardan los recursos en cargarse:
const start = performance.now()
fetch('/image.png').then(() => {
const rtt = performance.now() - start
})
Mitigación: No se puede prevenir completamente — el proxy añade su propia latencia pero la temporización relativa sigue filtrando información.
6. Fuga de IP por WebRTC
Mecanismo
WebRTC evita el proxy usando servidores STUN/TURN para descubrir la IP real.
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 contiene la dirección IP
console.log(e.candidate.candidate)
}
}
Mitigación mediante Inyección JS
// Bloquear WebRTC completamente
Object.defineProperty(window, 'RTCPeerConnection', { value: undefined })
Object.defineProperty(window, 'RTCDataChannel', { value: undefined })
Object.defineProperty(window, 'RTCSessionDescription', { value: undefined })
Efecto
| Configuración | Fuga WebRTC | Detección |
|---|---|---|
| WebRTC disponible | La IP se filtra | No detectado |
| WebRTC bloqueado | Sin fuga | Detectable (ausencia de característica) |
7. Fingerprint DNS
Señales
- IP del resolver DNS (Cloudflare 1.1.1.1 vs Google 8.8.8.8 vs ISP)
- DNS sobre HTTPS vs DNS sobre TLS vs DNS plano
- EDNS0 client subnet (revela ubicación de red aproximada)
- Soporte DNSSEC
Mitigación
Obscura controla el DNS completamente. Usar un upstream consistente centrado en privacidad (Quad9 9.9.9.9 o Cloudflare 1.1.1.1) y eliminar EDNS0 client subnet.
Conclusiones para Obscura
| Vector | Controlable | Prioridad | Notas |
|---|---|---|---|
| Fingerprint TCP/IP | No (heredado del contenedor) | Baja | Baja entropía, rara vez usado solo |
| Fingerprint TLS | Sí (mediante utls) | Crítica | Debe falsificarse o se revela el proxy |
| Fingerprint HTTP/2 | Parcial | Media | Requiere impl. HTTP/2 personalizada |
| QUIC/HTTP/3 | Bloquear o heredar | Media | Bloquear UDP 443 |
| Ataques de temporización | Parcial | Baja | Redondear performance.now() |
| Fuga de IP por WebRTC | Sí (bloquear mediante JS) | Alta | Crítico para usuarios de VPN |
| Fingerprint DNS | Sí | Alta | Obscura controla el DNS |