暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Nginx 配置 HTTP/2

程序猿研究所 2021-04-12
1831

      目前流行的 Web 服务器,例如 Apache, Nginx 都已经对 http/2 支持得比较完善了,Nginx 在版本 1.9.5 开始支持 Http/2。


      Http/2 的配置是兼容 Http/1.1 的,客户端发起请求时,在握手之前,会发起 ALPN,查询服务端是否支持 Http/2, 如果不支持会回退到 Http/1.1 协议。


       在这里我们使用 Curl 来测试一个 http/2 的站点:

    ➤ /usr/local/opt/curl-openssl/bin/curl --tlsv1.3 --http2 -v https://http2.example.com 
    *   Trying 129.211.xx.xxx:443...
    Connected to https://http2.example.com (129.211.xx.xxx) port 443 (#0)
    * ALPN, offering h2
    * ALPN, offering http/1.1
    * successfully set certificate verify locations:
    * CAfile: usr/local/etc/openssl@1.1/cert.pem
    * CApath: usr/local/etc/openssl@1.1/certs
    * TLSv1.3 (OUT), TLS handshake, Client hello (1):
    * TLSv1.3 (IN), TLS handshake, Server hello (2):
    * TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
    * TLSv1.3 (IN), TLS handshake, Certificate (11):
    * TLSv1.3 (IN), TLS handshake, CERT verify (15):
    * TLSv1.3 (IN), TLS handshake, Finished (20):
    * TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
    * TLSv1.3 (OUT), TLS handshake, Finished (20):
    * SSL connection using TLSv1.3 TLS_AES_256_GCM_SHA384
    * ALPN, server accepted to use h2
    * Server certificate:
    *  subject: CN=http2.example.com
    * start date: Sep 30 18:16:51 2020 GMT
    * expire date: Dec 29 18:16:51 2020 GMT
    * subjectAltName: host "http2.example.com" matched cert's "http2.example.com"
    * issuer: C=US; O=Let's Encrypt; CN=Let's Encrypt Authority X3
    * SSL certificate verify ok.
    * Using HTTP2, server supports multi-use
    * Connection state changed (HTTP/2 confirmed)
    * Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
    * Using Stream ID: 1 (easy handle 0x7f90c2814e00)
    > GET HTTP/2
    > Host: http2.example.com
    > user-agent: curl/7.73.0
    > accept: */*
    >
    * TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
    * TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
    * old SSL session ID is stale, removing
    * Connection state changed (MAX_CONCURRENT_STREAMS == 128)!
    < HTTP/2 200
    < content-type: Application/json;charset=utf-8
    < vary: Accept-Encoding
    < cache-control: no-cache, private
    < date: Mon, 07 Dec 2020 05:37:58 GMT
    x-robots-tag: noindex
    <
    * Connection #0 to host http2.example.com left intact
    {"code":0,"data":{"title":"api server","version":"0.1.0","stage":"dev"},"msg":"ok"}⏎ 



         因此无论是出于安全性还是性能方面的考虑,都应该使用 Http/2。在Nginx 中配置 Http/2,同时需要启用 SSL 加密,Http/2 协议本身并没有规定需要使用 SSL 加密,但是各大浏览器都统一默认 Http/2 需要 SSL 加密。SSL 的加密证书可以使用 Let’s encrypt,https://certbot.eff.org/,这个工具可以生成 Let’s encrypt 证书。

            Let’s encrypt 证书适合用作开发环境的证书,因为 IE 和 Safari 浏览器在访问 https 站点的时候,客户端会发起 OCSP 证书检验,而 Let’s encrypt 的 ocsp 服务器在大陆访问非常缓慢,所以在 苹果设备访问 Let’s encrypt 会非常缓慢,这个也没有很好的解决方案,所以在生成环境中尽量使用其他证书,好在阿里云和腾讯云都有提供免费的 DV 证书,个人推荐使用。


          Http/2 在 Nginx 中的配置:


      server {
      listen 443 ssl http2 fastopen=3 reuseport;
      ssl_certificate var/www/certs/api.example.tech.pem;
      ssl_certificate_key var/www/certs/api.example.tech.key;
      ssl_session_timeout 1d;
      ssl_session_cache builtin:1000 shared:SSL:10m;
      ssl_protocols TLSv1.2 TLSv1.3;
      ssl_ciphers "ECDHE-ECDSA-CHACHA20-POLY1305 ECDHE-RSA-CHACHA20-POLY1305 DHE-RSA-CHACHA20-POLY1305";
      ssl_ocsp off;
      ssl_prefer_server_ciphers on;


      root var/www/html/app/prod/current/public;
      index index.php index.html;


      server_name api.example.tech;


      location / {
      try_files $uri $uri/ /index.php?$query_string;
      }


      error_page 404 /404.html;
      error_page 500 502 503 504 /50x.html;
      location = /50x.html {
      root /usr/share/nginx/html;
      }


      location ~ \.php$ {
      fastcgi_split_path_info ^(.+\.php)(/.+)$;
      fastcgi_pass unix:/run/php-fpm/www.sock;
      fastcgi_index index.php;
      fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
      fastcgi_param APP_ENV prod;
      include fastcgi_params;
      }
      }


              最主要的配置是以下几行:

            listen 443 ssl http2 fastopen=3 reuseport;
        ssl_certificate /var/www/certs/api.example.tech.pem;
        ssl_certificate_key /var/www/certs/api.example.tech.key;
        ssl_session_timeout 1d;
        ssl_session_cache builtin:1000 shared:SSL:10m;
        ssl_protocols TLSv1.2 TLSv1.3;
        ssl_ciphers "ECDHE-ECDSA-CHACHA20-POLY1305 ECDHE-RSA-CHACHA20-POLY1305 DHE-RSA-CHACHA20-POLY1305";
        ssl_ocsp off;
        ssl_prefer_server_ciphers on;

               根据需要对 ssl 的证书目录和 ssl 支持的协议和加密方式进行更改,配置完成之后就可以使用 curl 对站点进行测试,查看是否配置生效。

              


        文章转载自程序猿研究所,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

        评论