介绍
Apache Tomcat 是一个 Web 服务器和 servlet 容器,旨在为 Java 应用程序提供服务。 Tomcat 经常用于生产企业部署和较小的应用程序需求,既灵活又强大。
在本指南中,我们将讨论如何使用 SSL 保护您的 Ubuntu 16.04 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 Ubuntu 16.04 安装指南 中的说明进行设置。
启动并运行 Tomcat 后,请继续下面的首选 Web 服务器部分。 Apache 直接在下面开始,而 Nginx 配置可以通过向前跳过一点找到。
(选项 1)使用 Apache Web 服务器的 mod_jk
代理
Apache Web 服务器有一个名为 mod_jk
的模块,它可以使用 Apache JServ 协议直接与 Tomcat 通信。 在 Tomcat 中默认启用此协议的连接器,因此 Tomcat 已经准备好处理这些请求。
部分先决条件
在我们讨论如何将 Apache Web 服务器连接代理到 Tomcat 之前,您必须安装并保护 Apache Web 服务器。
您可以按照 本指南 的步骤 1 安装 Apache Web 服务器。 不要安装 MySQL 或 PHP。
之后,您需要在服务器上设置 SSL。 您执行此操作的方式取决于您是否拥有域名。
- 如果您有域名... 保护您的服务器的最简单方法是使用 Let's Encrypt,它提供免费、受信任的证书。 按照我们的 Let's Encrypt Apache 指南进行设置。
- 如果您没有域...并且您只是将此配置用于测试或个人使用,您可以使用自签名证书代替。 这提供了相同类型的加密,但没有域验证。 按照我们的 Apache 自签名 SSL 指南进行设置。
完成这些步骤后,请继续以下内容以了解如何将 Apache Web 服务器连接到您的 Tomcat 安装。
第一步:安装配置【X30X】【X34X】
首先,我们需要安装 mod_jk
模块。 Apache Web 服务器使用它通过 Apache JServ 协议与 Tomcat 通信。
我们可以从 Ubuntu 的默认存储库中安装 mod_jk
。 更新本地包索引并通过键入以下内容进行安装:
sudo apt-get update sudo apt-get install libapache2-mod-jk
该模块将在安装时自动启用。
接下来,我们需要配置模块。 主配置文件位于/etc/libapache2-mod-jk/workers.properties
。 现在在您的文本编辑器中打开此文件:
sudo nano /etc/libapache2-mod-jk/workers.properties
在里面,找到 workers.tomcat_home
指令。 将此设置为您的 Tomcat 安装主目录。 对于我们的 Tomcat 安装,应该是 /opt/tomcat
:
/etc/libapache2-mod-jk/workers.properties
workers.tomcat_home=/opt/tomcat
完成后保存并关闭文件。
第 2 步:使用 mod_jk
将 Apache 虚拟主机调整为代理
接下来,我们需要调整 Apache 虚拟主机以代理对 Tomcat 安装的请求。
要打开的正确虚拟主机文件取决于您用于设置 SSL 的方法。
如果您使用上面链接的指南设置自签名 SSL 证书,请打开 default-ssl.conf
文件:
sudo nano /etc/apache2/sites-available/default-ssl.conf
如果您使用 Let's Encrypt 设置 SSL,文件位置将取决于您在证书过程中选择的选项。 您可以通过键入以下内容来查找服务 SSL 请求所涉及的虚拟主机:
sudo apache2ctl -S
您的输出可能会以这样的开头:
OutputVirtualHost configuration: *:80 example.com (/etc/apache2/sites-enabled/000-default.conf:1) *:443 is a NameVirtualHost default server example.com (/etc/apache2/sites-enabled/000-default-le-ssl.conf:2) port 443 namevhost example.com (/etc/apache2/sites-enabled/000-default-le-ssl.conf:2) port 443 namevhost www.example.com (/etc/apache2/sites-enabled/default-ssl.conf:2) . . .
查看与 SSL 端口 443 相关联的行(本示例中的第 3-6 行),我们可以确定哪些虚拟主机文件涉及为这些域提供服务。 在这里,我们看到 000-default-le-ssl.conf
文件和 default-ssl.conf
文件都涉及,因此您应该编辑这两个文件。 您的结果可能会有所不同:
sudo nano /etc/apache2/sites-enabled/000-default-le-ssl.conf sudo nano /etc/apache2/sites-enabled/default-ssl.conf
无论您必须打开哪些文件,过程都是相同的。 在 VirtualHost
标签的某处,您应该输入以下内容:
<VirtualHost *:443> . . . JKMount /* ajp13_worker . . . </VirtualHost>
保存并关闭文件。 对您确定需要编辑的任何其他文件重复上述过程。
完成后,通过键入以下内容检查您的配置:
sudo apache2ctl configtest
如果输出包含 Syntax OK
,请重新启动 Apache Web 服务器进程:
sudo systemctl restart apache2
您现在应该可以通过在 Web 浏览器中访问站点的 SSL 版本来安装 Tomcat:
https://example.com
接下来,跳过下面的 Nginx 配置并继续详细介绍如何限制对 Tomcat 的访问以完成配置的部分。
(选项 2)使用 Nginx 的 HTTP 代理
如果您更喜欢 Apache Web 服务器,使用 Nginx 进行代理也很容易。 虽然 Nginx 没有允许它使用 Apache JServ 协议的模块,但它可以使用其强大的 HTTP 代理功能与 Tomcat 通信。
部分先决条件
在我们讨论如何将 Nginx 连接代理到 Tomcat 之前,您必须安装并保护 Nginx。
您可以按照 我们在 Ubuntu 16.04 上安装 Nginx 的指南来安装 Nginx。
之后,您需要在服务器上设置 SSL。 您执行此操作的方式取决于您是否拥有域名。
- 如果您有域名... 保护您的服务器的最简单方法是使用 Let's Encrypt,它提供免费、受信任的证书。 按照我们的 Let's Encrypt 指南为 Nginx 进行设置。
- 如果您没有域...并且您只是将此配置用于测试或个人使用,您可以使用自签名证书代替。 这提供了相同类型的加密,但没有域验证。 按照我们的 自签名 SSL 指南为 Nginx 进行设置。
完成这些步骤后,继续下面的内容以了解如何将 Nginx Web 服务器连接到您的 Tomcat 安装。
第 1 步:调整 Nginx 服务器块配置
将 Nginx 设置为代理到 Tomcat 非常简单。
首先打开与您的站点关联的服务器块文件。 我们将假设您使用本指南中的默认服务器块文件:
sudo nano /etc/nginx/sites-available/default
在里面,靠近文件的顶部,我们需要添加一个 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”。
我们还需要在此块中包含 proxy_params
配置。 该文件定义了 Nginx 如何代理连接的许多细节:
/etc/nginx/sites-available/default
upstream tomcat { server 127.0.0.1:8080 fail_timeout=0; } server { . . . location / { #try_files $uri $uri/ =404; include proxy_params; proxy_pass http://tomcat/; } . . . }
完成后,保存并关闭文件。
第二步:测试并重启 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 nano /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" /> . . . <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" /> . . . <Connector port="8009" address="127.0.0.1" protocol="AJP/1.3" redirectPort="8443" />
完成这两项更改后,保存并关闭文件。
我们需要重新启动 Tomcat 进程来实现这些更改:
sudo systemctl restart tomcat
如果您遵循我们的 Tomcat 安装指南,您的安装中启用了 ufw
防火墙。 现在我们对 Tomcat 的所有请求都限制在本地环回接口,我们可以从防火墙中删除允许外部请求到 Tomcat 的规则。
sudo ufw delete allow 8080
您的 Tomcat 安装现在应该只能通过您的 Web 服务器代理访问。
结论
此时,与您的 Tomcat 实例的连接应该在 Web 服务器代理的帮助下使用 SSL 加密。 虽然配置单独的 Web 服务器进程可能会增加为应用程序提供服务所涉及的软件,但它可以显着简化保护流量的过程。