I have a system running with a very simple firewall. Everything not explicitly permitted is dropped. FreePBX firewall is not used.
Chain INPUT (policy DROP)
num target prot opt in out source destination
1 ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED
2 ACCEPT icmp -- * * 0.0.0.0/0 0.0.0.0/0
3 ACCEPT all -- lo * 0.0.0.0/0 0.0.0.0/0
4 ACCEPT udp -- * * 0.0.0.0/0 0.0.0.0/0 udp dpts:10000:20000
5 ACCEPT udp -- * * 0.0.0.0/0 0.0.0.0/0 udp dpts:5000:5999 STRING match "my.pbx.com" ALGO name bm TO 65535
6 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 multiport dports 22,80,443
- Accept replies and everything already recognized by conntrack.
- Allow ping, etc.
- Allow loopback traffic.
- Allow RTP.
- Allow SIP packets containing my ‘secret’ domain name.
- Allow SSH, HTTP, HTTPS.
In addition, there is some simple Apache configuration that permits only requests with the domain name. Requests by IP address or an incorrect name receive a dummy site and a dummy (self-signed) certificate.
SSH is configured to require RSA authentication (a password will not work).
Notes on trunking:
Although register trunks will work automatically (incoming INVITEs appear as ESTABLISHED to conntrack), I put the domain name in the Contact user (using from-pstn-toheader as the context), so if a network interruption causes the conntrack association to be lost, an incoming call will still pass the firewall.
On IP authentication trunks, the incoming SIP URI will normally have the domain name. If the provider requires a numeric IP address for the destination, I put the domain name in the user part of the URI. If you have a provider that also doesn’t allow you to configure that, you will need to add iptables rules to accept packets from their IP addresses.