Назад | Перейти на главную страницу

Apache mod_substitute для HTTP-запросов к хосту с обратным проксированием

У меня следующая установка:

Два принтера доступны (из локальной сети и с сервера Apache) по следующим URL-адресам IPP:

(Принтеры физически не подключены к веб-серверу.)

Я хочу, чтобы они были доступны из Интернета по следующим URL-адресам:

  1. http://server-external-ip/prn1
  2. http://server-external-ip/prn2

IPP работает исключительно через HTTP-запросы к адресу принтера (т.е. весь процесс печати происходит через запросы POST на http: // принтер-X-локальный-ip / принтер URL-адреса), поэтому мне нужно только перенаправить (т.е. обратный прокси с Apache) URL-адреса 1 и 2 выше.

Apache обслуживает другой контент, поэтому я не могу заменить его специальной программой (например, netcat или netsed). Кроме того, я не могу запустить специальную программу на другом порту, поскольку клиенты принтера смогут подключиться к серверу только через порт 80.

Затем я попробовал следующую конфигурацию Apache:

RewriteRule ^/prn1$ http://printer-1-local-ip:80/printer [P]
ProxyPassReverse /prn1 http://printer-1-local-ip

Подключение клиента Windows к http: // сервер-внешний-ip / prn1 URL, обратный прокси работает. Но протокол IPP также отправляет на принтер (внутри данных POST-ed) полный URL-адрес устройства.

Это означает, что принтер получает явный запрос IPP для http: // сервер-внешний-ip / prn1 принтер, а не его правильный адрес (http: // принтер-1-локальный-IP / принтер). Так он отказывается от связи.

Я добавил эту запись в файл HOST на клиенте Windows:

server-external-ip    printer-dns-name

Но он по-прежнему не работает, поскольку принтер получает запрос IPP для http: // имя-DNS-принтера /prn1 который по-прежнему имеет неправильное имя службы (т. е. prn1 вместо того принтер).

Я не могу изменить URL обратного прокси с http: // сервер-внешний-ip / prn1 к http: // server ‑ external ‑ ip /принтер так как я должен предоставить доступ к обоим принтерам (и я не могу изменить принтер имя службы в конфигурации принтера).

Что я хочу сделать, так это изменить данные IPP, отправленные HTTP POST на принтер, чтобы заменить http: // server ‑ external ‑ ip / prnX с участием http: // принтер-X-локальный-ip / принтер (в протоколе IPP нет контрольных сумм, и из захваченных мной пакетов это должно работать).

Проблема в том, что все модули Apache, которые я могу найти в Google, не помогут вам в манипулировании HTTP. органы запроса отправлено на принтер с обратным прокси. mod_rewrite работает только с заголовками, mod_substitute работает на органах реагирования, mod_headers работает с заголовками запросов и ответов, mod_replace работает со всем, кроме органов запросов и т. д.

С участием mod_substitute Я пробовал со следующим:

<Location /> 
    AddOutputFilterByType SUBSTITUTE application/ipp
    Substitute "s|server-external-ip/prn1|printer-1-local-ip/printer|"
</Location>

Но, как и ожидалось, он отлично работает с телами ответов, но не с проксируемыми запросами (я проверял проксирование на другой сервер). Также обратите внимание, что запросы IPP относятся к приложение / ipp Тип MIME, поэтому фильтрация не повлияет (существенно) на нормальный трафик.

Есть идеи, как решить этот беспорядок? Я чувствую, что должно быть простое решение, и я смотрю на вещи неправильно. Вот почему я прошу это всегда отличное сообщество (у меня здесь еще нет сообщений, но я давний поклонник).

Я хотел бы остаться на этом «подходе перенаправления», поэтому обходные пути будут полезны только в том случае, если прямого решения не существует. И да, я мог бы модифицировать модуль Apache для этой цели, но мне это не очень нравится ... :-)

А пока я попробую netsed магия ... :-)

Почему бы не сделать следующее: Определите два DNS-имени для вашего внешнего принтера, например.

printer-1-external.mydomain.com CNAME external-server.mydomain.com
printer-2-external.mydomain.com CNAME external-server.mydomain.com

Вы даже можете использовать те же имена, что и внутри компании. Попросите внутренний DNS разрешить имена принтеров непосредственно на принтере, а внешний DNS - на ваш внешний IP ...

Добавьте на свой сервер два виртуальных хоста на основе имени:

<VirtualHost *:80>
    ServerName printer-1-external.mydomain.com
    ProxyPass / http://printer-1-local-ip/
</VirtualHost>
<VirtualHost *:80>
    ServerName printer-2-external.mydomain.com
    ProxyPass / http://printer-2-local-ip/
</VirtualHost>

Таким образом, ваш запрос IPP на http://printer-2-external.mydomain.com/printer в параметрах поста будет правильное название сервиса.

Извините, я не могу добавлять комментарии, однако, если вы еще этого не сделали, проверьте:

ProxyPreserveHost On

настроен в вашем файле conf.

Подход с перезаписью хорош для корневого контекста, но для проблемы с именем хоста похоже, что вы хотите проверить ProxyPreserveHost.

http://httpd.apache.org/docs/2.2/vhosts/examples.html