Fork me on GitHub

HTTPD配置重定向与过滤器

本文介绍如何配置HTTPD服务器的反向代理服务,实现目标网页的控制和过滤。

此处输入图片的描述

一、简介

Apache HTTP Server(简称Apache或httpd)是Apache软件基金会的一个开放源代码的网页服务器软件,旨在为unix,windows等操作系统中提供开源httpd服务。由于其安全性、高效性及可扩展性,被广泛使用,自1996年4月以来,Apache一直是Internet上最流行的HTTP服务器。它快速、可靠并且可通过简单的API扩充,将Perl/Python等解释器等编译到httpd的相关模块中。

如果要实现对用户访问网页资源的控制和过滤,可以通过两种方式实现:重定向过滤器

二、设置重定向

通过在配置文件中设置RewriteRule实现。
HTTPD的服务器配置文件conf/httpd.conf中,通过如下设置:

  • 去掉Module的注释,或者添加如下配置:

    1
    LoadModule rewrite_module modules/mod_rewrite.so`
  • 开启RewriteEngine(也可以自定义配置文件,注意需要在httpd.conf中添加相关路径)

  • 配置ServerName
  • 利用正则配置重定向路径规则
    1
    RewriteRule old-URL new-URL

在自定义的配置文件中,完整的配置如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<Directory target-file-path>
#target-file-path:为目标资源路径名
AllowOverride NONE
Require all granted
</Directory>
<VirtualHost *:80>
RewriteEngine on
ServerName test.com
RewriteRule ^/test.js target-file-path
ProxyPreserveHost On
ProxyRequests off
ProxyPass / http://test.com/
ProxyPassReverse / http://test.com/
</VirtualHost>

对于配置中的问题,可以在var/log/errorlog中查看错误日志:

1
2
3
4
5
6
7
8
[Fri May 17 20:53:36.109491 2019] [auth_digest:notice] [pid 18476] AH01757: generating secret for digest authentication ...
[Fri May 17 20:53:36.109917 2019] [lbmethod_heartbeat:notice] [pid 18476] AH02282: No slotmem from mod_heartmonitor
[Fri May 17 20:53:36.131890 2019] [mpm_prefork:notice] [pid 18476] AH00163: Apache/2.4.6 (CentOS) PHP/5.6.40 configured -- resuming normal operations
[Fri May 17 20:53:36.131908 2019] [core:notice] [pid 18476] AH00094: Command line: '/usr/sbin/httpd -D FOREGROUND'
[Fri May 17 20:53:46.777123 2019] [mpm_prefork:notice] [pid 18476] AH00170: caught SIGWINCH, shutting down gracefully
[Fri May 17 20:53:47.824784 2019] [suexec:notice] [pid 18529] AH01232: suEXEC mechanism enabled (wrapper: /usr/sbin/suexec)
[Fri May 17 20:53:47.827118 2019] [so:warn] [pid 18529] AH01574: module rewrite_module is already loaded, skipping
AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using --------. Set the 'ServerName' directive globally to suppress this message

三、过滤器

过滤器用来对 server 收到/发送的数据进行再加工。过滤器分两种:input filters 用于处理 serverclient 收到的数据,output filters 用于处理 serverclient 发送的数据。一个数据流上可以挂多个过滤器。这些过滤器可以通过显式指定来确定执行顺序。

注意: InputFilter 只能拦截客户端的POST请求,对于GET请求,需要设置如下的过滤方式。

3.1 JS注入

为了实现对网页的过滤,可以利用过滤器得到网页,通过JS注入的方式改变网页DOM数结构。而过滤器实现可以通过PHP或者Python等脚本语言。

  • 首先配置过滤器,配置文件如下:
1
2
3
4
5
6
7
8
9
ExtFilterDefine testOutFilter mode=output cmd="/usr/bin/php /etc/httpd/filters/test.php"
<VirtualHost *:80>
ServerName test.com
ProxyPreserveHost On
ProxyRequests off
ProxyPass / http://test.com/
ProxyPassReverse / http://test.com/
SetOutputFilter testOutFilter
</VirtualHost>
  • 利用PHP脚本JS注入
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?php
# test.php
$stream = file_get_contents("php://stdin");
$stream = gzdecode($stream);
$jsContent = file_get_contents("/etc/httpd/filters/test.js");
$dom = new DOMDocument();
$dom -> loadHTML($stream);
$nodes = $dom -> getElementsByTagName('body');
foreach($nodes as $node){
$script = $dom -> createElement('script',$jsContent);
$script -> setAttribute( "type","text/javascript");
$js = $node -> appendChild($script);
}
echo gzencode($dom -> saveHTML());
?>
  • JavaScript的脚本test.js实现对HTML页面的DOM树修改。
1
2
3
4
<script type="text/javascript">
// test.js
alert('0');
</script>

3.2 脚本过滤

  • 也可以直接用PHP对拦截的数据流直接处理,首先是修改配置文件,示例如下:
1
2
3
4
5
6
7
8
9
10
11
ExtFilterDefine testOutFilter2 mode=output cmd="/usr/bin/php /etc/httpd/filters/test2.php"
<VirtualHost *:80>
ServerName newkeeper-web.jd.com
ProxyPreserveHost On
ProxyRequests off
ProxyPass / http://test.com/
ProxyPassReverse / http://test.com/
<Location "/static/js/test.js">
SetOutputFilter testOutFilter2
</Location>
</VirtualHost>
  • PHP脚本替换拦截的JS文件内容:
1
2
3
4
5
6
7
8
<?php
# test2.php
$stream = file_get_contents("php://stdin");
$stream = gzdecode($stream);
$stream = preg_replace('old_string', 'new_string', $stream);
$stream = gzencode($stream);
echo $stream;
?>

参考链接
[HTTPD] Linux(Apache)Httpd服务器安装,启动及httpd.conf配置详解
Apache HTTP Server - Dev

-------------本文结束感谢阅读-------------