0

ルーターで「トラフィックを監視する」種類のアプリケーションを開発しています。この機能を使用して、TPROXYDNS パケットをインターセプトし、ポートでリッスンしているアプリケーション サーバーに送信します。処理後、TTL を変更した後、パケットを実際の宛先 (dnsmasq) に転送します。

JFYI、ポート 2345 でリッスンしているアプリケーション サーバーに DNS 応答パケットを転送する TPROXY に対する私のファイアウォール ルールは次のようになります。

iptables -t mangle -A PREROUTING -i <WAN-INTERFACE> -p udp --sport 53 -j TPROXY --tproxy-mark 0x3 --on-port 2345

私のアプリケーションサーバーでは、エラーチェックなし:

sock_fd = socket(AF_INET, SOCK_DGRAM, 0 );

setsockopt(socket_fd, SOL_IP, IP_PKTINFO, &enabled, sizeof(int));
setsockopt(socket_fd, SOL_IP, IP_TRANSPARENT, &enabled, sizeof(int));
setsockopt(socket_fd, SOL_IP, IP_RECVORIGDSTADDR, &enabled, sizeof(int));
setsockopt(socket_fd, SOL_SOCKET, SO_REUSEADDR, &enabled, sizeof(int));

/* client_addr points to the source IP (i.e. upstream DNS server's IP) */
bind(sock_fd, (const struct sockaddr *)client_addr, sizeof(struct sockaddr));

/* dst_addr points to the router IP on the WAN interface */
sendto(sock_fd, dns_packet_buffer, data_len, 0,
            (const struct sockaddr *)dst_addr, sizeof(struct sockaddr));

これsendtoは成功です。つまり、エラーは発生しません!!! しかし、dnsmasq はデータを受信しません! より正確には、dnsmasq がデータを待機している fd は「準備完了」になりません。

内部の dnsmasq コードでcheck_dns_listeners

for (serverfdp = daemon->sfds; serverfdp; serverfdp = serverfdp->next)
    if (FD_ISSET(serverfdp->fd, set))
        reply_query(serverfdp->fd, serverfdp->source_addr.sa.sa_family, now);

FD_ISSET()返しますfalse。DNS 応答フローをインターセプトしない場合、これFD_ISSET()は true を返します。ここで何が欠けていますか?

4

1 に答える 1

1

ついに答えを見つけました!! Lemme は、他の誰かに役立つと仮定してここに置きます。

前述したように、私のアプリケーションはルーター上で実行されていました。ルーターの製造元は、既存の dnsmasq コードを変更して、アップストリーム サーバーからリッスンするインターフェイスを制限するオプションを追加しました。つまり、特定のインターフェイス (eth2 など) を介してのみアップストリーム サーバーからの応答を受け入れます。コードの観点から見ると、eth2 以外のインターフェースをリッスンすることさえありません。私の応答は「lo」経由だったので、彼らは聞いていませんでした!! :)

そのオプションなしで dnsmasq を再起動したところ、動作しました! :)

彼らが公開フォーラムでそれを文書化していたらよかったのに!そのため、一般的なグーグルが機能し、数千行のコードを読み取らないようになります!!

于 2015-10-04T18:36:50.997 に答える