Communicator Automatic Configuration and Split-Brain DNS

A lot has been written about the way that Microsoft Office Communicator uses DNS to automatically discover a registration point for a given SIP URI. I won’t repeat all of that here. But, I do want to emphasize one of the unique constraints that Communicator places on the DNS SRV records it uses.

For automatic configuration to succeed, Communicator requires that the domain of the target host match the domain of the user’s SIP URI. This requirement is driven by a security decision the Communicator team made (not by a DNS requirement). The reason is provided in the documentation this way:

This tight validation between the host name and the URI is done specifically because the only configuration with which the client is provided is the SIP URI. Because of this, the client must be very careful not to allow DNS attacks to allow it to connect to any man-in-the-middle, who could thereby watch Communicator’s traffic. By having a tight tie between the URI and the host names allowed for logon, Communicator has better certainty that the certificate the user is validating actually has authority for the domain to which he is trying to log on to.

In other words, it’s not sufficient for an attacker to simply create the appropriate DNS SRV records to fool your Communicator to logon through his server. (Which would be trivial.) He’ll also need to get a certificate that you trust for an FQDN that falls within in your organization’s domain. (Which should be much harder.)

In practice, this constraint means that this is a valid SRV record to be used in automatic configuration for the user alice@contoso.com:

   _sipinternaltls._tcp.contoso.com. 86400 IN SRV 0 0 5061 sip.contoso.com.

However, this record will not be used by Communicator for automatic configuration even though it is a valid SRV record:

   _sipinternaltls._tcp.contoso.com. 86400 IN SRV 0 0 5061 sip.litwareinc.com.

(I’m using this standard format for representing SRV records: _Service._Proto.Name TTL Class SRV Priority Weight Port Target. In the second example, notice that the target host is not in the contoso.com domain.)

This can create problems for organizations that do not resolve queries for their public DNS name internally. If you use an internal DNS namespace, it is likely to be unrelated to the domain of your SIP URIs (because we recommend that your SIP URI match your SMTP address which must be a public DNS domain). You might be tempted to put a record like this in your public DNS:

   _sipinternaltls._tcp.contoso.com. 86400 IN SRV 0 0 5061 ocspool.contoso.local.

Unfortunately, Communicator will not attempt to connect to ocspool.contoso.local for the someone in the contoso.com SIP domain. (To be more correct, it will connect to ocspool.contoso.local if that name is provided by group policy or configured manually in Communicator. It is only considered invalid for the purposes of automatic configuration.)

Additionally, creating these records in your external DNS for internal clients will reveal something about your internal addressing to the outside world. Most security folk consider this a “no-no.”

For these reasons, I generally say that split-brain DNS is required to enable the automatic configuration of Communicator to work properly for both internal use (where Communicator should find a director or pool server) and external use (where Communicator should find your Access Edge). For many of my customers, this has not been a problem. They have already been resolving some form of their public name internally already.

For the customers that don’t already have split-brain DNS implemented, it is a big leap for them to begin resolving their external domain internally. To suggest that Contoso should suddenly put the DNS zone contoso.com on their internal DNS servers simply to accommodate an OCS deployment will likely get you laughed out of the room.

A more reasonable suggestion is to create what I’ll call two “pinpoint” DNS zones. These are internal zones that will resolve just the names that we want for automatic configuration. All other names in their external DNS domain will be unaffected.

To implement this for Contoso, we would create a zone “_sipinternaltls._tcp.contoso.com” and zone “sip.contoso.com.” Notice that these are two zones – not two records in one “contoso.com” zone. A zone is a name resolution boundary in the hierarchical DNS namespace. By configuring the internal DNS server to be authoritative only for these two names, clients will continue resolving other names in the contoso.com domain as they always have.

Coincidentally, over on his blog, Geoff Clark has just suggested the same thing. He describes the problem and suggests the same solution but shows a method of creating the zone on a Windows DNS server via the DNS management console. Unfortunately, there is a limitation in the management console that is not present in the underlying Windows DNS implementation. This limitation required Geoff to create the zone as “_tcp.contoso.com” when what we would really like is a zone named “_sipinternaltls._tcp.contoso.com.”

This limitation in the user interface can be resolved by creating the zones and the records using the Dnscmd command line tool. For Contoso, here are the required commands:

 dnscmd . /zoneadd _sipinternaltls._tcp.contoso.com. /dsprimary
dnscmd . /recordadd _sipinternaltls._tcp.contoso.com. @ SRV 0 0 5061 sip.contoso.com.
dnscmd . /zoneadd sip.contoso.com. /dsprimary
dnscmd . /recordadd sip.contoso.com. @ A 172.16.45.12

Of course, you’ll need to make the appropriate changes for your environment. If you are not running the command on your Windows DNS server, you will need to replace the first dot with your server name. You may also prefer a different zone type than “dsprimary.” If so, change the zoneadd commands appropriately. I doubt that your pool’s IP address is the same as my example but, if you have followed me this far, you already know what to change there.

I hope this suggestion helps somebody. Please let me know by providing feedback.

--Doug

This post has been brought to you by someone who disagreed with me and forced me to explain myself.