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 22.214.171.124 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!