使用反向代理保护您的端口

作者:Shawn Powers

在之前的文章中,我讨论了 Apache Tomcat,这是从您的服务器运行 Java 应用程序的理想方式。我解释说,您可以从 Tomcat 的默认 8080 端口运行这些应用程序,或者您可以将 Tomcat 配置为使用 80 端口。但是,如果您想要运行传统的 Web 服务器并且在 80 端口上托管 Java 应用程序,该怎么办?答案是运行反向代理。

我在这里做的唯一假设是您有一个基于 Web 的应用程序在 80 端口以外的端口上运行。这可以是 Tomcat 应用程序,就像我在上一篇文章中讨论的那样,也可以是任何通过 Web 界面访问的 Web 应用程序(例如 Transmission、Sick Beard 等)。我在这里介绍的另一种情况是从第二台服务器运行 Web 应用程序,即使它在 80 端口上,但您希望从您的中央 Web 服务器访问它。(如果您只有一个静态 IP 用于托管,这将特别有用。)

反向代理的工作方式,至少对于 Apache Web 服务器而言,是将每个应用程序配置为虚拟主机。就像您可以使用虚拟主机从单个服务器托管多个网站一样,您也可以从同一服务器将单独的 Web 应用程序托管为虚拟主机。配置起来并不太困难,但在实践中非常有用。首先。在您的服务器上,您安装了 Web 服务器(图 1)。您还在 8080 端口上安装了一个 Web 应用程序(图 2)。除了工作的 Apache Web 服务器外,您还需要确保启用(按名称)虚拟主机。

图 1. 我安装了 Apache,它正在 80 端口上托管一个非常简单的页面。

图 2. 我在位于 192.168.1.11 的服务器上的 8080 端口上运行了一个 Web 应用程序。

启用基于名称的虚拟主机

在 Apache 上启用基于名称的虚拟主机非常常见,而且非常简单。根据您使用的发行版,启用基于名称的虚拟主机的“正确”位置可能会有所不同。然而,Apache 的好处是,通常只要指令在配置中的某个位置指定,Apache 就会遵守它。

我的本地测试服务器正在运行 Ubuntu。为了确定启用基于名称的虚拟主机的“正确”位置,我只需转到 /etc/apache2 目录并执行


grep NameVirtualHost *

该命令搜索 NameVirtualHost 指令,它返回了以下内容


root@server:/etc/apache2# grep NameVirtualHost *
ports.conf:NameVirtualHost *:80
ports.conf:    # If you add NameVirtualHost *:443 here, 
               # you will also have to change

这些结果告诉我,NameVirtualHost 指令在 /etc/apache2/ports.conf 文件中指定。(请注意,grep 将仅返回包含搜索词的行,这就是为什么它在上面显示了两个不相关的行。重要的是文件名 ports.conf,这正是我要查找的内容。)同样,对于 Apache,通常在何处指定指令并不重要,但我喜欢坚持我正在使用的特定发行版的标准,只是为了未来的管理员考虑。

要启用基于名称的虚拟主机,您只需取消注释


NameVirtualHost *:80

文件中的行并保存它。如果您找不到包含此类注释指令的文件,只需将该行添加到您的 apache.conf 或 httpd.conf 文件中。然后,您需要为您要创建的虚拟主机指定 VirtualHost 指令。无论您是创建传统的虚拟主机还是反向代理虚拟主机,此过程都相同。

创建虚拟主机

如本文前一节所述,重要的是要注意 Apache 配置文件布局会因发行版而异。在 Ubuntu 中,有两个文件夹:sites-available 和 sites-enabled。第一个文件夹包含文本文件,其中包含定义各个虚拟主机的代码片段,第二个文件夹包含指向 sites-available 文件夹中文件的符号链接。这看起来肯定很复杂,但实际上是为了方便起见。您可以在 sites-available 文件夹中定义任意数量的虚拟主机,但在将它们符号链接到 sites-enabled 文件夹之前,Apache 不会解析它们。

让我们创建一个虚拟主机,但不是创建一个定义要查找文件的目录的传统虚拟主机,而是定义反向代理规则。这是我在 sites-available 中创建的文件(接下来我解释每一行)



root@server:/etc/apache2# cat sites-available/reverseprox 
<VirtualHost *:80>
        LoadModule proxy_module modules/mod_proxy.so
        LoadModule proxy_http_module modules/mod_proxy_http.so
        ServerName sab.mydomain.com
        ServerAlias sab
        ProxyRequests Off 
        ProxyPass / http://192.168.1.11:8080/
        ProxyPassReverse / http://192.168.1.11:8080/
</VirtualHost>

首先,如果不清楚,我创建的文件的名称是“reverseprox”,我在 /etc/apache2/sites-available 文件夹中创建了它。如果您使用不同的发行版,您可能没有这种文件夹设置。实际上,您可以将 VirtualHost 指令直接添加到 apache.conf 或 httpd.conf 文件中。Ubuntu 只是使用文件夹结构来提高清晰度和便利性。

以下是逐行分解

  • <VirtualHost *:80> — 这打开了节,它的意思是“监听 80 端口上所有 IP 地址,以接收任何请求我的服务器名称的人”。

  • LoadModule proxy_module modules/mod_proxy.soLoadModule proxy_http_module modules/mod_proxy_http.so — 这些行加载了两个单独的模块。请注意,尽管模块名称看起来相似,但它们实际上是两个模块:mod_proxy 和 mod_proxy_http。有时模块在另一个配置文件中全局加载。这样做也可以,但这只是确保为您的虚拟主机加载所需模块的一种方法。(注意:如果您在启动期间收到有关“找不到文件”的错误,您可能需要创建到系统模块文件夹的符号链接。在我的 Ubuntu 系统上,这意味着 sudo ln -s /usr/lib/apache2/modules /etc/apache2/。)

  • ServerName sab.mydomain.com — 这是虚拟主机应监听的域名。如果对“sab.mydomain.com”的请求进入 Apache,它就知道使用此虚拟主机声明来响应。当然,“sab.mydomain.com”是一个通用示例;您应该使用您的实际域名。

  • ServerAlias sab — 可以有多个 ServerAlias 语句,但在这种情况下,只有一个。我单独添加了“sab”作为 Apache 要监听的别名。它将像使用对“sab.mydomain.com”的请求一样使用对“sab”的请求——这只是一个别名。

  • ProxyRequests Off — 这实际上是 ProxyRequests 指令的默认设置。我总是将它添加到我的 VirtualHost 节中,以确保我不会无意中允许某人将我的服务器用作匿名代理。ProxyRequests On 将允许其他人通过访问您的服务器将其用作代理,从而有效地将自己隐藏在 Internet 上,并让您对他们的上网行为负责!希望很清楚为什么我指定“Off”,即使它是默认设置。

  • ProxyPass / http://192.168.1.11:8080/ — 这告诉 Apache 当有人请求此虚拟主机的根级别文件夹时,“服务”他们列出的地址。从最终用户的角度来看,备用端口以及可能的备用服务器地址将被隐藏。他们只会看到他们输入的 URL 以访问虚拟主机。如果您希望将特定子文件夹定向到其他位置,则可以有多个 ProxyPass 指令。Apache 在反向代理情况下可以非常灵活地指定内容。

  • ProxyPassReverse / http://192.168.1.11:8080/ — 此规则使反向代理工作。它重写来自代理服务器的响应,以便最终用户永远不会看到除他们浏览到的虚拟主机名以外的任何信息。来自底层服务器(在本例中为监听 8080 端口的服务器)的任何响应都会被动态重写,使其看起来响应直接来自虚拟主机服务器。

  • </VirtualHost> — 这关闭了节,或定义虚拟主机的部分。在 Ubuntu 中,这是一个 sites-available 文件夹中的单个文件。在另一个发行版中,它也可能只是附加到 apache.conf 文件末尾的内容。

使其全部工作

为反向代理站点创建虚拟主机声明后,您需要重新加载 Apache。请记住,如果您使用的是 Ubuntu,则需要创建一个符号链接,以便 Apache 从 sites-enabled 文件夹读取您的配置。为此,进入 sites-enabled 文件夹,然后键入


ln -s ../sites-available/reverseprox .

这将创建一个从您创建的 reverseprox 文件到 sites-available 文件夹的符号链接。如果您使用的是另一个发行版,并且只是将该节附加到 apache.conf 文件的末尾,则无需创建任何符号链接。

接下来,重新加载 Apache。我实际上更喜欢重新启动 Apache 以确保它正确加载所有内容,但重新加载应该可以解决问题。在 Ubuntu 中,我这样做


sudo service apache2 restart

并且,反向代理应该已准备就绪。您只需要确保您的 DNS 正确指向服务器。做到这一点并确保一切正常的最快方法是将一个简单的行添加到您的工作站的 /etc/hosts 文件中。我添加了这个


192.168.1.11     sab sab.mydomain.com

然后,我保存了它。接下来,我打开浏览器,并浏览到“sab”而不是 192.168.1.11:8080,图 3 显示了结果。成功了!

图 3. 现在我可以访问该 Web 应用程序,而无需输入任何端口号!此外,它获得了自己的域名!

现在怎么办?

使用 Apache 的反向代理技术的优点在于,您不仅限于仅重定向到同一服务器上的不同端口。您可以创建一个反向代理,使 google.yourdomain.com 返回实际的 Google 搜索引擎。您只需为 google.yourdomain.com 创建一个虚拟主机,并将 ProxyPass 和 ProxyPassReverse 指令设置为指向 http://www.google.com/。这真的很简单。实际上,本地网络上的反向代理可能是一种为您的用户提供对原本被阻止的网站的访问的方式。如果您的 Web 过滤策略阻止了某个特定的新闻站点,但您的服务器可以访问呢?您可以在您的服务器上创建一个反向代理,您的用户可以连接到该代理并访问该站点,而不会被您的 Web 过滤器过滤!(另一个警告:这就是为什么将 ProxyRequests 设置为 Off 很重要的原因,这样他们就不会使用您的反向代理来规避所有 Web 过滤!)

使用反向代理,可以使您的 Web 基础设施对最终用户而言不那么令人困惑。它还允许您在不影响用户的情况下对底层 Web 应用程序进行更改。如果服务更改了 IP 地址或端口,您只需调整您的反向代理定义,最终用户永远不会知道差异。反向代理易于配置且易于维护。它们将有助于保持您的 URL 清晰,并使您的系统易于管理!

Shawn 是 Linux Journal 的副编辑,并且从一开始就接触 Linux。他对开源充满热情,并且热爱教学。他还喝了太多咖啡,这经常在他的写作中体现出来。

加载 Disqus 评论