4 Stimmen

getsockopt(...,SO_ORIGINAL_DST,...) liefert gelegentlich die Client-Adresse

Ich arbeite an einem Projekt, das HTTP-Anfragen annimmt und sie an ein Ziel weiterleitet. Wir verwenden Linux (2.6.35.14-106.fc14.x86_64) und TPROXY. Ich werde die Details unten einfügen.

Das Problem, das ich sehe, ist, dass Linux gelegentlich (1 Mal von 1000, manchmal 1 Mal von einer Million) die Peer-Adresse als Zieladresse zurückgibt.

Hat jemand so etwas schon einmal erlebt? Ich habe im Internet eine Notiz aus dem Jahr 2007 gesehen, die vielleicht etwas veraltet ist.

Ich habe den folgenden Code (entschuldigen Sie die inkonsistente Methodik hier angezeigt):

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");
}

Was passiert, ist, dass Die meisten der Zeit melden getpeername und getsockopt korrekt (siehe die IPTABLE-Konfiguration unten).

Leider gelegentlich get getsockopt report ist dasselbe wie getpeername, d.h. das Ziel ist dasselbe wie die Gegenstelle.

IPTABLE Konfig:

-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

Wir haben die Aktivitäten protokolliert und es sieht gut aus. Zum Beispiel erhalten wir die folgende Ausgabe:

Socket::acceptConnection: getpeername :  10.2.0.203:48517
Socket::acceptConnection: getsockopt :  10.2.0.203:48517

Das Protokoll von IPTables zeigt jedoch, dass die IP-Adressen korrekt sind:

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

Ich bin in dieser Sache wirklich ratlos.

2voto

dongle26 Punkte 806

Warum verwenden Sie getsockopt( ... SOL_IP, SO_ORIGINAL_DST ... ) ? AFAIK SO_ORIGINAL_DST ist für die Verwendung mit dem NAT REDIRECT Ziel nicht TPROXY .

Versuchen Sie eine einfache getsockname() stattdessen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X