Exchange 2016共存 – OWA不会在负载均衡器后面login

目前,我正在开发实验室环境,将混合的Exchange 2010和2013环境迁移到Exchange 2016。

我已经在实验室中运行了1x 2013和2x 2016,现在已经运行了好几个星期,并且运行良好 – 我已经完成了对RPC,OWA,ActiveSync和EWS的testing。 一切似乎都很好。

本周,我试图通过在前面引入负载平衡器来完成我的部署,计划在我的2013和2016 CAS节点之间提供循环LB。 从我所研究的2013年和2016年起,CAS完全兼容CASangular色,因为他们很乐意代理对方。 而且要确定我通过每个CAS进行手动testing(没有负载平衡器)似乎表明了这一点。

但是现在我已经介绍了HA代理,OWA似乎不想正常工作。

症状

这里有一些症状:

  • 当我通过2016 OWAlogin到2013邮箱时,它会正确login,redirect我,并开始加载收件箱。 但是在加载收件箱后的一两秒钟之后,我重新回到了OWAlogin页面,就好像我从未login过一样。

  • 我可以多次重复,只要我通过2016 CASlogin,似乎也是这样做的。

  • 有时当我通过2016login时,它只会挂起“仍在工作”。 不过,这种情况远不那么频繁,只是把我退出了。

  • 有些时候,它很快redirect到login页面,我什至不能告诉我login,并没有错误信息。 这只是一个闪光,然后回到login页面。

  • 在Mac和Windows 8.1上,我已经尝试了最新版本的Chrome和Firefox。 所以这不是terminal设备问题。

  • 如果我通过2013年CAS上的OWAlogin到2013邮箱,即使通过负载平衡器,它似乎第一次正确login。

  • 我在负载均衡器上有一个IP,然后以循环方式代理每个CAS节点的stream量。 这是我用来testing我的LB. 我有其他IP直接指向个别CAS节点。

  • 如果我直接login到2016年CAS节点到2013邮箱,这工作正常。 这是我通过负载均衡器login到2016 CAS的一个问题。

  • 有趣的是,我刚刚注意到即使login到2016邮箱也会出现完全相同的问题。 所以只要我login到2016 CAS,它就会退出。

  • 一旦我通过2013 CAS成功login,我可以多次刷新页面,会话仍然保持开放。 对我来说,这表明一旦会话build立,代理一定程度上正常工作,因为我的LB是循环(round-robin),所以每次刷新OWA页面时,stream量都应该重新分布在各个CAS节点上。

我似乎很清楚,在负载平衡器后面还有其他人遇到与Exchange 2010-2016类似的问题。 不幸的是,这是我们第一次使用负载平衡器,因为我们正在从单一CAS升级到3,并且升级到Exchange 2016。

我发现有相似症状的公平的几个职位:

我所试过的

  • 我已经确认,所有的CAS前端(第三方CA)证书都与所有CAS节点上的thumprint和serial相同。 我读过这可以影响的东西。 我正在使用生产证书来正确testing我的实验室。

  • 后端证书保留为默认的Microsoft Exchange证书, 从我读过的这个很好。 我实际上试图在后端使用我们的通配证书,似乎打破了一切。

  • 我已经validation,在没有负载均衡器的情况下访问2016 CAS时,情况似乎正常。 在此基础上,我想如果要在负载平衡器上启用完整会话持久性,以便特定用户只处理一个CAS,则可以解决问题。 但是, 我不应该这样做 。 这让我担心有一个更深的错误要解决。

  • 我启用了IIS失败的请求跟踪。 我发现了一些关于PowerShell的错误报告。 但是他们似乎与健康监测请求失败有关,而且我的OWAtesting并不一定是按照时间顺序排列的。

  • 我已经通过Wireshark做了一些基本的检查来寻找任何奇怪的东西。 我注意到,单个OWA页面加载肯定是至less分布在多个CAS节点上的。 有时候是2016年的两个节点,有时候是2016年和2013年的节点。

  • 我注意到在我的捕获(在负载平衡器),在一个失败的login尝试期间,我一直从CAS节点重复440login超时响应。 在这种情况下,我得到了其中的多个,每个CAS节点至less有一个。

  • 在初始login请求之后有很多单独的HTTP请求,很难指出问题所在,但似乎是一堆OWA service.svc请求开始被浏览器发送,并且在某些时候它们都是作为来自CAS节点的响应返回相同的440login超时错误。 最后我们被redirect回login页面。

  • 我还没有find任何通过我的研究什么实际上导致440login超时,或者如果它的预期行为等…

  • 我已经重新检查了所有我的虚拟目录设置对我们的生产设置。 他们看起来不错。

编辑:2017-03-04

  • 我已经尝试了多种不同的VirtualDirectory内部和外部URL组合。 exchange.isp.com.au是内部AD域(这与现场设置相匹配)。 实验室的外部URL是exchlab.isp.com.au。

  • 我努力了:

    • exchlab.isp.com.au内部和外部。
    • exchange.isp.com.au内部和外部。
    • 我坚持exchlab外部和内部交stream。 这些组合没有一个有所作为。
  • 从那以后,我也在HA Proxy中添加了基于Cookie的会话持久性,似乎有所作为。 我只做了OWA和ECP的坚持,但其余的都不是持久的。 注意事项:

    • 我不再反复退出OWA。 它变得更加稳定。
    • 它仍然发生在我第一次注销邮箱(例如2013)并login到不同版本的邮箱。 (如2016)。 但是,在我第一次登出后,我现在可以成功login了。
    • 如果我从邮箱注销并退回速度太快(10秒内),我会立即将其退回。
  • 除了OWA之外,我还决定继续testingHA代理服务。 我可以确认:

    • Outlook Anywhere对所有3个CAS节点进行负载均衡,并正常工作。
    • EWS也负载均衡3和工作正常。
    • 主动同步似乎只想过去2倍2016年CASes,但也负载平衡罚款。

我需要尝试的东西

  • 重置我所有的虚拟目录
  • 重新同步IIS IUSR帐户: https ://technet.microsoft.com/en-us/library/dd789741( v= exchg.80).aspx
  • validationIUSR授权级别。

我还没有真正做到这一点,因为我觉得有一个实际的configuration问题。 此外,因为一切似乎没有负载平衡器工作,我看不到这个帮助。

更多的环境信息

关于我正在testing的实验室环境的更多细节。

  • 我们的负载均衡configuration取自以下url : https : //www.haproxy.com/doc/aloha/7.0/deployment_guides/microsoft_exchange_2013.html#aloha-configuration – 我们使用“SSL卸载 – HTTP反向代理”configuration(高级版)。
  • 我们正在根据本指南进行SSL卸载: https : //serversforhackers.com/using-ssl-certificates-with-haproxy和本指南: https : //javawesselius.com/2014/02/28/exchange-2013-sp1 -ssl-卸载/

  • 我们的Exchange 2013框正在运行SP1 \ w CU11

  • 我们的Exchange 2016盒子正在运行CU2。 我故意避免升级到CU4,因为我想testing并logging负载平衡器的正常升级过程。
  • 我们运行2个额外的虚拟机作为专用AD。 Exchange节点上没有AD。
  • 所有Windows系统(包括AD)都运行Windows 2012 R2。

  • 我们的路由器是一个做NAT的Linux机器。 负载均衡器与Exchange服务器和AD盒位于同一个/ 24子网中。

  • LB的HTTP前端是.7,交换框是.1,.2和.3

  • 我们还在.4,.5和.6的每个交换箱的专用IP上运行简单的HTTPredirect。 虽然我打算将这个简单的redirect转移到负载平衡器,因为它可以很容易地做HTTPredirect。

我的负载均衡器configuration的相关位:

# This is the L7 HTTPS Front End # ------------------------------ # We redirect to different backends depending on the URI # Each backend has its own separate health checks. So that each service can fail on an Exchange CAS node without affecting the other services. frontend ft_ISP_EXCHANGE_https bind 172.16.10.7:80 name INT_http bind 172.16.10.7:443 name INT_https ssl crt wildcard.isp.com.au.pem # Specify SSL Cert for offloading. mode http option http-keep-alive option prefer-last-server no option httpclose no option http-server-close no option forceclose no option http-tunnel timeout client 600s log global capture request header Host len 32 capture request header User-Agent len 64 capture response header Content-Length len 10 # log-format directive must be written on a single line # it is splitted for documentation convnience log-format %ci:%cp\ [%t]\ %ft\ %b/%s\ %Tq/%Tw/%Tc/%Tr/%Tt\ %ST\ %B\ %CC\ %CS\ %tsc\ %ac/%fc/%bc/%sc/%rc\ %sq/%bq\ %hr\ %hs\ {%sslv/%sslc/%[ssl_fc_sni]/%[ssl_fc_session_id]}\"%[capture.req.method]\ %[capture.req.hdr(0)]%[capture.req.uri]\ HTTP/1.1 maxconn 1000 acl ssl_connection ssl_fc # Set ACL ssl_connection if ssl_fc returns TRUE # Route request to a different backend depending on the path: # http://serverfault.com/questions/127491/haproxy-forward-to-a-different-web-server-based-on-uri acl host_mail hdr(Host) -i exchange.isp.com.au acl path_slash path / acl path_autodiscover path_beg -i /Autodiscover/Autodiscover.xml acl path_activesync path_beg -i /Microsoft-Server-ActiveSync acl path_ews path_beg -i /ews/ acl path_owa path_beg -i /owa/ acl path_oa path_beg -i /rpc/rpcproxy.dll acl path_ecp path_beg -i /ecp/ acl path_oab path_beg -i /oab/ acl path_mapi path_beg -i /mapi/ acl path_check path_end -i HealthCheck.htm # HTTP deny rules http-request deny if path_check # HTTP redirect rules http-request redirect scheme https code 302 unless ssl_connection # Force SSL http-request redirect location /owa/ code 302 if path_slash host_mail # Redirect / to /owa # HTTP routing rules -- This is where we decide where to send the request # Based on HTTP path. use_backend bk_ISP_EXCHANGE_https_autodiscover if path_autodiscover use_backend bk_ISP_EXCHANGE_https_ews if path_ews # other services go here default_backend bk_ISP_EXCHANGE_https_default # Backends # -------- # Now we define each backend individually # Most of these backends will contain all the same Exchange CAS nodes, pointing to the same IPs # The reason we define each backend individually is because it allows us to do separate Health Checks # for each individual service running on each CAS node. # The failure of one service on a CAS node does not exclude that CAS node from participating in other # types of requests. This gives us better overall high-availability design. # HTTPS OWA # I have added additional comments on this definition, but the same applies to all Exchange HTTPS backends. backend bk_ISP_EXCHANGE_https_owa balance roundrobin # Use round-robin load balancing for requests option http-keep-alive # Enable HTTP Keepalives for session re-use and lowest latency for requests. option prefer-last-server # Prefer to keep related connections for a session on the same server. # This is not the same as persistence, and is mainly to try and take advantage of HTTP Keepalives. # See here for an example of why this is needed: http://stackoverflow.com/questions/35162527/haproxy-keep-alive-not-working-as-expected no option httpclose # Disable all options that are counter to keepalives no option http-server-close no option forceclose no option http-tunnel mode http # Operate in L7 HTTP Mode (vs TCP mode etc) log global option httplog option forwardfor # Enable insertion of the X_FORWARDED_FOR HTTP Header option httpchk GET /owa/HealthCheck.htm # Use L7 HTTP Health Check. This is recommended by Microsoft. http-check expect string 200\ OK default-server inter 3s rise 2 fall 3 timeout server 60s # Define CAS Nodes for this service. We're using SSL offloading to allow L7 HTTP Checks # We've avoided SSL Bridging as that would halve our LB's throughput. server ISP_exch16_syd_01 172.16.10.2:80 maxconn 1000 weight 10 check server ISP_exch16_syd_02 172.16.10.3:80 maxconn 1000 weight 10 check server ISP_exch13 172.16.10.1:80 maxconn 1000 weight 10 check 

我最终合理地解决了这个问题。 有几个post提到类似的问题,在其负载平衡器上添加基于Cookie的持久性已经解决了他们的问题。

我抵制这个“因为我不应该”,所有来自微软的技术文章都说这已经不再需要了,实际上并不推荐。

但是我放弃了,最终增加了OWA和ECP的持久性。 结果是这个问题没有完全解决,但几乎没有引起注意。 我遇到问题的唯一时间是如果我注销一个邮箱OWA,然后立即login到另一个。 即使这样,它会踢你一次,但如果你尝试再次login它工作正常。

此后没有持续的问题。 此外,我只注意到从2013年到2016年邮箱的问题。

这不是我们的最终用户可能做的事情,而且我们几乎已经完成将所有邮箱移动到2016年。所以我正在考虑这项工作“够好”。

由于我们使用的是HA代理,因此在configuration中添加一些第7层基于cookie的持久性并不是什么大问题。 其实只花了5分钟左右就搞定了:

 # HTTPS Outlook Web App (OWA) backend bk_EXCHANGE_https_owa cookie LB01 insert indirect nocache # <-- Added this balance roundrobin mode http ... # Added the "cookie <name>" at the end of each CAS node definition # These names must be unique to each node. server n1_exch16_syd_01 172.16.10.2:80 maxconn 1000 weight 10 check cookie EXCH16-SYD-01 server n1_exch16_syd_02 172.16.10.3:80 maxconn 1000 weight 10 check cookie EXCH16-SYD-02 server n1_exch13 172.16.10.1:80 maxconn 1000 weight 10 check cookie EXCH13-SYD