2012-07-10 91 views
2

我正在接受HTTP請求並將它們轉發到目標上的項目。我們使用Linux(2.6.35.14-106.fc14.x86_64)和TPROXY。我會在下面詳細說明。getsockopt(...,SO_ORIGINAL_DST,...)偶爾返回客戶端地址

我看到的問題是,偶爾(1000次中的1次,有時是100萬次中的1次),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配置)。

不幸的是偶爾 get 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 

我們已記錄的活動,它看起來OK。例如,我們得到以下的輸出:

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 

我真的難倒這一點。

回答

1

爲什麼使用getsockopt(... SOL_IP, SO_ORIGINAL_DST ...)? AFAIK SO_ORIGINAL_DST旨在與NAT REDIRECT目標不使用TPROXY一起使用。

改爲嘗試一個簡單的getsockname()