SIP 協定詳解
SIP(Session Initiation Protocol)是現在 VoIP 最普遍的信令協定,由 IETF 在 RFC 3261 定義。它是文字型協定,負責多媒體會話的建立、修改和結束——注意,它只管信令,實際的語音媒體是交給 RTP 傳的。
SIP 基本概念
協定特性
SIP 屬於應用層協定,具有以下設計特性:
| 特性 | 說明 |
|---|---|
| 文字型協定 | 類似 HTTP,人類可讀,便於除錯 |
| 信令與媒體分離 | SIP 只處理信令,媒體由 RTP 承載 |
| 端對端架構 | 用戶端具備完整的協定能力 |
| 可擴展性 | 透過標頭擴展支援新功能 |
| 傳輸層無關 | 可使用 UDP、TCP 或 TLS |
SIP 網路元件
| 元件 | 角色說明 |
|---|---|
| User Agent Client (UAC) | 發起 SIP 請求的客戶端 |
| User Agent Server (UAS) | 接收並回應 SIP 請求的伺服端 |
| Proxy Server | 中繼轉發 SIP 請求,可進行路由決策 |
| Registrar | 接受 REGISTER 請求,維護位置資料庫 |
| Redirect Server | 回傳替代的 URI,引導 UAC 重新發送請求 |
| Location Service | 儲存 UA 的聯繫位址資料庫 |
Proxy 有兩種模式:Stateful Proxy 會記錄交易狀態,能做分叉(Forking)、重試這類邏輯;Stateless Proxy 只單純轉發,效能高但功能有限。客服中心的 SIP 伺服器通常是 Stateful Proxy。
SIP URI 格式
SIP URI 是 SIP 網路中的定址方式:
sip:user@domain[:port][;parameters][?headers]
sips:user@domain[:port][;parameters][?headers]常見範例:
| URI | 說明 |
|---|---|
sip:1001@pbx.example.com | 分機 1001 |
sip:+886227001234@gw.example.com;user=phone | E.164 號碼格式 |
sips:agent@cc.example.com | TLS 加密的 SIP URI |
sip:conference@example.com;transport=tcp | 指定 TCP 傳輸 |
SIP 方法(Methods)
核心方法(RFC 3261)
| 方法 | 說明 | 使用時機 |
|---|---|---|
| REGISTER | 向 Registrar 註冊聯繫位址 | UA 開機或定期更新註冊 |
| INVITE | 發起會話邀請 | 撥打電話 |
| ACK | 確認最終回應 | 收到 INVITE 的 2xx/3xx-6xx 回應後 |
| BYE | 終止已建立的會話 | 掛斷電話 |
| CANCEL | 取消尚未完成的請求 | 撥號後對方未接前取消 |
| OPTIONS | 查詢對方能力 | 健康檢查或能力偵測 |
擴展方法
| 方法 | RFC | 說明 |
|---|---|---|
| SUBSCRIBE | RFC 6665 | 訂閱事件通知 |
| NOTIFY | RFC 6665 | 發送事件通知 |
| REFER | RFC 3515 | 指示對方聯繫第三方(用於轉接) |
| MESSAGE | RFC 3428 | 即時訊息 |
| INFO | RFC 6086 | 在對話中傳送應用層資訊(如 DTMF) |
| UPDATE | RFC 3311 | 修改尚未確認的會話參數 |
| PRACK | RFC 3262 | 對暫時回應的可靠確認 |
呼叫建立流程
基本呼叫流程
以下為一通標準 SIP 呼叫的信令流程:
Alice (UAC) SIP Proxy Bob (UAS)
| | |
|--- INVITE -------->| |
| |--- INVITE ------->|
| |<-- 100 Trying ----|
|<-- 100 Trying -----| |
| |<-- 180 Ringing ---|
|<-- 180 Ringing ----| |
| |<-- 200 OK --------|
|<-- 200 OK ---------| |
|--- ACK ----------->| |
| |--- ACK ---------->|
|<=============== RTP Media ============>|
| | |
|--- BYE ----------->| |
| |--- BYE ---------->|
| |<-- 200 OK --------|
|<-- 200 OK ---------| |SDP 媒體協商(Offer/Answer)
SDP(Session Description Protocol, RFC 4566)描述多媒體會話的參數,嵌入在 SIP 訊息的 Body 中。
典型的 SDP 內容:
v=0
o=alice 2890844526 2890844526 IN IP4 192.168.1.100
s=Phone Call
c=IN IP4 192.168.1.100
t=0 0
m=audio 49170 RTP/AVP 0 8 18 101
a=rtpmap:0 PCMU/8000
a=rtpmap:8 PCMA/8000
a=rtpmap:18 G729/8000
a=rtpmap:101 telephone-event/8000
a=fmtp:101 0-16
a=ptime:20
a=sendrecvSDP 欄位說明:
| 欄位 | 說明 |
|---|---|
v= | 協定版本(固定為 0) |
o= | 會話發起者資訊 |
s= | 會話名稱 |
c= | 連線資訊(媒體接收的 IP 位址) |
t= | 時間(0 0 表示永久) |
m= | 媒體描述(類型、埠號、傳輸協定、Payload Type 列表) |
a=rtpmap: | Payload Type 與 Codec 的對應 |
a=fmtp: | 格式參數(如 DTMF 事件範圍) |
a=ptime: | 封包時間(毫秒) |
a=sendrecv | 媒體方向(sendrecv/sendonly/recvonly/inactive) |
Codec 就是這樣談定的——所謂 Offer/Answer 模型(RFC 3264):發起方在 INVITE 的 SDP 裡列出自己支援的 Codec(Offer),接收方在 200 OK 裡挑出雙方都有的回覆(Answer),最後用哪個以 Answer 為準。
呼叫轉接流程
SIP 呼叫轉接使用 REFER 方法(RFC 3515):
諮詢轉接(Attended Transfer):
- A 與 B 通話中
- A 按下轉接鍵,B 被保留(re-INVITE with
a=sendonly) - A 撥給 C,建立新通話
- A 確認 C 接聽後,A 向 B 發送 REFER(Refer-To: C)
- B 向 C 發起新 INVITE
- A 的兩通通話均終止
SIP 回應碼
1xx 暫時回應(Provisional)
| 代碼 | 說明 | 用途 |
|---|---|---|
| 100 | Trying | Proxy 已收到請求,正在處理 |
| 180 | Ringing | 被叫方正在振鈴 |
| 181 | Call Is Being Forwarded | 來電正在轉接中 |
| 182 | Queued | 來電已排入佇列 |
| 183 | Session Progress | 早期媒體(Early Media),常用於播放回鈴音 |
2xx 成功回應(Success)
| 代碼 | 說明 | 用途 |
|---|---|---|
| 200 | OK | 請求成功 |
| 202 | Accepted | 請求已接受處理(用於 REFER) |
3xx 重新導向(Redirection)
| 代碼 | 說明 | 用途 |
|---|---|---|
| 300 | Multiple Choices | 多個可選位址 |
| 301 | Moved Permanently | URI 永久變更 |
| 302 | Moved Temporarily | URI 暫時變更(常用於呼叫轉接) |
4xx 用戶端錯誤(Client Error)
| 代碼 | 說明 | 常見原因 |
|---|---|---|
| 400 | Bad Request | SIP 訊息格式錯誤 |
| 401 | Unauthorized | 需要驗證(Registrar 回應) |
| 403 | Forbidden | 權限不足,拒絕請求 |
| 404 | Not Found | 用戶不存在 |
| 407 | Proxy Authentication Required | 需要 Proxy 驗證 |
| 408 | Request Timeout | 請求逾時 |
| 480 | Temporarily Unavailable | 暫時無法聯繫 |
| 486 | Busy Here | 被叫方忙線 |
| 487 | Request Terminated | 請求被 CANCEL 取消 |
| 488 | Not Acceptable Here | SDP 協商失敗(無共同 Codec) |
5xx 伺服器錯誤(Server Error)
| 代碼 | 說明 | 常見原因 |
|---|---|---|
| 500 | Server Internal Error | 伺服器內部錯誤 |
| 502 | Bad Gateway | 上游伺服器回應異常 |
| 503 | Service Unavailable | 服務暫時不可用(過載或維護) |
| 504 | Server Time-out | 上游伺服器無回應 |
6xx 全域錯誤(Global Failure)
| 代碼 | 說明 | 用途 |
|---|---|---|
| 600 | Busy Everywhere | 被叫方在所有位置都忙線 |
| 603 | Decline | 被叫方拒接 |
| 604 | Does Not Exist Anywhere | 用戶不存在於任何位置 |
實務上,客服中心最常撞到的錯誤碼就那幾個:401/407(驗證問題)、408/480(網路或設備不可達)、486(座席忙線)、488(Codec 不匹配)。排障時先抓封包——sngrep 或 Wireshark——把完整信令流程攤開來看,通常比猜快。
SIP 安全性
認證機制
SIP 使用 HTTP Digest 認證(RFC 2617),流程為:
- UAC 發送 REGISTER
- Registrar 回應 401 + nonce 值
- UAC 計算 MD5 摘要,重新發送 REGISTER 帶 Authorization 標頭
- Registrar 驗證成功,回應 200 OK
傳輸層加密
| 方案 | 說明 |
|---|---|
| SIP over TLS(SIPS) | 信令加密,埠號 5061 |
| SRTP | 媒體加密(需搭配 SDES 或 DTLS-SRTP) |
| IPsec | 網路層加密,保護所有流量 |
SIP 常見攻擊與防護
| 攻擊類型 | 說明 | 防護措施 |
|---|---|---|
| 註冊劫持 | 偽造 REGISTER 替換合法用戶 | 強制認證 + TLS |
| INVITE 洪水 | 大量 INVITE 造成 DoS | SBC 速率限制 |
| 竊聽 | 攔截 SIP/RTP 封包 | SIPS + SRTP |
| 盜打 | 非法使用 SIP Trunk 撥打國際電話 | IP ACL + 強密碼 + 通話限制 |
參考標準
| 標準 | 名稱 |
|---|---|
| RFC 3261 | SIP: Session Initiation Protocol |
| RFC 4566 | SDP: Session Description Protocol |
| RFC 3264 | Offer/Answer Model with SDP |
| RFC 3515 | SIP REFER Method |
| RFC 6665 | SIP-Specific Event Notification |
| RFC 3262 | Reliability of Provisional Responses (PRACK) |
| RFC 4733 | RTP Payload for DTMF Digits (取代 RFC 2833) |