Replacing JNOS with Linux

From Ohio Packet

Revision as of 20:49, 20 March 2013 by Opadmin (Talk | contribs)

When we think about packet radio and TCP/IP, most of us think of JNOS. The efforts of all current and past developers has given us a "swiss army knife" of packet programs. No other software package comes close to providing as many services as JNOS. The cost of offering so many options is the ability to have feature rich components. While no component of JNOS is bad, the prospect of being able choose what flavor of services can be an attractive one. This article is intended to a somewhat seasoned Linux veteran. It assumes you are capable of setting up LinuxNode and any other network daemons such as Postfix (SMTP), Apache (HTTP), etc. As time permits, we will try to add additional setup steps.

Out of the box, LinuxNode can support AXIP and AXUDP connections, support KISS type TNCs and can even be setup to accept telnet sessions (with help if (x)inetd). The other component of JNOS which is used heavily in our installations is the ability to encapsulate AMPRNet (44.x.x.x) traffic into normal IP frames. This is often used to bridge "pockets" of AMPRNet traffic across Internet links. Fortunately, Linux can natively handle this as well, but the documentation and examples we found seemed confusing. With a bit of research and some trial and error, we discovered that what takes one line in JNOS, takes 3 lines in Linux.

For those of you who subscribe to the AMPRNet robot provided by http://www.ampr-gateways.org, you are probably receiving encap.txt files in the format of

route addprivate 44.x.x.x/nn encap internet.ip.of.gateway

JNOS can happily accept this syntax, but Linux needs it to be broken apart into 3 steps.

# This creates the interface with the destination gateway. Only one of these is needed per gateway

ip tunnel add <interfacename> mode ipip remote internet.ip.of.gateway local local.ip.of.linux

# This sets the IP address on the interface. We've used the AMPRNet address. We will use 44.128.0.1 for this example.

ifconfig <interfacename> 44.128.0.1 netmask 255.255.255.255

# Lastly, we must create a route to the target AMPRNet host or network via the newly created interface (which implies the gateway). We will use 44.128.1.0/24 for this example.

route add 44.128.1.0/24 dev <interfacename>

The union of these 3 commands will produce the same IPIP encapsulation that JNOS uses. The next hurdle is how to convert the encap.txt to a format that will work within Linux. One solution is the following bash script. It will

1) Read the native formatted encap.txt and translate it into the Linux command set
2) Create a tunnel interface per remote gateway (starts with ampr0 and adds additional per gateway) The limit of interface is not limited to 255, in our testing we've had 512 without any trouble.
3) Replace empty octets of the target IP address with zeros (required by route command)
4) Perform sanity checking for incorrect network addresses (some entries in encap.txt don't have the correct network address for a given subnet, if fed directly, the Linux route command will fail).
5) Remove any preexisting tunnels (if you kernel has the ipip compiled in a module)
6) It will error out if it encounters any issue with any command. This is useful to ensure everything is running before it gets added to crontab.



#!/bin/bash
IPIPLOAD=$(lsmod | grep -c ipip)
if [ ${IPIPLOAD} != "0" ];
then
rmmod ipip
fi
modprobe ipip
ENCAP=encap.txt
LOCALENCAP=$(/sbin/ifconfig eth0)
LOCALAMPR=44.128.0.1
ENCAPGW=$(cat $ENCAP | grep -v '#' | awk '{print $5}' | sort | uniq)
for gw in $ENCAPGW
do

AMPRIFCHK=$(/sbin/ifconfig eth0 | grep 'inet addr:' | awk '{print $2}' | awk -F ':' '{print $2}')
# This will assign the next available interface, we're calling these amprN
if [ ${AMPRIFCHK} = "0" ]
then
DEVICE=ampr0
else
DEVNUMBER=$(expr $(/sbin/ifconfig | grep ampr | awk '{print $1}' | tail -n 1 | sed s/'ampr'//g) + 1)
DEVICE=ampr${DEVNUMBER}
fi

iptunnel add $DEVICE mode ipip remote $gw local $LOCALENCAP
RETVAL=$?
if [ ${RETVAL} != "0" ];
then
exit 1
fi
ifconfig $DEVICE $LOCALAMPR netmask 255.255.255.255

RETVAL=$?
if [ ${RETVAL} != "0" ];
then
exit 1
fi

for net in $(cat $ENCAP | grep $gw | awk '{print $3}')
do

# We need to omit -net to route when it is a host record (CIDR = 32)
# If no CIDR is specified, host is assumed, set CIDR to 32

CIDR=$(echo $net | awk -F '/' '{print $2}')
if [ -z $CIDR ];
then
CIDR=32
fi

# We need a host route
if [ ${CIDR} = "32" ]
then
route add $net dev $DEVICE

RETVAL=$?
if [ ${RETVAL} != "0" ];
then
exit 1
fi

else
# We need a network route
OCTET1=$(echo $net | awk -F '.' '{print $1}' | awk -F '/' '{print $1}')
OCTET2=$(echo $net | awk -F '.' '{print $2}' | awk -F '/' '{print $1}')
OCTET3=$(echo $net | awk -F '.' '{print $3}' | awk -F '/' '{print $1}')
OCTET4=$(echo $net | awk -F '.' '{print $4}' | awk -F '/' '{print $1}')

# Check to see if octets are empty, if they are, insert 0
if [ -z $OCTET1 ];
then
OCTET1=0
fi

if [ -z $OCTET2 ];
then
OCTET2=0
fi

if [ -z $OCTET3 ];
then
OCTET3=0
fi

if [ -z $OCTET4 ];
then
OCTET4=0
fi

net="${OCTET1}.${OCTET2}.${OCTET3}.${OCTET4}/${CIDR}"

# In some cases, the target network has an incorrect network number
# This causes the route addition to fail.
#
# Fortunately, ipcalc can handle the calculation of the correct network
# Just to be safe, we will pass all networks through ipcalc to verify
# their accuracy.
#
NETSCRUB=$net

net=$(ipcalc --nocolor $NETSCRUB | grep Network | awk '{print $2}')

route add -net $net dev $DEVICE

RETVAL=$?
if [ ${RETVAL} != "0" ];
then
exit 1
fi

fi

echo "Adding route to $net via $gw on $DEVICE"

done
done



The end result is an output of routes, their gateways and device names

Adding route to 44.x.x.x/32 via <internet.ip.of.gateway147> on ampr147
Adding route to 44.x.x.y/32 via <internet.ip.of.gateway148> on ampr148
Adding route to 44.x.x.z/32 via <internet.ip.of.gateway149> on ampr149

It is recommended that the system run iptables with sensible rules to restrict access to certain services. We will try to add this information as time permits.

Please contact us with any questions or comments