Hay dos proxies SOCKS que conozco que admiten el proxy transparente para cualquier conexión TCP saliente:Tor y redsocks. A diferencia de los proxies HTTP, estos proxies SOCKS pueden representar de manera transparente cualquier conexión TCP saliente, incluidos protocolos encriptados y protocolos sin metadatos ni encabezados.
Ambos proxies requieren el uso de NAT para redirigir cualquier tráfico TCP saliente al puerto local del proxy. Por ejemplo, si estoy ejecutando Tor con TransPort 9040
en mi máquina local, necesitaría agregar una regla de iptables como esta:
iptables -t nat -A OUTPUT -p tcp -j REDIRECT --to-port 9040
Que yo sepa, esto reemplazaría la IP y el puerto de destino originales con 127.0.0.1
y 9040
, entonces, dado que se trata de una secuencia cifrada (como SSH) o sin encabezados (como whois), ¿cómo sabe el proxy la IP y el puerto de destino originales?
Respuesta aceptada:
Así es como lo hace:
static int getdestaddr_iptables(int fd, const struct sockaddr_in *client, const struct sockaddr_in *bindaddr, struct sockaddr_in *destaddr)
{
socklen_t socklen = sizeof(*destaddr);
int error;
error = getsockopt(fd, SOL_IP, SO_ORIGINAL_DST, destaddr, &socklen);
if (error) {
log_errno(LOG_WARNING, "getsockopt");
return -1;
}
return 0;
}
iptables sobrescribe la dirección de destino original pero recuerda la anterior. El código de la aplicación puede recuperarlo solicitando una opción de socket especial, SO_ORIGINAL_DST
.