Asterisk Configuration behind NAT
Our network is becoming rather complicated and I am sort of paranoid and I wanted to have our Asterisk server locked away where it cannot do much harm... in a VM :-). The first time I tried to do this it did not work so well and I had a large number of other tasks to get done. When I had some time I spent some of it making the bloody thing work.
Important Ports are those used for signaling (in my case I make sure ports 5060 to 5063 actually reach the VM, in most cases though only 5060 is required, even when you have lots of SIP accounts) also the RTP ports are very important otherwise you will be able to connect but you will not be able to hear the other party (even if they can hear you).
Find out your RTP Ports
Your RTP port settings are in /etc/asterisk/rtp.conf, this is mine:
[general] ; ; RTP start and RTP end configure start and end addresses ; ; Defaults are rtpstart=5000 and rtpend=31000 ; rtpstart=10000 rtpend=20000
Make sure you know the internal IP of your Asterisk box mine is 192.168.30.2. The following rules allow the Asterisk box to send UDP packets to the internet, the source address will 
be changed from 192.168.30.2 to the external IP address of your router.
iptables -t nat -A PREROUTING --proto udp --dport 5060:5063 -j DNAT --to 192.168.30.2 iptables -t nat -A PREROUTING --proto udp --dport 10000:20000 -j DNAT --to 192.168.30.2 iptables -t nat -A POSTROUTING --proto udp --src 192.168.30.2 -j MASQUERADE
Important Extra 
Information: the configuration does not work if your 
configuration calls for traffic to be routed in your subnet via the 
server that is NATing traffic between your local network and the 
internet. The setup at my workplace is like this and I need 
to route traffic between 192.168.10.x and 
192.168.30.x (and even places on the VPN which is another 
story) so you should make the rules above a little more restrictive 
if you want your configuration to function properly.
iptables -t nat -A PREROUTING --dst 173.194.67.9 --proto udp --dport 5060:5063 -j DNAT --to 192.168.30.2 iptables -t nat -A PREROUTING --dst 173.194.67.9 --proto udp --dport 10000:20000 -j DNAT --to 192.168.30.2 iptables -t nat -A POSTROUTING --proto udp --src 192.168.30.2 -j MASQUERADE
You will see that I have added a simple extra requirement so that the 
netfilter subsystem in the Linux kernel will check that the packet is 
destined for the internet facing IP address before mangling it and 
sending it on to the Asterisk server. In the case that the 
machine should forward the packets, for example they came from a 
192.168.10.x address and are destined for a 
192.168.30.x, the packet will be forwarded as 
normal. To achieve the same effect you could add an interface rule 
instead, please see the iptables howto for more 
information on this.
This is a graphical illustration of how the packets will be routed 
through the network, as you can see the green packets are internet bound 
and have been mangled by the nat. 
For the green packets the Asterisk server is acting as a 
back-to-back user agent and 
will perform a task known as "native bridging" this means that it will 
repeat the RTP packets that come in from the internet to the 
user agent (the telephone). The user agent will send packets 
back to Asterisk which will send them back out over the internet.
The blue packets are simply routed and are not mangled by 
the router. Asterisk does not have to act as a back-to-back user agent 
for 192.168.10.34 and 192.168.30.34 (the blue 
packets) because packets can be routed between these user agents.
Configure your Firewall
Next up: Configure your firewall so that these packets are 
not dropped. these rules are only required if your firewall 
policy is DROP or REJECT.
iptables -t filter -L iptables -t filter -A FORWARD --proto udp --dport 5060:5063 -j ACCEPT iptables -t filter -A FORWARD --proto udp --dport 10000:20000 -j ACCEPT
Please see my page on iptables for more information on 
setting firewall rules.
Configuring Asterisk
The important thing about the Asterisk configuration is making 
sure that it knows the destinations that will simply be routed or 
are immediately available on your local ethernet network) and those 
addresses that will be NATed. 
SIP signaling packets are the cause of the problem here, these packets 
have contain addresses and the 
Asterisk server will use the address assigned to the machine (in my case 
this address is 192.168.30.2 which, naturally, will not 
go well if my SIP provider tries to send RTP packets to that 
address.
The important options are configured in sip.conf.
[general] externip=173.194.67.9 localnet=192.168.0.0/255.255.0.0 context=incoming_calls bindport=5060 bindaddr=0.0.0.0
Local net is where all your phones are... or all the phones that 
will use addresses that can be routed. I could have put 
192.168.30.0/255.255.255.0 but if I did that I would 
not be able to connect softphones from the laptops on the 
192.168.10.0/24 network.
That is it, now all SIP packets whose destination begins 
with 192.168. will contain local addresses and all 
packets that do not begin with 192.168. will contain 
the address defined in externip meaning you can talk 
with your SIP provider over the internet and also with clients 
locally or on your VPN.
