Open source SMS Connector Module

Just installed the SMS Connector Module GitHub - simontelephonics/smsconnector: SMS Connector module for FreePBX 16 and 17 with Twilio. I can send messages, but I can’t receive them. This is a fresh installation of the FreePBX distro. Any ideas @billsimon , Thanks in advance

Ideas -

Check firewall/network: ensure you are able to receive HTTPS (port 443) requests from Twilio to your PBX

Check certificate: ensure you have HTTPS TLS set up with a valid (not self-signed) cert

Check logs: SMS Connector logs to /var/log/asterisk/freepbx.log (along with all the other modules, so you’ll have to search a bit)

Thanks for the reply. The certificate is fine for HTTPS. FreePBX is able to receive requests from Twilio, and there’s nothing relevant in the FreePBX log. However, the firewall seems to be the problem again. When it’s disabled, all messages work inbound and outbound. I whitelisted all possible Twilio IPs and further analyzed Apache logs to check if any other IP is missing, but found nothing any ideas ?

AFAIK, this is not possible, Twilio doesn’t publish a list of possible IPs that SMS can come from. These are not SIP servers which they do enumerate.

That might be the problem. How should we address this situation?

You could open a ticket and ask them whether there’s any way to narrow down the range so that you can apply a filter, but I suspect they will only say “we use AWS and it could be any AWS subnet.”

They just replied:

The IP addresses used for Twilio REST APIs are highly dynamic, and span a large range, so it’s impractical to list each of them. Instead we recommend you allow all outbound HTTPS traffic to any *.twilio.com subdomain.

I did this:

But still not working…

It seems they misunderstood your question and told you about outbound traffic to their servers. They didn’t tell you how to match inbound traffic from them to you.

From Twilio:

For security reasons, Twilio does not offer a specific range of IP addresses for incoming webhook requests, as we use a dynamic pool of IP addresses. To manage this, we recommend placing your servers in a DMZ (Demilitarized Zone) and routing Twilio webhook requests through these servers before they reach your application servers.

Additionally, we recommended utilizing the X-Twilio-Signature header that Twilio includes with each webhook request to your server. Twilio’s HTTP request IP addresses are highly dynamic and span a large range, making it impractical to manage permissions based on IPs.

“For security reasons” makes no sense; using dynamic IPs from AWS is actually less secure because you can’t establish an IP filter.

@billsimon Who said it was for security reasons for YOUR benefit…

Sounds like a job for a reverse proxy and not an IP based one.

Perhaps use an iptables rule for inbound TCP/443 that matches the header twilio said they send? Not sure it will match a potentially still encrypted packet, but it’s worth a shot?

iptables -A INPUT -p tcp --dport 443 -m string --algo kmp --string ‘X-Twilio-Header’ -j ACCEPT

While this would require some modifications to the module, you could check for custom headers being sent by the carrier such as how Twilio does it. You can also add a parameter to the query string of the webhook like authToken=xxxxxxxxxx and have that validated against.

If a request is missing a header or the authToken field you deny the request otherwise accept it and process it.

@jcolp maybe you should keep your “commercial module bias” for your employer back in its box, your snipe shines through in your comment, remember FreePBX is first and foremost Open Source, not a $$$$$ making cash cow that your employer is trying to stifle by attacking open source contributors, because it might affect your employers bottom line.

It is attitudes like this that give Sangoma and FreePBX a bad name and drive to alternatives, and since 3CX have reversed their several year old decision on ending their free offering, it would be foolish to act in way that is detrimental to FreePBX.

https://stackoverflow.com/questions/58589331/haproxy-how-to-forward-traffic-to-backend-by-a-matching-header

@nickzed My comment was in regards to the fact that Twilio didn’t state who the security benefited. It wasn’t against anyone here, and as I have a friendly relationship with @billsimon I didn’t elaborate further. I’ll do so now. For Twilio by having different IP addresses it can help/reduce the attack area on their own infrastructure, since attackers won’t have a known set of IP addresses and Twilio can change it around at will. For actual users, however, it doesn’t help with their own security because as demonstrated in this thread it means you yourself can’t directly firewall/allow those IP addresses through but either have to allow all through or go to greater lengths to restrict traffic (for example what @dicko is referring to with an edge HTTP proxy). So the security decision really benefits Twilio.

4 Likes

And the lengths aren’t too great as haproxy is probably already installed and running on your recent FreePBI distros.

I had the same problem and here is how I solved it. By no means is this probably the correct way to do it and I welcome suggestions on how to improve this. But what I did was create a proxy just for the SMS Connector and opened it up to the internet. SSH into the server and create a new configuration file /etc/apache2/sites-enabled/sms.conf with the following contents:

Listen 9443
<VirtualHost *:9443>
    ProxyPass /smsconn/ https://127.0.0.1:8443/smsconn/
    ProxyPassReverse /smsconn/ https://127.0.0.1:8443/smsconn/
    ProxyPassReverse /smsconn/ https://{server hostname}/smsconn/
    ProxyRequests Off
    ProxyPreserveHost On

    <LocationMatch "^(?!/smsconn/)(.*)$">
        Require all denied
    </LocationMatch>

    SSLEngine on
    SSLProxyEngine On
    SSLCertificateFile /etc/apache2/pki/webserver.crt
    SSLCertificateKeyFile /etc/apache2/pki/webserver.key
    SSLCertificateChainFile /etc/apache2/pki/ca-bundle.crt
</VirtualHost>

Reload Apache2 running /etc/init.d/apache2 reload.

Then in FreePBX, I added a custom firewall rule. Navigate to Connectivity > Firewall and then from the menu click Advanced. The rule I added is:

-I INPUT 1 -p tcp -s 0/0 --dport 9443 --syn -j ACCEPT

Then in Twilio you set the WebHook for messaging to https://{server hostname}:9443/smsconn/provider.php?provider=twilio.

Note, you will see I used port 8443 in my Apache config. That is because I have changed the port of my Web GUI from the default. If you didn’t change yours, either replace 8443 with 443 or remove it entirely.

2 Likes