我正在开发一个接受HTTP请求并将它们转发到目标的项目。我们使用Linux(2.6.35.14-106.fc14.x86_64)和TPROXY。我将在下面详细介绍。
我看到的问题是偶尔(1000次中有1次超过100次),Linux正在返回对等地址作为目标地址。
有没有人见过这种情况?我从2007年开始在网上看到一条说明,所以我认为这可能有点过时了。
我有以下代码(请原谅这里显示的不一致方法):
struct sockaddr clientaddr;
socklen_t clientlen = sizeof(clientaddr);
int status = getpeername(acceptedSocket, &clientaddr, &clientlen);
char clientName[256];
clientName[0] = '\0';
int clientport = 0;
if (status == 0) {
inet_ntop(AF_INET, (void *) &((struct sockaddr_in *)&clientaddr)->sin_addr, clientName, 256);
clientport = ntohs(((struct sockaddr_in *)& clientaddr)->sin_port);
**printf("Socket::acceptConnection: getpeername : %s:%d\n", clientName, clientport); fflush(stdout);**
}
else
{
LOGINFO(WARNING(352), "Socket::acceptConnection: Could not get client from accepted socket.\n");
}
status = getsockopt(acceptedSocket, SOL_IP, SO_ORIGINAL_DST, (struct sockaddr *) &destaddr, &destlen);
if (status == 0) {
inet_ntop(AF_INET, (void *) &destaddr.sin_addr, destinationName, 256);
int portnumber = ntohs(destaddr.sin_port);
ssize_t dl = strlen(destinationName);
sprintf(&destinationName[dl], ":%d", portnumber);
**printf("Socket::acceptConnection: getsockopt : %s\n", destinationName); fflush(stdout);**
}
else
{
LOGINFO(WARNING(352), "Socket::acceptConnection: Could not get destination from accepted socket.\n");
}
当getpeername和getsockopt正确报告时,大多数会发生什么(请参阅下面的IPTABLE配置)。
不幸的是偶尔获取getsockopt报告与getpeername相同,即目标与对等方相同。
IPTABLE配置:
-A PREROUTING -p tcp -m socket -j DIVERT
-A PREROUTING -s 10.2.0.203/32 -p tcp -m tcp --dport 80 -j TPROXY --on-port 8080 --on-ip 10.2.0.204 --tproxy-mark 0x1/0xffffffff
-A DIVERT -j MARK --set-xmark 0x1/0xffffffff
-A DIVERT -j ACCEPT
我们记录了活动,看起来还不错。例如,我们得到以下输出:
Socket::acceptConnection: getpeername : 10.2.0.203:48517
Socket::acceptConnection: getsockopt : 10.2.0.203:48517
然而,来自IPTables的日志显示IP地址是正确的:
Jul 9 17:37:06 2U-204 kernel: [258876.105481] IN=eth3 OUT= MAC=00:1b:21:61:03:99:00:1b:21:61:c0:70:08:00 **SRC=10.2.0.203 DST=192.168.200.206** LEN=60 TOS=0x00 PREC=0x00 TTL=64 ID=56054 DF PROTO=TCP **SPT=48517 DPT=80** WINDOW=17896 RES=0x00 SYN URGP=0
Jul 9 17:37:06 2U-204 kernel: [258876.105697] IN=eth3 OUT= MAC=00:1b:21:61:03:99:00:1b:21:61:c0:70:08:00 **SRC=10.2.0.203 DST=192.168.200.206** LEN=52 TOS=0x00 PREC=0x00 TTL=64 ID=56055 DF PROTO=TCP **SPT=48517 DPT=80** WINDOW=35 RES=0x00 ACK URGP=0
我真的很难过。
答案 0 :(得分:1)
您为什么使用getsockopt( ... SOL_IP, SO_ORIGINAL_DST ... )
? AFAIK SO_ORIGINAL_DST
旨在与NAT REDIRECT
目标一起使用而不是TPROXY
。
尝试使用简单的getsockname()
。