Iptables
透明 SOCKS 代理如何知道使用哪個目標 IP?
我知道有兩個 SOCKS 代理支持任何傳出 TCP 連接的透明代理:Tor和redsocks。與 HTTP 代理不同,這些 SOCKS 代理可以透明地代理任何傳出 TCP 連接,包括加密協議和沒有元數據或標頭的協議。
這兩個代理都需要使用 NAT 將任何傳出 TCP 流量重定向到代理的本地埠。例如,如果我
TransPort 9040
在本地機器上執行 Tor,我需要添加一個 iptables 規則,如下所示:iptables -t nat -A OUTPUT -p tcp -j REDIRECT --to-port 9040
據我所知,這會將原始目標 IP 和埠替換為
127.0.0.1
and9040
,因此假設這是一個加密流(如 SSH)或沒有標頭的流(如whois),代理如何知道原始目標 IP 和埠?
下面是它是如何做到的:
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 會覆蓋原始目標地址,但它會記住舊地址。然後應用程式碼可以通過請求一個特殊的套接字選項來獲取它,
SO_ORIGINAL_DST
.