南琴浪博客

本博客 Nginx 配置(第二季)

03/05/2018

不久前,我完成了 “本博客 Nginx 配置” 的系列文章。而就在这之后,我又对着自己的配置文件唰唰唰的改了起来。遂有了这里的第二季。

在第二季中,本博客现已转用 OpenResty 环境,并在细节上进行更多细分,新增一些特性。

浏览本文时,同时也可参考 本博客 Nginx 配置(第一季) 文章。

本文最后更新: 2018-05-08

环境安装

本博客使用 Debian 8 x64 作为系统环境,Ubuntu 也同理。

关于本博客 OpenResty 环境的安装,已完整记述于 这篇文章

全局配置

Nginx 的全局配置位于 nginx.conf 中:

# 运行 Nginx 的用户组和用户
user                    naive naive;
# 进程数,一般设置为 CPU 核心数的两倍,推荐使用 auto 即可
worker_processes        auto;
# 错误日志路径
error_log               /home/openresty/nginx/logs/error.log crit;
# pid 路径
pid                     /home/openresty/nginx/sbin/nginx.pid;
# 指定 --with-pcre-jit 参数时可用
pcre_jit                on;
# 最大访问文件数限制
worker_rlimit_nofile    4096;

events {
    use                 epoll;
    epoll_events        4096;
    worker_connections  4096;
    multi_accept        off;
    accept_mutex        on;
    accept_mutex_delay  500ms;
}

http {
    include         mime_types.conf;
    default_type    text/html;
    charset         UTF-8;

    # https://sometimesnaive.org/article/20
    log_format  logformat '[$time_local] [ $remote_addr $http_user_agent $http_cookie] [$status] [$request $scheme] [$http_referer]';

    # https://sometimesnaive.org/article/32
    limit_conn_zone  $binary_remote_addr    zone=https_conn_ip:1m;
    limit_conn_zone  $server_name           zone=https_conn_server:10m;
    limit_conn_zone  $binary_remote_addr    zone=http_conn_ip:1m;
    limit_conn_zone  $server_name           zone=http_conn_server:10m;
    limit_conn_status 503;

    # https://sometimesnaive.org/article/32
    limit_req_zone   $binary_remote_addr    zone=http_req_ip:2m rate=10r/s;
    limit_req_status  503;

    client_header_buffer_size   4k;
    client_body_buffer_size     16k;
    large_client_header_buffers 8 8k;
    client_max_body_size        2m;

    client_body_timeout         20s;
    client_header_timeout       10s;
    send_timeout                30s;
    keepalive_timeout           0s;

    # https://sometimesnaive.org/article/16
    sendfile                    on;
    tcp_nopush                  on;
    tcp_nodelay                 off;

    # https://sometimesnaive.org/article/36
    proxy_cache_path    /home/openresty/nginx/proxy_cache/cache levels=1:2 keys_zone=proxycache:60m max_size=120m inactive=24h use_temp_path=off;
    proxy_cache_key     $uri;

    # https://sometimesnaive.org/article/16
    open_log_file_cache         max=4096 min_uses=1 valid=10m inactive=10m;
    open_file_cache             max=4096 inactive=24h;
    open_file_cache_min_uses    3;
    open_file_cache_valid       24h;
    open_file_cache_errors      off;

    # https://sometimesnaive.org/article/16
    ssl_session_tickets         on;
    ssl_session_cache           shared:ssl_session_cache:1m;
    ssl_session_timeout         30m;

    # https://sometimesnaive.org/article/49
    brotli                      on;
    brotli_min_length           20;
    brotli_buffers              16 10k;
    brotli_window               512k;
    brotli_comp_level           6;
    brotli_types                text/html text/xml text/plain application/json text/css image/svg application/font-woff application/vnd.ms-fontobject application/vnd.apple.mpegurl application/javascript image/x-icon image/jpeg image/gif image/png;
    brotli_static               always;

    # https://sometimesnaive.org/article/40
    gzip                        on;
    gzip_vary                   on;
    gzip_min_length             20;
    gzip_buffers                16 10k;
    gzip_comp_level             3;
    gzip_proxied                any;
    gzip_types                  text/html text/xml text/plain application/json text/css image/svg application/font-woff application/vnd.ms-fontobject application/vnd.apple.mpegurl application/javascript image/x-icon image/jpeg image/gif image/png;
    gzip_http_version           1.0;
    gzip_disable                "msie6";
    gzip_static                 always;
    gunzip                      on;

    lua_code_cache              on;
    init_by_lua_file            /home/openresty/nginx/conf/lua/init.lua;

    include  nginx-0-proxypass.conf;
    include  nginx-1-https.conf;
    include  nginx-2-http.conf;
}

站点配置

从上面的配置文件可以看出,本站的站点配置 include 四个部分:

  • nginx-0-proxypass.conf
  • nginx-1-https.conf
  • nginx-2-http.conf

nginx-0-proxypass.conf;

server {
    # https://sometimesnaive.org/article/43
    # https://sometimesnaive.org/article/16
    # https://sometimesnaive.org/article/19
    # https://sometimesnaive.org/article/56
    listen 443 ssl spdy http2 fastopen=3 reuseport;

    # https://sometimesnaive.org/article/32
    limit_conn  https_conn_ip       10;
    limit_conn  https_conn_server   100;

    # https://sometimesnaive.org/article/43
    server_name sometimesnaive.org;

    # https://sometimesnaive.org/article/20
    access_log      /home/site/access-log/access.log logformat;
    log_not_found   off;

    # https://sometimesnaive.org/article/65
    ssl_prefer_server_ciphers on;
    ssl_ecdh_curve  X25519:P-256;
    ssl_protocols   TLSv1.3 TLSv1.2;
    ssl_ciphers     'ECDHE-ECDSA-AES128-GCM-SHA256 ECDHE-ECDSA-CHACHA20-POLY1305 ECDHE-ECDSA-AES256-GCM-SHA384 ECDHE-RSA-AES256-SHA384 ECDHE-RSA-AES128-SHA256 ECDHE-RSA-AES256-SHA ECDHE-RSA-AES128-SHA';
    ssl_dhparam     /home/site/crt/dhparam-4096.pem;

    # https://sometimesnaive.org/article/19
    ssl_certificate     /home/site/crt/EncryptionEverywhere/EncryptionEverywhere-chained.crt;
    ssl_certificate_key /home/site/crt/EncryptionEverywhere/EncryptionEverywhere.key;

    # 本站因为使用 LibreSSL 而不再支持 OCSP Stapling 特性
    # 如果想使用此特性,你需要使用 OpenSSL
    # https://sometimesnaive.org/article/13
    ssl_stapling            on;
    ssl_stapling_verify     on;
    ssl_trusted_certificate /home/site/crt/EncryptionEverywhere/EncryptionEverywhere-bundle.crt;
    resolver                8.8.8.8 valid=30m;
    resolver_timeout        5s;

    # https://sometimesnaive.org/article/9
    add_header  Strict-Transport-Security   "max-age=31536000; preload" always;
    add_header  X-Frame-Options             "deny" always;
    add_header  X-Content-Type-Options      "nosniff" always;
    add_header  X-Xss-Protection            "1; mode=block" always;
    add_header  Access-Control-Allow-Origin "*" always;

    # https://sometimesnaive.org/article/46
    location / {
        access_by_lua_file  /home/openresty/nginx/conf/lua/https/access.lua;

        # https://sometimesnaive.org/article/46
        proxy_pass                  http://localhost:8000;
        proxy_http_version          1.1;
        proxy_ignore_headers        Set-Cookie;

        # https://sometimesnaive.org/article/46
        proxy_set_header            User-Agent  $http_user_agent;
        proxy_set_header            Referer     $http_referer;

        # https://sometimesnaive.org/article/36
        proxy_cache                 proxycache;
        proxy_cache_valid           304 24h;
        proxy_cache_valid           404 24h;
        proxy_cache_valid           403 444 24h;
        proxy_cache_valid           500 502 503 10m;
        proxy_cache_use_stale       invalid_header http_404 http_403 http_500 http_502 http_503;
        proxy_cache_lock            on;
        proxy_cache_lock_timeout    5s;

        # https://sometimesnaive.org/article/44
        proxy_buffering             on;
        proxy_buffers               16 20k;
        proxy_buffer_size           4k;
        proxy_busy_buffers_size     24k;
        proxy_max_temp_file_size    2m;
    }
}

nginx-1-https.conf

server {
    listen 8000;

    root   /home/site/blog;
    index  index.html;

    access_log  off;

    allow  127.0.0.1;
    deny   all;

    etag        on;
    add_header  Cache-Control "public, max-age=21600, must-revalidate" always;
}

nginx-2-http.conf

server {
    listen 80 fastopen=3;

    limit_conn http_conn_server     10;
    limit_conn http_conn_server     100;
    limit_req  zone=http_req_ip     burst=10 nodelay;

    access_log      /home/site/access-log/access.log logformat;
    log_not_found   off;

    server_name     sometimesnaive.org;

    # https://sometimesnaive.org/article/57
    # 使用 meta.html 刷新网页来达到重定向
    # 根据 meta.html 中的内容,一律重定向到 https://sometimesnaive.org/
    root            /home/site/meta;
    index           meta.html;
    error_page  404 meta.html;

    add_header  X-Frame-Options             "deny" always;
    add_header  X-Content-Type-Options      "nosniff" always;
    add_header  X-Xss-Protection            "1; mode=block" always;
    add_header  Access-Control-Allow-Origin "*" always;

    etag       on;
    add_header Cache-Control "public, max-age=31536000, must-revalidate" always;
}