如何在.htaccess中设置代理

bgibtngc  于 2022-12-04  发布在  其他
关注(0)|答案(2)|浏览(198)

Apache文档声明RewriteRule和the应该放在服务器配置中,但是由于共享主机的情况,它们可以放在htaccess中。
我正在尝试设置透明代理:

RewriteEngine On
 RewriteCond %{REQUEST_URI} ^/foo [OR]
 RewriteCond %{REQUEST_URI} ^/bar
 RewriteRule ^(.*)$ http://example.com/$1 [P]

这是工作正常...除了重定向(如如果/foo重定向到/bar)。重定向回到example.com,而不是我的服务器。
我知道ProxyPassReverse指令可以解决此问题,但当我将此指令添加到.htaccess时,出现“Internal Server Error”(内部服务器错误)页面
与重写指令不同,ProxyPassReverse在htaccess中不起作用。
我如何在共享主机的情况下设置一个透明代理,或者这是不可能的?
(This看起来是合理的,因为重写已经完成了80%的工作,在一个htaccess中使用透明代理不会影响在另一个htaccess中使用透明代理。)

aij0ehis

aij0ehis1#

不幸的是,我相当肯定您想做的事情是不可能的:从我的研究来看,我相当有信心这是不可能的。
简单地说,您需要使用ProxyPassReverse,它只在VirtualHost级别(或类似级别)可用;而不是HTAccess级别。
编辑:我实现这一点的唯一方法是配置响应服务器/应用程序,使其知道它在代理后面,并适当地提供页面。也就是说,我使用.htaccess重定向到另一个服务器,如下所示:

RewriteEngine on
  RewriteRule  (.*)  http://localhost:8080/$1  [P,L]

然后在应用程序服务器上--在本例中是JIRA安装--我适当地配置了JavaTomcat/ Catalina 来提供带有代理信息的页面:

proxyName="my.public.address.com"
 proxyPort="80"

然而,这并不是完全透明的;应用服务器需要以代理的方式提供页面。2不过,这可能会有一些用处。

hvvq6cgz

hvvq6cgz2#

我设法收集了一些资源来弄清楚如何做到这一点。我使用一个共享主机提供商,所以我没有访问服务器配置(httpd.conf)。我只能使用.htaccess来完成代理。这个例子是一个WordPress站点,我希望大部分内容由www.example.com提供origin.example.com,但将有一些页面在本地提供。有点像覆盖。你可以走另一条路,只代理特定的子目录使用不同的RewriteCond规则。
须知:
1.在.htaccess中不能使用ProxyPass或ProxyPassReverse,所以我们必须使用其他方法来模仿它们的功能。
1.如果您的提供程序未启用SSLProxyEngine,则无法通过HTTPS进行代理调用,因此,如果您担心MITM攻击,则会失去一些安全性。如果源服务器是内部服务器,则这可能不是问题。您还可以在源服务器上使用.htaccess,以从除代理服务器之外的任何位置强制HTTPS。
1.您需要重写标头
1.您需要重写从源服务器返回的HTML,这需要在源服务器上完成。您可以将其限制为特定的IP(即代理的IP),这样当您在其他地方访问它时,它就不会中断。
我想要的:
我希望调用proxy.example.com来提供内容origin.example.com。在我的例子中,我希望Map所有内容,但有几个例外。如果您只想Map站点的一部分,请相应地调整您的规则。
操作方法:
1.配置www.example.com上的.htaccess文件proxy.example.com,将所有URI代理到origin.example.com。我希望能够登录到proxy.example.com,所以我不重写/wp-admin或/wp-login. php。在我的例子中,我有一个/programs/节,我希望由代理服务器本身(也是一个WordPress示例)提供服务。通过检查REDIRECT_STATUS来防止循环。

# I force everything coming into proxy.example.com to be HTTPS <IfModule mod_rewrite.c>
RewriteEngine On

RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteCond %{HTTPS} off
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301] </IfModule> <IfModule mod_proxy.c>
# Redirect access for / (or any index) to the origin. NOTE target is http:// without SSLProxyEngine
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule ^(index\.(php|html|cgi))?$ http://origin.example.com/ [P]

# Do NOT redirect these patterns
RewriteCond %{REQUEST_URI} !^/wp-admin/
RewriteCond %{REQUEST_URI} !^/wp-login.php
RewriteCond %{REQUEST_URI} !^/programs/

# Redirect everything else. NOTE target is http:// without SSLProxyEngine
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule ^(.+)$ "http://origin.example.com/$1" [P]

# Mimic ProxyPassReverse. Fix the headers. Force to be https.
Header edit  Location ^https?://origin\.example\.com/(.*)$ https://proxy.example.com/$1
Header edit* Link https?://origin\.example\.com/ https://proxy.example.com/ </IfModule>

1.只为代理服务器的IP,重写HTML本身中的任何引用。这个例子是针对一个WordPress站点。
WordPress filter to modify final html output窃取
2a)添加一个必须使用的插件来添加一个'final_output'钩子。在wp-content/mu-plugins/buffer.php中添加一个文件:

<?php

/**  * Output Buffering  *  * Buffers the entire WP process, capturing
the final output for manipulation.  */

ob_start();

add_action('shutdown', function() {
    $final = '';

    // We'll need to get the number of ob levels we're in, so that we can iterate over each, collecting
    // that buffer's output into the final output.
    $levels = ob_get_level();

    for ($i = 0; $i < $levels; $i++) {
        $final .= ob_get_clean();
    }

    // Apply any filters to the final output
    echo apply_filters('final_output', $final); }, 0); ?>

2b)将以下PHP添加到wp-content/themes//functions.php。它使用上面的'final_output'挂钩。(使用匿名函数需要PHP 5.3或更高版本。)

add_filter('final_output', function($output) {
    // IP of the proxy server
    $WWW_IP = “4.4.4.4”; 
    //$WWW_IP = “4.4.2.2”;  // My workstation, for testing purpose only
    if ($_SERVER[REMOTE_ADDR] == $WWW_IP) {
        // Force HTTPS when rewriting
        $output = str_replace('http://origin.example.com', 'https://proxy.example.com’, $output);
        // Catch anything that wasn’t a URL
        return str_replace(‘origin.example.com, 'proxy.example.com', $output);
    }
    return $output;
});

如果一切顺利,您现在应该可以看到proxy.example.com提供的origin.example.com内容。
我还在测试中,所以如果你发现错误或遗漏,请添加评论。

相关问题