1. 程式人生 > >GNUGK 作為Gatekeeper穿透防火墻和NAT

GNUGK 作為Gatekeeper穿透防火墻和NAT

polycom gnugk gatekeeper

背景信息

由於內部使用Polycom的視頻會議,在北、上、深各有辦事處也用polycom ,偶爾需要和外部的視頻會議互聯,發現直接把視頻會議設備在防火墻上開端口實在是太困難,首先大堆的動態端口,這個防火墻的例外開的實在太多了,而且防火墻和視頻設備的NAT之間的兼容太差勁,調試的時候,我都差點把所有端口例外了,把h323相關的防火墻特別設置取消了,還是不能正常的視頻。

之前用Juniper防火墻的時候抓了下正常的包和不正常視頻狀態的包,對比發現是NAT的問題,Hack一下做了個半nat 才把視頻調通,但是端口暴露還是挺多啊。現在換了paloalto ,結果死活調不通。每次開個會要大動幹戈。我的要求並不多,只需要能各個視頻會議室能方便外聯,然後又能保證安全即可。

然後沒辦法開始看h323的協議,找到了這個站點https://www.h323.net,發現竟然有gnugk 這麽個好東西,雖然GNUGK官方的文檔還算全,但是例子少啊。但是h323.net 上提供的信息不少。

準備開始

要求:

1. 從北、上、深任意一個點可以撥外面的點。

2. 北、上、深三點之間可以互撥,多點的話由於其中一個點帶MCU,所以也沒有問題。

3. 網絡環境,gatekeeper 和視頻會議點之間路由可達,在企業防火墻或者nat後面,gatekeeper 需要能訪問互聯網。大概如下圖所示(用了h323.net上的圖)

4. gatekeeper不需要在企業防火墻上開放任何端口。所以設置非常方便,這個和h323.net上的示例稍微不一樣(因為我們暫時沒有被呼入的需要)。

技術分享

安裝:

  • 操作系統選擇ubuntu 16.04 lts,因為官方的x64編譯版本是ubuntu 14.04 ,我發現編譯的版本在16.04上也可以用,就選擇16.04作為最終版本。

  • gnugk的機器使用了一個虛擬機,網卡只分配了一個。

  • 使用gnugk 的編譯版本前有個技巧,就是使用apt-get install gnugk ,這個步驟是為了安裝gnugk使用的很多依賴包,然後apt-get remove gnugk(這個ubuntu自帶的版本太舊了,所以卸載後用最新的版本)

  • 下載最新編譯好的gnugk-4.7-linux-x86_x64,解壓

  • 拷貝二進制文件sudo cp gnugk-4.7-linux-x86_x64/bin/* /usr/sbin

  • Sudo chmod a+x /usr/sbin/gnugk

  • Sudo chmod a+x /usr/sbin/addpasswd

  • 拷貝sudo cp gnugk-4.7-linux-x86_x64/etc/gnugk.ini /etc/gatekeeper.ini

  • 修改gatekeeper.ini 的內容(詳細內容後面貼出

  • 編輯下面內容為gnugk.service並放入 /etc/systemd/system/ ,註意-ttttt 部分,初始測試的時候這個詳細程度開到最大,生產穩定的時候,建議兩個t或者三個t

; place into /etc/systemd/system/ as gnugk.service

[Unit]

Description=GNU Gatekeeper

After=network-online.target

[Service]

Type=simple

ExecStart=/usr/sbin/gnugk -c /etc/gatekeeper.ini -ttttt -o /var/log/gnugk.log

ExecReload=/usr/bin/killall -HUP gnugk

LimitRTPRIO=100

[Install]

WantedBy=multi-user.target

  • 啟用gnugk 服務

                 sudo systemctl enable gnugk.service

                 sudo systemctl start gnugk.service

監聽端口一覽:

7000 是監視端口,配置為只可以本機telnet,1718,1719,1720等用於h323連接建立


gatekeeper.ini 詳細內容:

[Gatekeeper::Main]
Name=gk1
#Home=
#NetworkInterfaces=
TimeToLive=600
CompareAliasType=0
CompareAliasCase=0
#TotalBandwidth=100000
#MinimumBandwidthPerCall=1280
#MaximumBandwidthPerCall=100000

# 狀態監控端口
StatusPort=7000

# 狀態監控的信息詳細程度,最大和默認都為2
StatusTraceLevel=2
UseBroadcastListener=0
UnicastRasPort=1719
UseMulticastListener=1
MulticastPort=1718
MulticastGroup=224.0.1.41
EndpointSignalPort=1720
ListenQueueLength=1024
TimestampFormat=RFC822

[GkStatus::Auth]

# 只允許127.0.0.1 連接狀態監控端口
rule=explicit
127.0.0.1=allow
default=forbid
Shutdown=allow


[RoutedMode]

# 開啟route mode
GKRouted=1

# 對h245 啟用route
H245Routed=1

# 該設置沒有設置時,遇到一個問題,和遠端連接300秒後會自動RST,設置後問題消失,影響h245 隧道建立。
H245TunnelingTranslation=1
RemoveH245AddressOnTunneling=1
AcceptNeighborsCalls=1

# 允許未註冊的終端呼叫(如果要接受外部呼叫這個可以打開)
AcceptUnregisteredCalls=1
SupportNATedEndpoints=1
DropCallsByReleaseComplete=1
CallSignalPort=1720
CallSignalHandlerNumber=5
RtpHandlerNumber=1
RemoveCallOnDRQ=1
SendReleaseCompleteOnDRQ=0
ForwardOnFacility=1
ShowForwarderNumber=1
Q931PortRange=20000-20999
H245PortRange=30000-30999
SetupTimeout=8000
SignalTimeout=15000
AlertingTimeout=60000
TcpKeepAlive=1
TranslateFacility=1
SocketCleanupTimeout=5000
ActivateFailover=1
FailoverCauses=1-15,21-127
CpsLimit=10
CpsCheckInterval=5
GenerateCallProceeding=1
UseProvisionalRespToH245Tunneling=1

# 啟用h46017,h46018,h46019  h460和nat穿越有關系

EnableH46017=1
EnableH46018=1
EnableH46023=1

# 由於h46017,18,19需要STUN服務器,因此我們使用公開可用的STUN服務器,這裏使用ekiga 和qq的stun
H46023STUN=stun.ekiga.net,stun.qq.com
#H46023PublicIP=1
# 下面這個配置後,發現內部之間無法互聯,禁用
#NATStdMin=18
#EnableH460P=1
AutoProxyIPv4ToIPv6Calls=0

[Proxy]

# 啟用代理模式
Enable=1
T120PortRange=40000-40999
RTPPortRange=50000-59999
ProxyForNAT=1
ProxyForSameNAT=0
EnableRTPMute=1
RTPDiffServ=46

[RoutingPolicy]
default=explicit,internal,srv,dns


[RasSrv::RRQFeatures]

# 這段是抄gnugk 關於polycom部分的優化設置。
AliasTypeFilter=terminal;dialeddigits
AliasTypeFilter=gateway;h323id

[RasSrv::LRQFeatures]
AcceptNonNeighborLCF=1
AcceptNonNeighborLRQ=1
[LogFile]

# 日誌文件每天23:59 rotate,也就是每天一個log
Rotate=Daily
RotateTime=23:59

[Gatekeeper::Auth]

# 註冊認證方式,我使用了fileIPAuth,就是直接根據IP地址來限定是否能註冊。因為終端比較少。
FileIPAuth=required;GRQ,RRQ,LRQ,Setup

; Put only allowed IPs, the rest will be rejected by the "required" rule specifier
[FileIPAuth]

# 這裏設置允許註冊的IP地址
#10.0.0.15=allow
any=reject

# 配置記錄CDR 通話詳情記錄到/var/log/gnugkcdr.log,每天23:59 rotate

[Gatekeeper::Acct]
FileAcct=required
[FileAcct]
DetailFile=/var/log/gnugkcdr.log
Rotate=daily
RotateTime=23:59

Polycom 設置:

需要配置h323網閘,polycom 防火墻和nat 都不需要配置了。

技術分享

技術分享

檢測視頻終端註冊狀態:

  • 在gnugk (網閘gatekeeper)本地telnet 127.0.0.1 7000,輸入rv ,查看已經註冊成功的終端,我這裏顯示有兩個終端註冊上來了。當然你可以通過tail –f /var/log/gnugk.log 看更詳細的

技術分享

外部資源

公共的可測試站點及賬號

用於測試的資源非常少,但是找到了這個lifesize的站點,有15天免費測試賬號,也有公開的測試賬號,放出來方便大家測試

Video only:

[email protected] [Demo - Austin Skyline]

[email protected] [Demo - Austin Skyline 2]

[email protected] [Demo - Dancing Fountains]

[email protected] [Demo - Fish Tank 1]

[email protected] [Demo - Fish Tank 2]

[email protected] [Demo - Fish Tank 3]

[email protected] [Demo - Fish Tank 4]

[email protected] [Demo - Gear Clock 1]

[email protected] [Demo - Gear Clock 2]

[email protected] [Demo - Sydney Harbour]

Video + Audio:

[email protected] [Demo - Video w/ Audio 1]

[email protected]sizecloud.com [Demo - Video w/ Audio 2]

[email protected] [Demo - Video w/ Audio 3]

[email protected] [Demo - Video w/ Audio 4]

公共的可用的STUN服務器

STUN 服務器

用來讓客戶端探測自己的NAT類型,及NAT 的公網IP和端口。

List of 263 public STUN servers from EmerCoin project: http://olegh.ftp.sh/public-stun.txt.

gnugk 排錯一例

使用gnugk 對外進行呼叫時發現連接對方5分鐘(300s) 後會自動斷開,由於之前測試一直都是使用lifesize 進行的測試,但並沒有發現這個問題。所以這個問題有點棘手。gnugk的log記錄的關於這個斷開的信息很簡單,就是yasocket.cxx(918) Q931d xxx.xxx.xxx.xx:1720 Error(0) Input/output Error(12:104)

  1. 第一這個肯定和防火墻或者網絡絕對有關系,因為300秒太有規律了。

  2. 第二懷疑是遠端防火墻導致了該問題。所以當時做了兩個測試,拿我方連接lifesize(沒有斷開問題),拿lifesize 連對方(也沒有斷開問題)

  3. 這個時候有點無法判斷是哪方問題。但懷疑lifesize的可能在公網上,可能沒有nat問題。這個應該還是nat 穿越或者防火墻問題,無奈只有抓包對比吧。正常情況抓一個,不正常的抓一個

  4. 對比發現了倪端。對方的地址發了一個RST的包過來,這個時間和視頻會議的斷開時間一致。但是為什麽會300s後發過來?

技術分享

進一步發現了問題,對方IP地址在和我方建立了會議之後,也就是下面圖中382數據包之後,到165543 數據包之間差不多正好300s, 165543 數據包是RST數據包,這個問題很明了了,就是會議建立後由於和對方IP交互少於300秒,對方防火墻認為你已經不再連了,所以斷開了。但是會議依舊是開的,而且有音視頻在傳輸,但為什麽沒有用對方IP進行傳輸,這裏有點奇怪,應該還是和nat或者proxy 有關。

技術分享

參考查找gnugk proxy 和routed 模式裏的各個參數及意思。改一個測試一下。終於找到這個。問題解決。

H245TunnelingTranslation=1
Default: 0

Allow one side of a call to use H.245 tunneling even if the other side does not, with the gatekeeper performing the appropriate H.245 message conversion. This will reduce the number of ports required on the tunneling side of the connection.

GNUGK 作為Gatekeeper穿透防火墻和NAT