20

わかりました、この状況がやや異常であることは認識していますが、生のソケット (C では Linux) のみを使用して TCP 接続 (3 ウェイ ハンドシェイク) を確立する必要があります。つまり、IP ヘッダーと TCP ヘッダーを自分で構築する必要があります。 . 私はサーバーを書いています (そのため、最初に着信 SYN パケットに応答する必要があります)、何らかの理由でそれを正しく行うことができないようです。はい、私は SOCK_STREAM がこれを処理することを理解していますが、私が入りたくない理由から、それはオプションではありません。

raw ソケットの使用に関するオンラインで見つけたチュートリアルはすべて SYN フラッダーを構築する方法を説明していますが、元のパケットに基づいて応答を構築する必要がないため、これは実際に TCP 接続を確立するよりもいくらか簡単です。SYNフラッダーのサンプルが動作するようになり、受信SYNパケットを生のソケットから問題なく読み取ることができますが、クライアントからの受信SYNに対する有効なSYN/ACK応答を作成するのにまだ問題があります.

それで、SYNフラッダーの作成を超えた生のソケットの使用に関する優れたチュートリアルを知っている人はいますか、またはこれを実行できるコードを持っている人はいますか(SOCK_STREAMではなくSOCK_RAWを使用)? 私は非常に感謝されます。


MarkR は完全に正しいです。問題は、カーネルがポートが閉じていると考えているため、初期パケットに応答してリセット パケットを送信していることです。カーネルは私を応答に打ち負かし、接続は切断されます。私はすでに接続を監視するために tcpdump を使用していました。もっと注意を払うべきだったのですが、2 つの応答があり、そのうちの 1 つは物事を台無しにしていたリセットであり、プログラムが作成した応答であることに気付きました。ドー!

MarkR で提案されているように、iptables ルールを使用してアウトバウンド パケットをブロックするのが最も効果的と思われる解決策です。ただし、提案されているように、マーク オプションを使用するよりも簡単な方法があります。リセット TCP フラグが設定されているかどうかを照合するだけです。通常の接続の過程でこれが必要になることはまずありません。また、使用中のポートからのすべてのアウトバウンド リセット パケットをブロックしても、アプリケーションにとっては問題になりません。これにより、カーネルの不要な応答が効果的にブロックされますが、自分のパケットはブロックされません。プログラムがリッスンしているポートが 9999 の場合、iptables ルールは次のようになります。

iptables -t filter -I OUTPUT -p tcp --sport 9999 --tcp-flags RST RST -j DROP
4

7 に答える 7

12

ユーザー空間に TCP スタックの一部を実装したい...これは問題ありません。他のいくつかのアプリがこれを行います。

遭遇する問題の 1 つは、カーネルが着信パケットに対して (通常は否定的で役に立たない) 応答を送信することです。これにより、開始しようとする通信が台無しになります。

これを回避する 1 つの方法は、カーネルが使用する独自の IP スタックを持たない IP アドレスとインターフェースを使用することです。これは問題ありませんが、リンク層のもの (具体的には arp) を自分で処理する必要があります。それには、IPPROTO_IP、SOCK_RAWよりも低いソケットが必要です-パケットソケットが必要です(私は思います)。

iptables ルールを使用してカーネルの応答をブロックすることも可能かもしれませんが、別の方法で処理することができない限り (おそらく netfilter の「マーク」を適用するあなた自身のパケット?)

マニュアルページを読む

ソケット(7) ip(7) パケット(7)

ソケットの種類に適用されるさまざまなオプションと ioctl について説明します。

もちろん、何が起こっているのかを調べるには、Wireshark のようなツールが必要です。これをテストするには複数のマシンが必要です。必要なハードウェアの量を減らすために、vmware (または同様のもの) を使用することをお勧めします。

申し訳ありませんが、特定のチュートリアルをお勧めできません。

幸運を。

于 2008-09-21T06:57:38.577 に答える
4

これが古いスレッドであることは認識していますが、通常の SYN フラッダーを超えたチュートリアルがあります: http://www.enderunix.org/docs/en/rawipspoof/

それが誰かの助けになることを願っています。

于 2012-07-30T11:30:25.827 に答える
2

チュートリアルについてはお手伝いできません。

ただし、デバッグを支援するために使用できるツールについてアドバイスできます。

まず、bmdhacksが示唆しているように、wireshark (または tcpdump - ただし、wireshark の方が使いやすい) のコピーを入手してください。良い握手をキャプチャします。これを必ず保存してください。

失敗したハンドシェイクの 1 つをキャプチャします。Wireshark は非常に優れたパケット解析とエラー チェック機能を備えているため、単純なエラーがあれば、おそらくそれでわかるでしょう。

次に、tcpreplayのコピーを入手してください。これには、「tcprewrite」というツールも含まれている必要があります。tcprewrite を使用すると、以前に保存したキャプチャ ファイルを 2 つ (ハンドシェイクの両側に 1 つずつ) に分割できます。次に、tcpreplay を使用してハンドシェイクの片側を再生し、一貫した一連のパケットを再生することができます。

次に、wireshark を (再び) 使用して応答を確認します。

于 2008-09-21T06:44:13.010 に答える
1

チュートリアルはありませんが、最近Wiresharkを使用して、行っていた未加工のソケット プログラミングをデバッグしました。送信しているパケットをキャプチャすると、wireshark はパケットの形式が正しくないかどうかを適切に示してくれます。通常の接続との比較にも便利です。

于 2008-09-21T05:51:49.500 に答える
0

netinet/ip.h と netinet/tcp.h でそれぞれ宣言された IP ヘッダーと TCP ヘッダーの構造があります。このディレクトリ内の他のヘッダーを調べて、追加のマクロと使用できるものを確認することをお勧めします。

SYN フラグが設定されたパケットとランダムなシーケンス番号 (x) を送信します。反対側から SYN+ACK を受信する必要があります。このパケットには、相手側が受信することを期待している次のシーケンス番号と別のシーケンス番号 (z) を示す確認応答番号 (y) があります。シーケンス番号 x+1 と ack 番号 z+1 を持つ ACK パケットを送り返し、接続を完了します。

また、適切な TCP/IP チェックサムを計算し、送信するパケットのヘッダーの残りの部分を埋める必要があります。また、ホストとネットワークのバイト順なども忘れないでください。

TCP は RFC 793 で定義されています。こちらから入手できます: http://www.faqs.org/rfcs/rfc793.html

于 2008-09-21T07:22:20.640 に答える
0

何をしようとしているのかによっては、既存のソフトウェアで TCP ハンドシェイクを処理する方が簡単な場合があります。

オープン ソースの IP スタックの 1 つは、完全な tcp/ip スタックを提供するlwIP ( http://savannah.nongnu.org/projects/lwip/ ) です。SOCK_RAW または pcap のいずれかを使用して、ユーザー モードで実行することは非常に可能です。

于 2009-06-06T14:53:24.783 に答える
0

raw ソケットを使用している場合、実際の送信元 MAC アドレスとは異なる送信元 MAC アドレスを使用して送信すると、Linux は応答パケットを無視し、最初のパケットを送信しません。

于 2012-11-02T16:07:51.263 に答える