Apache als Reverse Proxy

RPC und Apache
Anscheinend kann Apache ab Version 2.0.55 nicht mehr als Reverse Proxy für RPC over HTTP eingesetzt werden. Laut Apache Entwickler verhält sich Outlook/Exchange nicht HTTP-Konform und könnte bei einer Umsetzung dieser Abweichung ein Sicherheitsloch öffnen.
http://www.mail-archive.com/bugs@httpd.apache.org/msg23000.html
Andere Quellen behauten aber mit 2.2.8 eine funktionierende Konfiguration zu haben

Case Sensibel
Die Apache Veröffentlichungen beachten Groß/Kleinschreibung. Die Benutzer müssen also die "richtige" URL eingeben. Das ist ungewohnt, da ISA und IIS nicht darauf achten.

Lesen Sie dazu auch die Seite OWA Absichern

Zwar ist der Marktanteil des ISA-Servers schon recht hoch aber sehr viele Firmen setzen andere Proxy Systeme für den Zugriff auf das Internet und die Veröffentlichung von Webseiten ein. für den Outlook Webzugriff sind auch hier einige "Besonderheiten" zu beachten

Auch wenn Apache eher als leistungsstarker Webserver bekannt ist, so kann Apache über die "MOD"-Schnittstelle mit zusätzlichen Funktionen erweitert werden, z.B. mit einer Anmeldung gegen ein Active Directory. Apache kann zwar nicht als OWA-Server arbeiten, da er ISAPI-Filter nicht unterstützt, aber Apache kann über das Modul MOD_PROXY als HTTP-Proxy arbeiten. Das  funktioniert sogar in beide Richtungen. Apache kann also als "OWA Veröffentlichungsserver" als auch als Proxy für den Zugriff über das Internet auf einen entfernten OWA-Server genutzt werden.

Beispielkonfiguration

Ich bin nun kein Apache Spezialist, aber folgende Einträge in der httpd.conf sollen für OWA und ActiveSync funktionieren, wenn Sie "exchangeserver.firma.tld." durch ihren Server ersetzen.

Verschiedene Leser (und Apache Nutzer) haben mit Tipps die Konfiguration immer weiter verbessert.

LoadModule proxy_module /usr/lib/apache/mod_proxy.so
AddModule mod_proxy.c


# Security Header removal
Header always set X-Frame-Options SAMEORIGIN
Header set Server Apache
Header unset X-AspNet-Version
Header unset X-OWA-Version
Header unset X-Powered-By
 
# http://stackoverflow.com/questions/3889574/apache-and-mod-proxy-not-handling-http-100-continue-from-client-http-417
RequestHeader unset Expect early
 
# Rewrite the WWW-Authenticate header to strip out Windows Integrated Authentication (NTLM) and only use Basic-Auth -> http://social.technet.microsoft.com/Forums/exchange/en-US/7eb1f39f-c53f-49aa-9038-6962bfc386ca/autodiscover
 
 SetEnvIf User-Agent ".*MSIE.*" value BrowserMSIE
  Header unset WWW-Authenticate
  Header add WWW-Authenticate "Basic realm=webmail.msxfaq.de"
 
 
ProxyPreserveHost On
#Config:
#Veroeffentlichungen fuer OWA

ProxyPass /owa https://exchangserver.firma.tld/owa
ProxyPassReverse /owa https://exchangeserver.firma.tld/owa

ProxyPass /exchange https://exchangserver.firma.tld/exchange
ProxyPassReverse /exchange https://exchangeserver.firma.tld/exchange

ProxyPass /Exchange https://exchangeserver.firma.tld/exchange
ProxyPassReverse /Exchange https://exchangeserver.firma.tld/exchange

ProxyPass /exchweb https://exchangeserver.firma.tld/exchweb
ProxyPassReverse /exchweb https://exchangeserver.firma.tld/exchweb

ProxyPass /public https://exchangeserver.firma.tld/public
ProxyPassReverse /public https://exchangeserver.firma.tld/public


# Einstellungen um per OWA das Kennwort zu aendern
ProxyPass /iisadmpwd https://exchangeserver.firma.tld/iisadmpwd
ProxyPassReverse /iisadmpwd https://exchangeserver.firma.tld/iisadmpwd

# Einstellungen fuer ActiveSync
# Hier sollte man das connection timout auf 600sek hinaufdrehen, 
# da sonst meistens im Apache-Log ein Timout-error auftritt.

ProxyPass /Microsoft-Server-ActiveSync https://exchangeserver.firma.tld/Microsoft-Server-ActiveSync connectiontimeout=600
ProxyPassReverse /Microsoft-Server-ActiveSync https://exchangeserver.firma.tld/Microsoft-Server-ActiveSync


# AutoDiscover  -> Autodiscover für non-AD integrated Clients (Mac, eg.)
ProxyPass /autodiscover https://exchangeserver.firma.tld/autodiscover
ProxyPassReverse /autodiscover https://exchangeserver.firma.tld/autodiscover
ProxyPass /Autodiscover https://exchangeserver.firma.tld/Autodiscover
ProxyPassReverse /Autodiscover https://exchangeserver.firma.tld/Autodiscover
ProxyPass /AutoDiscover https://exchangeserver.firma.tld/AutoDiscover
ProxyPassReverse /AutoDiscover https://exchangeserver.firma.tld/AutoDiscover


# Proxy fuer SSL aktivieren
SSLProxyEngine On

# Zeichensatz spezifieren fuer umlaute
AddDefaultCharset ISO-8859-1


# Connection handshake between IIS and Apache
        SetEnv proxy-nokeepalive 1
        SetEnv force-proxy-request-1.0 1
        Order deny,allow
        Allow from all


  BrowserMatch "MSIE [2-6]" \
    nokeepalive ssl-unclean-shutdown \
    downgrade-1.0 force-response-1.0
  # MSIE 7 and newer should be able to use keepalive
  BrowserMatch "MSIE [17-9]" ssl-unclean-shutdown

Auch wenn hier sich mehrere Parameter oft wiederholen, möchte ich drei Einträge erläutern, da sie sehr wichtig sind

  • ProxyPreserveHost On
    http://httpd.apache.org/docs/2.0/mod/mod_proxy.html#proxypreservehost
    Dieser Eintrag stellt sicher, dass der Hostname, welcher im Request durch den Client angekommen ist auch 1:1 an den nachfolgenden Server weiter gegeben wird. Sehr viele Webseiten (auch Exchange und WSUS) nutzen den Namen im Request um nicht nur die richtige Webseite anzusprechen, sondern auch in der Rückgabe vorhandenen Links mit dem richtigen Namen zu versehen. Nicht alle Anwendungen nutzen nämlich immer relative URLs. Und hiermit werden Probleme aufgrund interner (nicht erreichbarer) Hostnamen in Antworten schon mal verhindert
  • ProxyPass /owa https://exchangserver.firma.tld/owa
    http://httpd.apache.org/docs/2.0/mod/mod_proxy.html#proxypass
    Dieser Eintrag lässt die angegeben remote Seite "https://exchangserver.firma.tld/owa" so erscheinen, als wenn Sie auf dem lokalen Server liegen würde. Dieser Eintrag ist also die relevante Konfiguration, dass der Apache auch tatsächlich einen Reverse Proxy ausführt
  • ProxyPassReverse /owa https://exchangeserver.firma.tld/owa
    http://httpd.apache.org/docs/2.0/mod/mod_proxy.html#proxypassreverse
    Dieser Eintrag weißt den Apache an, die Namen im HTTP-Reply-Header umzuschreiben, d.h. immer wenn in der Antwort die Interne URL auftaucht, wird dieser durch die Adresse des Apache ersetzt. Das gilt aber nur für die Felder "Location", "Content-Location" und "URI header". Apache ersetzt aber so erst mal keine Einträge in den Nutzdaten. Diese sollten vom eigentlichen Webserver im Hintergrund durch die ProxyPreserveHost-Directive korrekt erstellt werden oder Sie können mit dem Modul "MOD_PROXY" auch noch diese Daten ersetzt.

Dies sind die drei wichtigsten Einstellungen aber nicht die einzigen Parameter, die in Verbindung mit Apache als Reverse Proxy eingesetzt werden können. Wer z. B. Kerberos oder NTLM einsetzt, wird in größeren Umgebungen die Buffer für die Ticketsize (Siehe Kerberos Ticketsize) und andere Dinge anpassen müssen.

ProxyVia: Reverse Proxy mit verschiedenen Sessions

Bei der Konfiguration des Apache als Reverse Proxy gibt es die Option "ProxyVia". Die ist normalweise "Off" ,so dass der Header nicht addiert wird. Das kann aber zugleich dazu führen, dass Exchange nicht erkennt, dass ein Proxy in der Kette ist und dass mehrere Client-Connections von vorne nach hinten über die gleiche Backend-Verbindung geroutet werden. Das kann so natürlich nicht gehen.

Es ist daher erforderlich, den Eintrag auf "On" oder "Full" zu stellen, damit MOD_PROXY in jeden Request auch den ProxyVia addiert und alle beteiligten Systemen dies korrekt umsetztn

X-Forwarded-For

Wann immer ein Reverse-Proxy in der Kette ist, kann der nachgelagerte Webserver ohne Mitarbeit des Proxy-Servers nicht mehr die eigentliche Client-IP protokollieren. Er sieht ja nur noch die IP-Adresse des Proxy-Servers. Daher sollten Sie den Proxy-Server anweisen, die anfragende Client-IP-Adresse in einen zusätzlichen Header zu übertragen und dann auch auf dem Webserver dieses Feld mit in die Protokollierung aufnehmen.

Reverse Proxy mit Authentifizierung

Apache kann aber nicht nur ein dummer Reverse Proxy sein. Über entsprechende Module kann Apache sogar Windows DCs zur Überprüfung der Anmeldedaten heran ziehen. So könnte ein Apache den Zugriff auf die per Reverse Proxy veröffentlichten Dateien ebenfalls per Anmeldung absichern. Der Client würde also zuerst eine 401 Meldung vom Apache bekommen und müsste sich z.B.: per Kerberos anmelden, ehe der Apache dann die Anfragen weiter gibt. Allerdings wäre dann zu prüfen, wie der nachgeschaltete Server die Anmeldung akzeptiert. Apache kann zwar Header-Felder setzen aber das Kennwort des Anwender hat er in der Regel erst einmal nicht und kann dies daher auch nicht weiter geben. Inwieweit Kerberos Constraint Delegation möglich ist, wäre zu testen.

Outlook Anywhere

Lange Zeit war es nicht möglich, Outlook Anywhere über Apache bereit zu stellen, da Outlook hier mit den Header-Length-Angaben getrickst hat. Mittlerweile gibt es Beschreibungen im Internet, dass es doch gehen soll. Ich konnte diese aber noch nicht umsetzen.

Allerdings funktioniert mod_proxy_msrpc nur ab Apache Version 2.4.x

Apache mit Lync 2013 WebServices

Externe Anwender benötigen für die Arbeit mit Lync nicht nur einen Edge-Server, sondern auch die Lync Web Services sind für den Zugriff erforderlich. Das gilt um so mehr beim Einsatz von UCWA, welches z.B. von den mobilen Clients genutzt wird. Auch LyncDiscover, Meeting-Join, DialIn und andere Dienste werden von Lync so bereit gestellt.

Microsoft veröffentlicht z.B. die Liste "Qualified für Lync" ( http://technet.microsoft.com/en-us/lync/gg131938) entsprechende Proxies. Damit sind aber andere Proxies nicht ausgeschlossen. Microsoft dokumentiert das selbst

Lync Server 2013 does not specify a particular reverse proxy that you must use. Lync Server 2013 only defines operational requirements that the reverse proxy must be able to do. Typically, the reverse proxy that you already have deployed in your infrastructure may be able to meet the requirements
Configuration Requirements für Reverse Proxy (http://technet.microsoft.com/en-us/library/jj945651.aspx )

Auf der Seite wird natürlich nicht beschrieben, was der Proxy nicht machen darf. Er sollte "transparent" sein. Gerade Apache kennt aber z.B. Direktiven, mit denen der Proxy die Rückgaben "korrigiert". Und das hat durchaus negative Auswirklungen. So fordern die Lync Mobile Clients per UCWA Informationen an, z.B.

2014-03-16 09:54:20.206 Lync[1952:699b000] INFO TRANSPORT TransportUtilityFunctions.cpp/634:<SentRequest>
POST https://lyncweb.msxfaq.net/UCWA/v1/applications/213846428157/people/contactsAndGroupsSubscription/startOrRefresh?duration=60
Request Id: 0x66e45c9
HttpHeader:Accept application/vnd.microsoft.com.UCWA+xml
HttpHeader:Content-Type application/vnd.microsoft.com.UCWA+xml
HttpHeader:X-MS-Namespace internal
HttpHeader:X-MS-WebTicket xxxxxxxxxx

<input xmlns="http://schemas.microsoft.com/rtc/2012/03/UCWA"/>

</SentRequest>

Bei einer falschen Konfiguration hat hier die Antwort wie folgt ausgesehen.

2014-03-16 09:54:20.308 Lync[1952:699b000] INFO TRANSPORT TransportUtilityFunctions.cpp/928:<ReceivedResponse>
POST https://lyncweb.msxfaq.net/UCWA/v1/applications/213846428157/people/contactsAndGroupsSubscription/startOrRefresh?duration=60
Request Id: 0x66e45c9
HttpHeader:Cache-Control no-cache
HttpHeader:Connection Keep-Alive
HttpHeader:Content-Length 0
HttpHeader:Content-Type text/plain; charset=UTF-8
HttpHeader:Date Wed, 16 Jul 2014 07:54:18 GMT
HttpHeader:Keep-Alive timeout=15, max=94
HttpHeader:Server Microsoft-IIS/8.5
HttpHeader:StatusCode 204
HttpHeader:X-AspNet-Version 4.0.30319
HttpHeader:X-Ms-Namespace internal
HttpHeader:X-MS-Server-Fqdn FE1.msxfaq.local
HttpHeader:X-Powered-By ASP.NET

xxxxxxxxxx

</ReceivedResponse>

Wer genau hinschaut findet die dass der "Content-Type" nicht das erwartete "application/vnd.microsoft.com.UCWA+xml" sondern ein einfaches "test/plain" ist. Da ist also ein Reverse Proxy dazwischen, der etwas korrigiert. Nicht überraschend ist dann in der nächsten Zeile die Fehlermeldung im Log

ERROR TRANSPORT TransportUtilityFunctions.cpp/1770:Accept-types (application/vnd.microsoft.com.UCWA+xml) 
not found in Content-Type response from server (text/plain;).  Not decoding.

Weitere Links

Weitergehende Informationen finden Sie auf: