nginx开启http2和TLS1.3

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了nginx开启http2和TLS1.3相关的知识,希望对你有一定的参考价值。

HTTP/2 的优势

相比 HTTP/1.x,HTTP/2 在底层传输做了很大的改动和优化:

  1. HTTP/2 采用二进制格式传输数据,而非 HTTP/1.x 的文本格式。二进制格式在协议的解析和优化扩展上带来更多的优势和可能。
  2. HTTP/2 对消息头采用 HPACK 进行压缩传输,能够节省消息头占用的网络的流量。而 HTTP/1.x 每次请求,都会携带大量冗余头信息,浪费了很多带宽资源。头压缩能够很好的解决该问题。
  3. 多路复用,直白的说就是所有的请求都是通过一个 TCP 连接并发完成。HTTP/1.x 虽然通过 ​​pipeline ​​​也能并发请求,但是多个请求之间的响应会被​​阻塞​​的,所以 pipeline  至今也没有被普及应用,而 HTTP/2 做到了真正的并发请求。同时,流还支持优先级和流量控制。
  4. Server Push:服务端能够更快的把资源推送给客户端。例如服务端可以主动把 JS 和 CSS 文件推送给客户端,而不需要客户端解析 html 再发送这些请求。当客户端需要的时候,它已经在客户端了。

升级HTTP2和TLS1.3必要条件

  1. nginx必须大于1.3
  2. 必须支持https
  3. openssl必须大于1.1.0

我的nginx小于1.3,故而选择安装nginx-1.14.2版本,不覆盖原安装路径,如果是升级nginx,切记最后不要make install

软件安装位置

openssl
1、编译位置
/usr/local/openssl
软链接位置/usr/bin/openssl
/usr/include/openssl

nginx
1、编译及配置文件位置
软链接位置
/usr/local/data/ngin
编译位置
/usr/local/data/nginx-14.2

升级openssl

#备份旧版
mv /usr/bin/openssl /usr/bin/openssl.old
mv /usr/include/openssl /usr/include/openssl.old
#
wget https://www.openssl.org/source/openssl-1.1.1i.tar.gz --no-check-certificate
tar zxvf openssl-1.1.1i.tar.gz
cd openssl-1.1.1i
./config --prefix=/usr/local/openssl shared zlib
make depend
make && make install
ln -s /usr/local/openssl/bin/openssl /usr/bin/openssl
ln -s /usr/local/openssl/include/openssl /usr/include/openssl
echo /usr/local/openssl/lib >> /etc/ld.so.conf
ldconfig
openssl version
OpenSSL 1.1.1i 8 Dec 2020
#查看支持的tls版本
openssl s_client -help 2>&1 | awk /-(ssl|tls)[0-9]/print $1
-tls1
-tls1_1
-tls1_2
-tls1_3
/usr/local/openssl/bin/openssl s_client -connect test.lovepik.com:443 -tls1_3

安装nginx

wget -q -nc http://nginx.org/download/nginx-1.14.2.tar.gz
tar zxvf nginx-1.14.2.tar.gz
#改之前
cat nginx-1.14.2/auto/lib/openssl/conf
CORE_INCS="$CORE_INCS $OPENSSL/.openssl/include"
CORE_DEPS="$CORE_DEPS $OPENSSL/.openssl/include/openssl/ssl.h"
CORE_LIBS="$CORE_LIBS $OPENSSL/.openssl/lib/libssl.a"
CORE_LIBS="$CORE_LIBS $OPENSSL/.openssl/lib/libcrypto.a"
#改之后
CORE_INCS="$CORE_INCS $OPENSSL/include"
CORE_DEPS="$CORE_DEPS $OPENSSL/include/openssl/ssl.h"
CORE_LIBS="$CORE_LIBS $OPENSSL/lib/libssl.a"
CORE_LIBS="$CORE_LIBS $OPENSSL/lib/libcrypto.a"
cd nginx-1.14.2
./configure --prefix=/usr/local/data/nginx-1.14.2 \\
--user=ooopic \\
--group=ooopic \\
--with-http_stub_status_module \\
--with-http_ssl_module \\
--with-pcre \\
--with-http_flv_module \\
--with-http_gzip_static_module \\
--with-http_secure_link_module \\
--with-openssl-opt=enable-tlsext \\
--with-http_v2_module \\
--with-openssl=/usr/local/openssl \\
--with-openssl-opt=enable-tls1_3
make && make install #(升级nginx,不要执行make install操作)

#复制旧版nginx中的配合到新版
#修改https配置
listen 443 http2;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;

#批量修改(vhosts下面的配置文件必须都改才能生效,由于我这个下面存在多个子域名,改了其中两个,折腾一下午)
sed -i s/ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;/ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;/ *.conf
sed -i s/ssl_protocols TLSv1 TLSv1.1 TLSv1.2;/ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;/ *.conf
sed -i s/443/443 http2/ *.conf

测试

/usr/local/openssl/bin/openssl s_client -connect test.lovepik.com:443 -tls1_3
返回信息包含一下内容则说明配置成功
SSL-Session:
Protocol : TLSv1.3
Cipher : TLS_AES_256_GCM_SHA384
Session-ID: 98BB361E1DF0546E2887B3C52F89D8E3D33B0B5D9BAECF579196D902ACAE4A34
Session-ID-ctx:
Resumption PSK: 1B8D6677552D1DD0C03EB07EDD4EEB50A66E027CEB6E0D8CEA2B2C4E94D270BA8373CD2A44EDD06DC9BAEB5965AF136E
PSK identity: None
PSK identity hint: None
SRP username: None
TLS session ticket lifetime hint: 300 (seconds)

​配置参考链接​

nginx开启http2和TLS1.3_nginx

Golang + nginx的+ HTTPS

我有 - 作为监听器http和https转到服务器。 Nginx配置为处理http + https的传入请求。证书有序。使用单独的服务器可以在https协议上对它们的查询结果完美运行。但是,当我使用代理nginx时,https没有从服务器和服务器Go获得响应

“http:来自127.0.0.1:54037的TLS握手错误:tls:第一条记录看起来不像是TLS握手

可能是什么问题呢?

客户去:

package main

import (
    "net/http"
    "log"

)

func HelloSSLServer(w http.ResponseWriter, req *http.Request) {
    w.Header().Set("Content-Type", "text/plain")
    w.Write([]byte("This is an example server.
"))
    // fmt.Fprintf(w, "This is an example server.
")
    // io.WriteString(w, "This is an example server.
")
}

func main() {
    http.HandleFunc("/", HelloSSLServer)
    go http.ListenAndServe("192.168.1.2:80", nil)
    err := http.ListenAndServeTLS("localhost:9007", "/etc/letsencrypt/live/somedomain/fullchain.pem", "/etc/letsencrypt/live/somedomain/privkey.pem", nil)

    if err != nil {
        log.Fatal("ListenAndServe: ", err)
    }



}

Nginx配置:

server {
    listen       192.168.1.2:80;
    server_name   somedomain;
    rewrite ^ https://$host$request_uri? permanent;    
}
server {
    listen        192.168.1.2:443 ssl;
    server_name   somedomain;
    access_log    /var/log/nginx/dom_access.log;
    error_log     /var/log/nginx/dom_error.log;
    ssl_certificate     /stuff/ssl/domain.cert;
    ssl_certificate_key /stuff/ssl/private.cert;
    ssl_protocols       TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers         ALL:!ADH:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP;


    location /
    {
        proxy_pass http://localhost:9007;
#       proxy_redirect    http://localhost:1500 http://site1;
        proxy_cookie_domain localhost somedomain;
        proxy_buffering off;

        proxy_http_version 1.1;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header Client-IP $remote_addr;
        proxy_set_header X-Forwarded-For $remote_addr;
    }
}
答案

https与proxy_pass一起使用

location /
{
    proxy_pass https://localhost:9007;
    ...
}
另一答案

nginx .config文件应该是这样的

server {
        listen 443 ssl http2;
        listen 80;
        server_name www.mojotv.cn;
        ssl_certificate     /home/go/src/my_go_web/ssl/**.pem; 
        ssl_certificate_key /home/go/src/my_go_web/ssl/**.key; 
        ssl_session_timeout 5m;
        ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
        ssl_ciphers AESGCM:ALL:!DH:!EXPORT:!RC4:+HIGH:!MEDIUM:!LOW:!aNULL:!eNULL;
        ssl_prefer_server_ciphers on;
        location /(css|js|fonts|img)/ {
            access_log off;
            expires 1d;
            root "/home/go/src/my_go_web/static";
            try_files $uri @backend;
        }
        location / {
            try_files /_not_exists_ @backend;
        }
        location @backend {
           proxy_set_header X-Forwarded-For $remote_addr;
           proxy_set_header Host $http_host;
           proxy_pass http://127.0.0.1:********;
        }
        access_log  /home/wwwroot/www.mojotv.cn.log;## nginx log path
}

the golang web app with http2 ssl feature shiped with nginx

另一答案

对于没有额外配置的更基本的Go服务器,我向OP收到类似的错误消息。

tls:第一条记录看起来不像是TLS握手

我的临时修复只是为了确保测试URL包含“https://”和URL中的端口号。

没用 - ipaddress

没有用 - https://ipaddress

工作 - https://ipaddress:8081

它将用于测试,直到更高级的设置。只需发布此内容即可帮助其他人进

以上是关于nginx开启http2和TLS1.3的主要内容,如果未能解决你的问题,请参考以下文章

开启 TLS 1.3 加密协议,极速 HTTPS 体验

记录nginx启用http2后不生效的问题

具有多个套接字连接的 HTTP2 和 TLS

又拍云 CDN 正式支持 TLS 1.3 加密协议,一键开启极速 HTTPS 体验

http2是日本人的时代,在下不才先走一步

TLS1.3抓包分析(1)——ClientHello