CentOS 6.7 (64位)配置nginx支持http2

基础知识

其实nginx配置http2大部分工作都是配置ssl,这个网上资料很多,重点是要做好ssl的优化,比如OCSP的配置,这里推荐Jerry Qu的博客,他上面有很多web优化方面的文章,自然也包括ssl优化,比如:

这些文章对ssl的基础配置和高级优化做了比较好的概括,最后我的nginx相关部分配置如下:

user  nginx;
worker_processes  1;#这个根据实际情况来

events {
    
    worker_connections  31024;#这个要根据实际情况来计算
    multi_accept on;
}

http {
    include       mime.types;
    default_type  application/octet-stream;
    
    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    keepalive_timeout 65;
    types_hash_max_size 2048;
    server_tokens off;
    server_name_in_redirect off;
    server_names_hash_bucket_size 128;
    client_header_buffer_size 32k;
    large_client_header_buffers 4 32k;
    client_max_body_size 200m;

    gzip on;
    gzip_disable "msie6";

    gzip_vary on;
    gzip_proxied any;
    gzip_comp_level 3;
    gzip_buffers 16 8k;
    # gzip_http_version 1.1;
    gzip_types text/plain application/javascript text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;

    proxy_connect_timeout 5;
    proxy_read_timeout 60;
    proxy_send_timeout 5;
    proxy_buffer_size 16k;
    proxy_buffers 4 64k;
    proxy_busy_buffers_size 128k;

    proxy_temp_path /data/nginx/tmp_dir 1 2;
    proxy_cache_path           /data/nginx/cache_dir/cache1 levels=1:2 keys_zone=cache1:100m inactive=30d max_size=10g;

    upstream local_api {
        server 127.0.0.1:8080 weight=1 max_fails=3 fail_timeout=30s;
    }
    
    server {
	listen 443 ssl http2;

	server_name domain;# 配置成自己的域名

	ssl on;
        ssl_certificate      cert/domain.crt;
        ssl_certificate_key  cert/domain_private.key;
        ssl_session_cache    shared:SSL:20m;
        ssl_session_timeout  60m;
	ssl_session_tickets  on;

	ssl_dhparam cert/dhparam.pem;

	ssl_protocols	TLSv1 TLSv1.1 TLSv1.2;	
        #ssl_ciphers  HIGH:!aNULL:!MD5;
	#ssl_ciphers  "ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS";
	ssl_ciphers "EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA384 EECDH+ECDSA+SHA256 EECDH+aRSA+SHA384 EECDH+aRSA+SHA256 EECDH+aRSA+RC4 EECDH EDH+aRSA !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS !RC4";
        ssl_prefer_server_ciphers  on;

	ssl_stapling on;
	ssl_stapling_verify on;

	ssl_trusted_certificate cert/domain.crt;

	resolver 100.100.2.136 100.100.2.138 valid=300s;
	resolver_timeout 10s;	

	add_header Strict-Transport-Security max-age=15768000;

	root html;
	index index.html index.htm;

	location /api {
                # First attempt to serve request as file, then
                # as directory, then fall back to displaying a 404.
                #try_files $uri $uri/ =404;
                index index.html;
                proxy_pass http://local_api/api;
                proxy_redirect off;
                proxy_set_header Host $host;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header X-Forwarded-Proto $scheme;
                add_header  Front-End-Https on;
                error_page 404 500 @proxy;
        }


	location ~ '.*\.(gif|jpg|jpeg|png|bmp|swf|js|css)$' {
    		proxy_pass http://local_api;
		access_log off;
    		expires 1d;
	}

	location ~ ^/(WEB-INF)/ {
    		deny all;
	}

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

    }    

    ...
}

升级openssl

在配置之前,先要升级系统自带的openssl到1.0.2+,原因看为什么我们应该尽快支持 ALPN?。本来我想直接升级到最新的1.1.0,但是似乎在CentOS 6.7的版本里,在编译进nginx 1.10.1时会出错,只能编译1.0.2h的版本了

  1. openssl官网源码下载页面里复制openssl-1.0.2h.tar.gz的下载地址
  2. 编译并替换系统自带的openssl
su
cd /usr/local/src
wget "https://www.openssl.org/source/openssl-1.0.2h.tar.gz"
tar zxf openssl-1.0.2h.tar.gz
cd openssl-1.0.2h
./config --prefix=/usr/local --openssldir=/usr/local/openssl
make
make install
# 找出openssl命令的所有路径
whereis openssl
# 这里我只要替换/usr/bin/openssl就可以了
ln -sf /usr/local/bin/openssl /usr/bin/openssl
# 检查openssl版本
openssl version
# 注意为了系统其他应用编译的时候能够共享到升级版openssl的库,建议安装两次,生成动态连接库
export CFLAGS=-fPIC
./config shared --prefix=/usr/local --openssldir=/usr/local/openssl
make depend
make
make install
echo "/usr/local/lib64" >> /etc/ld.so.conf
ldconfig
ldconfig -v
编译nginx
  1. nginx官网下载页复制最新的stable version的下载地址,如果你要更完善和更新的http2支持,就下载最新的mainline version,我这里还是继续使用stable version
    2.编译nginx,openssl模块要指定之前的openssl源码文件夹
su
cd /usr/local/src
wget "http://nginx.org/download/nginx-1.10.1.tar.gz"
tar zxf nginx-1.10.1.tar.gz
cd nginx-1.10.1
./configure --prefix=/usr/local/nginx --sbin-path=/usr/sbin/nginx --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/log/run/nginx.pid --lock-path=/var/log/lock/subsys/nginx --with-openssl=/usr/local/src/openssl-1.0.2h  --with-http_gzip_static_module --with-http_realip_module --with-http_stub_status_module --with-http_ssl_module --with-http_addition_module --with-stream --with-stream_ssl_module --with-http_v2_module --with-threads
make
make install
nginx
Show Comments