dieses Ding kann ich Original erhalten Ziel-IP-Adresse von socket(PF_INET, SOCK_DGRAM, 0)
socket.
Wie bekomme ich den ursprünglichen Zielport?
Hängt vom Umleitungsmechanismus ab. Wenn Sie REDIRECT (NAT unter der Haube) verwenden, müssen Sie SO_ORIGINAL_DST oder libnetfilter_conntrack verwenden, um das ursprüngliche Ziel der Verbindung abzufragen, bevor NAT angewendet wurde. Da Sie jedoch mehrere Verbindungen mit demselben Listener-Socket bedienen können, muss diese Suche für jedes Paket durchgeführt werden.
Sie können mit libnetfilter_conntrack und den angebotenen Diensten mit dem conntrack Kommandozeilen-Tool experimentieren.
Eine Alternative ist die Verwendung von TPROXY für die Umleitung, die in solchen Fällen verwendet werden sollte. Dort können Sie das ursprüngliche Ziel des Pakets mithilfe einer ancillirary-Nachricht mit recvmsg () abrufen. Der Schlüssel zum Suchen ist IP_RECVORIGDST setsockopt.
Weitere Informationen zu TPROXY finden Sie im Dokumentationsverzeichnis des Kernels in einer Datei namens tproxy.txt. Es ist ein bisschen schwierig zu verwenden, aber arbeitet zuverlässiger, da es durch den Stapel implementiert wird, anstatt das Paketfilter-Subsystem.
Bearbeitet: um hinzuzufügen, wie UDP-Zieladressen mit TProxy abgefragt werden.
Bearbeitet: SO_ORIGINAL_DST vs. udp
SO_ORIGINAL_DST sollte mit Udp-Sockets arbeiten, aber der Kernel lässt Sie die Verbindungsendpunkte nicht angeben, es verwendet den Socket, den Sie SO_ORIGINAL_DST aufrufen, um diese Adressinformationen zu erhalten.
Dies bedeutet, dass es nur funktioniert, wenn der UDP-Socket ordnungsgemäß gebunden (an die umgeleitete Adresse / Port) und verbunden (mit dem fraglichen Client) ist. Ihr Listener-Socket ist wahrscheinlich an 0.0.0.0 gebunden und bedient nicht nur einzelne, sondern mehrere Clients.
Sie müssen jedoch nicht Ihren tatsächlichen Listener-Socket verwenden, um die Zieladresse abzufragen. Da UDP bei der Verbindungsherstellung keine Datagramme überträgt, können Sie einen neuen UDP-Socket erstellen, ihn an die Weiterleitungsadresse binden und mit dem Client verbinden (dessen Adresse Sie kennen, da er das erste Paket sowieso an Ihren Listener gesendet hat). Dann könnten Sie diesen Socket benutzen, um SO_ORIGINAL_DST zu starten, aber es gibt Schuldige:
Die TProxy-basierte Methode ist eindeutig besser.