Linksys/Cisco SPA3102 with Freepbx & BT

This guide works great, with the one amendment; PJSIP Registration should be set to “none”.

https://frag.co.uk/2017/08/14/cisco-spa-3102-freepbx-uk-caller-id/

Critical config info is as follows:

SPA-3102 Configuration

Admin login > Advanced > Voice > PSTN Line:

  • Line Enable: Yes
  • SIP Transport: UDP
  • SIP Port: 5060
  • SIP Remote-Party-ID: Yes
  • Auth Invite: Yes
  • Proxy: [set to FreePBX IP]
  • Register: No
  • User ID: pstn_fxo
  • Auth ID: pstn_fxo
  • Use Auth ID: Yes
  • Password: password
  • Line 1 VoIP Caller DP: None
  • PSTN Caller Default DP: 1
  • Dial Plan 1: (S0<:pstn_fxo@192.168.0.181>)
    Including brackets – and where 192.168.0.181 is your FreePBX IP

FreePBX Configuration

Create a new PJSIP Trunk

  • Trunk Name: <My DID>
  • Outbound Caller ID: <My DID>
  • Maximum Channels: 1
  • Username:  <My DID>
  • Password: password
  • Authentication: Outbound
  • Registration: Send
  • SIP Server: [set to IP address of SPA-3102]
  • SIP Server Port: 5060
  • Context: from-pstn
  • Contact User:  <My DID>  (thanks to Aly)

Inbound Route

  • Set up a default route with Destination as a Ring Group

Outbound Route

  • Route Name: POTS Outgoing
  • Route CID: <My DID>
  • Trunk Sequence for Matched Routes:  <My DID>

Asterisk Remove Sipgate Alphanumeric ID Extension

Sipgate provide SIP account numbers with alphanumeric sub-accounts. The sub-account extension needs to be removed in order for FreePBX to generate the trunks inbound route.

The following has been added to extensions_custom.conf

[from-trunk-sipgate]
exten => _.,1,Noop(Remove Sipgate Extra Digits)
exten => _.,n,Goto(from-trunk,${EXTEN:0:7},1)

and the following added to the trunks PEER Details

context=from-trunk-sipgate

Ping Watchdog for Strongswan

#!/bin/bash
HOST=$1 ##Host IP at endpoint to test
ConnName=$2 ##StrongSwan connection name to call
OfflineCount=1
while [ $OfflineCount -gt 0 ]
do
echo loop $OfflineCount
ping=$(ping -c 1 -w 2 $HOST | grep bytes | wc -l)
if [[ $ping -gt 1 ]];then
echo "HOST ONLINE"
logger "[vpnwatchdog] host $HOST online"
OfflineCount=0
exit
else
echo "HOST OFFLINE"
let OfflineCount++
sleep 1
fi
if [[ $OfflineCount -gt 9 ]];then
logger "[vpnwatchdog] host $HOST timeout reached. Restarting VPN..."
echo "OFFLINE LIMIT REACHED"
sudo strongswan down $ConnName
sudo strongswan up $ConnName
exit
fi
done

Centos Comms PC for Home

After some pontification on how I want to setup the network in my new house, I’ve decided I need to have a dedicated comms PC in order to manage the various new and existing VPN connections between existing networks.

I’ve successfully been using Centos 7 for development at work, so have decided to use this OS for the new comms PC.

The comms PC has three proposed functions:

  • Act as an internet gateway for traffic on my private wireless/wired network (192.168.11.0).
  • Act as a gateway for traffic going to the existing subnets at the old house (192.168.0.0 & 192.168.1.0).
  • Act as a server for encrypted traffic from clients dialling-in

 

Within the bigger picture, the new network will also need to serve a wifi network for the other tenants on the 192.168.10.0 subnet, which needs to be kept reasonably secure and separate from the VPN data on the 192.168.11.0 subnet.

Part 1: setting-up the comms PC to act as a NAT gateway between the two networks.

For this I’m using a wireless card to access the tenants wifi (192.168.10.0) and an integrated ethernet NIC to connect to the Switch/Wireless Access Point for my private network (192.168.11.0). The first set of instructions which proved vaguely helpful were here

This was helpful with setting up the network port configuration, Gateway configuration, DNS configuration, and DHCP server setup. Further explanation of the dhcpd service is here.

ifcfg-enp2s0-2

HWADDR=F4:CE:46:04:7F:CF
TYPE=Ethernet
PROXY_METHOD=none
BROWSER_ONLY=no
BOOTPROTO=none
IPADDR=192.168.11.254
PREFIX=24
DEFROUTE=yes
IPV4_FAILURE_FATAL=no
IPV4_DNS_PRIORITY=100
IPV6INIT=no
NAME=enp2s0
UUID=3bbaec33-4a8f-4899-b916-37e2ed9d9716
DEVICE=enp2s0
ONBOOT=no
ZONE=internal

ifcfg-my wifi ssid

HWADDR=7C:8B:CA:12:E4:C5
ESSID=my wifi ssid
MODE=Managed
KEY_MGMT=WPA-PSK
SECURITYMODE=open
MAC_ADDRESS_RANDOMIZATION=default
TYPE=Wireless
PROXY_METHOD=none
BROWSER_ONLY=no
BOOTPROTO=static
IPADDR=192.168.10.250
BROADCAST=192.168.10.255
NETMASK=255.255.255.0
NETWORK=192.168.10.0
GATEWAY=192.168.10.1
DNS1=8.8.8.8
DNS2=8.8.4.4
ONBOOT=yes
DEFROUTE=yes
IPV4_FAILURE_FATAL=no
IPV6INIT=no
NAME=my wifi ssid
UUID=ed58ce63-1e07-41f2-99ff-e92178939810
USERCTL=no
PREFIX=24
ZONE=external

/etc/dhcp/dhcpd.conf

option domain-name-servers 8.8.8.8, 8.8.4.4;
default-lease-time 600;
max-lease-time 7200;
ddns-update-style interim;
authoritative;
subnet 192.168.11.0 netmask 255.255.255.0 {
range 192.168.11.10 192.168.11.90;
option broadcast-address 192.168.11.255;
option routers 192.168.11.254;
}

Unfortunately the instructions are slightly outdated, as CENTOS 7 uses the firewalld service, not iptables for firewalling the interfaces.

Redbranch.net have an article here, explaining pretty much what I needed to do to configure firewalld.

Static routing then needed a bit of work at this point. “sudo route -n” revealed that there were two default gateway routes, one for each interface, however the wired interface does not have access to the internet. Further, the metric of the wired interface was giving priority to internet traffic via this (dead) route – I assume its some kind of default in CENTOS to give wired adapters a higher metric than wireless adapters (makes sense under usual circumstances). More info about static routing here.

sudo route del -net 0.0.0.0 gw 192.168.10.1 netmask 0.0.0.0 dev enp2s0

Annoyingly, at around this point the PC hung, and needed a reboot. This uncovered further issues:

  • dhcpd may not be set to automatically start on reboot – guide here to adjust that.
  • Changes to static routes are not persistent. I had to generate the following to make the changes persist:

/etc/sysconfig/network-scripts/route-wlp3s0

default 192.168.10.1 dev wlp3s0

Once these were resolved, I was able to identify the following issues with my configuration.

  • The internally facing interface (192.168.11.254) must not have a gateway address in its /etc/sysconfig/network-scripts/ifcfg-NIC file.
  • The DHCP server config,  /etc/dhcp/dhcpd.conf must list the internal network interface IP (192.168.11.254) as the network gateway (Something somewhere made me think the tenants WiFi gateway (192.168.10.1) should be used).

At this point I could now access the internet on the basement desktop PC, and the basement IP phone should now be able to register.

Part 2: Establishing PPTP connectivity back to the existing network.

Why PPTP?

Good question! I’m choosing to use this compromised protocol because the main router (Provided by ISP Talktalk) on the existing network does not allow forwarding of all the needed TCP ports in order to use L2TP. This is very frustrating, as the comms PC I’m building otherwise wouldn’t need to have the L2TP server (mentioned later) if the main network could host one.

The guide found here pretty much covers everything. To my shock at the end of the guide the following GUI on my windows server indicated that the PPTP route was open.

 

Ok, so now the new virtual interface ppp0 is connected I’m going to need to do some more static routing stuff. Interface ppp9 has IP 192.168.0.41 and the remote server has virtual IP 192.168.0.50. The remote (main) network has subnets in the 192.168.0.0 and 192.168.1.0 ranges)

route add-net 192.168.0.0 gw 192.168.0.50 netmask 255.255.255.0 dev ppp0

route add-net 192.168.1.0 gw 192.168.0.50 netmask 255.255.255.0 dev ppp0

However, these changes will not persist if I reboot. This is where the ip-up and ip-up.local files come in.

 

/etc/ppp

#!/bin/bash
# This file should not be modified -- make local changes to
# /etc/ppp/ip-up.local instead

PATH=/sbin:/usr/sbin:/bin:/usr/bin
export PATH

LOGDEVICE=$6
REALDEVICE=$1

[ -f /etc/sysconfig/network-scripts/ifcfg-${LOGDEVICE} ] && /etc/sysconfig/network-scripts/ifup-post --realdevice ${REALDEVICE} ifcfg-${LOGDEVICE}

/etc/ppp/ip-up.ipv6to4 ${LOGDEVICE}

[ -x /etc/ppp/ip-up.local ] && /etc/ppp/ip-up.local "$@"

exit 0

/etc/ppp/ip-up.local

#!/bin/bash
case "$5" in
192.168.0.50)
/sbin/route add -net 192.168.0.0/24 gw 192.168.0.41
/sbin/route add -net 192.168.1.0/24 gw 192.168.0.41
;;
esac
exit 0

ip-up is run after each call to pppd, ip-up in turn then calls ip-up.local which should contain the local variables. ip-up.local uses the case syntax in order to establish which routes to add based upon the parameters which are handed to it from the ip-up script.

At this point I decided that an icon on my desktop may be handy for establishing the vpn connection manually. A desktop object starts the following script in persistent mode.

/var/Auto-FE_PPTP.sh persist

#!/bin/bash
modprobe nf_conntrack_pptp
IFACE=$(/sbin/ip a show wlp3s0 up)
PPP9=$(/sbin/ip a show ppp9 up 2>&1)
ROUTE=$(ping -c 2 -w 2 HOST_PPTP_SERVER)
case $PPP9 in
*'UP'*)
echo -e "Virtual Interface \e[31mBusy\e[0m"
if [[ $1 == "persist" ]]; then
read -p "Press enter to continue"
fi
exit 1
;;
*'does not exist.'*)
echo -e "Virtual interface \e[32mready!\e[0m"
;;
*)
echo -e "Virtual interface \e[31mfault\e[0m"
if [[ $1 == "persist" ]]; then
read -p "Press enter to continue"
fi
exit 1
esac

if [[ $IFACE == *"192.168.10.250/24"* ]]; then
echo -e "Outbound interface \e[32mready!\e[0m"
else
echo -e "\e[31mNo Connection....\e[0m Trying again in 5 Seconds"
sleep 5
exec "/var/Auto-FE_PPTP.sh"
fi

case $ROUTE in
*"2 received,"*)
echo -e "Path to host \e[32mready!\e[0m"
;;
*)
echo -e "Path to host \e[31mfault\e[0m"
if [[ $1 == "persist" ]]; then
read -p "Press enter to continue"
else
echo -e "\e[31mNo Connection....\e[0m Trying again in 5 Seconds"
sleep 5
exec "/var/Auto-FE_PPTP.sh"
fi
exit 1
esac

echo "Starting VPN connection to HOST"
$(sudo /sbin/pppd call FE_PPTP)
unset PPP9
PPP9=$(/sbin/ip a show ppp9 up 2>&1)
declare -i TIMEOUT

while [[ $PPP9 != *"192.168.0.41"* && $TIMEOUT < 5 ]]; do
printf "connecting...\n"
sleep 2
let "TIMEOUT++"
unset PPP9
PPP9=$(/sbin/ip a show ppp9 up)
done

if [[ $PPP9 == *"192.168.0.41"* ]]; then
echo -e "\e[32mconnected!\e[0m"
else
echo -e "Timeout error occurred"
fi

if [[ $1 == "persist" ]]; then
read -p "Press enter to continue"
fi

exit 0

The Auto-FE_PPTP.sh script now needs to be run at startup. the following guide explains how to do that here.