申请Let'sEncrypt证书,让Tomcat启用HTTP2.0

发布时间:

最后更新:

关键词: HTTP2.0 JAVA9 Let'sEncrypt Tomcat

本文介绍如何申请Let's Encrypt的证书,Tomcat开启HTTP2的方式,以及JAVA9下无需ToncatNative库也能启用HTTP2的方法。给你自己的站点也开启HTTP2.0吧

目录:

  1. HTTP2.0的优势
  2. 证书申请
  3. 使用TomcatNative
  4. 使用Tomcat9的内置实现

1. HTTP2.0的优势

HTTP/2 (原名HTTP/2.0)即超文本传输协议 2.0,是下一代HTTP协议。是由互联网工程任务组(IETF)的Hypertext Transfer Protocol Bis (httpbis)工作小组进行开发。是自1999年http1.1发布后的首个更新。HTTP 2.0在2013年8月进行首次合作共事性测试。在开放互联网上HTTP 2.0将只用于https://网址,而 http://网址将继续使用HTTP/1,目的是在开放互联网上增加使用加密技术,以提供强有力的保护去遏制主动攻击。

HTTP/2.0 通过支持首部字段压缩和在同一连接上发送多个并发消息,让应用更有效地利用网络资源,减少感知的延迟时间。而且,它还支持服务器到客户端的主动推送机制。 HTTP 2.0 的出现,相比于 HTTP 1.x ,大幅度的提升了 web 性能。在与 HTTP/1.1 完全语义兼容的基础上,进一步减少了网络延迟。而对于前端开发人员来说,无疑减少了在前端方面的优化工作。

HTTP/2: the Future of the Internet这是 Akamai 公司建立的一个官方演示,演示中分别使用HTTP1.1和2.0加载一张地球的图片,整张图被分割成许多小块来加载,HTTP1.1花费了17.5秒,而HTTP2只用了2.5秒,比香港记者还快,比起HTTP1.1更是不知道高到哪里去了。

本站使用了Let's Encpty的证书,并启用了基于JAVA9实现的Tomcat的HTTP2.0功能,是不是感觉访问的时候特别快呢?(不可能的,服务器在国外你告诉我怎么快)接下来就讲解如何让自己的站点也用上HTTP2.0!

2. 证书申请

上面的简介提到了HTTP2.0必须要Https,也就是得有一个SSL证书,你可以自己用OpenSSL生成一个、从证书发行商那里买一个,或是申请免费的证书。自己生成的证书没有认证,浏览器会显示一个很难看的提示,比如使用了自签名证书的某网站:

当然这个网站是安全的,只是它使用的证书不是由CA颁发(注:2017年11月29日起该网站也买了CA证书),也就不在浏览器的默认信任列表里面,浏览器就会出现这样的提示。作为个人的的网站,可没法像这个站这么任性,如果用户在打开你的网站时出现了这种提示,八成以为你的站被挂了木马,立刻就关页面走人了。自签名证书也就能在开发的时候用用,上线使用是万万不可取的,还是得使用CA签发的证书才行。

在以前想搞一个证书并不容易,大多数CA认证的证书都得花钱,而且申请流程也颇为复杂。但是现在,为了拯救还在用HTTP的网站,为了让人人都用上HTTPS,一个网站站了出来,那就是Let's Encrypt

Let's Encrypt作为一个公共且免费SSL的项目逐渐被广大用户传播和使用,是由Mozilla、Cisco、Akamai、IdenTrust、EFF等组织人员发起,主要的目的也是为了推进网站从HTTP向HTTPS过度的进程,目前已经有越来越多的商家加入和赞助支持。

Let's Encrypt具有签发的证书是通过认证的,在浏览器的地址栏上显示的是象征安全的绿色,而且它完全免费,改版后的申请流程也十分简单,实乃个人网站的不二之选。

目前的Let's Encrypt使用Certbot自动颁发证书,不用像最初那样自己去费老大劲验证域名。首先要安装Certbot,以本站运行的CentOS为例,首先按照它的官方教程来,直接从yum库里安装。

yum -y install yum-utils
yum-config-manager --enable rhui-REGION-rhel-server-extras rhui-REGION-rhel-server-optional
yum install certbot

如果它显示找不到certbot包,有可能是缓存太旧,可以尝试如下操作:

  1. 执行yum remove epel-release,删除epel-release缓存
  2. 清一下全局缓存yum clean all
  3. 删除/etc/yum.repos.d/目录下以epel开头的文件
  4. 执行yum install epel-release,重新安装epel-release
  5. 重新执行yum install certbot,此时就能安装了。

certbot装好后就可以一键(一条指令)安装证书了,运行以下命令

certbot certonly --webroot -w /var/www/example -d example.com

或者

certbot certonly --standalone -d example.com

这两者的区别是验证域名所有权的方式不同,Let's Encrypt颁发证书当然不能乱发,它需要验证证书的域名的所有权,方式就是向该域名发送一个随机的文件,接收到后把它发送回Let's Encrypt确认。

--webroot参数使用的是你现有的Web服务器来接收验证文件,这需要你在自己的程序里加上相应的验证代码,这里就不贴了,其他文章里有讲。

--standalone参数则使用自带的一个服务器来处理上述流程,不需要做任何额外的操作,相比之下这一种更方便。

回到流程上来,把上面命令中的example.com换成你自己的域名,然后会要你确它的协议,输入A按回车即可。之后还会问你是否分享邮箱,这里就不分享了,输入N按回车。运行结束后在/etc/letsencrypt/live/[你的域名]下生成4个以pem结尾的证书文件,有了它们就能让网站装备上SSL了!

证书有3个月的期限,可以使用certbot renew命令来让它自动续命

3. 使用TomcatNative处理HTTPS

如果你去百度Tomcat+HTTP2之类的关键字,基本上都是使用这种配置方式的文章,其优点是支持老版本的平台,Tomcat9以及JAVA9之前的版本。

如果你使用的是Windows,那就方便了,官网提供了编译好的TomcatNative库,只有一个dll文件,名字叫tcnative-1.dll,放进Tomcat的bin目录里即可,而且它一般都自带,连下载的功夫都省了。

Linux就没这么幸运了,它首先需要安装APR(Apache Portable Runtime)库,这个库是干嘛的呢?

Tomcat can use the Apache Portable Runtime to provide superior scalability, performance, and better integration with native server technologies. The Apache Portable Runtime is a highly portable library that is at the heart of Apache HTTP Server 2.x. APR has many uses, including access to advanced IO functionality (such as sendfile, epoll and OpenSSL), OS level functionality (random number generation, system status, etc), and native process handling (shared memory, NT pipes and Unix sockets).

These features allows making Tomcat a general purpose webserver, will enable much better integration with other native web technologies, and overall make Java much more viable as a full fledged webserver platform rather than simply a backend focused technology.

从这段官方介绍可以看出,Apache嫌JAVA功能太弱、速度太慢,于是把一些功能做成了本地程序提供他们的各个项目使用,TomcatNative就用到了这里头的功能。

APR可以用yum直接安装,当然如果没装OpenSSL的话也得装上,再就是编译需要的make、gcc等库

yum install gcc
yum install make
yum install apr-devel openssl-devel

之后解压tomcat-native的源码包,在tomcat的bin目录下就有,没有的话可以去官网下一个。解压后转到它的native目录下,运行

./configure --with-java-home=JDK安装位置 --with-ssl=yes --prefix=$CATALINA_HOME

其中的$CATALINA_HOME就是Tomcat的目录,之后就是make && make instal编译安装即可。

TomcatNaive装好了,接下来就是修改配置文件,打开编辑server.xml,找到这一段

<!--
    <Connector port="8443" protocol="org.apache.coyote.http11.Http11AprProtocol"
               maxThreads="150" SSLEnabled="true" >
        <UpgradeProtocol className="org.apache.coyote.http2.Http2Protocol" />
        <SSLHostConfig>
            <Certificate certificateKeyFile="conf/localhost-rsa-key.pem"
                         certificateFile="conf/localhost-rsa-cert.pem"
                         certificateChainFile="conf/localhost-rsa-chain.pem"
                         type="RSA" />
        </SSLHostConfig>
    </Connector>
    -->

把它取消注释,然后找到Certificate标签,将其中的3个证书路径改成刚刚申请的证书

  • certificateKeyFile: 证书私钥,对应privkey1.pem
  • certificateFile:证书文件,对应cert1.pem
  • certificateChainFile:证书链文件,对应chain1.pem

修改之后大致如下(这里以本站为例)

<Connector port="8443" protocol="org.apache.coyote.http11.Http11AprProtocol"
               maxThreads="150" SSLEnabled="true" >
        <UpgradeProtocol className="org.apache.coyote.http2.Http2Protocol" />
        <SSLHostConfig>
            <Certificate certificateKeyFile="/etc/letsencrypt/live/kaciras.net/privkey.pem"
                         certificateFile="/etc/letsencrypt/live/kaciras.net/cert.pem"
                         certificateChainFile="/etc/letsencrypt/live/kaciras.net/chain.pem"
                         type="RSA" />
        </SSLHostConfig>
    </Connector>

如果不想每次访问都输入端口的话,可以把Connector的port属性改为443,然后找到所有redirectPort="8443"的也全改成443,最后把最上头有个port="8080"的端口改成80,这样就使用了公认的HTTP 80和HTTPS 443端口,以后访问不需要再在域名后面加端口了。

最后重启Tomcat,打开浏览器看看,运气好的话就能成功变身HTTP2.0了,如果运气不好,也不要紧请往下看。

4. 使用Tomcat9的内置的HTTPS实现

把上一节忘了吧,因为我也没能成功配置好TomcatNaive,那一大堆其实都是失败经验(把博主拉出去打死)。这里我就得吐槽一下,在Linux上装这玩意可费劲了,需要手动编译不说,还很容易出错,比如在logs/localhost-xxxx.log里出现这样的信息:

org.apache.catalina.core.AprLifecycleListener lifecycleEvent
SEVERE: Failed to initialize the SSLEngine.
org.apache.tomcat.jni.Error: 70023: This function has not been implemented on this platform
...

在跟这个错误斗智斗勇一下午之后我还是选择了认输,要是出现了这种错误,恭喜你,用TomcatNative这条路多半是废了。

或许是我搜索的姿势不对,百度和谷歌找了半天也没能解决这个问题,全都是说把sslEngine="on"改成off,我就纳闷了,难道他们都不用SSL的么

但是HTTP2.0还是要滴,既然一种办法行不通那就得换个思路。HTTP2在2015年5月份,由RFC 7540正式确定的,距今已有2个年头了,没理由不能用JAVA实现。在回去翻它的官网时,突然发现了这么一段话:

Apache Tomcat 9.x is the current focus of development. It builds on Tomcat 8.0.x and 8.5.x and implements the Servlet 4.0, JSP 2.3, EL 3.0, WebSocket 1.1 and JASPIC 1.1 specifications (the versions required by Java EE 8 platform). In addition to this, it includes the following significant improvements:

  • Adds support for HTTP/2 (requires either running on Java 9 (since Apache Tomcat 9.0.0.M18) or the Tomcat Native library being installed)
  • Adds support for using OpenSSL for TLS support with the JSSE connectors (NIO and NIO2)
  • Adds support for TLS virtual hosting (SNI)

列表中第一条说到了在Java 9平台下运行9.0.0.M18之后的Tomcat内置的实现JSSEImplementation支持HTTP2,所以无需Tomcat Native library也是可以的,正好我装的都是最新版,一瞬间就看到了黎明的曙光。

既然可以那就开干,经过一番查阅,发现开启内置引擎是非常的方便,只需要改改server.xml即可,接着上一节的配置文件,首先先干掉万恶的APR

 <!--APR library loader. Documentation at /docs/apr.html -->
 <!--<Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />-->

接着修改之前配置的Connector,把protocol属性改成Http11NioProtocol,然后再把默认的SSL实现加上,方法就是在Connector里插入这么一句sslImplementationName="org.apache.tomcat.util.net.jsse.JSSEImplementation",修改后的部分如下

<Connector port="443" protocol="org.apache.coyote.http11.Http11NioProtocol"
					  sslImplementationName="org.apache.tomcat.util.net.jsse.JSSEImplementation"
                      maxThreads="150" SSLEnabled="true" >
        <UpgradeProtocol className="org.apache.coyote.http2.Http2Protocol" />
        <SSLHostConfig>
            <Certificate certificateKeyFile="/etc/letsencrypt/archive/kaciras.net/privkey1.pem"
                         certificateFile="/etc/letsencrypt/archive/kaciras.net/cert1.pem"
                         certificateChainFile="/etc/letsencrypt/archive/kaciras.net/chain1.pem"
                         type="RSA" />
        </SSLHostConfig>
    </Connector>

然后保存退出,重启Tomcat,再打开浏览器看看,是不是已经变成HTTP2.0了呢?

这种配置方式可谓是非常简单,再对比上一节TomcatNaive的方式,不得不说直接搜索出来的教程大都比较老,多看看官网,第一时间了解新的功能是很有用的。

本文讲解了如何让Tomcat启用HTTP2.0的两种方式,特别是后一种非常方便,希望看到此文的小伙伴们也能让自己的站用上Http2.0

评论加载中