next up previous contents
Next: 6.1.3 UDP Up: 6.1 プロトコル Previous: 6.1.1 コネクション

6.1.2 TCP

TCP はデータストリーム型のコネクションで、全二重であるとも言いますが、 データパケットの中身や順序についての保証がプロトコル上されています。 そのために常にデータは受けとられたかどうかのハンドシェークを行いながら 通信を行っています。こうした性質からTCPコネクションはフィルタリングで 良く制御出来るようになっています。ここでは、TCPヘッダのフラグの種類 とTCPコネクションの状態遷移について見ることで、TCPをフィルタリングする ために必要な知識を簡単に解説します。

TCPヘッダにはシーケンスやチェックサムなど多くのヘッダ情報がありますが、 中でもフィルタリングに関係するのはヘッダフラグ情報でしょう。ヘッダフラグ 情報には2byteのフィールドがあり、第10ビットから第15ビットまでにコネクション 状態に関する情報が格納されています。

bit フラグ 意味
10 URG 緊急転送データ
11 ACK 受信確認
12 PSH プッシュ。アプリケーションに直に引き渡す。
13 RST 接続のリセット
14 SYN 同期
15 FIN 送出の終了

TCP では接続状態は以下のように遷移します(RFC793)。

  1. クライアントの状態遷移
    1. SYN_SENT 接続のオープン(3ハンドシェーク)
    2. ESTABLISHED 接続の確立
    3. FIN_WAIT_1, FIN_WAIT_2 接続終了の通知(half-closed)
    4. TIME_WAIT 終了確認の待ち状態
    5. CLOSED 接続の終了
  2. サーバの状態遷移
    1. LISTEN 接続待ち状態
    2. SYN_RECVD クライアントからの接続要求受信
    3. ESTABLISHED 接続の確立
    4. CLOSE_WAIT 接続終了の通知
    5. LAST_ACK 接続終了の通知確認
    6. CLOSED 接続の終了

これらの状態遷移がどのようなパケット交換で成立しているかを次に示します。

状態 クライアント 方向 サーバ
コネクションの開設 SYN  
    SYN,ACK
  ACK  
確立 ACK(,PSH,URG)データ  
    ACK(,PSH,URG)データ
クライアントからの終了通知 ACK,FIN  
    ACK
サーバからの終了通知   FIN,ACK
  ACK  

このようにコネクションが確立するまでに3つのパケットが往復するので、 この過程を3ウェイハンドシェークと呼びます。 通常、この状態はフィルタリングではsetupなどとも呼んでいます。一方、 接続の確立から終了状態まではフィルタリングでは established と呼びます (特に終了状態は区別しなくても構いません)。 しかし、これらのパケット交換を注意深く見れば分かるとおり、最初の SYN 以外は 全て ACKビットが立っています。つまり、フィルタリングでは最初の SYN ビット のみが立ったコネクション要求が重要で、それ以外は特に重要ではないことに 気がつくでしょう(ですから、そこしか見ないようなフィルタリングアルゴリズム があるかも知れません)。特に、どちらからどちらに向かってSYNパケットが飛んでいる かがフィルタリングをする際には重要になります。 一方、ここで出てきた以外のビットが立ったパケットは 要注意です。また、こうした遷移過程についての知識は重要ですが、フィルタリング においては一つ一つのパケットのみを見ているために、単純な、あるいは古い フィルタリングツールでは状態遷移は分からない場合があります。 ですから、単に ACK のみが立ったパケットはフィルタリングでは原理的にすり抜ける 可能性があります。こうした問題についても対処するには状態の遷移過程まで 見るようなフィルタリングツールが必要ですが、幸い IPFilter にはその機能が ついています(しかも、UDP,ICMPにまで及んでいます。一方、ようやく最近になって IPFW にもこうしたステートフルの機能がサポートされました)。

このような状態遷移を追いかけるものを stateful と呼び、状態遷移のない ものを stateless と呼んで区別します。また、stateful は本当に状態遷移を 完全に追いかけようとすると、Sequence Number や ACK Number なども見なければ なりませんが、ここではこれ以上取り上げません。(Sequence Number や ACK Number は、パケットの順序性や、次に期待されるパケットの正当性を ある程度保証するものです。初期の実装においては、Sequence Number が 非常に類推しやすいものであったりしましたが、現在では乱数などのアルゴリズム も改善されています。)


next up previous contents
Next: 6.1.3 UDP Up: 6.1 プロトコル Previous: 6.1.1 コネクション
Noriyo Kanayama