Best way to handle remote SIP registrations with iptables

What is the best way to configure IP tables for incoming SIP registrations from remote extensions?

I’m interested in configurations using two factor authentication.

When I say remote extension I’m referring to an extension behind a unique public address / nat device.
For example, SIP client application for android installed on a Verizon phone which has a constantly changing public address as it wirelessly associates to different towers.

In my topology, an asterisk server sits behind another Linux firewall box with a public interface, and an internal network interface. (RFC 1918 non routable network
The topology looks like this:

Internet --> cable modem --> Linux server Public interface DHCP --> Internal interface --> Non-managed switch on network --> asterisk server at

As of now, the Linux firewall is doing DNAT’s of external connections to the internal host. This works fine as long as the public interface that the remote client is behind doesn’t change IP’s or I use something like dynamic DNS host record with a low TTL value.

I’m looking for a better way to do it.
I don’t want to just open UDP 5060 to the world because of DDOS, and bots trying to brute force authentication etc.

Googling turns up several pages that talk about rate limiting incoming SIP registration / invites, and requests. The accepted norm seems to be; Open SIP to the world, and then do things like rate limiting. What is the best practice here? I only have a small number of remote extensions that need to register with asterisk.
Is there a good way to only allow these connections?

For example here are some of the pages I have found:

My first idea was to use shorewall to setup iptables / netfilter with string matching to match on the user agent string in the packet, but shorewall doesn’t seem to support this in the rules file, and needs patchomatic-ng extension scripts to use it, and it seems to be frowned upon because according to the documentation, “the application level data stream can be split across packets in arbitrary ways” which could cause the string match to fail, on packet fragmentation, and leaves it vulnerable to half open attack.

Despite the warnings, I tested the following and other similar rules to see if I could get it to work, but it doesn’t seem to.

iptables -t nat -I net_dnat 10 -p udp -m udp --dport 5161 -m string --to 663 --string ‘CSimSimple’ --algo bm -j DNAT --to-destination

Is there a better way to allow SIP registrations based on something other than the truly dynamic IP address of the remote extension?

Thank you in advance for any advice.

If this is a small rollout VPN’s are always the preferred route.

If this is some type of carrier environment it sound like you need to review the roll of Session Border Controllers and the “Admission Control” function.

Essentially any SIP router can function in an Admission Control role and provide isolation from the telephony platform.

OpenSER/Kamailio can function in this roll. Commercial boxes from Acme Packet and Mediatrix can support 100k+ SIP sessions.

I would suggest using the hardware firewall as it is intended. Configure your permit/deny rules there. Allowing unknown traffic into the DMZ/LAN is one step beyond comfort for me.


I was thinking the same thing. How much logic do I want to occur on the perimeter firewall, and how much should happen on the asterisk server? I’m using the freepbx distro with fail2ban enabled. It looks like fail2ban does a lot of this by default. How much should I rely on fail2ban, and what should be augmented with iptables and other security controls?


I got openvpn working on a motorola droid 2 and that did work well. The sip client, in this case csipsimple worked well and had no registration problems. I set the algorithim and cipher strength to the lowest possible values to save on bandwidth because I really didn’t care about the security of it, I just wanted to tunnel through. One problem with this is that I’m capable of setting it up. Other users that I want to provide SIP extensions for, are not able to, or are not comfortable rooting their phones which is necessary to use things like tun/tap needed by openvpn.

I haven’t used Session Border Controllers. Thanks for the recommendation!

With this command I’m able to get csipsimple to register.

iptables -t nat -I net_dnat 4 -p udp -m udp -m string --to 623 --string “csipsimple” --algo bm --dport 5161 -j DNAT --to-destination

It provides at least some basic security by checking for the user-agent string, but I’m still not entirely comfortable with it.

I still have an issue with natting it seems.

wireshark shows that the packets arriving to the sip server are from a source IP on the remote internal natted carriers network. So packets sent back to this IP never reach the device. If I set nat to no in the extension config, I see the packets arriving from the public interface of the carriers nat device, but of course it doesn’t DNAT or forward them in to my device.

The symptoms of this are that I can call out from the sip client on the droid, but have no audio. I’m unable to call the sip extension on the droid from any other sip extension.

For now this almost mandates that I use vpn to tunnel through the carriers nat device and other public infrastructure.

Do you have your NAT settings right in Asterisk/FreePBX? The localnet and externip values need to be populated.


Yes, it’s configured as follows in freepbx:

Tools --> Asterisk SIP settings

NAT is set to yes.
Extern IP shows the correct external IP.
Local Networks shows the correct Class C network space.

Odly enough, /etc/asterisk/sip_nat is a blank file.

I’m assuming these settings are stored in another file by freepbx.