Linking JNOS to BPQ32

From Ohio Packet
Revision as of 16:41, 18 December 2010 by Opadmin (talk | contribs)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

Creating AXUDP links between JNOS2 and BPQ32 systems can sometimes be problematic. There are some things to keep in mind when trying to troubleshoot broken connections.


The problem

The root cause of this issue is that JNOS2 requires the source and destination ports of an AXUDP link to exactly match what is defined within the attach statement. If the attach line looks like this:

attach axudp 1024 remote.bpq32.system.address callsign-ssid 10093 10093

The JNOS2 system will only accept AXUDP traffic originating from the IP address as defined in remote.bpq32.system.address (be it an IPv4 address or resolved hostname) that the traffic has a source port of 10093.

Cause 1

In BPQ32 versions prior to 4.10.16.8, if the remote BPQ32 system has more than one UDP port defined in it's BPQ32.cfg/BPQAXIP.cfg, the first defined port will be used for all return UDP traffic by default. This means in the above example, if the remote host has:

UDP 10091
UDP 10093

The AXUDP conversation will look like this:

JNOS:10093 -> RemoteBPQ32:10093
RemoteBPQ32:10091 -> JNOS:10093 (note the source port is 10091 and not 10093)
JNOS -> RemoteBPQ32 ICMP Port Unreachable

Resulting in a failed AXUDP link.

As of BPQ32 version 4.10.16.8, the default behavior is to match the destination port with the source port. If there is still a port mismatch, it is now possible to define a source port on a per map basis. If for some reason the BPQ32 side had to source from 10094 and the JNOS side was 10093, the updating mapping would look like this:

MAP callsign-ssid remote.jnos.system.address UDP 10093 SOURCEPORT 10094

Cause 2

If the remote BPQ32 system only has one UDP port defined in it's BPQ32.cfg/BPQAXIP.cfg, this usually will just work. The exception to this rule is when they BPQ32 system is sitting behind a connection sharing device which mangles (changes) the source port of the AXUDP packet on it's way out to the Internet. If this is the case, changes to the connection sharing system may be required. If these are BSD (pf) or Linux (iptables) based, it is possible to create rules to force the outbound traffic to retain it's source port.

For BSD, inject the following into the appropriate section of /etc/pf.conf

nat on $ext_if proto udp from $bpq32_computer to any port 10093 -> ($ext_if:0) port 10093

For Linux, insert the following rule where the POSTROUTING chain of the nat table is defined

iptables -t nat -A POSTROUTING -o $EXT_IF --sport 10093 -d 0/0 -j SNAT --to-source $EXT_ADDR:10093

In both cases, this will force the source port to be preserved while being passed via network address translation (NAT).

A Workaround (JNOS side)

If you are the sysop of the JNOS system and you do not have control of the remote BPQ32 instance, it is possible to leverage netfilter to "trick" JNOS2 into believing the source port matches what is defined in the attach line. We will assume our remote BPQ32 peer is responding on 10091 and JNOS is expecting it to come from 10093. This rule will switch the source port from 10091 after being forwarded through the IP stack on the Linux host computer:

/sbin/iptables -t nat -A POSTROUTING -o sl0 -p udp -s $BPQ32_PEER_IP --sport 10091 -d $JNOS --dport 10093 -j SNAT --to-source $BPQ32_PEER_IP:10093

The main challenge with this approach is that there is not an easy way to update the BPQ32_PEER_IP of the remote system. If their address is static, this is not an issue. If their address is dynamic, some other means to look up the address and update is needed. It is possible to wrap a shell command at the beginning of a firewall script (assuming you're using a command interpreter such as !/bin/bash or !/bin/sh). For the above statement, the line would look like this:

BPQ32_PEER_IP=$(host remote.bpq32.system.address | grep 'has address' | awk '{print $4}')

The output from the "host" command may vary depending on the Linux distribution. The above works on Ubuntu 8.04. If you are unsure about your distribution, you can execute everything between $( and ) at a shell to verify it's output. If all goes well, you should be given just an IP address.

$ host foo.com | grep 'has address' | awk '{print $4}'
64.94.125.138

If you get an error or unexpected value, remove the awk portion and count the placement of the IP address. Replace the numeric value (4 in the example) with the appropriate number of the IP address.

The only thing left to do now is to periodically check for updates to the IP address. Depending on the connection type and DNS time to live (TTL), it may make sense to check on a fairly regular basis. In this instance, we will say we want to check every 10 minutes and our iptables (firewall) script lives in /etc/init.d/firewall.

We will add this to root's crontab by executing as root (or via sudo)

crontab -e

Paste in the following lines:

*/10 * * * * /etc/init.d/firewall restart 2>&1

This will automatically execute a "restart" of the script, each time calling "host" to do a DNS lookup.

Please keep in mind this workaround is only treating the symptom (port mismatch), not the problem (misconfiguration on remote side).

Further Reading

There were several technologies used to diagnose and correct the above issue. If you want to see the traffic in action and understand the solutions, please find additional resources.

Linux Netfilter (iptables)

Netfilter is the name given to the ip filtering code built on top of the Linux kernel. The current implementation is called iptables and is capable of a wide variety of uses. You can find documentation on iptables here:

http://www.netfilter.org/documentation/index.html#documentation-howto

tcpdump

The tcpdump utility allows a system operator to watch raw packets as they traverse to/from or through a given systems IP stack. Using this, it was possible to "see" the failing AXUDP sessions, getting an understanding for what was wrong and eventually applying the correct workaround or fix. The tcpdump utility generally exists on Linux/BSD systems, but versions for Windows may be available. You can find more information on tcpdump here:

http://www.tcpdump.org/#documentation

Wireshark

A graphical alternative to tcpdump is Wireshark. It too is capable of packet capture, and allows capture/saving/review of traffic. Versions for both Windows and Linux are available. You can find more information on Wireshark here:

http://www.wireshark.org/


If there are any other questions or concerns, please feel free to email us[1].