This is very easy to do on FreePBX (or any Linux-based system). For example, see PBX Security - #7 by Stewart1
I’ve found it to be virtually 100% effective against ‘riff-raff’ (automated tools scanning all IPv4 addresses). Unfortunately, except for the smallest systems (home or micro-business), it’s not an adequate solution. Organizations of significant size have adversaries who will target them explicitly, e.g. a competitor trying to steal a customer list or business plan, or an associate’s wife looking for evidence of his cheating. It’s not hard for an such an enemy to learn the domain name (spearphishing or other social engineering, open Wi-Fi, etc.) Even worse, you may face attackers with specific knowledge of your system (disgruntled employee or former employee).
So, additional restrictions are needed. However, I’m disappointed that the official FreePBX firewall doesn’t also filter by domain name. If you never see attempts from the riff-raff, you can take any attempt that does get logged with the seriousness it deserves. Also, keeping the logs free of scanner probes makes it easier to find and fix problems not related to security.
OK, enough of my rant.
Most NAT routers don’t modify the source port number unless the requested port is already in use. Those that do, e.g. pfsense, have a setting to turn this off. Then, set up all the phones behind a given NAT to use unique local port numbers, e.g. ext. 101 uses 5061, ext 102 uses 5062, etc. The port numbers seen by pjsip should no longer change.