[asterisk-users] IAX2 over OpenVPN connection.... working but
Dave Platt
dplatt at radagast.org
Mon Dec 10 12:26:32 CST 2012
>> Here's where I am baffled and I am hoping someone with intricate
>> knowledge of this implementation may be able to explain it to me. What
>> we had to do to get this working was to set the host= parameter to the
>> respective endpoint IP's of the VPN tunnel, 172.10.1.1 in my case, and
>> 172.10.1.2 in his case. Calls flow normally now and we cannot understand
>> how or why. I would have assumed with a destination of either LAN as
>> defined by the routing table it would have left out on the OpenVPN
>> connection by default, and what's even more strange is that IAX is the
>> only protocol that does not appear to function as intended.
> My guess is asterisk is replying using the tunnel ip address which your original box won't accept unless you actually sent to that address. Thats what I see on our remote openvpn tunnels. If you want to know whats going on use tcpdump to check packets through the tunnel.
Yes, I've seen this same problem. It has two possible solutions.
The reason for the problem is this: IAX2 (the Asterisk
implementation, at least) depends on the "source" address in the
UDP packet it receives, to know which connection the packet
is part of. When it talks to a peer, it expects to see the
packets arrive from the peer with a source address which
matches what it understands the peer's address to be. Packets
arriving from "unknown" addresses, are simply dropped on the
floor (considered to be misrouted, misconfigured, or forged,
I think).
Normally, the Asterisk IAX2 implementation does not
bind itself to a single network interface. It will
receive UDP packets to the IAX2 port, arriving from
any interface.
And, when it sends an IAX2 UDP packet, it simply sends
it out through the socket which is bound to the
"any interface" port.
Because the socket isn't bound to a specific interface,
it doesn't have a specific IP address associated with it.
The Linux kernel chooses an IP address to put into the
UDP packet "source" field, and the one it chooses is the
IP address of the interface on which it is transmitting
the packet.
In the scenario that's being described here, an address
result mismatches. Each system is transmitting UDP packets
*to* the "primary" or "official" or "public" interface on
its peer... and these packets are being transmitted by
the Linux kernel on the OpenVPN interface, and are being
given the system's OpenVPN tunnel endpoint address. In each
case, when the packet arrives at the peer, the Asterisk IAX2
stack receives the packets, finds that it has no known peer
at the tunnel IP address and no IAX2 session set up for this
address, and discards the packet.
There are, I believe, two solutions which don't involve
modifying the IAX2 code in Asterisk. Both work equally
well, as far as I know.
One approach is the one you've taken - tell each system to
"talk to" its peer's OpenVPN tunnel endpoint address, rather
than to the "primary" address. This eliminates the IP address
mismatch. This approach works fine if both systems are connected
only via this OpenVPN tunnel, and always have the same OpenVPN
addresses.
The other approach is to configure each system to bind its
IAX2 port *only* to one IP interface (usually the public one),
to ensure that each peer knows how to reach its peer's
public IP address (either directly, or via a route though the
OpenVPN tunnel), and to tell each system to speak IAX2 to its
peer's public IP address.
In this case, since the Asterisk socket is bound to a specific
interface, all packets sent through that socket will have
the bound interface's IP address in its "source" field, and
(once again) the address mismatch is eliminated.
This second approach is preferable for "road warrior"
configurations in which you might sometimes be using the
OpenVPN tunnel, and sometimes not (e.g. a laptop or tablet
IAX2 client which is sometimes on the corporate LAN and
sometimes out on the Internet using OpenVPN).
More information about the asterisk-users
mailing list