Tuesday, January 19, 2021

H.323: IPv4 to IPv6 migration

Many networks are migrating from IPv4 to IPv6. What can you do if still have H.323 endpoints that only support IPv4 ?

The GNU Gatekeeper can translate IPv4 into IPv6 calls and vice versa.
You can use one GnuGk to IPv6 enable all of your existing IPv4 endpoints.


 


 

All you have to do is enable IPv6 in your configuration and GnuGk will automatically
detect the connection type of your endpoints and convert the call.

All it takes is one switch in your config:

[Gatekeeper::Main]
EnableIPv6=1 
 

Wednesday, January 13, 2021

Using the GNU Gatekeeper to create TLS tunnels

Most H.323 vendors did not implement encrypting the signaling connection with TLS. They only encrypt the media (RTP). But you can use the two GNU Gatekeepers to encrypt you call signaling even when your endpoints don't support this natively.

Suppose you have 2 locations and want to connect them securely over the public internet.

GnuGk can encrypt call signalling between those locations using TLS and encrypt the media (RTP) using H.235.6 (AES encryption). 


 Configuration for GNU Gatekeeper 1 (prefix 01)

 

[Gatekeeper::Main]

[RoutedMode]
GKRouted=1
H245Routed=1
CallSignalPort=1720
AcceptUnregisteredCalls=1
; make sure H.245 gets tunneled for TLS
H245TunnelingTranslation=1
; add AES media encryption if the endpoint doesn't encrypt itself
EnableH235HalfCallMedia=1
; only allow encrypted calls
RequireH235HalfCallMedia=1
; change the media key after 2^31 operations
EnableH235HalfCallMediaKeyUpdates=1

[Proxy]
Enable=1

[ModeSelection]
0.0.0.0/0=PROXY
; only use routed mode for local calls
192.168.0.0/18=H245ROUTED

[TLS]
EnableTLS=1
PrivateKey=/path/to/server.pem
Certificates=/path/to/server.pem
CAFile=/path/to/rootcert.pem
Passphrase=MySecret
CheckCertificateIP=1

[Gatekeeper::Auth]
FileIPAuth=required;Setup

[FileIPAuth]
; allow all calls from local network
192.168.1.0/24=allow
; only allow TLS encrypted and authenticated calls from elsewhere
any=onlyTLS

[RasSrv::PermanentEndpoints]
; the GnuGk in the other location, serving prefix 02
1.2.3.4:1300=remote-gw;02

[EP::remote-gw]
; use TLS to call remote GnuGk
UseTLS=1 
 

Configuration for GNU Gatekeeper 2 (prefix 02)

[Gatekeeper::Main]

[RoutedMode]
GKRouted=1
H245Routed=1
CallSignalPort=1720
AcceptUnregisteredCalls=1
; make sure H.245 gets tunneled for TLS
H245TunnelingTranslation=1
; add AES media encryption if the endpoint doesn't encrypt itself
EnableH235HalfCallMedia=1
; only allow encrypted calls
RequireH235HalfCallMedia=1
; change the media key after 2^31 operations
EnableH235HalfCallMediaKeyUpdates=1

[Proxy]
Enable=1

[ModeSelection]
0.0.0.0/0=PROXY
; only use routed mode for local calls
192.168.0.0/18=H245ROUTED

[TLS]
EnableTLS=1
PrivateKey=/path/to/server.pem
Certificates=/path/to/server.pem
CAFile=/path/to/rootcert.pem
Passphrase=MySecret
CheckCertificateIP=1

[Gatekeeper::Auth]
FileIPAuth=required;Setup

[FileIPAuth]
; allow all calls from local network
192.168.1.0/24=allow
; only allow TLS encrypted and authenticated calls from elsewhere
any=onlyTLS

[RasSrv::PermanentEndpoints]
; the GnuGk in the other location, serving prefix 01
1.2.3.5:1300=remote-gw;01

[EP::remote-gw]
; use TLS to call remote GnuGk
UseTLS=1 
 

Other options

You could also configure the remote GNU Gatekeeper as a neighbor, but beware that the RAS traffic between neighbors will show meta data (whois is caling who) in clear text! 

See the GnuGk manual section on TLS for more details and examples how to generate the OpenSSL certificates. 

 

Friday, January 8, 2021

Using TCP Keepalive to Detect Network Errors

This is not only a H.323 topic, but since H.323 also uses TCP connections, it applies to H.323 as well:

To detect network errors and signaling connection problems, you can enable TCP keep alive feature. It will increase signaling bandwidth used, but as bandwidth utilized by signaling channels is low from its nature, the increase should not be significant. Moreover, you can control it using keep alive timeout.

The problem is that most system use keep alive timeout of 7200 seconds, which means the system is notified about a dead connection after 2 hours. You probably want this time to be shorter, like one minute or so. On each operating system, the adjustment is done in a different way.

After settings all parameters, it's recommended to check whether the feature works correctly - just make a test call and unplug a network cable at either side of the call. Then see if the call terminates after the configured timeout.

Linux systems

Use sysctl -A to get a list of available kernel variables
and grep this list for net.ipv4 settings (sysctl -A | grep net.ipv4).
There should exist the following variables:
net.ipv4.tcp_keepalive_time:   time of connection inactivity after which
                               the first keep alive request is sent
net.ipv4.tcp_keepalive_probes: number of keep alive requests retransmitted
                               before the connection is considered broken
net.ipv4.tcp_keepalive_intvl:  time interval between keep alive probes

You can manipulate with these settings using the following command:

sysctl -w net.ipv4.tcp_keepalive_time=60 net.ipv4.tcp_keepalive_probes=3 \
    net.ipv4.tcp_keepalive_intvl=10

This sample command changes TCP keepalive timeout to 60 seconds with 3 probes,
10 seconds gap between each. With this, your application will detect dead TCP
connections after 90 seconds (60 + 10 + 10 + 10).

FreeBSD and MacOS X

For the list of available TCP settings (FreeBSD 4.8 an up and 5.4):

sysctl -A | grep net.inet.tcp

net.inet.tcp.keepidle - Amount of time, in milliseconds, that the (TCP) 
connection must be idle before keepalive probes (if enabled) are sent.

net.inet.tcp.keepintvl - The interval, in milliseconds, between 
keepalive probes sent to remote machines. After TCPTV_KEEPCNT (default 
8) probes are sent, with no response, the (TCP)connection is dropped.

net.inet.tcp.always_keepalive - Assume that SO_KEEPALIVE is set on all 
TCP connections, the kernel will periodically send a packet to the 
remote host to verify the connection is still up.

therefore formula to calculate maximum TCP inactive connection time is 
following:

net.inet.tcp.keepidle + (net.inet.tcp.keepintvl x 8)

the result is in milliseconds.

therefore, by setting
net.inet.tcp.keepidle = 10000
net.inet.tcp.keepintvl = 5000
net.inet.tcp.always_keepalive =1 (must be 1 always)

the system will disconnect a call when TCP connection is dead for:
10000 + (5000 x 8) = 50000 msec (50 sec)

To make system remember these settings at startup, you should add them 
to /etc/sysctl.conf file

Solaris

For the list of available TCP settings:

ndd /dev/tcp \?

Keepalive related variables:
- tcp_keepalive_interval - idle timeout

Example:
ndd -set /dev/tcp tcp_keepalive_interval 60000

Windows 2000 and Windows NT

Search Knowledge Base for article ID 120642:
http://support.microsoft.com/kb/120642/EN-US

Basically, you need to tweak some registry entries under
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters