编译Nginx及配置记录

编译 Nginx

编译环境: ubuntu 16.04

准备C/C++编译环境

ubuntu :

sudo apt install build-essential libtool 

centos :

sudo yum install gcc gcc-c++ automake autoconf libtool make

安装依赖库

sudo apt install libpcre3 libpcre3-dev zlib1g-dev unzip git 

pcre使nginx支持rewrite功能,zlib使nginx支持gzip压缩

准备组件

ngx_brotli组件

使nginx支持 google 开发的 Brotli 压缩格式,Brotli是一种通用的无损压缩算法,它使用LZ77算法的现代变体,霍夫曼编码和二阶上下文建模的组合来压缩数据,实现了更高的压缩比率,同时几乎不影响压缩和解压速度。

cd ~/nginx_build
git clone https://github.com/google/ngx_brotli.git
cd ./ngx_brotli
git submodule update --init
cd ./deps/brotli
git clone git@github.com:google/brotli.git

nginx-ct组件(未启用)

nginx-ct 模块用于启用 Certificate Transparency 功能。从 github 上获取:
PS: 目前最新的是v1.3.2

cd ~/nginx_build
wget -O nginx-ct.zip -c https://github.com/grahamedgecombe/nginx-ct/archive/v1.3.2.zip
unzip nginx-ct.zip

Cloudflare 补丁

Cloudflare 的 ChaCha20/Poly1305 for OpenSSL 补丁,以及 Dynamic TLS Records for Nginx 补丁。

cd ~/nginx_build
git clone https://github.com/cloudflare/sslconfig.git

OpenSSL

OpenSSL 库用于支持nginx的ssl功能模块,获取openssl源码:
(现在使用openssl-1.0.2)

cd ~/nginx_build
wget -O openssl.tar.gz -c https://github.com/openssl/openssl/archive/OpenSSL_1_0_2k.tar.gz
tar -zxf openssl.tar.gz
mv openssl-OpenSSL_1_0_2k/ openssl

打上ChaCha20/Poly1305 补丁

cd openssl
patch -p1 < ../sslconfig/patches/openssl__chacha20_poly1305_draft_and_rfc_ossl102j.patch 

获取nginx源码 & 开始编译并安装 Nginx

获取 Nginx 源码,并打上 Dynamic TLS Records 补丁:

cd ~/nginx_build
wget -c https://nginx.org/download/nginx-1.11.13.tar.gz
tar -zxf nginx-1.11.13.tar.gz
cd nginx-1.11.13/
patch -p1 < ../sslconfig/patches/nginx__1.11.5_dynamic_tls_records.patch

编译和安装nginx

cd nginx-1.11.13/
./configure --add-module=../ngx_brotli  --with-openssl=../openssl --with-http_v2_module --with-http_ssl_module --with-http_gzip_static_module
make
sudo make install

./configure 的配置参数
参考链接1: Installation and Compile-Time Options
参考链接2: Building nginx from Sources
参考链接3: 附录C 模块编译,调试与测试
以下是一些常用配置参数的含义:

参数
--prefix=path 配置nginx安装目录,默认在/usr/local/nginx (configure 的其他选项如果使用相对路径,那么以此路径为根路径)
--sbin-path=path 设置 nginx 二进制程序的路径名,这个名字只在安装期间使用,默认在prefix/sbin/nginx
--conf-path=path 设置 nginx.conf 的路径,nginx 可在启动时手动以 -c file 参数指定其他配置文件。默认在 prefix/conf/nginx.conf
--pid-path=path 设置 nginx.pid 文件的路径,安装nginx之后,可在 nginx.conf 文件中使用 pid 指令修改该路径。默认在 prefix/logs/nginx.pid
--error-log-path=path 设置 nginx的error_log的路径,安装nginx之后,可在 nginx.conf 文件中使用 error_log 指令修改该路径。默认在prefix/logs/error.log
--http-log-path=path 设置 nginx 的access_log的的路径。安装nginx之后,可在 nginx.conf 文件中使用 access_log 指令修改该路径。默认在prefix/logs/access.log
--user=name --group=name 设置启动 worker 进程时所使用的用户名和用户组。安装nginx之后,可在 nginx.conf 文件中使用 user 指令修改用户名和用户组。默认用户名和用户组为nobody
--with-select_module``--without-select_module 启用或禁用编译 select 模块。使用 select 模块可使 nginx 工作于 select 模式。如果 nginx 不支持其他更合适的模块,如 kqueue, epoll 或者 /dev/poll,则会自动构建该模块。
--with-poll_module --without-poll_module 启用或禁用编译 poll 模块。使用 poll 模块可使 nginx 工作于 poll 模式。如果 nginx 不支持其他更合适的模块,如 kqueue, epoll 或者 /dev/poll,则会自动构建该模块。
--lock-path=path 配置lock文件的路径,默认在prefix/logs/nginx.lock;(安装文件锁定,防止安装文件被恶意修改,或自己误操作)
--without-http_gzip_module 不启用编译 gzip 模块。该模块用于压缩 HTTP 响应报文。该模块的编译和运行依赖 zlib 库。
--without-http_rewrite_module 不启用编译 rewrite 模块。该模块用于重定向 HTTP 请求,也可以改写 HTTP 请求的 URI。该模块的编译和运行依赖 PCRE 库。
--without-http_proxy_module 不编译 proxy 模块。该模块常用与端口转发,反向代理
--with-http_ssl_module 开启HTTP SSL模块,以支持HTTPS请求,该模块默认不编译,该模块的编译和运行依赖 OpenSSL 库。
--with-http_v2_module 启用http/2模块,以支持http/2功能
--with-pcre=path 编译时采用自定义的pcre路径,nginx 使用 PCRE 库用于支持正则表达式,正则表达式在 location 指令和 rewrite 模块中会用到。ps:pcre需为源码
--with-pcre-jit 编译 PCRE 库时,加入 “just-in-time compilation” 支持 (1.1.12, the pcre_jit directive)
--with-openssl=path 编译时采用自定义的openssl路径,ssl模块启用依赖openssl,ps:openssl需要为源码
--with-zlib=path 编译时采用自定义的zlib路径,gzip 压缩模块依赖 zlib,ps:zlib需为源码
--with-cc-opt=*parameters* 设置将添加到CFLAGS变量的其他参数,当在FreeBSD下使用系统PCRE库时,应指定--with-cc-opt ="-I /usr/local/include";如果需要增加select所支持的文件数量,也可以在这里指定,如: --with-cc-opt ="-D FD_SETSIZE = 2048"。
--with-ld-opt=*parameters* 设置链接期间将使用的其他参数。在FreeBSD下使用系统PCRE库时,应指定--with-ld-opt="-L /usr/local/lib"。
--with-http_dav_module 开启WebDAV扩展动作模块,可为文件和目录指定权限
--with-http_flv_module 支持对FLV文件的拖动播放
--with-http_realip_module 支持显示真实来源IP地址
--with-http_gzip_static_module 预压缩文件传前检查,防止文件被重复压缩
--with-http_stub_status_module 取得一些nginx的运行状态
--with-mail 配置允许POP3/IMAP4/SMTP代理模块
--with-mail_ssl_module 配置允许POP3/IMAP/SMTP可以使用SSL/TLS
--with-debug 启用debug日志
--http-client-body-temp-path 客户端请求临时文件路径
--http-proxy-temp-path 配置http proxy临时文件路径
--http-fastcgi-temp-path 配置http fastcgi临时文件路径
--http-uwsgi-temp-path=/var/tmp/nginx/uwsgi 配置uwsgi 临时文件路径
--http-scgi-temp-path=/var/tmp/nginx/scgi 配置scgi 临时文件路径

以上步骤会把 Nginx 默认安装到 /usr/local/nginx/ 目录下。

配置Nginx启动脚本

编辑启动脚本 (init.d)

sudo vim /etc/init.d/nginx
#! /bin/sh

### BEGIN INIT INFO
# Provides:          nginx
# Required-Start:    $all
# Required-Stop:     $all
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: starts the nginx web server
# Description:       starts nginx using start-stop-daemon
### END INIT INFO

PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
DAEMON=/usr/local/nginx/sbin/nginx
NAME=nginx
DESC=nginx

test -x $DAEMON || exit 0

# Include nginx defaults if available
if [ -f /etc/default/nginx ] ; then
  . /etc/default/nginx
fi

set -e

. /lib/lsb/init-functions

case "$1" in
  start)
    echo -n "Starting $DESC: "
    start-stop-daemon --start --quiet --pidfile /usr/local/nginx/logs/$NAME.pid \
        --exec $DAEMON -- $DAEMON_OPTS || true
    echo "$NAME."
    ;;
  stop)
    echo -n "Stopping $DESC: "
    start-stop-daemon --stop --quiet --pidfile /usr/local/nginx/logs/$NAME.pid \
        --exec $DAEMON || true
    echo "$NAME."
    ;;
  restart|force-reload)
    echo -n "Restarting $DESC: "
    start-stop-daemon --stop --quiet --pidfile \
        /usr/local/nginx/logs/$NAME.pid --exec $DAEMON || true
    sleep 1
    start-stop-daemon --start --quiet --pidfile \
        /usr/local/nginx/logs/$NAME.pid --exec $DAEMON -- $DAEMON_OPTS || true
    echo "$NAME."
    ;;
  reload)
    echo -n "Reloading $DESC configuration: "
    start-stop-daemon --stop --signal HUP --quiet --pidfile /usr/local/nginx/logs/$NAME.pid \
        --exec $DAEMON || true
    echo "$NAME."
    ;;
  status)
    status_of_proc -p /usr/local/nginx/logs/$NAME.pid "$DAEMON" nginx && exit 0 || exit $?
    ;;
  *)
    N=/etc/init.d/$NAME
    echo "Usage: $N {start|stop|restart|reload|force-reload|status}" >&2
    exit 1
    ;;
esac

exit 0

提升执行权限:

sudo chmod a+x /etc/init.d/nginx   

现在管理 Nginx 只需使用以下命令即可:

sudo service nginx start|stop|restart|reload

要开机自动启动 Nginx,可执行以下命令:

sudo update-rc.d -f nginx defaults

编辑启动脚本(Systemd)

[Unit]
Description=nginx - high performance web server
Documentation=http://nginx.org/en/docs/
After=network.target remote-fs.target nss-lookup.target
[Service]
Type=forking
PIDFile=/var/run/nginx.pid
ExecStartPre=/usr/sbin/nginx -t -c /usr/local/nginx/conf/nginx.conf
ExecStart=/usr/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s QUIT $MAINPID
PrivateTmp=true
[Install]
WantedBy=multi-user.target

保存为 /lib/systemd/system/nginx.service

chmod +x /lib/systemd/system/nginx.service
systemctl daemon-reload
systemctl start nginx
systemctl enable nginx

nginx的conf配置

nginx.conf


user nginx nginx; ## 设置 nginx 运行的user和group,Default: nobody
worker_processes 1; ## nginx 进程数,建议等于 CPU 总核心数。这个还可以和 worker_cpu_affinity 配合
error_log /var/log/nginx/error.log warn; ## 全局错误日志定义类型,[ debug | info | notice | warn | error | crit ]
pid /var/run/nginx.pid; ## 设置进程文件路径

worker_rlimit_nofile 65535;  ## 一个nginx进程打开的最多文件描述符(句柄)数目,建议值为最多打开文件数(系统的值ulimit -n)与nginx进程数相除

events {
  use epoll; ## example: `use [ kqueue | rtsig | epoll | /dev/poll | select | poll ]`;epoll模型是Linux2.6以上版本内核中的高性能网络I/O模型,如果跑在FreeBSD上面,就用kqueue模型。
  worker_connections  4096;  ## 单个进程最大连接数(max_clients = worker_processes * worker_connections)该值受系统进程最大打开文件数(系统值ulimit -n )限制  Default: 1024
}

http {
  include    conf/mime.types; ## 文件扩展名与文件类型映射表
  include    /etc/nginx/proxy.conf;
  include    /etc/nginx/fastcgi.conf;
  
  charset utf-8; ## 默认编码
  
  index    index.html index.htm index.php;

  default_type application/octet-stream;   ## 默认文件类型为二进制流
  log_format   main '$remote_addr - $remote_user [$time_local]  $status '
    '"$request" $body_bytes_sent "$http_referer" '
    '"$http_user_agent" "$http_x_forwarded_for"';  ## 日志格式
  
  access_log   logs/access.log  main;
  
  sendfile     on; ## 开启高效文件传输模式,sendfile指令指定nginx是否调用sendfile函数来输出文件,对于普通应用设为 on,如果用来进行下载等应用磁盘IO重负载应用,可设置为off,以平衡磁盘与网络I/O处理速度,降低系统的负载。注意:如果图片显示不正常把这个改成off。
  autoindex    on; ## 开启目录列表访问,适合下载服务器,默认off。
  keepalive_timeout 120; ## 长连接超时时间,单位是秒
  tcp_nopush     on;
  tcp_nodelay    on;
  keepalive_timeout  65;
   
  #gzip模块设置
  gzip on; ## 开启gzip压缩输出
  gzip_vary on;
  
  gzip_min_length    1k;    ## 最小压缩文件大小
  gzip_buffers       4 16k; ## 压缩缓冲区
  gzip_proxied       any;
  gzip_http_version  1.0;   ## 压缩版本(默认1.1)
  gzip_comp_level    2;     ## 压缩等级
  gzip_types         text/plain application/x-javascript text/css application/xml;   ## 压缩类型,默认已经包含text/html
 
  # 如果编译时添加了 ngx_brotli 模块,需要增加 brotli 相关配置
  brotli             on;
  brotli_comp_level  6;
  brotli_types       text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript application/javascript image/svg+xml;
  
  #limit_zone crawler $binary_remote_addr 10m; ## 开启限制IP连接数的时候需要使用
  #server { ## php/fastcgi
  #  listen       80;
  #  server_name  domain1.com www.domain1.com; 
  #  access_log   logs/domain1.access.log  main;
  #  root         html;
  #
  #  location ~ \.php$ {
  #    fastcgi_pass   127.0.0.1:1025;
  #  }
  #}

  server {
    listen       80 default_server;  ## 监听端口 
    server_name  domain.com;
    error_log    logs/domain.error.log   error;
    access_log   logs/domain.access.log  main;

  ## 静态文件
  #  location ~ ^/(images|javascript|js|css|flash|media|static)/  {
  #   root    /var/www/virtual/big.server.com/htdocs;
  #   expires 30d; ## 缓存时间设置
  #  }
    
    ## 反向代理
   # location / {
   #    proxy_pass http://127.0.0.1:3000;  ## 设置反向代理 uri
   #    proxy_redirect off; ## 设置后端服务器“Location”响应头和“Refresh”响应头的替换文本
   #    proxy_set_header X-Real-IP $remote_addr; ## 获取用户的真实 IP 地址
   #    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; ## 后端的Web服务器可以通过    #  X-Forwarded-For 获取用户真实IP
   #    proxy_set_header Host $host; ## 允许重新定义或者添加发往后端服务器的请求头。
   #    client_max_body_size 10m; ## 允许客户端请求的最大单文件字节数
   #    client_body_buffer_size 128k; ## 缓冲区代理缓冲用户端请求的最大字节数,
   #    proxy_connect_timeout 90; ## nginx跟后端服务器连接超时时间(代理连接超时)
   #    proxy_send_timeout 90; ## 后端服务器数据回传时间(代理发送超时)
   #    proxy_read_timeout 90; ## 连接成功后,后端服务器响应时间(代理接收超时)
   #    proxy_buffer_size 4k; ## 设置代理服务器(nginx)保存用户头信息的缓冲区大小
   #    proxy_buffers 4 32k; ## proxy_buffers缓冲区,网页平均在32k以下的设置
   #    proxy_busy_buffers_size 64k; ## 高负荷下缓冲大小(proxy_buffers*2)
   #    proxy_temp_file_write_size 64k; ## 设定缓存文件夹大小
   # }
}
 
 #负载均衡模块配置,upstream 的负载均衡,weight 是权重,可以根据机器配置定义权重。weigth 参数表示权值,权值越高被分配到的几率越大。
  # upstream big.server.com {
  #   server 127.0.0.3:8000 weight=5;
  #   server 127.0.0.3:8001 weight=5;
  #   server 192.168.0.1:8000;
  #   server 192.168.0.1:8001;
  # }
  # server { ## simple load balancing
  #  listen          80;
  #  server_name     big.server.com;
  #  access_log      logs/big.server.access.log main;

  #  location / {
  #    proxy_pass      http://big_server_com;
  #  }
  # }
  
  #加载其余server配置文件
  include     sites/*.conf;
  
}

proxy.conf文件

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;
client_max_body_size    10m;
client_body_buffer_size 128k;
proxy_connect_timeout   90;
proxy_send_timeout      90;
proxy_read_timeout      90;
proxy_buffers           32 4k;

fastcgi.conf文件

fastcgi_param  SCRIPT_FILENAME    $document_root$fastcgi_script_name;
fastcgi_param  QUERY_STRING       $query_string;
fastcgi_param  REQUEST_METHOD     $request_method;
fastcgi_param  CONTENT_TYPE       $content_type;
fastcgi_param  CONTENT_LENGTH     $content_length;
fastcgi_param  SCRIPT_NAME        $fastcgi_script_name;
fastcgi_param  REQUEST_URI        $request_uri;
fastcgi_param  DOCUMENT_URI       $document_uri;
fastcgi_param  DOCUMENT_ROOT      $document_root;
fastcgi_param  SERVER_PROTOCOL    $server_protocol;
fastcgi_param  GATEWAY_INTERFACE  CGI/1.1;
fastcgi_param  SERVER_SOFTWARE    nginx/$nginx_version;
fastcgi_param  REMOTE_ADDR        $remote_addr;
fastcgi_param  REMOTE_PORT        $remote_port;
fastcgi_param  SERVER_ADDR        $server_addr;
fastcgi_param  SERVER_PORT        $server_port;
fastcgi_param  SERVER_NAME        $server_name;

fastcgi_index  index.php;

fastcgi_param  REDIRECT_STATUS    200;

mime.types文件

types {
  text/html                             html htm shtml;
  text/css                              css;
  text/xml                              xml rss;
  image/gif                             gif;
  image/jpeg                            jpeg jpg;
  application/x-javascript              js;
  text/plain                            txt;
  text/x-component                      htc;
  text/mathml                           mml;
  image/png                             png;
  image/x-icon                          ico;
  image/x-jng                           jng;
  image/vnd.wap.wbmp                    wbmp;
  application/java-archive              jar war ear;
  application/mac-binhex40              hqx;
  application/pdf                       pdf;
  application/x-cocoa                   cco;
  application/x-java-archive-diff       jardiff;
  application/x-java-jnlp-file          jnlp;
  application/x-makeself                run;
  application/x-perl                    pl pm;
  application/x-pilot                   prc pdb;
  application/x-rar-compressed          rar;
  application/x-redhat-package-manager  rpm;
  application/x-sea                     sea;
  application/x-shockwave-flash         swf;
  application/x-stuffit                 sit;
  application/x-tcl                     tcl tk;
  application/x-x509-ca-cert            der pem crt;
  application/x-xpinstall               xpi;
  application/zip                       zip;
  application/octet-stream              deb;
  application/octet-stream              bin exe dll;
  application/octet-stream              dmg;
  application/octet-stream              eot;
  application/octet-stream              iso img;
  application/octet-stream              msi msp msm;
  audio/mpeg                            mp3;
  audio/x-realaudio                     ra;
  video/mpeg                            mpeg mpg;
  video/quicktime                       mov;
  video/x-flv                           flv;
  video/x-msvideo                       avi;
  video/x-ms-wmv                        wmv;
  video/x-ms-asf                        asx asf;
  video/x-mng                           mng;
}

开启https配置文件示例

server{
    listen 80;
    server_name www.domain.cn;    
    return 301 https://$host$request_uri;
    server_tokens off;
}
server{
    listen 443 ssl http2 fastopen=3 reuseport;
    server_name www.domain.cn;
    server_tokens        off;
    ssl on;
    ssl_certificate /home/ubuntu/ssl/cacert.pem;        #cacert.pem 文件路径
    ssl_certificate_key /home/ubuntu/ssl/privkey.pem;    #privkey.pem 文件路径
    
    ssl_session_timeout 5m;
    ssl_session_cache shared:SSL:5m;
    keepalive_timeout   70;
    
    ssl_dhparam /home/ubuntu/ssl/dhparam.pem;
    ssl_prefer_server_ciphers on;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-CAMELLIA256-SHA:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-SEED-SHA:DHE-RSA-CAMELLIA128-SHA:HIGH:!aNULL:!eNULL:!LOW:!3DES:!MD5:!EXP:!PSK:!SRP:!DSS;
    ssl_prefer_server_ciphers on;

    access_log            /var/log/nginx/sites/access.www.domain.log;
    error_log             /var/log/nginx/sites/error.www.domain.log;
    
     location / {
         
        proxy_http_version       1.1;
        add_header               X-Frame-Options deny;
        add_header               X-Content-Type-Options nosniff;
        add_header               Cache-Control no-cache;
        proxy_ignore_headers     Set-Cookie;
        proxy_set_header         Connection       "";
        proxy_set_header         X-Real_IP        $remote_addr;
        proxy_set_header         X-Forwarded-For  $proxy_add_x_forwarded_for;
        proxy_set_header         Host www.domain.cn;
        proxy_hide_header        Vary;
        proxy_hide_header        X-Powered-By;
        proxy_pass               http://127.0.0.1:4567;
     }
}

给nginx日志进行切割

创建bash脚本
如在 /usr/local/nginx/logs/ 下创建 nginx_log.sh

logs_path="/usr/local/nginx/logs/"
pid_path="/usr/local/nginx/logs/nginx.pid"
mv ${logs_path}access.log ${logs_path}access_$(date -d "yesterday" +"%Y%m%d").log
mv ${logs_path}error.log ${logs_path}error_$(date -d "yesterday" +"%Y%m%d").log
mv ${logs_path}sites ${logs_path}sites_$(date -d "yesterday" +"%Y%m%d")
mkdir ${logs_path}sites
kill -USR1 `cat ${pid_path}`

创建crontab定时事件

crontab -u root -e

添加如下命令

0 0 * * * bash /usr/local/nginx/logs/nginx_log.sh

ps:该命令是定时0点进行日志的切割的脚本运行

完成了日志切割的设置了

本文章部分参考自:imququ的文章《本博客 Nginx 配置之完整篇》,感谢imququ的技术分享