ท่านที่กำลังมีปัญหาติดตั้ง Asterisk ไว้หลัง Nat Device เช่น ADSL Router ลองเทคนิคนี้ดูนะครับ อาจช่วยแก้ปัญหาได้ ผมมีเทคนิคมาแนะนำอยู่ 3 วิธี เลือกวิธีใดวิธีหนึ่งนะครับ
1. ใช้ STUN Server
STUN ย่อมาจาก Simple Transversal UDP over NAT เป็นโปรโตคอลหรือเทคนิคอย่างหนึ่งที่จะทำให้อุปกรณ์ VoIP ที่ติดตั้งหลัง NAT ทำงานได้ เทคนิคนี้นะครับมันอาจจะทำงานได้หลายอย่างแต่ผมจำเอาว่ามันเป็นเทคนิคที่จะทำให้อุปกรณ์ VoIP รู้ว่าตอนนี้ Public IP Address ของมันคือ IP อะไร แล้วมันก็จะเอา IP นี้ไปใส่แทน Private IP ของมันก่อนที่จะส่ง VoIP Packets ไปยังปลายทาง
ให้เพิ่ม 3 บรรทัดนี้ไว้ในไฟล์ sip.conf
- โค้ด: เลือกทั้งหมด
localnet=192.168.0.0/255.255.255.0
stunaddr=stun.xten.com:3478
externrefresh=15
บรรทัด localnet ใส่เป็น Subnet ของวงแลนครับเช่นถ้า Asterisk มีไอพีเป็น 192.168.0.200 ซับเน็ต 255.255.255.0 ก็แสดงว่า Subnet คือ 192.168.0.0/255.255.255.0 ครับ ก็ใส่แบบนี้ แต่ถ้ามีหลาย Subnet เช่นอาจจะเชื่อมต่อไปสาขาด้วย ก็ให้เพิ่มบรรทัด localnet ได้อีกเรื่อยๆ
บรรทัด stunaddr ใส่ IP Address หรือ DNS Name ของ STUN Server และใส่หมายเลขพอร์ตด้วย ดีฟอลท์คือ 3478 เป็น UDP ครับ ถ้าไม่รู้จะใส่อะไรจะใช้เหมือนผมก็ได้
บรรทัด extenrefresh ใส่เวลาเป็นวินาทีซึ่ง Asterisk (ในฐานะ STUN client) จะส่งแพ็กเก็ตไปสอบถาม STUN Server ว่าตอนนี้ Public IP ของมันเป็น IP อะไร ต้องเช็คอยู่เรื่อยๆครับ กันลิ้งค์ดาวน์แล้ว IP เปลี่ยน
มาดูผลลัพธ์กันครับ
ก่อนใช้ STUN
ตัว Asterisk ผมส่ง Register ออกไปหา True NetTalk บ่อยมาก เหมือนกับว่ามันยังขาดข้อมูลอะไรสักอย่างที่ยังไม่ได้รับจาก True NetTalk สังเกตุนะครับว่า IP ที่ Asterisk ใช้ใน Message เป็น IP ขา Private ของมัน 192.168.0.200
U 192.168.0.200:5060 -> 61.90.255.132:5060
REGISTER sip:61.90.255.132 SIP/2.0..Via: SIP/2.0/UDP 192.168.0.200:5060;branch=z9hG4bK4f5bc07a;rport..Max-Forwards: 70..From: <
sip:98000003233@61.90.255.132>;tag=as0b86f4f6..To: <sip:98000003233@61.90.255.132>..Call-ID: 470764435e8c94a94842e0943cbb0ec6@1
27.0.0.1..CSeq: 105 REGISTER..User-Agent: SuperCall v1.09..Authorization: Digest username="98000003233", realm="huawei", algori
thm=MD5, uri="Huawei.com", nonce="3a22375d5325dfcc59d1b945c49a0a32", response="bf5243d69f9dd424fb43e50a13d622b4"..Expires: 120.
.Contact: <sip:98000003233@192.168.0.200>..Content-Length: 0....
#
U 61.90.255.132:5060 -> 192.168.0.200:5060
SIP/2.0 200 OK..Via: SIP/2.0/UDP 192.168.0.200:5060;received=58.64.115.11;branch=z9hG4bK4f5bc07a;rport=5060..From: <sip:9800000
3233@61.90.255.132>;tag=as0b86f4f6..To: <sip:98000003233@61.90.255.132>;tag=aprqt3p6jg2-vf9gh110000i6..Call-ID: 470764435e8c94a
94842e0943cbb0ec6@127.0.0.1..CSeq: 105 REGISTER..Contact: <sip:98000003233@192.168.0.200>;expires=30..Expires: 30....
หลังใช้ STUN
นิ่งเลยครับ Register ได้แล้วก็นิ่ง พอถึงเวลาก็ Register ไปใหม่อีก สมบูรณ์แบบ อยากให้สังเกตุว่าตอนนี้ IP ที่ Asterisk ใช้กลายเป็น Public IP แล้ว
U 192.168.0.200:5060 -> 61.90.255.132:5060
REGISTER sip:61.90.255.132 SIP/2.0..Via: SIP/2.0/UDP 58.64.115.11:5060;branch=z9hG4bK2d64cd07;rport..Max-Forwards: 70..From: <s
ip:98000003233@61.90.255.132>;tag=as085ac132..To: <sip:98000003233@61.90.255.132>..Call-ID: 1b17f5e61014bcc26a7c73343ebacc37@12
7.0.0.1..CSeq: 103 REGISTER..User-Agent: SuperCall v1.09..Authorization: Digest username="98000003233", realm="huawei", algorit
hm=MD5, uri="Huawei.com", nonce="7959f3fd794f89f9cb14220c37c00177", response="fce8d093a3d77293442dee2bef5f6f48"..Expires: 120..
Contact: <sip:98000003233@58.64.115.11>..Content-Length: 0....
#
U 61.90.255.132:5060 -> 192.168.0.200:5060
SIP/2.0 200 OK..Via: SIP/2.0/UDP 58.64.115.11:5060;received=58.64.115.11;branch=z9hG4bK2d64cd07;rport=5060..From: <sip:98000003
233@61.90.255.132>;tag=as085ac132..To: <sip:98000003233@61.90.255.132>;tag=b6618b25..Call-ID: 1b17f5e61014bcc26a7c73343ebacc37@
127.0.0.1..CSeq: 103 REGISTER..Expires: 300..Contact: <sip:98000003233@58.64.115.11>;expires=300..Server: Huawei SoftX3000 V300
R006B06D060SP32..Content-Length: 0....
แต่ถ้าเจอปัญหาว่า STUN Server ล่มเป็นบางครั้งบางคราวโดยเฉพาะตอนที่ต้องการใช้งาน อย่างเช่นเจอข้อความแบบนี้
[Mar 9 22:56:36] WARNING[12447]: chan_sip.c:3647 ast_sip_ouraddrfor: stun failed
ต้องเจอบ่อยๆนะครับ หลายๆวันเจอทีผมว่าเป็นเรื่องปกติ ไม่มีปัญหา ผมแนะนำให้ใช้วิธีที่ 2 แทนครับ ซึ่งผมไม่รู้ว่าเทคนิคนี้เขาเรียกว่าอะไร ขอเรียกเป็นเทคนิค Extenal Host ก็แล้วกันครับ
2. ใช้ External Host
วิธีนี้ต้องเอา NAT Device เช่น ADSL Router ไปรีจิสเตอร์กับ Dynamic DNS ก่อนนะครับ เพราะเราต้องใช้ชื่อ สมมติว่าลงทะเบียนเป็นชื่อ kikka.dyndns.org จากนั้นแก้ไขไฟล์ sip.conf ดังนี้ โดยสมมติว่ายังไม่เคยทำวิธีที่ 1 มาก่อนนะครับ
- โค้ด: เลือกทั้งหมด
localnet=192.168.0.0/255.255.255.0
externhost=kikka.dyndns.org
externrefresh=30
เทคนิคนี้ Asterisk จะไปถาม DNS Server ว่าโฮสต์ที่ชื่อ kikka.dyndns.org นี้มี IP อะไร มันก็จะเอา IP นี้มาแทน Private IP ของมัน
รีโหลด SIP ใหม่ ก็จะให้ผลเหมือนวิธีแรกครับ
U 192.168.0.200:5060 -> 61.90.255.132:5060
REGISTER sip:61.90.255.132 SIP/2.0..Via: SIP/2.0/UDP 58.64.115.11:5060;branch=z9hG4bK41d82ba5;rport..Max-Forwards: 70..From: <s
ip:98000003233@61.90.255.132>;tag=as6c4932e8..To: <sip:98000003233@61.90.255.132>..Call-ID: 3acbde313b38ba783c62dd3b611a6a74@12
7.0.0.1..CSeq: 102 REGISTER..User-Agent: SuperCall v1.09..Expires: 120..Contact: <sip:98000003233@58.64.115.11>..Content-Length
: 0....
#
U 61.90.255.132:5060 -> 192.168.0.200:5060
SIP/2.0 401 Unauthorized..Via: SIP/2.0/UDP 58.64.115.11:5060;received=58.64.115.11;branch=z9hG4bK41d82ba5;rport=5060..From: <si
p:98000003233@61.90.255.132>;tag=as6c4932e8..To: <sip:98000003233@61.90.255.132>;tag=e2111a5d..Call-ID: 3acbde313b38ba783c62dd3
b611a6a74@127.0.0.1..CSeq: 102 REGISTER..WWW-Authenticate: Digest realm="huawei", nonce="ea586b10e0fdfa51bea0c50bbb7bc1fd",doma
in="Huawei.com", stale=false,algorithm=MD5..Server: Huawei SoftX3000 V300R006B06D060SP32..Content-Length: 0....
#
U 192.168.0.200:5060 -> 61.90.255.132:5060
REGISTER sip:61.90.255.132 SIP/2.0..Via: SIP/2.0/UDP 58.64.115.11:5060;branch=z9hG4bK653d5ce4;rport..Max-Forwards: 70..From: <s
ip:98000003233@61.90.255.132>;tag=as3fbe702f..To: <sip:98000003233@61.90.255.132>..Call-ID: 3acbde313b38ba783c62dd3b611a6a74@12
7.0.0.1..CSeq: 103 REGISTER..User-Agent: SuperCall v1.09..Authorization: Digest username="98000003233", realm="huawei", algorit
hm=MD5, uri="Huawei.com", nonce="ea586b10e0fdfa51bea0c50bbb7bc1fd", response="7f2a46603f2b89dee0b86072eb77bbcb"..Expires: 120..
Contact: <sip:98000003233@58.64.115.11>..Content-Length: 0....
#
U 61.90.255.132:5060 -> 192.168.0.200:5060
SIP/2.0 200 OK..Via: SIP/2.0/UDP 58.64.115.11:5060;received=58.64.115.11;branch=z9hG4bK653d5ce4;rport=5060..From: <sip:98000003
233@61.90.255.132>;tag=as3fbe702f..To: <sip:98000003233@61.90.255.132>;tag=a3bd6483..Call-ID: 3acbde313b38ba783c62dd3b611a6a74@
127.0.0.1..CSeq: 103 REGISTER..Expires: 300..Contact: <sip:98000003233@58.64.115.11>;expires=300..Server: Huawei SoftX3000 V300
R006B06D060SP32..Content-Length: 0....
แต่วิธีที่ 2 นี้ก็ใช่ว่าจะไม่มีปัญหา ลองนึกดูครับว่าตอนที่กำลังจะใช้งานปรากฏว่าลิ้งค์เพิ่งอัพขึ้นมาใหม่ๆ แน่นอนว่าไอพีก็ต้องเปลี่ยนไป แต่ DNS ยังไม่อัพเดท Asterisk มันก็จะได้ IP เดิมไป ซึ่งก็จะมีปัญหาในการใช้งาน
ถ้ามีตังหน่อยก็ใช้วิธีขอเน็ต Fixed IP ไปเลยครับ แล้วมาทำตามวิธีที่ 3
3. ใช้ External IP Address ระบุ Public IP Address
สมมติว่า Fixed IP ของเราคือ 58.59.60.61
- โค้ด: เลือกทั้งหมด
localnet=192.168.0.0/255.255.255.0
externip=58.59.60.61
ผมว่าเลือกเอาวิธีที่ที่เหมาะที่สุดก็แล้วกันครับ แบบที่ 3 นี่มันเวอร์คชัวร์ๆอยู่แล้ว แต่สองแบบแรกอาจต้องลองเทสดูทั้งสองวิธี ถ้าถามผมว่าใช้วิธีไหนดีที่สุด ถ้าไม่ค่อยมีตังเช่าเน็ตแบบ Fixed IP ก็ต้องวิธีแรกครับ คือใช้ STUN และใช้ STUN Server ที่เสถียรๆหน่อย ตัวที่ผมเอามาเป็นตัวอย่างก็เวอร์คดีนะครับ แต่ไม่ว่าจะใช้วิธีไหนก็ตามทั้ง 3 วิธีนี้ True NetTalk หรือผู้ให้บริการรายอื่นๆจะไม่รู้เลยว่า Asterisk ของเราอยู่หลัง NAT
บทความที่เกี่ยวข้อง
1. อธิบายพารามิเตอร์ externhost, externip และ stunaddr
2. บทความแนวคิดและลักษณะการติดตั้ง Asterisk ไว้หลัง NAT