Linux下源码安装Nginx

很早之前有一篇源码安装Nginx的文章,其中因为时间有些久远,有很多内容都发生了变化,再加上涉及到一些安全性的问题,因此集中将这些问题都整理到此篇文章中。

这里以CentOS 7.6和Nginx 1.12.2为例进行说明。

创建Nginx专用的用户和用户组

groupadd www
useradd -s /sbin/nologin -M -g www www

安装基础库

安装基础依赖库

详情参考 CentOS中使用yum更新安装依赖库

sudo -s
LANG=C
yum -y install gcc gcc-c++ autoconf libjpeg libjpeg-devel libpng libpng-devel freetype freetype-devel libxml2 libxml2-devel zlib zlib-devel glibc glibc-devel glib2 glib2-devel bzip2 bzip2-devel ncurses ncurses-devel curl curl-devel e2fsprogs e2fsprogs-devel krb5 krb5-devel libidn libidn-devel openssl openssl-devel openldap openldap-devel nss_ldap openldap-clients openldap-servers

安装pcre-devel库

安装pcre库的目的是为了让Nginx支持HTTP rewrite模块,过程如下:

wget -c "http://downloads.sourceforge.net/project/pcre/pcre/8.45/pcre-8.45.tar.gz?ts=1347243907&use_mirror=nchc"
tar xzvf pcre-8.45.tar.gz
cd pcre-8.45
./configure
make && make install

安装TCMalloc提升Nginx性能(可选)

TCMalloc的全称为Thread-Caching Malloc,是谷歌开发的开源工具google-perftools中的一个成员。与标准的glibc库的Malloc相比,TCMalloc库在内存分配效率和速度上要高很多。

如果是64位系统的话首先需要安装libunwind库,32位系统不需要安装。

wget -c http://download.savannah.gnu.org/releases/libunwind/libunwind-1.0.1.tar.gz
tar xzvf libunwind-1.0.1.tar.gz
cd libunwind-1.0.1
CFLAGS=-fPIC ./configure
make CFLAGS=-fPIC
make CFLAGS=-fPIC install

然后安装google-perftools,可以从https://github.com/gperftools/gperftools/releases/latest下载。

wget -c https://github.com/gperftools/gperftools/releases/download/gperftools-2.7/gperftools-2.7.tar.gz
tar xzvf gperftools-2.7.tar.gz
cd gperftools-2.7
./configure
make && make install
echo "/usr/local/lib" > /etc/ld.so.conf.d/usr_local_lib.conf
ldconfig

安装或升级OpenSSL到最新版

安装OpenSSL是为了让Nginx多个虚拟主机支持SSL,需要安装最新版的OpenSSL,防止出现heart bleed漏洞,另外还需要注意OpenSSL从1.1.0开始默认取消了SSLv3

wget https://www.openssl.org/source/openssl-1.1.1l.tar.gz --no-check-certificate
tar xzvf openssl-1.1.1*.tar.gz
cd openssl-1.1.1*/
./config --prefix=/usr/local/openssl
make && make install

将系统默认的openssl替换成新安装的openssl:

mv /usr/bin/openssl /usr/bin/openssl.old
mv /usr/include/openssl /usr/include/openssl.old
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 -v

安装Nginx

配置安装

安装Nginx最关键的在于配置项,这里以1.12.2为例:

wget -c http://nginx.org/download/nginx-1.12.2.tar.gz
tar xzvf nginx-1.12.2.tar.gz
cd nginx-1.12.2
./configure --prefix=/usr/local/nginx --user=www --group=www --with-http_stub_status_module --with-http_gzip_static_module --with-http_ssl_module --with-google_perftools_module --with-openssl=<your openssl source path> --with-ld-opt=-pthread
make && make install

在默认情况下,经过编译安装的Nginx包含了大部分可用的模块。可以通过“./configure --help”选项来查看各个配置项的信息,也可以查看Nginx官方文档 http://nginx.org/en/docs/install.html
下面是几个常用的配置项:

--prefix 安装目录,默认为/usr/local/nginx
--user和--group 用来指定允许的用户和组
--with-http_stub_status_module 该模块可以启用Nginx的NginxStatus功能,来监控Nginx的当前状态
--with-http_ssl_module 启用SSL模块
--with-openssl 指定openssl的源码路径,不是openssl安装之后的路径
--with-google_perftools_module 支持TCMalloc,如果前面安装了该模块选择该项
--with-ld-opt=-pthread 如果nginx的版本低于1.13.11的时候,使用OpenSSL v1.1.1x的时候会出现undefined reference to `pthread_atfork'错误(ISSUE#3884-1),可以使用此参数在低版本nginx下避免该错误(ISSUE#3884-2

常用命令

启动命令在安装目录的sbin目录下面,常用命令参数如下:

nginx 启动Nginx
nginx -v 查看当前Nginx的版本号
nginx -V (v大写)查看Nginx的配置信息
nginx -t 检测配置信息是否有效
nginx -s reload 不中断重启Nginx
nginx -s stop 停止Nginx
nginx -h 查看nginx的帮助信息

Nginx的配置

nginx的配置文件存放在安装目录的 conf/nginx.conf 文件中,需要对默认的配置信息做一些调整。

设置用户、进程数和日志文件

建议启用下面的配置信息:

user www www;
worker_processes 2;
error_log logs/error.log;

其中worker_processes的值和系统的CPU数量相同。启用error日志文件方便进行拍错。

启用TCMalloc(可选)

创建一个线程目录,将文件放在/tmp/tcmalloc下面

mkdir /tmp/tcmalloc
chmod 777 /tmp/tcmalloc

修改nginx.conf配置文件,在pid这行下面添加配置如下信息:

google_perftools_profiles /tmp/tcmalloc;

然后使用 nginx -s reload 重新加载nginx,使用 lsof -n | grep tcmalloc 查看是否存在tcmalloc进程,如果存在的话就说明加载成功了。

优化设置http配置

在http模块下分别优化下面的配置:

性能和安全优化

tcp_nopush on;
tcp_nodelay on;
server_tokens off;
keepalive_timeout 65;
keepalive_requests 2800;

设置请求时间和请求数,server_tokens off的含义是向客户端关闭nginx的版本号等信息,增强安全性。

反向代理配置

Nginx最大的特色就是反向代理功能了,需要对反向代理进行优化配置如下:

# 代理相关配置
# 指定服务器名称哈希表的框大小
server_names_hash_bucket_size 128;
# 下面两个参数用来设定客户端请求的Header缓冲区大小的,如果Cookie内容比较大的内容应该增大该值(出现400或414错误)
client_header_buffer_size 32k;
large_client_header_buffers 4 128k;
# 允许客户端请求的最大单文件字节数
client_max_body_size 100m;
# 缓冲区代理缓冲用户端请求的最大字节数,可以理解为服务器端保存到本地再传给客户端
client_body_buffer_size 128k;
# 后端服务器连接的超时时间(秒)
proxy_connect_timeout    60;
# 连接成功之后后端服务器处理请求的时间(秒)
proxy_read_timeout       600;
# 后端服务器数据回传的时间(秒),即在规定的时间内后端服务器必须传完所有的数据
proxy_send_timeout       600;
# 是否开启代理缓冲(on|off),默认为on
proxy_buffering on;
# 设置缓冲区大小,存放后端服务器响应的Header内容,通常跟proxy_buffers设置相同
proxy_buffer_size        32k;
# 数据缓冲区大小
proxy_buffers            4 64k;
# 高负荷下缓冲大小(proxy_buffers*2)
proxy_busy_buffers_size 128k;
# 设定缓存文件夹大小,大于这个值,将从upstream服务器传递请求,而不缓冲到磁盘
proxy_temp_file_write_size 128k;
# 不允许代理端主动关闭连接
proxy_ignore_client_abort on;
# 设置代理缓存的目录
proxy_temp_path /tmp/proxy_tmp;
# 设置Web缓存区名称为cache_one,内存缓存空间大小为200MB,1天没有被访问的内容自动清除,硬盘缓存空间大小为30GB
proxy_cache_path /tmp/proxy_cache levels=1:2 keys_zone=cache_one:200m inactive=1d max_size=30g;

还需要做两个动作,一个是创建如下的两个目录:

mkdir /tmp/proxy_tmp
mkdir /tmp/proxy_cache

还有一个就是建议将上面的配置信息放到一个单独的 proxy.conf文件存放在conf/目录下面,然后在nginx.conf中使用下面的方式进行引用:

http {
    include proxy.conf;
}

需要注意的是,CentOS7默认创建了每日定时清空临时目录的设置,需要使用rm -f /etc/cron.daily/tmpwatch命令对其进行删除,否则会自动删除自己创建的/tmp目录下的目录。

设置gzip

建议开启gzip以提升网络传输的速度,配置如下:

http {
    gzip  on;
    # 允许压缩的页面最小字节数
    gzip_min_length 1k;
    gzip_buffers 4 16k;
    gzip_http_version 1.1;
    # 压缩比,从1到9,越大压缩率越高但越占资源,默认为1
    gzip_comp_level 2;
    # 指定压缩的类型,text/html总是被压缩
    gzip_types text/plain application/x-javascript text/css application/xml;
    # 是否让浏览器缓存压缩过的数据,默认为off
    gzip_vary on;
}

虚拟主机的设置

建议配置HTTP服务器默认访问显示403错误,这样使用IP访问到时候就会直接出错,而不是访问网站,防止别人使用域名恶意绑定。

将每个具体的虚拟主机配置单独一个文件,并放在conf/vhosts目录下面,方便进行管理。

http {
    server {
        listen       80 default;
        server_name  _;
        return 403;
    }

    include vhosts/*.conf;
}

设置自动分割日志文件

Nginx自身没有日志切割的功能,如果时间长的话日志文件会很大,可以使用下面的脚本实现日志文件自动每天进行切割:

#!/bin/bash

# The Nginx logs path
nglogs='/usr/local/nginx/logs'

mkdir -p ${nglogs}/$(date +%Y)/$(date +%m)
mv ${nglogs}/access.log ${nglogs}/$(date +%Y)/$(date +%m)/access.$(date +%Y%m%d).log
mv ${nglogs}/error.log ${nglogs}/$(date +%Y)/$(date +%m)/error.$(date +%Y%m%d).log
kill -USR1 `cat ${nglogs}/logs/nginx.pid`

将以上文件保存在/usr/local/nginx/sbin/cutlogs.sh中,然后修改执行权限并添加到任务中。

chmod +x /usr/local/nginx/sbin/cutlogs.sh
crontab -l > tmpcrontab
echo "00 00 * * * /bin/bash /usr/local/nginx/sbin/cutlogs.sh" >> tmpcrontab
crontab tmpcrontab
rm -f tmpcrontab

常见问题

参考资料:
Linux下源码方式安装Nginx和PHP(FastCGI)
让Nginx多个虚拟主机支持SSL
启用免费且自动更新的泛域名SSL证书
undefined reference to `pthread_atfork'

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注