lunedì 18 novembre 2019

SvxLink Echolink behind natted provider


Hosting a service on your server at home can be a big problem if you have (like me) a dsl/fiber connection with a provider that NAT his network, like Fastweb,TIM and Vodafone in Italy.
You can see technical description about how they make it on wikipedia https://en.wikipedia.org/wiki/Carrier-grade_NAT.
Now, we want to run svxlink software in order to have an echolink node connected to our station.
My setup is Kenwood TS-480 + audio usb key + Tinker board ( ASUS raspberry clone ).
In a previous post you can see how I made the audio cable.
Basic setup of our single board pc should be already done, connecting it to internet through lan cable is preferred over wifi.

Now connect the usb audio key and make it the default device disabling the onboard audio.

Login as root,
edit the following files ( create it if needed )
/etc/modprobe.d/blacklist.conf
and add the line: blacklist snd_bcm2835

edit : /lib/modprobe.d/aliases.conf and comment out "snd-usb-audio index=-2"

create: /etc/modprobe.d/snd_usb_audio.conf and write “options snd_usb_audio index=0”

edit: /etc/modprobe.d/alsa-base.conf and add the following 3 lines:
options snd_usb_audio index=0
options snd_bcm2835 index=1
options snd slots=snd_usb_audio,snd_bcm2835


Then, I force the cpu governor to be in performance mode rather then ondemand
echo performance > /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
and add it to /etc/rc.local to preserve the setting between reboots.

Next install svxlink,
apt-get update; apt-get install svxlink-server

and configure basic features as follow,
for now I have only created an echolink node to listen only in rx.
Edit /etc/svxlink/svxlink.conf
under [SimplexLogic] section edit the lines
CALLSIGN=IU2MEH
under [Rx1] section edit the lines
TYPE=Local
AUDIO_DEV=alsa:plughw:0

under [Tx1] section edit the lines
TYPE=Local
AUDIO_DEV=alsa:plughw:0
AUDIO_CHANNEL=0
PTT_TYPE=NONE 


To know which AUDIO_DEV you have to put in config you can run "aplay -l" and you will get an output like this:
aplay -l
**** List of PLAYBACK Hardware Devices ****
card 0: Device [USB Audio Device], device 0: USB Audio [USB Audio]
Subdevices: 1/1
Subdevice #0: subdevice #0

as you see, our usb audio key is the number 0.

Next step is to configure echolink module of svxlink,
edit the file /etc/svxlink/svxlink.d/ModuleEcholink.conf
and change the lines :
CALLSIGN=MyCall-L
PASSWORD=MyPass
SYSOPNAME=MyName
LOCATION=[Svx] …


Then run svxlink as root, if it is the first time you use callsign-L you should get a message that ask you to validate the callsign, you have to visit echolink website and follow the instructions.

SvxLink uses the TCP port 5200 and UDP 5198 and 5199, these ports have to be reacheable from internet cause echolink is a p2p protocol, but if we have a natted provider this is "impossible".
To resolve this issue we can use an external server with a vpn,
in my case a VPS bought from https://contabo.com/ where we have a linux system with full access as root and the server can be reached from internet without any issue.


On the external server side install openvpn:
apt-get install openvpn (assuming that your server is debian based)

Generate certification authority and keys:
cd /etc/openvpn/easy-rsa/
. ./vars
./clean-all
./build-ca
./build-key-server server
./build-dh

then generate they key for our svxlink server:
./build-key svxlink 

under keys directory you should find all the generated files, move them on /etc/openvpn/ directory
cd keys
mv ca.crt /etc/openvpn/ 

mv ca.key /etc/openvpn/
mv dh2048.pem /etc/openvpn/
mv server.crt /etc/openvpn/
mv server.key /etc/openvpn/


create and edit /etc/openvpn/server.conf , write the following lines:
port 5050
proto udp
dev tun0 ca /etc/openvpn/ca.crt
cert /etc/openvpn/server.crt
key /etc/openvpn/server.key
dh /etc/openvpn/dh2048.pem
server 10.8.0.0 255.255.255.128
persist-key
persist-tun
tun-mtu 1500
script-security 2
log /var/log/openvpn.log
sndbuf 393216 rcvbuf 393216
push "sndbuf 393216"
push "rcvbuf 393216"
ifconfig-pool-persist /etc/openvpn/ipp.txt
push "redirect-gateway def1 bypass-dhcp"

client-to-client
keepalive 10 120
verb 2

edit /etc/default/openvpn , find the line AUTOSTART and set it as:
AUTOSTART="server" # this is the same name of the conf file

reboot openvpn service:
/etc/init.d/openvpn restart

if all is ok you should see a new network interface named tun0 with address 10.8.0.1:

tun0: flags=4305<UP,POINTOPOINT,RUNNING,NOARP,MULTICAST>  mtu 1500
        inet 10.8.0.1  netmask 255.255.255.255  destination 10.8.0.2
        unspec 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00  txqueuelen 100  (UNSPEC)
        RX packets 86819  bytes 92236228 (87.9 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 70603  bytes 14042290 (13.3 MiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

enable ip forward:
edit /etc/sysctl.conf and uncomment the line
net.ipv4.ip_forward=1
then run:
sysctl -p /etc/sysctl.conf


On our svxlink mini server we have to install openvpn as before:
apt-get install openvpn

copy from /etc/openvpn/ the following files from the external server
and put them in the same directory on our svxlink server:
ca.crt
svxlink.key
svxlink.crt


cd under conf directory:
cd /etc/openvpn

create and edit client.conf file, write the following lines:
client
dev tun
proto udp
remote PUBLIC_IP_OF_EXT_SERVER 5050
tun-mtu 1500
resolv-retry infinite
nobind
persist-key
persist-tun
ca ca.crt
cert svxlink.crt
key svxlink.key
ns-cert-type server
verb 3
mute 20


edit /etc/default/openvpn to start this config as we did on external server:
AUTOSTART="client"

and reboot the service:
/etc/init.d/openvpn restart

if all is ok you should see a new interface, as we did on the other side, with an assigned ip, for example 10.8.0.5.

Now, all the connections going out from svxlink server will pass through the vpn, through the external server, and reaching the internet.

To check this you can run a traceroute pointing google and you will get an output like this, with hop 1 as 10.8.0.1 :

traceroute www.google.it
traceroute to www.google.it (172.217.21.67), 30 hops max, 60 byte packets
1 10.8.0.1 (10.8.0.1) 24.219 ms 24.220 ms 24.210 ms
2 * * *
3 * * *
4 108.170.241.141 (108.170.241.141) 36.046 ms 108.170.241.204 (108.170.241.204) 38.790 ms 108.170.241.140 (108.170.241.140) 40.744 ms
5 216.239.42.211 (216.239.42.211) 45.052 ms 45.054 ms 216.239.41.209 (216.239.41.209) 56.208 ms
6 209.85.142.97 (209.85.142.97) 35.210 ms 32.632 ms 36.636 ms
7 72.14.234.21 (72.14.234.21) 42.047 ms 72.14.235.39 (72.14.235.39) 40.588 ms 40.592 ms
8 108.170.245.65 (108.170.245.65) 44.236 ms 48.624 ms 48.084 ms
9 172.253.69.255 (172.253.69.255) 47.563 ms 172.253.69.253 (172.253.69.253) 40.401 ms 44.498 ms
10 mrs08s05-in-f3.1e100.net (172.217.21.67) 40.376 ms 40.374 ms 44.116 ms 


Now, using iptables linux firewall on the external server, we will close all ports except ports needed for ssh, openvpn and svxlink, then will tunnel connection from internet to our svxlink server,
to reassume we have the following network config:
external server:
eth0 is the network interface on internet
tun0 is the openvpn interface with ip address 10.8.0.1
ssh is running on default port 22
openvpn is running on upd port 5050 ( as we did in the config above )
svxlink server:
svxlink is running listening on default ports tcp 5200 udp 5198 5199
tun0 is the openvpn interface with ip address 10.8.0.5

on the external server create and edit /etc/iptables-myrules.conf, write the following lines:
*filter
:OUTPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:INPUT DROP [0:0]
-A INPUT ! -i eth0 -j ACCEPT
-A INPUT -p tcp -m tcp --tcp-flags ACK ACK -j ACCEPT
-A INPUT -m state --state ESTABLISHED -j ACCEPT
-A INPUT -m state --state RELATED -j ACCEPT
-A INPUT -p udp -m udp --dport 1024:65535 --sport 53 -j ACCEPT
-A INPUT -p icmp -m icmp --icmp-type 0 -j ACCEPT
-A INPUT -p icmp -m icmp --icmp-type 3 -j ACCEPT
-A INPUT -p icmp -m icmp --icmp-type 4 -j ACCEPT
-A INPUT -p icmp -m icmp --icmp-type 11 -j ACCEPT
-A INPUT -p icmp -m icmp --icmp-type 12 -j ACCEPT

# accept connections for openvpn
-A INPUT -p udp -m udp -i eth0 --dport 5050 -j ACCEPT

 # accept connections for the 3 ports needed for svxlink
-A INPUT -p udp -m udp -i eth0 --dport 5198:5199 -j ACCEPT
-A INPUT -p tcp -m state -i eth0 --dport 5200 --state NEW

# accept connections for ssh
-A INPUT -p tcp -m state -i eth0 --dport 22 --state NEW
COMMIT
*mangle
:PREROUTING ACCEPT [20138:1876903]
:INPUT ACCEPT [19363:1816814]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [20519:5382863]
:POSTROUTING ACCEPT [20519:5382863]
COMMIT
*nat
:PREROUTING ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
-A POSTROUTING -s 10.8.0.0/25 -o eth0 -j MASQUERADE
-A POSTROUTING -s 10.8.0.0/25 -o tun0 -j MASQUERADE

 # tunnel connections to reach our svxlink server
-A PREROUTING -p tcp -i eth0 --dport 5200 -j DNAT --to-destination 10.8.0.5:5200
-A POSTROUTING -d 10.8.0.5 -p tcp --dport 5200 -j SNAT --to-source 10.8.0.1
-A PREROUTING -p udp -i eth0 --dport 5198 -j DNAT --to-destination 10.8.0.5:5198
-A POSTROUTING -d 10.8.0.5 -p udp --dport 5198 -j SNAT --to-source 10.8.0.1
-A PREROUTING -p udp -i eth0 --dport 5199 -j DNAT --to-destination 10.8.0.5:5199
-A POSTROUTING -d 10.8.0.5 -p udp --dport 5199 -j SNAT --to-source 10.8.0.1


commit the changes now running:
iptables-restore < /etc/iptables-myrules.conf
and put this command on /etc/rc.local to preserve the settings between reboots.

Now run svxlink on our svxlink server,
then with another pc with echolink software you should see our node and been able to connect and listen the radio.

( if you will find some errors or something is missed please comment this post, thanks )

Nessun commento:

Posta un commento