I have a few customers that have deployed hosted VoIP solutions from WaveStreet and 8x8 - the usual complaint from time to time is that "the voice quality is bad" or "I could not hear the other party". Now most of these folks have simple networks like the one depicted below and I have managed to eliminate their VoIP issues with QoS configurations on the ASA.
In this particular example, we have a Cisco ASA 5505, a layer 3 switch with two VLANs, one for data and one for voice. Not included in this blog are the configs for the switches. It is advised that you turn on QoS on the switches if they supported it.
Prioritizing VoIP traffic using a Cisco ASA is well documented but the problem is Cisco's documents tend to omit a few important facts. Their example always use just the outside interface (ISP facing). Now, because QoS only acts on the egress traffic when applied to an interface, this does nothing for the inbound traffic from the ISP - the more important direction!
The second critical detail omitted is that even after you have applied the QoS to the correct interfaces, it does not help when a really long download is saturating the ISP link. Those VoIP packets don't have a chance getting down in time from the Internet to your network over that saturated pipe!
So how do we correct these. I used a nested policy on both the outside and inside interfaces of the firewall. The policy on the inside acts on the egress interface and therefore will impact the inbound traffic from the Internet whereas the outside one impacts the outbound traffic toward the Internet. Unfortunately, you've got to sacrifice the data bandwidth for this solution to work but there is no way around it. In my opinion it's a small price to pay.
Each call takes up about 80Kbps in our example and we have had about 10 simultaneous calls in the past so I reserved 1Mbps of our 3Mbps Internet pipe for voice traffic. This implies that the data traffic (or all but voip traffic) can share 2Mbps. To do this, you shape the default class to 2Mbps and nest the voice policy so that the voip traffic is omitted from shaping (or drops) which will give it the remaining 1Mbps. Since I had a symmetrical 3Mbps Internet connection, I applied 2Mbps of traffic shaping to both interfaces. Change the shape rate accordingly if you have asymmetrical speeds.
Here's the relevant ASA 5505 configs with some explanations.
interface Vlan1
nameif inside
security-level 100
ip address 10.0.0.1 255.255.255.0
!
interface Vlan2
nameif outside
security-level 0
ip address i.i.i.i 255.255.255.248
!
interface Ethernet0/0
switchport access vlan 2
!
interface Ethernet0/1
!
!I expect you to limit the udp ports to just what your provider has recommended. !I opened up all udp just to keep things simple
!
access-list outside_access_in extended permit udp any any
!
!Although I used the entire subnet to classify the voip packets, please
!feel free to use dscp, precedence or ports instead
!
!Inbound voip traffic classification
access-list voip_inside extended permit ip any 10.16.1.0 255.255.255.0
!
!outbound (toward Internet) voip traffic classification
access-list voip_outside extended permit ip 10.16.1.0 255.255.255.0 any
!
global (outside) 1 70.35.47.195 netmask 255.255.255.255 nat (inside) 1 10.0.0.0 255.0.0.0 ! access-group outside_access_in in interface outside route outside 0.0.0.0 0.0.0.0 i.i.i.a 1 !
!Enable the piority queues on both interfaces
priority-queue inside
priority-queue outside
!
!Define the class maps for both inbound and outbound voice traffic and prioritize
!the voice traffic
!
class-map voice-inside-class
match access-list voip_inside
class-map voip-outside-class
match access-list voip_outside
!
policy-map global_policy
class inspection_default
inspect dns migrated_dns_map_1
inspect ftp
inspect h323 h225
inspect h323 ras
inspect rsh
inspect rtsp
inspect sqlnet
inspect skinny
inspect sunrpc
inspect xdmcp
inspect netbios
inspect tftp
!
policy-map outside-policy
class voip-outside-class
priority
policy-map inside-policy
class voice-inside-class
priority
!
!Nested policy. Shapes all but VoIP traffic inbound from ISP at 2Mbps.
policy-map ins-policy
class class-default
shape average 2000000 8192
service-policy inside-policy
!
!Nested policy. Shapes all but VoIP traffic outbound to ISP at 2Mbps.
policy-map out-policy
class class-default
shape average 2000000 8192
service-policy outside-policy
!
service-policy global_policy global
service-policy ins-policy interface inside
service-policy out-policy interface outside
This will protect those sensitive real time packets in both directions but remember the bandwidth sacrifice!