2016-12-22 6 views
0

Я пытаюсь настроить обратный прокси с Apache 2.4.Collabora «Неизвестный ресурс» из-за Apache mod_rewrite proxy unescaping% 2F slashes

Похоже, я не могу использовать ужасный mod_proxy напрямую, так как он не поддерживает WebSockets (если вручную настроить для каждого URL), так что я должен использовать ужасный ужасный mod_rewrite вместо этого.

Моя конфигурация выглядит следующим образом до сих пор:

<VirtualHost *:80> 
    ServerName collabora.example.com 
    RewriteEngine on 
    RewriteCond %{HTTP:Upgrade} =websocket 
    RewriteRule ^(/.*)?$ wss://collabora-backend$1 [P] 
    RewriteCond %{HTTP:Upgrade} !=websocket 
    RewriteCond %{REQUEST_URI} !^/.well-known/acme-challenge/? 
    RewriteRule ^(/.*)?$ https://collabora-backend$1 [P] 
</VirtualHost> 

Одно приложение, которое я пытаюсь запустить (в horrible³ Collabora Online in combination with NextCloud) будет пытаться открыть WebSockets для URL-адресов, как это: ws://collabora.example.com/lool/https%253A%252F%252Fcloud.example.com%252Fapps%252Frichdocuments%252Fwopi%252Ffiles%252F51040%3Faccess_token%3DABCDEF%26permission%3Dedit/ws. К сожалению, с приведенной выше конфигурацией эти URL-адреса прибудут в бэкэнд со всеми %25 деталями, декодированными до % (и другие также): ws://collabora.example.com/lool/https%3A%2F%2Fcloud.example.com%2Fapps%2Frichdocuments%2Fwopi%2Ffiles%2F51040?access_token=ABCDEF&permission=edit/ws.

Collabora сообщит сообщения об ошибках, как это:

wsd-00026-0195 0:01:27.448231 [ client_ws_0003 ] ERR Unknown resource: /lool//ws/lool/https%253A%252F%252Fowncloud.mydomain.fr%252Findex.php%252Fapps%252Frichdocuments%252Fwopi%252Ffiles%252F5%3Faccess_token=R...c&permission=edit/ws| LOOLWSD.cpp:1154 

и соединения WebSocket потерпит неудачу с 400 Bad Request ошибки в браузере.

Установка AllowEncodedSlashes на On или NoDecode не изменяет это. (Насколько я понимаю, это влияет только на величину PATH_INFO.)

Чтение через RewriteRule flags, то [B] флаг, кажется, говорить о чем-то связано с моей проблемой. Там говорится: «mod_rewrite должен удалять URL-адреса перед их сопоставлением» (я предполагаю, что единственной причиной этого является максимизация досады), поэтому флаг [B] снова удалит их после сопоставления. Это, конечно же, не работает в этом случае и избежит всех косых черт, даже тех, которые не ускользнули раньше: "ws://collabora.example.com%2Flool%2Fhttps%253A%252F%252Fcloud.example.com%252Fapps%252Frichdocuments%252Fwopi%252Ffiles%252F51040%3Faccess_token%3DABCDEF%26permission%3Dedit%2Fws"

Есть ли способ исправить эту проблему или это тот момент, когда я, наконец, должен получить избавиться от Apache навсегда?

ответ

0

На основании ответа covener, я теперь придумал со следующей конфигурацией, которая работает:

<VirtualHost *:80> 
    ServerName collabora.example.com 
    RewriteEngine on 
    RewriteCond %{HTTP:Upgrade} =websocket [NC] 
    RewriteCond %{THE_REQUEST} "^[a-zA-Z]+ /(.*) HTTP/\d+(\.\d+)?$" 
    RewriteRule .? wss://collabora-backend/%1 [P,NE] 
    RewriteCond %{HTTP:Upgrade} !=websocket [NC] 
    RewriteCond %{REQUEST_URI} !^/.well-known/acme-challenge/? 
    RewriteCond %{THE_REQUEST} "^[a-zA-Z]+ /(.*) HTTP/\d+(\.\d+)?$" 
    RewriteRule .? https://collabora-backend/%1 [P,NE] 
</VirtualHost> 

я настроил ответ covener для поддержки всех видов HTTP запросов, и я должен был добавить NE флаг (в противном случае URI запроса будет сбежать еще раз).

0

Один трюк в этой области является использование захвата% {THE_REQUEST} вместо обратной ссылки, потому что он будет использовать запросы оригинальных кодирования, такие как:

<VirtualHost *:80> 
    ServerName collabora.example.com 
    RewriteEngine on 
    RewriteCond %{HTTP:Upgrade} =websocket 
    RewriteCond %{THE_REQUEST} "^GET /(.*) HTTP/1.?$" 
    RewriteRule ^(/.*)?$ wss://collabora-backend/%1 [P] 
    RewriteCond %{HTTP:Upgrade} !=websocket 
    RewriteCond %{REQUEST_URI} !^/.well-known/acme-challenge/? 
    RewriteRule ^(/.*)?$ https://collabora-backend$1 [P] 
</VirtualHost> 

Я только добавил новое условие ш/capture и сменил $ 1 на% 1. Я только проверял стол, но я подозреваю, что вы передали проблему с кодировкой всего лишь с небольшими трюками.

+0

Спасибо большое. Я не знал, что вы можете ссылаться на «RewriteCond's».Мне удалось заставить его работать с некоторыми твиками, см. Мой собственный ответ. – cdauth

0

Collabora обновила документацию, и я столкнулся с тем же вопросом.

Так что есть намного более хорошее решение (найдено в https://www.collaboraoffice.com/code/)

AllowEncodedSlashes NoDecode 
    ProxyPassMatch "/lool/(.*)/ws$" wss://127.0.0.1:9980/lool/$1/ws nocanon 
+0

Лично мне не нравится указывать для каждого шаблона URL-адреса, будет ли он использовать веб-узлы или нет. В моем случае моя конфигурация Apache даже автоматически генерируется, и мне пришлось бы добавить ненужную логику для поддержки этого. Насколько я знаю, 'nocanon' поддерживается только с помощью директивы ProxyPass, а не' RewriteRule', но 'ProxyPass' не имеет эквивалента' RewriteCond' для фильтрации того, является ли запрос websocket или нет. – cdauth