232 lines
21 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# SIP (Session Initiation Protocol)
{{#include ../../../banners/hacktricks-training.md}}
## 基本情報
SIP (Session Initiation Protocol) は、**シグナリングおよびコール制御プロトコル**であり、IPネットワーク上で音声、ビデオ、インスタントメッセージングを含むマルチメディアセッションを確立、変更、終了するために広く使用されています。**Internet Engineering Task Force (IETF)** によって開発され、SIPは**RFC 3261**で定義されており、VoIPおよび統合コミュニケーションの事実上の標準となっています。
SIPの主な特徴は以下の通りです
1. **テキストベースのプロトコル**: SIPはテキストベースのプロトコルであり、人間が読みやすく、デバッグが容易です。HTTPに似たリクエスト-レスポンスモデルに基づいており、コールセッションを制御するためにINVITE、ACK、BYE、CANCELなどのメソッドを使用します。
2. **スケーラビリティと柔軟性**: SIPは非常にスケーラブルであり、小規模な展開から大規模な企業やキャリアグレードの環境まで使用できます。新しい機能で簡単に拡張でき、さまざまなユースケースや要件に適応可能です。
3. **相互運用性**: SIPの広範な採用と標準化により、異なるデバイス、アプリケーション、サービスプロバイダー間の相互運用性が向上し、さまざまなプラットフォーム間でシームレスな通信が促進されます。
4. **モジュラー設計**: SIPは、メディア伝送のための**RTP (Real-time Transport Protocol)**やマルチメディアセッションを記述するための**SDP (Session Description Protocol)**など、他のプロトコルと連携して動作します。このモジュラー設計により、さまざまなメディアタイプやコーデックとの柔軟性と互換性が向上します。
5. **プロキシおよびリダイレクトサーバー**: SIPは、コールルーティングを促進し、コール転送、コール転送、ボイスメールサービスなどの高度な機能を提供するために、プロキシおよびリダイレクトサーバーを使用できます。
6. **プレゼンスおよびインスタントメッセージング**: SIPは音声およびビデオ通信に限定されません。プレゼンスおよびインスタントメッセージングもサポートしており、幅広い統合コミュニケーションアプリケーションを可能にします。
多くの利点があるにもかかわらず、SIPは特にNATトラバーサルやファイアウォールの問題に対処する際に構成および管理が複雑になることがあります。しかし、その多様性、スケーラビリティ、および業界全体での広範なサポートにより、VoIPおよびマルチメディア通信の人気の選択肢となっています。
### SIPメソッド
**RFC 3261**で定義されたコアSIPメソッドには以下が含まれます
1. **INVITE**: **新しいセッション(コール)を開始**するか、既存のセッションを変更するために使用されます。INVITEメソッドは、提案されたセッションの詳細メディアタイプ、コーデック、トランスポートプロトコルなどを受信者に通知するために、セッション記述通常はSDPを使用を運びます。
2. **ACK**: INVITEリクエストに対する最終応答の**受信を確認**するために送信されます。ACKメソッドは、エンドツーエンドの確認を提供することにより、INVITEトランザクションの信頼性を確保します。
3. **BYE**: 確立されたセッション(コール)を**終了する**ために使用されます。BYEメソッドは、通信を終了したいことを示すために、セッション内のいずれかの当事者によって送信されます。
4. **CANCEL**: セッションが確立される前に、保留中のINVITEリクエストを**キャンセル**するために送信されます。CANCELメソッドは、送信者が気が変わった場合や受信者からの応答がない場合に、INVITEトランザクションを中止することを可能にします。
5. **OPTIONS**: SIPサーバーまたはユーザーエージェントの**機能を照会**するために使用されます。OPTIONSメソッドは、セッションを実際に確立することなく、サポートされているメソッド、メディアタイプ、または他の拡張に関する情報を要求するために送信できます。
6. **REGISTER**: ユーザーエージェントがSIPレジストラサーバーに**現在の位置を登録**するために使用されます。REGISTERメソッドは、ユーザーのSIP URIと現在のIPアドレスとの間の最新のマッピングを維持するのに役立ち、コールルーティングと配信を可能にします。
> [!WARNING]
> 誰かに電話をかけるために、**REGISTER**を使用する必要はありません。\
> ただし、**INVITE**を実行するために、発信者が最初に**認証**を行う必要がある場合があり、そうでないと**`401 Unauthorized`**の応答を受け取ることになります。
これらのコアメソッドに加えて、他のRFCで定義された**いくつかのSIP拡張メソッド**があります:
1. **SUBSCRIBE**: RFC 6665で定義されており、SUBSCRIBEメソッドは特定のリソースの状態ユーザーのプレゼンスやコールステータスなどに関する**通知を要求**するために使用されます。
2. **NOTIFY**: RFC 6665でも定義されており、NOTIFYメソッドは、監視されているリソースの状態の変化について**サブスクライブされたユーザーエージェント**に通知するためにサーバーによって送信されます。
3. **REFER**: RFC 3515で定義されており、REFERメソッドは、受信者に**転送を実行するか、第三者を参照する**ように要求するために使用されます。これは通常、**コール転送**シナリオで使用されます。
4. **MESSAGE**: RFC 3428で定義されており、MESSAGEメソッドは、SIPユーザーエージェント間で**インスタントメッセージを送信**するために使用され、SIPフレームワーク内でのテキストベースの通信を可能にします。
5. **UPDATE**: RFC 3311で定義されており、UPDATEメソッドは、**既存のダイアログの状態に影響を与えずにセッションを変更**することを可能にします。これは、進行中のコール中にコーデックやメディアタイプなどのセッションパラメータを更新するのに便利です。
6. **PUBLISH**: RFC 3903で定義されており、PUBLISHメソッドは、ユーザーエージェントが**イベント状態情報をサーバーに公開**し、他の関心のある当事者が利用できるようにするために使用されます。
### SIPレスポンスコード
- **1xx (暫定応答)**: これらの応答は、リクエストが受信され、サーバーが処理を続けていることを示します。
- 100 Trying: リクエストが受信され、サーバーが処理中です。
- 180 Ringing: 呼び出し先が通知され、コールを受け取ります。
- 183 Session Progress: コールの進行状況に関する情報を提供します。
- **2xx (成功応答)**: これらの応答は、リクエストが正常に受信され、理解され、受け入れられたことを示します。
- 200 OK: リクエストが成功し、サーバーがそれを満たしました。
- 202 Accepted: リクエストは処理のために受け入れられましたが、まだ完了していません。
- **3xx (リダイレクション応答)**: これらの応答は、リクエストを満たすためにさらなるアクションが必要であることを示します。通常は代替リソースに連絡することによってです。
- 300 Multiple Choices: 複数のオプションが利用可能であり、ユーザーまたはクライアントが1つを選択する必要があります。
- 301 Moved Permanently: リクエストされたリソースに新しい永続的なURIが割り当てられました。
- 302 Moved Temporarily: リクエストされたリソースは一時的に異なるURIで利用可能です。
- 305 Use Proxy: リクエストは指定されたプロキシに送信する必要があります。
- **4xx (クライアントエラー応答)**: これらの応答は、リクエストに不正な構文が含まれているか、サーバーによって満たすことができないことを示します。
- 400 Bad Request: リクエストが不正または無効でした。
- 401 Unauthorized: リクエストにはユーザー認証が必要です。
- 403 Forbidden: サーバーはリクエストを理解しましたが、満たすことを拒否します。
- 404 Not Found: リクエストされたリソースはサーバー上に見つかりませんでした。
- 408 Request Timeout: サーバーは、待機する準備ができていた時間内に完全なリクエストを受信しませんでした。
- 486 Busy Here: 呼び出し先は現在ビジーで、コールを受け取ることができません。
- **5xx (サーバーエラー応答)**: これらの応答は、サーバーが有効なリクエストを満たすことに失敗したことを示します。
- 500 Internal Server Error: サーバーはリクエストを処理中にエラーに遭遇しました。
- 501 Not Implemented: サーバーはリクエストを満たすために必要な機能をサポートしていません。
- 503 Service Unavailable: サーバーは現在、メンテナンスまたは過負荷のためにリクエストを処理できません。
- **6xx (グローバル失敗応答)**: これらの応答は、リクエストがどのサーバーによっても満たされないことを示します。
- 600 Busy Everywhere: コールのすべての可能な宛先がビジーです。
- 603 Decline: 呼び出し先はコールに参加したくありません。
- 604 Does Not Exist Anywhere: リクエストされたリソースはネットワーク内のどこにも存在しません。
## 例
### SIP INVITEの例
```
INVITE sip:jdoe@example.com SIP/2.0
Via: SIP/2.0/UDP pc33.example.com;branch=z9hG4bK776asdhds
Max-Forwards: 70
To: John Doe <sip:jdoe@example.com>
From: Jane Smith <sip:jsmith@example.org>;tag=1928301774
Call-ID: a84b4c76e66710
CSeq: 314159 INVITE
Contact: <sip:jsmith@pc33.example.com>
User-Agent: ExampleSIPClient/1.0
Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY, MESSAGE, SUBSCRIBE, INFO
Content-Type: application/sdp
Content-Length: 142
v=0
o=jsmith 2890844526 2890842807 IN IP4 pc33.example.com
s=-
c=IN IP4 pc33.example.com
t=0 0
m=audio 49170 RTP/AVP 0
a=rtpmap:0 PCMU/8000te
```
<details>
<summary>各パラメータの説明</summary>
1. **Request-Line**: `INVITE sip:jdoe@example.com SIP/2.0` - この行は、メソッドINVITE、リクエストURIsip:[jdoe@example.com](mailto:jdoe@example.com)、およびSIPバージョンSIP/2.0)を示します。
2. **Via**: `Via: SIP/2.0/UDP pc33.example.com;branch=z9hG4bK776asdhds` - Viaヘッダーは、トランスポートプロトコルUDPとクライアントのアドレスpc33.example.comを指定します。「branch」パラメータは、ループ検出とトランザクションマッチングに使用されます。
3. **Max-Forwards**: `Max-Forwards: 70` - このヘッダーフィールドは、リクエストがプロキシによって転送される回数を制限し、無限ループを回避します。
4. **To**: `To: John Doe <sip:jdoe@example.com>` - Toヘッダーは、通話の受信者を指定し、表示名John DoeとSIP URIsip:[jdoe@example.com](mailto:jdoe@example.com))を含みます。
5. **From**: `From: Jane Smith <sip:jsmith@example.org>;tag=1928301774` - Fromヘッダーは、通話の送信者を指定し、表示名Jane SmithとSIP URIsip:[jsmith@example.org](mailto:jsmith@example.org)を含みます。「tag」パラメータは、ダイアログ内で送信者の役割を一意に識別するために使用されます。
6. **Call-ID**: `Call-ID: a84b4c76e66710` - Call-IDヘッダーは、2つのユーザーエージェント間の通話セッションを一意に識別します。
7. **CSeq**: `CSeq: 314159 INVITE` - CSeqヘッダーは、シーケンス番号とリクエストで使用されるメソッドを含みます。これは、リクエストに対する応答をマッチさせ、順序が乱れたメッセージを検出するために使用されます。
8. **Contact**: `Contact: <sip:jsmith@pc33.example.com>` - Contactヘッダーは、送信者への直接のルートを提供し、後続のリクエストや応答に使用できます。
9. **User-Agent**: `User-Agent: ExampleSIPClient/1.0` - User-Agentヘッダーは、送信者のソフトウェアまたはハードウェアに関する情報を提供し、その名前とバージョンを含みます。
10. **Allow**: `Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY, MESSAGE, SUBSCRIBE, INFO` - Allowヘッダーは、送信者がサポートするSIPメソッドをリストします。これにより、受信者は通信中に使用できるメソッドを理解できます。
11. **Content-Type**: `Content-Type: application/sdp` - Content-Typeヘッダーは、メッセージボディのメディアタイプを指定し、この場合はSDPSession Description Protocolです。
12. **Content-Length**: `Content-Length: 142` - Content-Lengthヘッダーは、メッセージボディのサイズをバイト単位で示します。
13. **Message Body**: メッセージボディには、メディアタイプ、コーデック、および提案されたセッションのトランスポートプロトコルに関する情報を含むSDPセッション記述が含まれます。
- `v=0` - プロトコルバージョンSDPの場合は0
- `o=jsmith 2890844526 2890842807 IN IP4 pc33.example.com` - 発信者とセッション識別子
- `s=-` - セッション名(単一のハイフンはセッション名がないことを示します)
- `c=IN IP4 pc33.example.com` - 接続情報(ネットワークタイプ、アドレスタイプ、およびアドレス)
- `t=0 0` - タイミング情報開始時刻と停止時刻、0 0はセッションが制限されていないことを意味します
- `m=audio 49170 RTP/AVP 0` - メディア記述メディアタイプ、ポート番号、トランスポートプロトコル、およびフォーマットリスト。この場合、RTP/AVPリアルタイムトランスポートプロトコル/オーディオビデオプロファイルを使用したオーディオストリームとフォーマット0PCMU/8000を指定します。
- `a=rtpmap:0 PCMU/8000` - フォーマット0をコーデックPCMUおよびそのクロックレート8000 Hzにマッピングする属性です。
</details>
### SIP REGISTERの例
REGISTERメソッドは、Session Initiation ProtocolSIPで、VoIP電話やソフトフォンなどのユーザーエージェントUAが**SIPレジストラサーバーに自分の位置を登録する**ために使用されます。このプロセスにより、サーバーは**登録されたユーザー宛ての着信SIPリクエストをどこにルーティングするかを知ることができます**。レジストラサーバーは通常、SIPプロキシサーバーまたは専用の登録サーバーの一部です。
以下は、REGISTER認証プロセスに関与するSIPメッセージの詳細な例です。
1. UAからレジスタサーバーへの初期**REGISTER**リクエスト:
```yaml
REGISTER sip:example.com SIP/2.0
Via: SIP/2.0/UDP 192.168.1.100:5060;branch=z9hG4bK776asdhds
Max-Forwards: 70
From: Alice <sip:alice@example.com>;tag=565656
To: Alice <sip:alice@example.com>
Call-ID: 1234567890@192.168.1.100
CSeq: 1 REGISTER
Contact: <sip:alice@192.168.1.100:5060>;expires=3600
Expires: 3600
Content-Length: 0
```
この初期のREGISTERメッセージは、UAアリスからレジストラサーバーに送信されます。これには、希望する登録期間Expires、ユーザーのSIP URIsip:[alice@example.com](mailto:alice@example.com)、およびユーザーの連絡先アドレスsip:alice@192.168.1.100:5060などの重要な情報が含まれています。
2. **401 Unauthorized** レジストラサーバーからの応答:
```css
cssCopy codeSIP/2.0 401 Unauthorized
Via: SIP/2.0/UDP 192.168.1.100:5060;branch=z9hG4bK776asdhds
From: Alice <sip:alice@example.com>;tag=565656
To: Alice <sip:alice@example.com>;tag=7878744
Call-ID: 1234567890@192.168.1.100
CSeq: 1 REGISTER
WWW-Authenticate: Digest realm="example.com", nonce="abcdefghijk", algorithm=MD5, qop="auth"
Content-Length: 0
```
レジストラサーバーは「401 Unauthorized」メッセージで応答し、これには「WWW-Authenticate」ヘッダーが含まれています。このヘッダーには、UAが自分自身を認証するために必要な情報、例えば**認証レルム、ノンス、およびアルゴリズム**が含まれています。
3. 認証情報を含むREGISTERリクエスト:
```vbnet
REGISTER sip:example.com SIP/2.0
Via: SIP/2.0/UDP 192.168.1.100:5060;branch=z9hG4bK776asdhds
Max-Forwards: 70
From: Alice <sip:alice@example.com>;tag=565656
To: Alice <sip:alice@example.com>
Call-ID: 1234567890@192.168.1.100
CSeq: 2 REGISTER
Contact: <sip:alice@192.168.1.100:5060>;expires=3600
Expires: 3600
Authorization: Digest username="alice", realm="example.com", nonce="abcdefghijk", uri="sip:example.com", response="65a8e2285879283831b664bd8b7f14d4", algorithm=MD5, cnonce="lmnopqrst", qop=auth, nc=00000001
Content-Length: 0
```
UAは別のREGISTERリクエストを送信します。このリクエストには、**必要な資格情報(ユーザー名、レルム、ノンス、および提供された情報とユーザーのパスワードを使用して計算されたレスポンス値)を含む"Authorization"ヘッダー**が含まれています。
これが**Authorizationレスポンス**の計算方法です:
```python
import hashlib
def calculate_sip_md5_response(username, password, realm, method, uri, nonce, nc, cnonce, qop):
# 1. Calculate HA1 (concatenation of username, realm, and password)
ha1_input = f"{username}:{realm}:{password}"
ha1 = hashlib.md5(ha1_input.encode()).hexdigest()
# 2. Calculate HA2 (concatenation of method and uri)
ha2_input = f"{method}:{uri}"
ha2 = hashlib.md5(ha2_input.encode()).hexdigest()
# 3. Calculate the final response value (concatenation of h1, stuff and h2)
response_input = f"{ha1}:{nonce}:{nc}:{cnonce}:{qop}:{ha2}"
response = hashlib.md5(response_input.encode()).hexdigest()
return response
# Example usage
username = "alice"
password = "mysecretpassword"
realm = "example.com"
method = "REGISTER"
uri = "sip:example.com"
nonce = "abcdefghijk"
nc = "00000001"
cnonce = "lmnopqrst"
qop = "auth"
response = calculate_sip_md5_response(username, password, realm, method, uri, nonce, nc, cnonce, qop)
print(f"MD5 response value: {response}")
```
4. **成功した登録** レスポンスはレジストラサーバーからのものです:
```yaml
SIP/2.0 200 OK
Via: SIP/2.0/UDP 192.168.1.100:5060;branch=z9hG4bK776asdhds
From: Alice <sip:alice@example.com>;tag=565656
To: Alice <sip:alice@example.com>;tag=7878744
Call-ID: 1234567890@192.168.1.100
CSeq: 2 REGISTER
Contact: <sip:alice@192.168.1.100:5060>;expires=3600
Expires: 3600
Content-Length: 0
```
レジストラサーバーが提供された認証情報を確認した後、**登録が成功したことを示す「200 OK」レスポンスを送信します**。レスポンスには、登録された連絡先情報と登録の有効期限が含まれています。この時点で、ユーザーエージェントアリスはSIPレジストラサーバーに正常に登録され、アリスへの着信SIPリクエストは適切な連絡先アドレスにルーティングされることができます。
### コールの例
<figure><img src="../../../images/image (1101).png" alt=""><figcaption></figcaption></figure>
> [!NOTE]
> 言及されていませんが、ユーザーBは**Proxy 2にREGISTERメッセージを送信する必要があります**。そうしないと、通話を受けることができません。
{{#include ../../../banners/hacktricks-training.md}}