我有以下设置:
server-external-ip Debian的Apache 2.2 Web服务器,我想用作IPP网关的两台打印机 这两台打印机可以通过以下IPP URL访问(从LAN和Apache服务器):
http://printer-1-local-ip/printer http://printer-2-local-ip/printer (打印机没有物理连接到Web服务器。)
我希望它们可以通过以下URL从Internet访问:
http://server-external-ip/prn1 http://server-external-ip/prn2 IPP专门通过对打印机地址的HTTP请求来工作(即,整个打印过程通过POST请求在http:// printer-X-local-ip /打印机 URL处发生),所以我只需要redirect(即反向代理与Apache)上面的URL 1和2。
Apache正在服务其他内容,所以我不能用自定义程序(例如netcat或netsed)来replace它。 另外,由于打印机客户端只能够在端口80处到达服务器,因此我无法在其他端口上运行自定义程序。
然后我尝试了下面的Apacheconfiguration:
RewriteRule ^/prn1$ http://printer-1-local-ip:80/printer [P] ProxyPassReverse /prn1 http://printer-1-local-ip
将Windows客户端连接到http:// server-external-ip / prn1 URL,反向代理就可以工作。 但是IPP协议还会向打印机(在POST-ed数据中)发送完整的设备URL。
这意味着打印机会收到http:// server-external-ip / prn1打印机的显式IPP请求,而不是其正确的地址( http:// printer-1-local-ip / printer )。 所以它拒绝连接。
我将这个条目添加到Windows客户端的HOST文件中:
server-external-ip printer-dns-name
但它仍然不起作用,因为打印机收到仍然具有错误服务名称的http:// printer-dns-name / prn1的IPP请求(即, prn1而不是打印机 )。
我无法将反向代理url从http:// server-external-ip / prn1更改为http:// server-external-ip / printer,因为我必须提供两台打印机的访问权限(并且我无法更改打印机服务打印机configuration中的名称)。
我想要做的是将IPP数据HTTP POST-ed打印到打印机,用http:// printer-X-local-ip / printerreplacehttp:// server-external-ip / prnX (没有校验和在IPP协议和我捕获的数据包应该工作)。
问题是,我可以谷歌所有的Apache模块将无法帮助您修改发送到反向代理打印机的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请求属于application / ipp MIMEtypes,因此过滤不会(显着)影响正常stream量。
任何想法如何解决这个烂摊子? 我觉得应该有一个简单的解决scheme,我不看正确的方式。 这就是为什么我问这个总是令人敬畏的社区(我在这里没有post,但我是一个长期的粉丝)。
我想继续使用这种“redirect方法”,所以只有在没有直接解决scheme的情况下,解决方法才有用。 是的,我可以修改一个Apache模块的目的,但我真的不喜欢它… 🙂
在此期间,我会尝试一些networking魔术… 🙂
为什么不这样做:定义两个DNS名称为您的外部打印机,例如。
printer-1-external.mydomain.com CNAME external-server.mydomain.com printer-2-external.mydomain.com CNAME external-server.mydomain.com
你甚至可以使用内部使用的相同名称。 让内部DNS直接将打印机名称parsing到打印机,并将外部DNSparsing到您的外部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。