Windows-Server-2012-R2

Exchange 2016 共存 - OWA 在負載平衡器後面時不會登錄

  • March 19, 2017

我目前正在開發實驗室環境以將我們的混合 Exchange 2010 和 2013 環境遷移到 Exchange 2016。

我已經在實驗室共存執行 1x 2013 和 2x 2016 幾個星期了,它執行良好 - 我已經完成了 RPC、OWA、ActiveSync 和 EWS 的測試。一切似乎都很好。

本週我嘗試通過在前面引入負載均衡器來完成我的部署,併計劃在我的 2013 年和 2016 年 CAS 節點之間提供循環 LB。從我研究的所有內容來看,2013 年和 2016 年 CAS 與 CAS 角色完全兼容,因為它們很樂意在彼此之間進行代理。為了確保我通過每個 CAS(沒有負載均衡器)進行的手動測試似乎表明了這一點。

但是既然前面已經介紹了HA Proxy,OWA似乎就不想正常工作了。

症狀

這裡有一些症狀:

  • 當我通過 2016 OWA 登錄到 2013 郵箱時,它確實正確登錄、重定向我並開始載入收件箱。但是在載入收件箱一兩秒鐘後,我被重定向回 OWA 登錄頁面,就好像我從未登錄過一樣。
  • 只要我通過 2016 CAS 登錄,我可以多次重複此操作,並且似乎做同樣的事情。
  • 有時當我通過 2016 登錄時,它只會掛起“仍在工作”。不過,這遠沒有讓我退出的頻率那麼高。
  • 有時它會很快重定向回登錄頁面,我什至根本無法告訴我是否已登錄,並且沒有錯誤消息。這只是一個閃光然後回到登錄頁面。
  • 我已經在 Mac 和 Windows 8.1 上嘗試了 Chrome 和 Firefox 的最新版本。所以這不是終端設備問題。
  • 如果我通過 2013 CAS 上的 OWA 登錄到 2013 郵箱,即使通過負載均衡器,它似乎第一次正確登錄。
  • 我在負載均衡器上有一個 IP,然後以循環方式代理到每個 CAS 節點的流量。這是我用來測試我的 LB 的。我有其他 IP 直接指向單個 CAS 節點。
  • 如果我直接登錄到 2016 CAS 節點到 2013 郵箱,這工作正常。這是我通過出現問題的負載均衡器登錄到 2016 CAS 的一個。
  • 有趣的是,我只是注意到即使登錄 2016 郵箱也會出現完全相同的問題。因此,只要我登錄 2016 CAS,它就會註銷。
  • 通過 2013 CAS 成功登錄後,我可以多次刷新頁面,會話仍將保持打開狀態。對我來說,這表明一旦建立會話,代理必須在某種程度上工作正常,因為我的 LB 是循環的,所以每次刷新 OWA 頁面時,流量都應該重新分配到各個 CAS 節點。

我似乎很清楚,在負載平衡器後面時,還有其他人在使用 Exchange 2010 - 2016 時遇到了類似的問題。不幸的是,這是我們第一次使用負載均衡器,因為我們正在從單個 CAS 遷移到 3,升級到 Exchange 2016。

我發現了一些具有類似症狀的文章:

我試過的

  • 我已經確認我們所有的 SSL 前端(第三方 CA)證書在所有 CAS 節點上都與相同的指紋和序列匹配。我讀過這會影響事情。我正在使用生產證書來正確測試我的實驗室。
  • 後端證書保留為預設的 Microsoft Exchange 證書,據我所知,這很好。無論如何,我實際上嘗試在後端使用我們的萬用字元證書,它似乎破壞了一切。
  • 我已經驗證,在沒有負載均衡器的情況下訪問 2016 CAS 時,一切似乎都正常。基於此,我想如果我要在負載均衡器上啟用完整的會話持久性,以便特定使用者只處理一個 CAS,它將解決問題。但是,我不應該那樣做。這讓我擔心有一個更深層次的錯誤需要解決。
  • 我已啟用 IIS 失敗請求跟踪。我發現一些關於 powershell 請求的 500 個錯誤的報告。但它們似乎與失敗的健康監控請求有關,並且在時間上似乎不一定與我的 OWA 測試讓我退出。
  • 我已經通過 Wireshark 進行了一些基本檢查,以尋找任何奇怪的東西。我注意到單個 OWA 頁面載入肯定至少分佈在多個 CAS 節點上。有時兩個 2016 節點,有時一個 2016 和一個 2013 節點。
  • 我在擷取(在負載均衡器上)中確實注意到,在一次失敗的登錄嘗試期間,我不斷收到來自 CAS 節點的重複**440 Login Timeout響應。**在這種情況下,我得到了多個,每個 CAS 節點至少有一個。
  • 初始登錄請求之後有很多單獨的 HTTP 請求,很難確定問題出在哪裡,但似乎瀏覽器開始發送一堆 OWA service.svc 請求,並且在某些時候它們都被返回與來自 CAS 節點的響應相同的**440 Login Timeout錯誤。**然後最終我們被重定向回登錄頁面。
  • 通過我的研究,我還沒有發現任何實際導致 440 登錄超時的原因,或者它是否是預期的行為等……
  • 我已經根據我們的生產設置重新檢查了我的所有虛擬目錄設置。他們看起來不錯。

編輯:2017-03-04

  • 我嘗試了多種不同的 VirtualDirectory 內部和外部 URL 組合。exchange.isp.com.au 是內部 AD 域(這與實時設置相匹配)。實驗室的外部 URL 是 exchlab.isp.com.au。

  • 我試過了:

    • exchlab.isp.com.au 用於內部和外部。
    • exchange.isp.com.au 用於內部和外部。
    • 我堅持使用 exchlab 進行外部交換並交換內部。這些組合都沒有產生任何影響。
  • 此後,我還在 HA Proxy 中添加了基於 Cookie 的會話持久性,似乎有所作為。我只對OWA和ECP做了持久化,其餘的都沒有持久化。注意事項:

    • 我不再重複退出 OWA。它變得更加穩定。
    • 當我第一次退出郵箱(例如 2013 年)並登錄到不同版本的郵箱時,它仍然會發生。(例如 2016 年)。但是,在我第一次註銷後,我現在可以成功重新登錄。
    • 如果我退出郵箱並太快(在 10 秒內)重新登錄,那麼我經常會立即被踢出。
  • 我還決定繼續測試除 OWA 之外的服務的 HA 代理。我可以確認:

    • Outlook Anywhere 在所有 3 個 CAS 節點上進行負載平衡並且工作正常。
    • EWS 還對所有 3 個進行負載平衡,並且工作正常。
    • Active Sync 似乎只想超過 2x 2016 CASes,但負載平衡也很好。

我需要嘗試的事情

我還沒有真正做到這些,因為我覺得有一個實際的配置問題。此外,由於沒有負載平衡器,一切似乎都可以正常工作,我看不到這有幫助。

更多環境資訊

有關我正在測試的實驗室環境的更多詳細資訊。

  • 我們的負載均衡器配置取自這裡:https ://www.haproxy.com/doc/aloha/7.0/deployment_guides/microsoft_exchange_2013.html#aloha-configuration - 我們使用“SSL 解除安裝 - HTTP 反向代理”配置(高級版)。
  • 我們正在根據本指南進行 SSL 解除安裝:https ://serversforhackers.com/using-ssl-certificates-with-haproxy和本指南:https ://jaapwesselius.com/2014/02/28/exchange-2013-sp1 -ssl-解除安裝/
  • 我們的 Exchange 2013 機器正在執行 SP1 \w CU11
  • 我們的 Exchange 2016 機器正在執行 CU2。我有意避免升級到 CU4,因為我想使用負載平衡器測試並記錄一個優雅的升級過程。
  • 我們正在執行 2 倍額外的虛擬機作為專用 AD。Exchange 節點上沒有 AD。
  • 所有 Windows 系統(包括 AD)都執行 Windows 2012 R2。
  • 我們的路由器是一個做 NAT 的 Linux 機器。負載平衡器與 Exchange 伺服器和 AD 框位於同一 /24 子網中。
  • LB HTTP 前端是 .7,交換框是 .1、.2 和 .3
  • 我們還在 .4、.5 和 .6 上的每個 Exchange 框的專用 IP 上執行簡單的 HTTP 重定向。雖然我計劃將這個簡單的重定向轉移到負載均衡器,因為它可以輕鬆地進行 HTTP 重定向。

我的負載均衡器配置的相關位:

   # 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

我最終合理地解決了這個問題。一些文章提到了類似的問題,在他們的負載均衡器上添加基於 Cookie 的持久性已經為他們解決了這個問題。

我拒絕了這種“因為我不應該這樣做”,微軟的所有技術文章都說不再需要,而且確實不推薦。

但我屈服了,最終為 OWA 和 ECP 添加了持久性。結果是問題沒有完全解決,但幾乎沒有引起注意。我遇到問題的唯一一次是如果我在一個郵箱上註銷 OWA,然後立即登錄到另一個郵箱。即使那樣,它也會將您踢出一次,但如果您嘗試再次登錄,它會正常工作。

在此之後沒有持續的問題。此外,我僅在從 2013 年遷移到 2016 年郵箱時才注意到剩下的問題。

這不是我們的最終使用者可能會做的事情,而且我們幾乎完成了將所有郵箱遷移到 2016 年的工作。所以我正在考慮圍繞“足夠好”進行這項工作。

由於我們使用的是 HA 代理,因此在配置中添加一些基於第 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

引用自:https://serverfault.com/questions/836124