Adding Sound to Raspberry Pi

I had a Raspberry Pi 3 running an Asterisk phone server.  I wanted to make use of the “console” functionality of Asterisk.  By setting up an audio console, I would be able to make a phone call to the console from any extension, and have whatever audio I speak from the extension play over the console speakers (sort of a paging function).  In addition, by connecting a microphone, I would also be able listen to sounds in the room where the console is located from any extension.

On a regular Linux PC, the Asterisk console is automatically created using the sound card.  However, the Raspberry Pi does not have built in sound.  I considered a couple of different solutions to add sound.  Dedicated hardware is available to add sound to a Raspberry Pi.  However, since that solution is not a standard sound card, I figured it might be difficult to get working with Asterisk.  And the hardware involved costs more than the Raspberry Pi itself!  High-end sound would be overkill for my application.  I still had 3 of the 4 USB ports available on the Raspberry Pi, and USB sound cards are cheap, so I decided to go that route.  I needed to purchase a USB sound card that was compatible with Linux.  I went with the UGREEN USB Audio Adapter.  This particular USB audio card also has a short cable connected to the USB plug – thus ensuring that there is physical room left for existing and future USB hardware.

Using information mainly from the following tutorial, I was able to get sound (both speaker and microphone) working from the Linux command line.

Once this was done, I needed to get Asterisk to recognize this sound card.  I edited the modules.conf file for Asterisk to enable Alsa sound.  However, there was an issue with the load order of the modules.  The module that handles the console driver was getting loaded before the the sound modules were loaded.  Eventually, I figured out that what I needed to do was pre-load the Alsa module, using the following command in modules.conf:

preload => chan_alsa.so

I found it was also necessary to use the “plughw:” Alsa device for the console, instead of the normal “hw:” device.  This is because Asterisk requires certain specific sampling rates.  My inexpensive usb sound card did not offer these specific rates, resulting in distorted and choppy audio.  Using the “plughw” device allows the Raspberry Pi itself to resample the audio going in and out of the sound card to match the sampling rates required by Asterisk.

Results

I connected a standard set of amplified PC speakers and a standard PC microphone to the USB sound card.  In the Asterisk extensions.conf file, I programmed an extension to connect to the console device.

This results in a working setup.  I can dial the extension of the Asterisk console from any phone on my system, and make paging announcements over the connected speakers.  I am also able to hear sounds in the room where the console is located through the phone.

While the sound quality of the paging audio is fine, I was disappointed in the quality of sound picked up from the microphone.  There is a noticeable amount of hum present.  Not enough to make the setup unusable, but enough to be annoying.  I suspect that the hum is coming from the USB power supply that I am using to power the Raspberry Pi.  Even though I am using a high-current USB supply designed specifically to power a Raspberry Pi, I suspect it still does not have as good of filtering as the power supply in a regular PC.  Though too small to be noticeable in the strong signal associated with the speaker output, the ripple from this power supply is likely enough to be significant for the small audio signal associated with the microphone.  A possible solution would be to use a USB power supply with better filtering to power the Raspberry Pi.

 

 

Setting up an OpenVPN Server

In last week’s blog article, I discussed what a VPN is, and why you might want to install a VPN client on your computer.  This week, I will be discussing the other side of things – installing a VPN server on a Linux computer.

We discussed how a VPN can help with security.  The assumption was that you have a server – provided by either an employer or a commercial VPN provider – that you connect to.  But what if you yourself provided the server that your remote PCs connect to?  Why would you want to do that?  There are several reasons.

Why Run a VPN Server?

  1. You do not trust the VPN provider.  By running your own VPN, you can secure your traffic from public WiFi networks by redirecting it through your home network, without being concerned that the VPN provider itself might be monitoring your traffic.
  2. You wish to save on the cost of a VPN.  If you already have a server running all the time at home, why not make it a VPN server instead of paying a commercial VPN provider for one?
  3. You wish to access applications running on your home network remotely, but don’t wish to open up a bunch of holes in your firewall to allow you to access them remotely.

I recently faced #3.  I wanted to be able to use my Asterisk server – on my home network – while traveling with my laptop computer.  As well, I wanted to be able to access a telephony database running in MySQL.

Just Forward the SIP Protocol Through the Firewall?

The usual way to allow remote access to an application on your home network is have your router forward the ports used by the application to the machine running the application.  While this is an okay solution for some simple protocols, I felt doing this with the SIP protocol used by my VoIP phone would be problematic.

First of all, allowing the SIP protocol through a firewall requires opening not just one port, but several different ranges of ports.  And because the application generating SIP packets (Asterisk in this case) includes the IP address in the metadata of each packet, arrangements also have to be made to have this address translated from the internal IP address to the external address on the other side of the network firewall.  Doing this requires additional configuration not only of the firewall, but of the application itself.  Once the call itself is set up, a separate protocol caries the audio for a phone call, again requiring more ports to be opened in the firewall, and additional IP address translation in the application.  Getting SIP to work through a firewall is known by many to be a time-consuming and often frustrating ordeal.

But even neglecting the difficulty in getting SIP to work through a firewall, opening a firewall to SIP traffic can result in a high volume of hacking attempts.  I once opened up a single SIP port (5060) on a commercial server in order to make VoIP services available externally.  Within hours of opening this port, I had received hundreds of hacking attempts.  These attempts, which came from multiple locations, continued in subsequent days.  While I did secure the server well, and there were no successful hacks, having hackers constantly pounding on the server trying to get in is not a good thing.  It consumes bandwidth, wastes processing power, and there’s always the chance the a hacker eventually succeeds in gaining access.

In fact, SIP services are among the top targets for hackers at present.  This may seem counter-intuitive.  With even international phone calls dirt-cheap these days, why would there be so much effort made to gain access to a phone system to commit toll fraud?  I think what the hackers are looking for is not so much saving money on phone calls, but instead gaining anonymity.  They wish to make “spam” calls that cannot be traced back to them.

No – Use a VPN Server Instead

Based on both the difficulty of setup, and the attractiveness to hackers, I decided it would not be a good idea to allow direct access to my telephony server.  But what I could do is run a VPN server on my network.  This would allow me to connect to applications such as Asterisk (my SIP server) and MySQL (my database server) remotely just as easily as if I was at home (once the VPN connection is established).  By running OpenVPN, I would also only need to open access to a single network port – not the multiple ports required for SIP and other applications.  And since OpenVPN makes use of certificates, hackers not possessing such a certificate would not be able to hack into the server – no mater how many passwords they tried.

Setting up OpenVPN Server

Since there are plenty of good tutorials already online, I won’t go into the details of setting up the OpenVPN server, other than to briefly note how I resolved a couple of issues I ran into.  The OpenVPN site itself has a good tutorial.  I also found this article helpful.

The setup went pretty much as described by the above sources, with the exception of two issues.

The first issue was that, although I could connect to the OpenVPN server itself, I was not able to connect to other machines on my home network.  The articles mention the need to turn on IP Forwarding, which I had done.  However, another thing not mentioned directly in the articles that is necessary is to add a route to other machines from the VPN server by using iptables.  Adding this route allowed me to connect to any machine on my network.  However, changes made to iptables are lost upon system reboot.  So the first time I rebooted the VPN server, I was again no longer able to connect to other machines on my network through the VPN.  I found a package called iptables-persistant (this is the package name for Debian Linux – other Linux distributions may have a similar package with a different name) that makes iptables changes persist between reboots.  Once I re-added the route to other machines and installed this package, access to other servers on my home network again works, and continues to work even after rebooting the VPN server.

Results

I am now able to connect to my home Asterisk VoIP server from a soft phone client on my laptop.  I am able to make an receive calls without any issues.  I even found an OpenVPN client and a soft phone that run on my iPhone, so I am able to use the full functionality of my home VoIP setup no matter where I travel.  I am also able to connect to MySQL Server, and to other applications located on other machines on my home network.

Best of all, if I later wish to connect to new servers or applications on my home server, no additional setup will be required.  And I only have a single port (one that runs a protocol that requires a certificate to successfully access) exposed on my home network.