Table of Contents

Websockets

Die Zeichen deuten stark darauf hin, dass in Zukunft immer mehr Websockets zum Einsatz kommen werden. Diese Art der Kommunikation muss vom Proxy unterstützt werden, was bei Apache ab Version 2.4 und dem Modul proxy_wstunnel_module der Fall ist. Dieser Artikel soll erklären, wie Websockets grob funktionieren und wie der Apache Proxy konfiguriert werden muss, um das Protokoll zu unterstützen.

Websocket Handshake

Die Websocket-Kommunikation wird über denselben Port wie HTTP abgewickelt. Um von HTTP- auf Websocket-Kommunikation zu wechseln, initiiert der Client einen “Upgrade”, der bspw. folgendermassen aussieht:

GET /eventbus/726/5p8l3sxw/websocket HTTP/1.1
Host: n.accountint2.post.ch
Pragma: no-cache
Cache-Control: no-cache
Origin: https://int.post.ch
Sec-WebSocket-Version: 13
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.85 Safari/537.36
Accept-Language: en-US,en;q=0.8,de;q=0.6
 [truncated]Cookie: ittrksessid=4f8e3827.5242fdad0c097; NSESSIONID=6980775628415330683; NCTRL=108161021:null; 
Sec-WebSocket-Key: L7lnvkZ6/AmVYHf3y38jWQ==
Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits
X-RP-UNIQUE_ID: VkICigoCZiAAADnKKfoAAAAP
X-Forwarded-For: 10.224.204.139
X-Forwarded-Host: n.accountint2.post.ch
X-Forwarded-Server: dev.wp.pnet.ch
Upgrade: WebSocket
Connection: Upgrade

Der Server antwortet darauf hin mit einem HTTP-Status 101:

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: 4s20mfOq2z5kJbK4ivlpm75HidQ=

Proxy-Konfiguration

Im spezifischen Fall von int.post.ch sieht die Konfiguration für den Websocket-Tunnel folgendermassen aus (das vollständige Konfigurations-File befindet sich im Anhang dieses Tickets):

LoadModule              proxy_wstunnel_module        modules/mod_proxy_wstunnel.so
    #-----------------------------------------
    # Start WebSockets Test Configuration for eventbus
    #-----------------------------------------

    RewriteCond        %{HTTP:Upgrade} websocket [NC]
    RewriteRule        /eventbus/(.*)$                    ws://v064vb.pnet.ch:7018/eventbus/$1 [proxy,last]

    RewriteRule        /eventbus(.*)$                     http://v064vb.pnet.ch:7018/eventbus$1 [proxy,last]
    ProxyPassReverse   /eventbus                          http://v064vb.pnet.ch:7018/eventbus

    #-----------------------------------------
    # End WebSockets Test Configuration for eventbus
    #-----------------------------------------

Die RewriteCond-Direktive ist deswegen notwendig, weil auch der Proxy merken muss, dass nun auf Websocket-Kommunikation gewechselt wird. ws ist das Websockets-Protokoll, wss die verschlüsselte Variante.