如何在CentOS7上使用Apache或Nginx加密Tomcat8连接
介绍
Apache Tomcat 是一个 Web 服务器和 servlet 容器,旨在为 Java 应用程序提供服务。 Tomcat 经常用于生产企业部署和较小的应用程序需求,既灵活又强大。
在本指南中,我们将讨论如何使用 SSL 保护您的 CentOS 7 Tomcat 安装。 默认情况下,安装时,Tomcat 服务器和客户端之间的所有通信都是未加密的,包括输入的任何密码或任何敏感数据。 我们可以通过多种方式将 SSL 合并到 Tomcat 安装中。 本指南将介绍如何设置启用 SSL 的代理服务器以安全地与客户端协商,然后将请求传递给 Tomcat。
我们将介绍如何使用 Apache 和 Nginx 进行设置。
为什么要反向代理?
您可以通过多种方式为 Tomcat 安装设置 SSL,每种方式都有其权衡取舍。 在了解到 Tomcat 能够在本地加密连接之后,我们讨论反向代理解决方案可能看起来很奇怪。
带有 Tomcat 的 SSL 存在许多难以管理的缺点:
- Tomcat,当按照非特权用户的建议运行时,不能绑定到像传统 SSL 端口 443 这样的受限端口:有解决方法,例如使用
authbind
程序映射非特权程序使用受限端口,使用防火墙设置端口转发等,但它们都引入了额外的复杂性。 - Tomcat 的 SSL 没有被其他软件广泛支持:像 Let's Encrypt 这样的项目没有提供与 Tomcat 交互的本地方式。 此外,Java 密钥库格式需要在使用前转换传统证书,这使自动化变得复杂。
- 传统 Web 服务器比 Tomcat 更频繁地发布:这可能会对您的应用程序产生重大的安全影响。 例如,受支持的 Tomcat SSL 密码套件可能很快就会过时,从而使您的应用程序得不到最佳保护。 如果需要安全更新,更新 Web 服务器可能比安装 Tomcat 更容易。
反向代理解决方案只需在 Tomcat 安装前放置一个强大的 Web 服务器即可绕过许多这些问题。 Web 服务器可以使用 SSL 处理客户端请求,这是专门设计用于处理的功能。 然后,它可以将请求代理到以正常、非特权配置运行的 Tomcat。
这种关注点分离简化了配置,即使它确实意味着运行额外的软件。
先决条件
为了完成本指南,您必须已经在您的服务器上设置了 Tomcat。 本指南将假定您使用我们的 Tomcat 8 on CentOS 7 安装指南 中的说明进行设置。
启动并运行 Tomcat 后,请继续下面的首选 Web 服务器部分。 Apache 直接在下面开始,而 Nginx 配置可以通过向前跳过一点找到。
(选项 1)使用 Apache Web 服务器的 mod_jk
代理
Apache Web 服务器有一个名为 mod_jk
的模块,它可以使用 Apache “JServ”协议直接与 Tomcat 通信。 在 Tomcat 中默认启用此协议的连接器,因此 Tomcat 已经准备好处理这些请求。
部分先决条件
在我们讨论如何将 Apache Web 服务器连接代理到 Tomcat 之前,您必须安装并保护 Apache Web 服务器。
您可以按照 CentOS 7 LAMP 安装指南 的步骤 1 安装 Apache Web 服务器。 不要安装 MySQL 或 PHP。
之后,您需要在服务器上设置 SSL。 您执行此操作的方式取决于您是否拥有域名。
- 如果您有域名... 保护您的服务器的最简单方法是使用 Let's Encrypt,它提供免费、受信任的证书。 按照我们的 Let's Encrypt Apache 指南进行设置。
- 如果您没有域...并且您只是将此配置用于测试或个人使用,您可以使用自签名证书代替。 这提供了相同类型的加密,但没有域验证。 按照我们的 Apache 自签名 SSL 指南进行设置。
完成这些步骤后,请继续以下内容以了解如何将 Apache Web 服务器连接到您的 Tomcat 安装。
第一步:编译安装mod_jk
虽然 Tomcat 本身带有 JServ 连接器,但 CentOS 7 软件包存储库不包括 Apache Web 服务器使用该协议进行通信所需的 mod_jk
模块。 要添加此功能,我们必须从 Tomcat 项目的站点下载并编译连接器。
在我们下载连接器的源代码之前,我们需要从 CentOS 存储库安装必要的构建和运行时依赖项。 我们将安装 GCC 来编译连接器和 Apache Web 服务器开发文件,以便所需的 Apache 库可用。
sudo yum install gcc httpd-devel
安装依赖项后,进入可写目录并下载连接器源代码。 您可以在 Tomcat 连接器下载页面 上找到最新版本。 复制与 Tomcat JK 连接器的最新 tar.gz
源关联的链接,并使用 curl
命令将其下载到您的服务器:
cd /tmp curl -LO http://mirrors.ibiblio.org/apache/tomcat/tomcat-connectors/jk/tomcat-connectors-1.2.48-src.tar.gz
接下来,将 tarball 解压缩到当前目录并移动到 native
子目录,其中源代码和构建脚本位于解压缩的文件层次结构中:
tar xzvf tomcat-connectors* cd tomcat-connectors*/native
现在,我们已准备好配置软件。 我们需要设置 apxs
Apache 扩展工具二进制文件的位置,以成功为我们的服务器配置源。 之后,我们可以使用make
来构建软件并安装编译好的模块:
./configure --with-apxs=/usr/bin/apxs make sudo make install
这会将 mod_jk
模块安装到 Apache 模块目录中。
第 2 步:配置 mod_jk 模块
现在模块已安装,我们可以配置 Apache Web 服务器以使用它与我们的 Tomcat 实例进行通信。 这可以通过设置一些配置文件来完成。
首先在 /etc/httpd/conf.d
目录中打开一个名为 jk.conf
的文件:
sudo vi /etc/httpd/conf.d/jk.conf
在内部,我们需要首先加载 mod_jk
模块。 之后,我们将配置一个专用的日志和共享内存文件。 最后,我们将使用 JkWorkersFile
指令指向我们将创建的文件以指定我们的工作人员配置。
将以下配置粘贴到文件中以将这些部分链接在一起。 您不必修改任何内容:
/etc/httpd/conf.d/jk.conf
LoadModule jk_module modules/mod_jk.so JkLogFile logs/mod_jk.log JkLogLevel info JkShmFile logs/mod_jk.shm JkWorkersFile conf/workers.properties
完成后保存并关闭文件。
接下来,我们将创建工作者属性文件。 我们将使用它来定义一个工作人员来连接到我们的 Tomcat 后端:
sudo vi /etc/httpd/conf/workers.properties
在这个文件中,我们将定义一个工作人员,它将使用 Apache JServ 协议的版本 13 在端口 8009 上连接到我们的 Tomcat 实例:
/etc/httpd/conf/workers.properties
worker.list=worker1 worker.worker1.type=ajp13 worker.worker1.host=127.0.0.1 worker.worker1.port=8009
完成后,保存并关闭文件。
第 3 步:使用 mod_jk
将 Apache 虚拟主机调整为代理
最后,我们需要调整启用 SSL 的 Apache 虚拟主机文件。 如果您遵循先决条件,则当前应配置为使用受信任或自签名 SSL 证书保护您的内容。
现在通过键入以下内容打开文件:
sudo vi /etc/httpd/conf.d/ssl.conf
在内部,在 VirtualHost
配置块中,添加一个 JkMount
指令以将此虚拟主机接收到的所有流量传递给我们刚刚定义的工作实例。 JkMount
可以放在 VirtualHost
部分的任何位置:
/etc/httpd/conf.d/ssl.conf
. . . <VirtualHost _default_:443> . . . JkMount /* worker1 . . . </VirtualHost>
完成后保存并关闭文件。
接下来,通过键入以下内容检查您的配置:
sudo apachectl configtest
如果输出包含 Syntax OK
,请重新启动 Apache Web 服务器进程:
sudo systemctl restart httpd
您现在应该可以通过在 Web 浏览器中访问站点的 SSL 版本来安装 Tomcat:
https://example.com
接下来,跳过下面的 Nginx 配置并继续详细介绍如何限制对 Tomcat 的访问以完成配置的部分。
(选项 2)使用 Nginx 的 HTTP 代理
如果您更喜欢 Apache Web 服务器,使用 Nginx 进行代理也很容易。 虽然 Nginx 没有允许它使用 Apache JServ 协议的模块,但它可以使用其强大的 HTTP 代理功能与 Tomcat 通信。
部分先决条件
在我们讨论如何将 Nginx 连接代理到 Tomcat 之前,您必须安装并保护 Nginx。
您执行此操作的方式取决于您是否拥有域名。
- 如果您有域名... 保护您的服务器的最简单方法是使用 Let's Encrypt,它提供免费、受信任的证书。 按照我们的 Let's Encrypt 指南为 Nginx 设置 Nginx 并使用 Let's Encrypt 保护它。
- 如果您没有域...并且您只是将此配置用于测试或个人使用,您可以使用自签名证书代替。 这提供了相同类型的加密,但没有域验证。 按照我们的 Nginx 自签名 SSL 指南安装 Nginx 并使用自签名证书对其进行配置。
完成这些步骤后,继续下面的内容以了解如何将 Nginx Web 服务器连接到您的 Tomcat 安装。
第 1 步:调整 Nginx 服务器块配置
将 Nginx 设置为代理到 Tomcat 非常简单。
首先打开与您的站点关联的服务器块文件。 自签名和 Let's Encrypt SSL 指南都在 /etc/httpd/conf.d/ssl.conf
文件中配置加密的服务器块,因此我们将使用它:
sudo vi /etc/nginx/conf.d/ssl.conf
在里面,靠近文件的顶部,我们需要添加一个 upstream
块。 这将概述连接详细信息,以便 Nginx 知道我们的 Tomcat 服务器正在侦听的位置。 将它放在文件中定义的任何 server
块之外:
/etc/nginx/sites-available/default
upstream tomcat { server 127.0.0.1:8080 fail_timeout=0; } server { . . .
接下来,在为端口 443 定义的 server
块中,修改 location /
块。 我们想将所有请求直接传递给我们刚刚定义的 upstream
块。 注释掉任何现有内容并使用 proxy_pass
指令传递给我们刚刚定义的上游“tomcat”。
我们还将设置一些允许 Nginx 传递有关请求的 Tomcat 信息的标头:
/etc/nginx/sites-available/default
upstream tomcat { server 127.0.0.1:8080 fail_timeout=0; } server { . . . location / { #try_files $uri $uri/ =404; proxy_pass http://tomcat/; proxy_set_header Host $http_host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } . . . }
完成后,保存并关闭文件。
第二步:测试并重启 Nginx
接下来,测试以确保您的配置更改没有引入任何语法错误:
sudo nginx -t
如果没有报错,重启 Nginx 来实现你的修改:
sudo systemctl restart nginx
您现在应该可以通过在 Web 浏览器中访问站点的 SSL 版本来安装 Tomcat:
https://example.com
限制对 Tomcat 安装的访问
现在您对 Tomcat 安装具有 SSL 加密访问权限,我们可以进一步锁定 Tomcat 安装。
由于我们希望对 Tomcat 的所有请求都通过我们的代理,我们可以将 Tomcat 配置为仅侦听本地环回接口上的连接。 这确保了外部各方无法尝试直接从 Tomcat 发出请求。
打开 Tomcat 配置目录中的 server.xml
文件以更改这些设置:
sudo vi /opt/tomcat/conf/server.xml
在这个文件中,我们需要修改 Connector 定义。 目前在配置中启用了两个连接器。 一个处理端口 8080 上的普通 HTTP 请求,而另一个处理端口 8009 上的 Apache JServ 协议请求。 配置将如下所示:
/opt/tomcat/conf/server.xml
. . . <Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" /> . . . <!-- Define an AJP 1.3 Connector on port 8009 --> <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
为了限制对本地环回接口的访问,我们只需要在每个连接器定义中添加一个设置为 127.0.0.1
的“地址”属性。 最终结果将如下所示:
/opt/tomcat/conf/server.xml
. . . <Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" address="127.0.0.1" redirectPort="8443" /> . . . <!-- Define an AJP 1.3 Connector on port 8009 --> <Connector port="8009" address="127.0.0.1" protocol="AJP/1.3" redirectPort="8443" />
完成这两项更改后,保存并关闭文件。
我们需要重新启动 Tomcat 进程来实现这些更改:
sudo systemctl restart tomcat
您的 Tomcat 安装现在应该只能通过您的 Web 服务器代理访问。
结论
此时,与您的 Tomcat 实例的连接应该在 Web 服务器代理的帮助下使用 SSL 加密。 虽然配置单独的 Web 服务器进程可能会增加为应用程序提供服务所涉及的软件,但它可以显着简化保护流量的过程。