SIP标准编码是什么?Python3脚本遭Fortigate SIP ALG拦截排查
First, let's break down your core questions about SIP encoding and why your Python script is getting blocked while SIPp works—even with "identical" message formats.
SIP's Standard Character Encoding
Per RFC 3261 (the official SIP specification), the default character encoding for SIP messages is ISO-8859-1 (Latin-1). That said, SIP does support other encodings like UTF-8, but you have to explicitly declare them via the charset parameter in the Content-Type header. For example:
Content-Type: application/sdp; charset=utf-8
Many strict SIP ALG implementations (like Fortigate's) can be finicky about UTF-8 if it's not properly declared, or if the message contains non-Latin-1 characters without proper charset tagging. This could be one factor, but it's rarely the only issue.
Why SIPp Works But Your Python Script Doesn't
Even if your message content looks identical to SIPp's, there are subtle, easy-to-miss differences that SIP ALGs flag as invalid. Here are the most common culprits:
- Incorrect Line Endings: SIP requires
CRLF (\r\n)as the line terminator for all headers and the final empty line. A lot of Python scripts accidentally useLF (\n)instead. Fortigate's SIP ALG is strict about this—non-compliant line endings get dropped immediately. - Header Order: While SIP doesn't technically mandate header order, many ALGs expect headers to follow the standard sequence used by most SIP clients (e.g.,
Viafirst, thenFrom,To,Call-ID,CSeq, etc.). SIPp adheres to this order by default, but your script might be generating headers in a different sequence. - Invalid Content-Length: If your script miscalculates the
Content-Lengthvalue (e.g., counting string characters instead of encoded bytes, or forgetting to account forCRLF), the ALG will treat the message as malformed and block it. SIPp automatically computes this value accurately. - Non-Standard Via Branch Parameter: SIP 2.0 requires the
branchparameter in theViaheader to start withz9hG4bK(a magic string defined in RFC 3261). If your script generates a branch without this prefix, the ALG might reject the request as non-compliant. - UDP Fragmentation: If your script sends a UDP packet larger than the MTU (usually 1500 bytes), it might get fragmented and dropped by the firewall. SIPp often handles this by keeping messages within MTU limits or falling back to TCP if configured.
Steps to Fix Your Script
- Enforce CRLF Line Endings: When building your SIP message string in Python, use
\r\nfor every line break, including the final empty line that separates headers from the message body. - Fix Content-Length Calculation: Convert your message body to bytes using your chosen encoding first, then use the length of those bytes for the
Content-Lengthheader. For example:body = "v=0\r\n..." body_bytes = body.encode('utf-8') # or 'iso-8859-1' content_length = len(body_bytes) - Match SIPp's Header Order: Copy the exact header sequence from a SIPp-generated message and replicate it in your script.
- Use Standard Branch Parameters: Generate
branchvalues that start withz9hG4bKfollowed by a random string (e.g.,z9hG4bK-12345678). - Declare Charset Explicitly: If you're using UTF-8, add
; charset=utf-8to yourContent-Typeheader. If you don't need UTF-8, switch to ISO-8859-1 to align with the default SIP standard. - Try TCP Instead of UDP: If UDP continues to get blocked, modify your script to send SIP requests over TCP (port 5060 supports both UDP and TCP). Many ALGs handle TCP-based SIP more leniently.
Final Thought
Encoding issues are possible, but the most likely cause is that your script is deviating from strict SIP standards in small, easy-to-overlook ways. SIPp is built to follow these standards perfectly, so aligning your script with SIPp's output (down to line endings and header order) will almost certainly resolve the ALG blocking issue.
内容的提问来源于stack exchange,提问作者Vino

