I haven’t found a comprehensive process documented for this yet so I figured I’d give it the first run. This information is accurate for the Release Candidate of Lync Server 2010.
Now the process to create the static route itself is very easy, in fact there is a nice cmdlet specifically for this purpose: New-CsStaticRoute. You can create either TCP or TLS routes, and the cmdlet documentation is pretty straightforward. The Beta Refresh docs did have a minor error, which is that you don’t shouldn’t put sip:*@ in the –MatchUri parameter. With that in mind, here is the command to route the SIP domain video.domain.com to the device rmx.domain.com on port 5061:
New-CsStaticRoute -TLSRoute -destination "rmx.domain.com" -port 5061 -matchuri "video.domain.com" -usedefaultcertificate $true
This will use the default certificate on the front end for the TLS communication to the destination device. You could use the TLSCertIssuer and TLSCertSerialNumber parameters if you needed to use a different certificate, for example if your front ends were using internally generated certificates but you needed to communicate with the destination device with a public certificate.
Creating that route by itself won’t really do anything because the routing configuration needs to be updated for the route to be used. To do this you need to use Set-CsStaticRoutingConfiguration. By default (at least in Beta Refresh and Release Candidate) only a global routing configuration exists, which is empty. You can see this by running the Get-CsStaticRoutingConfiguration command:
get-CsStaticRoutingConfiguration -Identity global
Identity : Global
Route : {}
Applying a route to the global collection will obviously apply globally. If you want to apply a route to only a specific collection, such as a pool (registrar) or site, you can do that as well. Since collections for these do not exist by default you need to create one. Here’s how you would do so for a pool/registrar or site
New-CsRegistrarConfiguration -Identity service:registrar:pool.domain.com
or…
new-CsRegistrarConfiguration -Identity site:Denver
Now that all that is clear we can put it all together. What we need to do to apply this route is combine the New-CsStaticRoute cmdlet with the Set-CsStaticRoutingConfiguration cmdlet. The easiest way is exactly what is documented, which is to set the new-csstaticroute as a variable and then pass it to then set-staticroutingconfiguration cmdlet, like so:
$route = New-CsStaticRoute -TLSRoute -destination "rmx.domain.com" -port 5061 -matchuri "video.domain.com" -usedefaultcertificate $true
Set-CsStaticRoutingConfiguration -identity global -route @{Add=$route}
If you had created routing collections for either your registrar or site you would replace “global” with “service:registar:<registrar>” or “site:<site>” as appropriate. The other benefit of doing it this way is that if you wanted to put this route in a couple places you could just hit the up arrow, modify the identity, and run it again.
Now you can check your routing config again with the get-csstaticroutingconfiguration cmdlet. If I don’t specify an identity it will return everything:
get-CsStaticRoutingConfiguration
Identity : Global
Route : {MatchUri=video.domain.com;MatchOnlyPhoneUri=False;Enabled=True;ReplaceHostInRequestUri=False}
Identity : Service:Registrar:pool.domain.com
Route : {MatchUri=video.domain.com;MatchOnlyPhoneUri=False;Enabled=True;ReplaceHostInRequestUri=False}
Great, looks good. If we stop here our servers will indeed route calls to those URIs over to our destination host, but things won’t really work. If you run a SipStack trace you’d probably see something like this when the remote host tries to do anything:
TL_ERROR(TF_CONNECTION) [0]1B78.0E94::09/08/2010-00:20:42.001.00001aed (SIPStack,SIPAdminLog::TraceConnectionRecord:SIPAdminLog.cpp(160))$$begin_record
LogType: connection
Severity: error
Text: The peer is not a configured server on this network interface
Peer-IP: 172.16.200.65:5061
Peer-FQDN: rmx.domain.com
Transport: TLS
Result-Code: 0xc3e93d6a SIPPROXY_E_CONNECTION_UNKNOWN_SERVER
Data: fqdn="rmx.domain.com"
$$end_record
That’s because it’s not authorized. If you ever did this in OCS you probably remember a tab called “Host Authorization” where you had checkboxes like “Throttle as Server” and “Treat as Authenticated.” We still need those, it’s just quite a bit different to put that config in. Now you need to use the CsTrustedApplication cmdlets. These trusted hosts need to belong to a Trusted Application Pool (which is associated to a registrar pool) and be a Trusted Application Server in that application pool. Finally, you need to create an application that is associated with that pool. All these application cmdlets are designed for developers but are needed here primarily because of two parameters found in the New-CsTrustedApplicationPool cmdlet: ThrottleAsServer and TreatAsAuthenticated.
The easiest way to address this is by using Topology Builder to create the Trusted Application Pool and Trusted Application Server:
By default the ThrottleAsServer and TreatAsAuthenticated are enabled. You can check this using get-csapplicationpool:
Get-CsTrustedApplicationpool -Identity video.domain.com |fl
Identity : TrustedApplicationPool:video.domain.com
Registrar : Registrar:lyncRC.domain.net
FileStore :
ThrottleAsServer : True
TreatAsAuthenticated : True
If you’re so inclined, here’s how you create the TrustedApplicationPool/Computer with the Lync Server Management Shell (powershell).
New-CsTrustedApplicationPool -Identity video.domain.com -Registrar Registrar:pool.domain.com -site 1 -ComputerFqdn rmx.domain.com -ThrottleAsServer $true -TreatAsAuthenticated $true
This creates the pool with the correct parameters and also creates my route destination FQDN and assigns it to the pool. The identity is completely up to you, it doesn’t need to match the SIP routing domain, that’s just what I chose to do. If you do not specify the ComputerFqdn parameter then a CsTrustedApplicationComputer with an FQDN matching the Application Pool will be created. The Site parameter uses the ID of the site, which can be found with get-cssite.
Next we need to create an application that is associated with the pool. We can make the ApplicationID whatever we want:
New-CsTrustedApplication -ApplicationID VideoRouting -TrustedApplicationPoolFqdn video.domain.com -Port 5061
The ApplicationID can be any string you would like and the TrustedApplicationPoolFqdn will match the FQDN of the application pool you created in either TB or via the previous cmdlets.
Lastly, for this to take effect we need to enable the topology with these updates:
Enable-CsTopology
And that’s it – whew! A few more steps than in OCS but the tradeoff is the granularity that you get. If you had 10 pools in OCS and wanted to put a route in for all of them you’d have to do it 10 times. Ditto if you needed to change that route. The “Global” routing collection makes this very simple, and of course all the flexibility with sites is going to be great for a bunch of reasons. One thing I have noticed is if I create a route in the Global collection and then create a Registrar collection that does not contain this route then the call fails as follows:
TL_WARN(TF_DIAG) [0]1024.1BC4::09/10/2010-03:10:17.510.0003ebae (SIPStack,SIPAdminLog::TraceDiagRecord:SIPAdminLog.cpp(145))$$begin_record
LogType: diagnostic
Severity: warning
Text: Non-trusted source sent an FQDN/IP that doesn't match a routing table rule
Result-Code: 0xc3e93c5e SIPPROXY_E_ROUTING
SIP-Start-Line: INVITE sip:1003@video.domain.com SIP/2.0
SIP-Call-ID: 2ee2c5825a1248e6b37f03d70f25732a
SIP-CSeq: 1 INVITE
Data: user="1003@video.domain.com"
$$end_record
This seems illogical to me since I would assume that the global routes would always apply, but I’m dealing with pre-release software here so maybe this will change in the release version.
A last point of reference – if you are configuring a route to an external audio or video system that does not support SRTP, make sure to set the media encryption level to SupportEncryption rather than the default of RequireEncrpytion:
Get-CsMediaConfiguration
Identity : Global
EnableQoS : False
EncryptionLevel : RequireEncryption
EnableSiren : False
MaxVideoRateAllowed : VGA600K
set-CsMediaConfiguration -EncryptionLevel supportencryption
Get-CsMediaConfiguration
Identity : Global
EnableQoS : False
EncryptionLevel : SupportEncryption
EnableSiren : False
MaxVideoRateAllowed : VGA600K
As you can probably guess from the identity of Global, media configuration policies can be set in multiple places just like the static routing configurations can. By default only a global policy exists.
Happy Routing!
Any way to do this in the GUI on Lync RC like there was in OCS?
Posted by: Doug | 10/11/2010 at 12:04
Partially. You can create the trusted application pool a trusted application computer with topology builder but the static route must be created with the management console.
Posted by: Mike Stacy | 10/11/2010 at 12:29
Hi Mike and thanks so much for this information. Unfortunately this is making my head hurt I have a merged R2 and Lync environment. In my R2 world we have a configuration supporting RCC with an Avaya AES. Both my R2 and Lync environments are comprised of dual FEs behind an F5 HLB. My Host Authorization and Static routed are configured as follows in R2:
Route
Matching URI = Avayaaes.net.domain.com
Next Hop = Avayaaes.net.domain.com
Transport = TLS
Port = 4723
To add the static route to Lync I ran the following:
$route = New-CsStaticRoute -TLSRoute -destination "avayaaes.net.domain.com" -port 4723 -matchuri "avayaaes.net.domain.com" -usedefaultcertificate $true
Set-CsStaticRoutingConfiguration -identity global -route @{Add=$route}
Host Authorization
FQDN = AvayaAes.domain.com
Throttle as Server = True
Treat As Authenticated = True
This is where I get hung up. I create the Trusted Application Pool with the FQDN of the Host authorization as it is in R2, however the topology builder can’t find it in AD. Well it doesn’t exist in AD…… not sure what to do here. When running the NetStat I see the connection established to the correct port, yet my Lync Client is not recognizing the RCC enabled phone system.
Any and all help is very much appreciated.
Posted by: Mike Carman | 12/20/2010 at 13:32
Hello again Mike. I created the trusted app server using power shell. The following are the errored results:
PS C:\Users\micarmx> New-CsTrustedApplicationPool -Identity avayaaesrsrv.domain.com -Registrar Registrar:lyncpool.domain.com -site 1 -ComputerFqdn avayaaesrsrv.domain.com -ThrottleAsServer $true -TreatAsAuthenticated $true
WARNING: Machine avayaaesrsrv.domain.com from the topology you are publishing was not found in Active Directory and will
result in errors during Enable-CsTopology as it tries to prepare Active Directory entries for the topology machines. If you
choose to publish this topology Enable-CsTopology will have to be re-run once the missing machines are domain-joined.
Missing Machine
The following machines from the topology you are publishing were not found in Active Directory and will result in errors during
Enable-CsTopology as it tries to prepare Active Directory entries for the topology machines. If you choose to publish this
topology Enable-CsTopology will have to be re-run once the missing machines are domain-joined:
avayaaesrsrv.domain.com
[Y] Yes [A] Yes to All [N] No [L] No to All [S] Suspend [?] Help (default is "Y"):
WARNING: The following changes must be made in order for the operation to be complete.
Enable-CsTopology must still be run for all changes to take effect.
Identity : 1-ExternalServer-6
Registrar : Registrar:lyncpool.domain.com
FileStore :
ThrottleAsServer : True
TreatAsAuthenticated : True
OutboundOnly : False
RequiresReplication : True
AudioPortStart :
AudioPortCount : 0
AppSharingPortStart :
AppSharingPortCount : 0
VideoPortStart :
VideoPortCount : 0
Applications : {}
DependentServiceList : {}
ServiceId : 1-ExternalServer-6
SiteId : Site:Americas
PoolFqdn : avayaaesrsrv.domain.com
Version : 5
Role : TrustedApplicationPool
Posted by: Mike Carman | 12/21/2010 at 07:29
Thanks for the write up Mike. Was able to get RCC going with CUPS as a result, much appreciated.
Posted by: Justin Morris | 01/14/2011 at 08:58
Mike: in your example \ TLS static route you write:
-destination "rmx.domain.com"
and little bit later: -matchuri "video.domain.com"
Let me translate that into human text:
if Lync sees a SIP URI ending with "video.domain.com" (for example my RCC user LineserverURI is congifured as: "sip:randomstring@video.domain.com"), exactly this route will match and as a result it will route it to rmx.domain.com
Question:
Can both "rmx.domain.com" and "video.domain.com" be the same string, like both being "rmx.domain.com" ? If yes, can this cause infinite routing loops?
I am fighting with the same issue in Avaya AES RCC as Mike Carman, and I suspect Lync-side inconsistent configuration of static routes and application pool names, but cannot find out where and how.
Posted by: Richard | 03/28/2011 at 10:02
That is correct. You can make them both the same - it will not cause any issues.
Posted by: Mike Stacy | 03/28/2011 at 10:06
Good to hear that :)
I am thinking on the rmx side \ listening port: this TLS port 5061 is on the RCC gateway (RMX side), so it has nothing to do with the fact, that Lync is also using the same port number 5061?
Posted by: Richard | 03/29/2011 at 02:47
One more thing is still bugging me:
you have chosen a "pool" as the type for trustedapplicationpool instead of the type "single computer" for trustedapplicationpool. As the result you could provide different pool and member server FQDN, and also you can expand the pool object to show the separate child object (screenshot)
Was that a requirement/recommendation of Polycom, or just here for demonstration purposes, how these application pools in Lync are represented?
Posted by: Richard | 03/29/2011 at 08:23
Correct - it's the destination port. You will not have a conflict.
You can use either a single computer pool or a multiple computer pool. I always do a multiple computer pool because if I need to add other FQDNs (maybe to add redundancy) or swap from one to another (new hardware, etc.) it minimizes the amount of changes I have to make.
Posted by: Mike Stacy | 03/29/2011 at 10:30
Mike:
Would this be a way to integrate Lync with Tandberg?
our MCU domain name is same as SIP URI, so for ex, mcu-sip@domain.com and sign in name of Lync user is abc@domain.com. If I create static route of same domain, does it affect Lync users OR it will only send all the request to mcu if user dosen't exist in Lync?
Posted by: Hemalkumar | 04/27/2011 at 15:54
I'm sure the Tandberg configuration uses the same basic aspects as the ones outlined here, which are based on Polycom integration. You can definitely create a route using the same name as your primary SIP domain.
Posted by: Mike Stacy | 04/28/2011 at 20:59
Hi guys,
i did all what was postet in blogs, whitepapers, technet and so on. But my Lync allways routes the traffic for VCS-Domain to the edge server instead directly to the trusted server.
A Get-CsStaticRoutingConfiguration brings that:
Identity : Global
Route : {MatchUri=vcs.domain.com;MatchOnlyPhoneUri=False;Enabled=True;ReplaceHostInRequestUri=True}
The VSC is hosted in a foreign domain. I want to route all traffic to VCS via 5060. SIPServerTCPPort is set to 5060 by the way.
Any hints ?!
Identity : Service:Registrar:pool.mydoamin,com
Route : {}
Regards Timo
Posted by: Timo Schönfeld | 09/29/2011 at 07:49
Timo,
You need to create the trusted application pool and trusted application computer in Topology Builder. The trusted application computer FQDN must match the FQDN you entered in the "destination" attribute of the new-csstaticroute cmdlet that you ran.
Posted by: Mike Stacy | 09/29/2011 at 07:53
Mike,
CSStaticRoute is unable to process FQDN when using TCP instead of TLS, what makes no sense for me....
If the FQDN is needed for a "URI-Routing" the IP-Address in TCP-Destination is total useless, or ?
Reagrds Timo
Posted by: Timo Schönfeld | 09/30/2011 at 01:23
Ok, I didn't realize that you were using TCP. I don't recommend TCP routes to my customers so I haven't used them very much but you still need the trusted computer and application pool but in your case the trusted computer will be an IP address rather than an fqdn.
Posted by: Mike Stacy | 10/08/2011 at 09:26
Hello Mike,
I've bumped into this error
TL_WARN(TF_DIAG) [0]1024.1BC4::09/10/2010-03:10:17.510.0003ebae (SIPStack,SIPAdminLog::TraceDiagRecord:SIPAdminLog.cpp(145))$$begin_record
LogType: diagnostic
Severity: warning
Text: Non-trusted source sent an FQDN/IP that doesn't match a routing table rule
Result-Code: 0xc3e93c5e SIPPROXY_E_ROUTING
SIP-Start-Line: INVITE sip:1003@video.domain.com SIP/2.0
SIP-Call-ID: 2ee2c5825a1248e6b37f03d70f25732a
SIP-CSeq: 1 INVITE
Data: user="1003@video.domain.com"
$$end_record
This is what you stated above and exactly there was a route created before I add a new front end pool
What should I do to fix this?
Please also refer to the post I asked here, thx
http://social.technet.microsoft.com/Forums/en-US/ocsplanningdeployment/thread/a28eccb1-e623-4841-a655-44c84b84d374
Posted by: Chan Andrew | 02/29/2012 at 16:49
Hi Mike,
this is an interesting post, especially considering the time when you wrote it.
I'm currently implementing a custom application on a UCMA server. Every time the application sends a SIP REGISTER on behalf of a user to the front end server, I can see exactly the error message you descibed in your article.
I configured a trusted application pool and a trusted application computer. The application is not routing for a different namespace or anything like that. It's just registering as some users and modifying settings for these users.
Do you have any idea why it's not accepting the traffic from the application server even though it should be a trusted computer?
Thanks a lot.
Jürgen
Posted by: Jürgen Pfeiffer | 06/13/2012 at 00:53
Hi all,
we found the answer to the question I posted before:
Even though you only leverage the signalling portion of UCMA, there still needs to be a trusted application associated to the trusted application pool. Without the trusted application, Lync server basically does not trust a trusted application computer assigned to a trusted application pool.
Cheers,
Jürgen
Posted by: Jürgen Pfeiffer | 06/13/2012 at 22:01
Hi Mike,
i want to clarify something related to my video domain and lync domains.
i have a situation where video domain and lync domain is same..now i don't know how the lync will differentiate where to route this calls.
i have created the trsusted application on the lync side. from video gatekeeper i am able to route the calls to lync clients.
but i am not getting what should i do on lync..the domain for video and lync is same for e.g. abc.com
can i write a static route on lync for shared domain as well?? can it effect something on lync??how the lync will understand that it should check the static routes, i mean on what condition it will check the static routes? is there anything like priority exist in the lync, so that if it doesn't find the user it check the static routes!!
Thanks
ALok
Posted by: Jaiswalok | 09/07/2012 at 06:22
Alok - Lync always checks a SIP address to determine if the user has a Lync account prior to sending the call out the static route. Therefore you can have a static route which matches any of the SIP domains which Lync is hosting.
Posted by: Mike Stacy | 09/11/2012 at 08:55
I have a further question about static routes, especially with regard to forwarding Lync to Lync calls via federation with a fall back to forwarding ALL other video call through a standards based SIP gateway.
We have a Cisco VCS environment which can be interrogated with Lync in this very fashion. The fact that register Lync users a queried first BEFORE the static route is great, but ideally we would want to ensure that all federated sites are also check before the static route is checked. It would be nice to ensure that ONLY video calls are forwarded via the VCS, as using the VCS for audio based calls could waste call licences.
So,
1) Can a static route be set up to forward ALL unknown address via a trusted application (in a similar vein to a default gateway)
2) Will all other Lync possibilities be check before failing back to a static rule?
3) Is it possible to set up a stic rule to ONLY forward video based calls?
Posted by: Swinster | 08/18/2013 at 17:12
Swinster - As far as I know it is not possible to do what you are asking. This is why I try to use one of the same SIP domains as Lync for the route (company.com rather than video.company.com). The downside to this is that requests to unknown users in your company (people that have left, etc.) will be sent across the static route as there is no simple way to send only video calls across the route. You could deploy an MSPL script to filter requests that you don't want and INVITEs that don't contain video SDP but you'd have to be very careful with both the MSPL code and the use of such a script since it can negatively impact performance. If you were going to do this I'd recommend using a separate pool for the routing connection that does not contain users. Alternatively you could build a go-between UCMA app. This would be a much better architecture but would require more code expertise and might cause support issues with your video vendor.
Posted by: Mike Stacy | 08/19/2013 at 09:23
Thanks Mike.
Indeed we are looking at the same SIP domain form all user within an organisation, however, I am more concerned with outbound calls to OTHER organisations outside of our control. This is quickly becoming a very common scenario.
Now, it maybe plausible that this "third party" organisation (lets call them otherlyncorg.com) utilises a Lync deployment, therefore the sensible way to go would be to set up a federation between my organisations Lync deployment and that of otherlyncorg.com, and so we have a native Lync-to-Lync call.
However, users in my organisation my want to call ANY other standard based SIP system/user direct from their Lync client. We can't possibly put static rules in place to cover all internet domains and so ideally would have to route ALL unknown domains (i.e those of users that that at not registered to Lync or that are not part of a Federated organisation), via the SIP gateway.
However, this could potentially overload the SIP Gateway itself which is designed for video calls not specifically voice calls. However, there should be a way out to the Internet in order that a standard DNS lookups can be made to place such a call to an unknown SIP destination (as is the case with our current videoconferencing infrastructure)
If this really isn't possible without custom code (which I fear is way beyond what I would be able to offer - I am entrenched in the video world with infrastructure from Tandberg/Cisco and this is my first foray into the Lync world), then the only possibility IS to add domain specific static rules as users request them - NOT pretty!. The Cisco VCS does offer a B2BUA, but there is not much scope in its configuration as well. My feeling should be that it would be down to Lync however, to simply not route a call that is not require by a particular app (i.e. stop voice calls place to an unknown SIP domain through the video trusted application.)
I take it that this would not be resolved in 2013?
As mentioned, I have not gone far with Lync as yet. How does Lync deal with calls to unknown SIP domains in general? I assume that it to would use DNS to look up to possibility of Lync based SIP systems via edge pools?
Posted by: Swinster | 08/19/2013 at 12:14
The only way to really deal with the situation you describe is to instruct users to dial a specific SIP URI format when calling non-Lync federated systems (192.168.1.10@externalvideo.com) and use whatever VCS/B2BUA features you need to modify the dial string and be able to route that call. Of course the two main problems with this are 1) the user needs to know in advance if they are calling a Lync system or not and 2) Lync isn't very accommodating to various URI strings so if you needed to dial IP/FQDN@extension or IP/FQDN##extension you will hit problems.
Lync 2013 drops H.263 so whatever you call would need to be able to communicate over RTV or H264UC (Lync's SVC).
For ubiquitous connectivity a virtual meeting room strategy works best. I don't know if Cisco has a similar approach to Polycom in this regard but by meeting on the RMX it means the dial experience for your internal users is always the same and you can connect H.323, OCS/Lync 2010/Lync 2013, and non-Lync SIP platforms all together. You can also gateway calls and the like when necessary.
Outside of that you will probably need some fancy code to make this work seamlessly.
Posted by: Mike Stacy | 08/19/2013 at 14:26