У меня следующая установка:
server-external-ip
который я хочу использовать в качестве шлюза IPP для двух принтеровДва принтера доступны (из локальной сети и с сервера Apache) по следующим URL-адресам IPP:
http://printer-1-local-ip/printer
http://printer-2-local-ip/printer
(Принтеры физически не подключены к веб-серверу.)
Я хочу, чтобы они были доступны из Интернета по следующим URL-адресам:
http://server-external-ip/prn1
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.