How to fix Microsoft Teams poor audio and video over VPN
Overview
Microsoft Teams is experiencing poor audio and video problems when clients are connected to the Cisco AnyConnect VPN gateway. We are able to consistently reproduce this problem by establishing a call between two users using the chat
option in Teams. Both users must be connected to the same VPN gateway.
The problem does NOT exist when a call is established through a meeting
or when multiple users are in a group call. Only singleuser-to-singleuser calls experience poor connection quality.
Resolution Summary
On the AnyConnect VPN, create a dACL to block UDP ports 50000-59999 to all client VPN IP subnets. This will force the clients to communicate through a Microsoft proxy. Clients are no longer able to communicate directly with each other.
Client and VPN Information
- VPN gateway: Cisco 1420 ASA Version 9.12(3)12
- Source Client IP: 192.168.0.1 (VPN Connected)
- Destination Client IP: 192.168.0.2 (VPN Connected)
Details
Poor call quality happens when the STUN process determines the two clients are able to establish a direct point-to-point connection.
The clients use the STUN protocol to determine if direct communication is possible:
$ tshark -r teams-chat-poor-quality.pcapng -Y 'frame.number>=804' | head -2
804 16.558653 192.168.0.1 → 192.168.0.2 STUN 148 Binding Request user: abcd:nxdf
805 16.558741 192.168.0.1 → 192.168.0.2 STUN 120 Binding Success Response XOR-MAPPED-ADDRESS: 192.168.0.2:50035
After the STUN process completes, clients establish a point-to-point connection. When clients are able to communicate directly, the call quality is poor:
$ tshark -r teams-chat-poor-quality.pcapng -Y 'frame.number>=985' | head -10
985 19.513739 192.168.0.1 → 192.168.0.2 UDP 1101 50032 → 50035 Len=1069
986 19.513809 192.168.0.1 → 192.168.0.2 UDP 1101 50032 → 50035 Len=1069
987 19.513864 192.168.0.1 → 192.168.0.2 UDP 1101 50032 → 50035 Len=1069
988 19.513914 192.168.0.1 → 192.168.0.2 UDP 1101 50032 → 50035 Len=1069
989 19.513964 192.168.0.1 → 192.168.0.2 UDP 1101 50032 → 50035 Len=1069
990 19.514015 192.168.0.1 → 192.168.0.2 UDP 1101 50032 → 50035 Len=1069
991 19.514069 192.168.0.1 → 192.168.0.2 UDP 1101 50032 → 50035 Len=1069
992 19.514115 192.168.0.1 → 192.168.0.2 UDP 1101 50032 → 50035 Len=1069
993 19.514166 192.168.0.1 → 192.168.0.2 UDP 1096 50032 → 50035 Len=1064
To resolve the problem, we configured a dACL that blocks the client VPN IP subnets from making connections over UDP 50000-59999 with each other:
deny udp any 192.168.0.0 255.255.255.0 range 50000 59999
permit ip any any
When the client attempts to make a STUN to the other client, the dACL blocks the request:
$ tshark -r teams-chat-blockedSTUN50000-59999-goodquality.pcapng -Y 'frame.number==1122 || frame.number==1131'
1122 12.957642 192.168.0.1 → 192.168.0.2 STUN 144 Binding Request user: abcd:dqVc
1131 13.261219 192.168.0.1 → 192.168.0.2 STUN 144 Binding Request user: abcd:dqVc
After the point-to-point STUN fails, a new STUN process maps a connection to the Microsoft proxy:
Frame 1553: 120 bytes on wire (960 bits), 120 bytes captured (960 bits) on interface utun5, id 0
Null/Loopback
Internet Protocol Version 4, Src: 52.114.157.102, Dst: 192.168.0.1
User Datagram Protocol, Src Port: 3480, Dst Port: 50030
Session Traversal Utilities for NAT
Message Type: 0x0101 (Binding Success Response)
.... ...1 ...0 .... = Message Class: 0x10 Success Response (2)
..00 000. 000. 0001 = Message Method: 0x0001 Binding (0x001)
..0. .... .... .... = Message Method Assignment: IETF Review (0x0)
Message Length: 68
Message Cookie: 2112a442
Message Transaction ID: da1f80952cecba4b85573e5b
Attributes
MS-IMPLEMENTATION-VERSION: Unknown (0x7)
Attribute Type: MS-IMPLEMENTATION-VERSION (0x8070)
1... .... .... .... = Attribute Type Comprehension: Optional (0x1)
.0.. .... .... .... = Attribute Type Assignment: IETF Review (0x0)
Attribute Length: 4
MS Version: Unknown (7)
XOR-MAPPED-ADDRESS: 192.168.175.65:50030
Attribute Type: XOR-MAPPED-ADDRESS (0x0020)
0... .... .... .... = Attribute Type Comprehension: Required (0x0)
.0.. .... .... .... = Attribute Type Assignment: IETF Review (0x0)
Attribute Length: 8
Reserved: 00
Protocol Family: IPv4 (0x01)
Port (XOR-d): e27c
[Port: 50030]
IP (XOR-d): a1ee0b03
[IP: 192.168.175.65]
When the client-to-client STUN process fails, Teams establishes a connection to a Microsoft server instead of directly to the client. Audio and video quality are good after implementing the dACL:
$ tshark -r teams-chat-blockedSTUN50000-59999-goodquality.pcapng -Y 'frame.number>=1572' | head -10
1572 17.961318 192.168.0.1 → 52.114.157.102 UDP 76 50030 → 3480 Len=44
1573 17.961397 192.168.0.1 → 52.114.157.102 UDP 1119 50030 → 3480 Len=1087
1574 17.961474 192.168.0.1 → 52.114.157.102 UDP 1119 50030 → 3480 Len=1087
1575 17.961545 192.168.0.1 → 52.114.157.102 UDP 1119 50030 → 3480 Len=1087
1576 17.961587 192.168.0.1 → 52.114.157.102 UDP 1119 50030 → 3480 Len=1087
1577 17.961626 192.168.0.1 → 52.114.157.102 UDP 1119 50030 → 3480 Len=1087
1578 17.961694 192.168.0.1 → 52.114.157.102 UDP 1119 50030 → 3480 Len=1087