如何为 Mojolicious 设置 SNI 支持?

How do I set up SNI support for Mojolicious?

Perl 的 Mojolicious supports Server Name Identification (SNI), which some web servers use to host several sites with one HTTPS certificate. I'm working on a system that's not set up to use this, and googling a bit doesn't turn up anything that makes the process clear and the various parts apparent. The Whosebug question Perl LWP GET or POST to an SNI SSL URL 提到了一些事情。

那么,我需要做什么?

首先,支持 SNI 的不是 Mojolicious(或 LWP 或其他)。这是 IO::Socket::SSL, but not really, because it's Net::SSLeay, but not really because it's your version of openssl.

  • 安装 openssl 1.0 或更高版本。您可能想使用 --prefix 选项来配置将其安装在一个新目录中,这样您就不会打扰您已经拥有的以及其他依赖的东西。
  • 更新 Net::SSLeay 以针对新的 openssl 进行编译。您需要 1.50 或更高版本。这里的问题是,后来的 Net::SSLeay 会很乐意与年长的 openssl 一起工作。升级模块不会让您获得新的 openssl。
  • IO::Socket::SSL 更新到 1.56 或更高版本。最早的版本是从 2012 年开始的,所以无论如何你都应该更新。
  • Mojolicious 2.83(2012 年发布,太老了)为客户端添加了 SN​​I 支持,Mojolicious 6.40(一个月前)为所有 Web 服务器添加了它。

您可以通过查看每个模块的 Changes 文件找到此信息,但是既然我们在这里,让我们对 Net::SSLeay 进行排序就没那么简单了安装模块。

需要注意的事项:

  • 您需要使用相同的工具编译 perl、openssl 和 Net::SSLeay,以便它们二进制兼容。

使用 OPENSSL_PREFIX 变量告诉 cpan(以及它运行的东西)在哪里可以找到正确的 openssl.

 $ export OPENSSL_PREFIX=/usr/local/ssl
 $ cpan Net::SSLeay IO::Socket::SSL

如果您已经拥有最新的 Net::SSLeay 但针对旧版本的 openssl 进行了编译,您可以强制安装该模块以重新编译它,即使 cpan 认为它是最新的:

 $ cpan -f Net::SSLeay IO::Socket::SSL

IO::Socket::SSL 有检查这个的方法(在 1.84 中添加):

 $ /usr/local/ssl/bin/openssl version
 OpenSSL 1.0.1r  28 Jan 2016
 $ perl -MIO::Socket::SSL -le 'print IO::Socket::SSL->VERSION'
 2.024
 $ perl -MIO::Socket::SSL -le 'print IO::Socket::SSL->can_client_sni'
 1

不是问题的直接答案,但可能是更好的解决方案。

根据我作为 ~400 个域的共享主机管理员的经验,在 Apache 中配置 SSL 更方便,并且在 mod_perl2 下安装 Mojolicious 运行ning。

在应用程序中放入过多的(网络)配置总是很痛苦 运行。在许多情况下,多域应用程序也会变得不方便。

在 Apache 中进行配置允许通过标准脚本进行管理,例如从 letsencrypt 更新 SSL 证书。

当然,对于其他设置来说,可能有充分的理由和特殊要求值得额外工作。