4

HTTP リクエストを受け入れて宛先に転送するプロジェクトに取り組んでいます。Linux (2.6.35.14-106.fc14.x86_64) と TPROXY を使用しています。以下に詳細を載せておきます。

私が見ている問題は、たまに (1000 回に 1 回、時には 100 万回に 1 回)、Linux が宛先アドレスとしてピア アドレスを返すことです。

これが起こるのを見た人はいますか?2007 年に Web で 1 つのメモを見たので、少し古いかもしれないと思います。

私は次のコードを持っています (ここに表示されている一貫性のない方法論を許してください):

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

アクティビティをログに記録しましたが、問題ないようです。たとえば、次の出力が得られます。

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

私はこれに本当に困惑しています。

4

1 に答える 1

2

なぜあなたは使用していgetsockopt( ... SOL_IP, SO_ORIGINAL_DST ... )ますか?AFAIKSO_ORIGINAL_DSTは、NATREDIRECTターゲット notで使用することを意図していますTPROXY

getsockname()代わりに単純なものを試してください。

于 2012-10-06T16:21:14.120 に答える