编译部署NGINX

一般部署nginx有2中方法。直接使用系统提供的包apt-get 方式安装,这种就非常方便,但是没有最新版本可用。另外一种就是使用源代码自己编译安装部署。

这里要说的就是使用源代码方式,用源代码编译部署nginx还是比较方便的,没什么特别绕的地方。基本就是下载代码、生成配置再编译的正常流程。对二次开发来说,编译部署是家常便饭的事情。不管后续运维还是二次开发,熟悉源代码编译部署还是很有必要的。后续的Django部署会使用这种编译的方法部署。

刚写完这篇文章就出了nginx-1.10.0的稳定版本。小伙伴们可以升级了。

测试环境:

  • windows 7
  • Oracle VirtualBox VM 5.0

搭建:

  • Debian 7.5 (全新环境)
  • Nginx 1.9.12
  • IP: 192.168.10.14
  • DIR: /usr/local/nginx

依赖模块:

  • rewrite模块需要 pcre 库
  • ssl 功能需要openssl库
  • gzip模块需要 zlib 库

安装编译工具:

$ sudo apt-get install gcc automake autoconf libtool make g++ -y

pcre 需要 g++ 编译

依赖库编译

安装zlib

基本流程:
1.获取zlib编译安装包,在http://www.zlib.net/上可以获取当前最新的版本。
2.解压缩openssl-xx.tar.gz包。
3.进入解压缩目录,执行./configure。
4.make & make install

$ cd ~
$ wget http://zlib.net/zlib-1.2.8.tar.gz
$ tar xzvf zlib-1.2.8.tar.gz
$ cd ~/zlib-1.2.8
$ ./configure --prefix=/usr/local/zlib
$ make
$ sudo make install

安装pcre

基本流程:
1.获取pcre编译安装包,在http://www.pcre.org/上可以获取当前最新的版本
2.解压缩pcre-xx.tar.gz包。
3.进入解压缩目录,执行./configure。
4.make & make install

$ cd ~
$ wget http://downloads.sourceforge.net/project/pcre/pcre/8.38/pcre-8.38.tar.gz
$ tar xzvf pcre-8.38.tar.gz
$ cd ~/pcre-8.38
$ ./configure --prefix=/usr/local/pcre
$ make
$ sudo make install

安装openssl

基本流程:
1.获取openssl编译安装包,在http://www.openssl.org/source/上可以获取当前最新的版本。
2.解压缩openssl-xx.tar.gz包。
3.进入解压缩目录,执行./config。
4.make & make install

$ cd ~
$ wget http://www.openssl.org/source/openssl-1.0.1r.tar.gz
$ tar xzvf openssl-1.0.1r.tar.gz
$ cd ~/openssl-1.0.1r
$ ./config --prefix=/usr/local/openssl
$ make
$ sudo make install

编译Nginx源代码

基本流程:
1.获取nginx,在http://nginx.org/en/download.html上可以获取当前最新的版本。 2.解压缩nginx-xx.tar.gz包。 3.进入解压缩目录,执行./configure 4.make & make install

上面已经把3个关联包解压,编译时只要指定代码路径。

$ cd ~
$ wget http://nginx.org/download/nginx-1.9.12.tar.gz
$ tar xzvf nginx-1.9.12.tar.gz
$ cd ~/nginx-1.9.12
$ ./configure \
--prefix=/usr/local/nginx \
--with-openssl=/home/abc/openssl-1.0.1r \
--with-zlib=/home/abc/zlib-1.2.8 \
--with-pcre=/home/abc/pcre-8.38
$ make
$ sudo make install

注意: 这里编译的时候不能用相对路径。

配置参数使用选项:指定使用源代码

--with-openssl=<openssl_dir> 
--with-pcre=<pcre_dir>
--with-zlib=<zlib_dir>

指定依赖的模块目录。上诉选项如果缺省,会自动找到当前系统安装的版本。这是不希望的结果,因此需要上面的参数,使用最新的稳定版本进行编译安装。

启动Nginx

安装完毕后nginx没有启动,需要手工启动

$ sudo /usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf

测试

启动nginx之后,浏览器中输入http://192.168.10.14(虚拟机Debian的地址) 可以验证是否安装启动成功。看到欢迎页面那就恭喜你OK了。

配置启动命令

上面还有个问题,每次启动系统或维护打这么一长串命令不方便。因此还是要和安装包那种一样,启动系统直接启动和增加维护命令。

自己编译安装的在启动目录/etc/init.d 中是没有nginx的启动文件,需要自己添加一个文件。创建一个启动文件,把下面的启动代码复制进去。

注意: 安装路径 nginx_location=/usr/local/nginx

$ cat >init.d.nginx
#! /bin/bash
# chkconfig: 2345 55 25
# Description: Startup script for nginx webserver on Debian. Place in /etc/init.d and
# run 'update-rc.d -f nginx defaults', or use the appropriate command on your
# distro. For CentOS/Redhat run: 'chkconfig --add nginx'

### 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
DESC="nginx daemon"
nginx_location=/usr/local/nginx
DAEMON=$nginx_location/sbin/nginx
CONFIGFILE=$nginx_location/conf/nginx.conf
PIDFILE=$nginx_location/logs/nginx.pid
SCRIPTNAME=/etc/init.d/nginx

set -e
[ -x "$DAEMON" ] || exit 0

acqNginxPid(){
    local pid
    if [ -f $PIDFILE ] ; then
        pid=`cat $PIDFILE`
        echo ${pid}
    fi
}

do_start() {
    local pid=`acqNginxPid`
    if [[ ".${pid}" == "." ]] ; then
       $DAEMON -c $CONFIGFILE 
    else
       echo -n "nginx already running"
    fi
}

do_stop() {
    local pid=`acqNginxPid`
    if [ ".${pid}" != "." ] ; then
        kill -INT ${pid}
    else
        echo -n "nginx not running"
    fi
}

do_reload() {
    local pid=`acqNginxPid`
    if [ ".${pid}" != "." ] ; then
        kill -HUP ${pid}
    else
        echo -n "nginx can't reload"
    fi
}

case "$1" in
    start)
        echo -n "Starting $DESC: $NAME"
        do_start
        echo "."
        ;;
    stop)
        echo -n "Stopping $DESC: $NAME"
        do_stop
        echo "."
        ;;
    reload|graceful)
        echo -n "Reloading $DESC configuration..."
        do_reload
        echo "."
        ;;
    restart)
        echo -n "Restarting $DESC: $NAME"
        do_stop
        do_start
        echo "."
        ;;
    *)
    echo "Usage: $SCRIPTNAME {start|stop|reload|restart}" >&2
    exit 3
    ;;
esac

exit 0

复制到启动目录中,并增加权限。

$ sudo cp -f init.d.nginx /etc/init.d/nginx
$ sudo chmod +x /etc/init.d/nginx

用正常维护命令测试一下,使用浏览器访问可以看到效果。如果有出现啥命令找不到之类的,应该是上面的配置路径有问题,确认一下实际的路径和配置目录是否一致。

$ sudo /etc/inint.d/nginx start      # 启动
$ sudo /etc/inint.d/nginx stop       # 关闭
$ sudo /etc/inint.d/nginx restart    # 重启

设置随系统自动启动

命令创建完后,最后将ngix加入到rc.local文件中,这样开机的时候nginx就默认启动了。

vim /etc/rc.local

添加到 exit 0 的前面
/etc/init.d/nginx start

保存并退出。下次重启就会生效,实现nginx的自启动。,reboot可以试一下^_^。

提示: 自动启动下面有更新说明

增加站点启动配置

在nginx.conf中增加包含配置路径,这样每次启动nginx自动会加载目录中的所有配置。这个方法是在一个服务器上部署多站点时就显现出便利性,修改一个站点配置不会影响其他站点。

由于是编译安装,全新的服务器是没有相应的目录,需要自己创建。

$ sudo mkdir /etc/nginx
$ sudo mkdir /etc/nginx/sites-enabled

在http块最下面增加一行内容配置包含目录

$ sudo vim /usr/local/nginx/conf/nginx.conf
增加
include /etc/nginx/sites-enabled/*;

说明:
为什么把路径设置到 /etc/nginx/sites-enabled。
是一般习惯的做法,使用apt-get 包安装方法就会放在这个地方。当然也可以放在其他地方,为维护方便减少记忆使用标准的会比较容易找。


补充提示:如果下载时使用wget出现无效证书错误,一般是没安装ca证书包导致的

安全问题

对外暴露版本号并不是个好主意,可能有人会利用现有漏洞来攻击。隐藏nginx的版本来降低风险。

可以使用curl命令来看服务器头的返回信息,第三行 Server: nginx/1.14.0,给客户端返回的服务器版本。

homepc@rpcsvr:~$ curl --head 127.0.0.1
HTTP/1.1 200 OK
Server: nginx/1.14.0
Date: Wed, 19 Sep 2018 12:55:53 GMT
Content-Type: text/html
Content-Length: 612
Last-Modified: Wed, 19 Sep 2018 07:42:17 GMT
Connection: keep-alive
ETag: "5ba1fdd9-264"
Accept-Ranges: bytes

隐藏版本信息比较简单,只需编辑 nginx.conf 文件,添加一行配置

server_tokens off;

在http配置块中插入

homepc@rpcsvr:~$ sudo vim /usr/local/nginx/conf/nginx.conf

.....
http {
  ....
  #keepalive_timeout 0;
  keepalive_timeout  65;
  server_tokens off;

  #gzip on;

  server {
      ... ...
  }
  ....
}

重启服务器

homepc@rpcsvr:~$ sudo /etc/init.d/nginx restart
Restarting nginx daemon: .
homepc@rpcsvr:~$ curl --head 127.0.0.1
HTTP/1.1 200 OK
Server: nginx
Date: Wed, 19 Sep 2018 13:09:49 GMT
Content-Type: text/html

第三行就不再出现版本信息

补充自动启动问题

在部署时发现Goolge的Debin9系统下没有rc.local文件。 在 /etc 目录中有 rc0~rcS 这几个文件目录

sunseed@rpcsvr:~$ ls /etc -l
...
drwxr-xr-x 2 root root    4096 Sep 19 07:35 rc0.d
drwxr-xr-x 2 root root    4096 Sep 19 07:35 rc1.d
drwxr-xr-x 2 root root    4096 Sep 19 07:35 rc2.d
drwxr-xr-x 2 root root    4096 Sep 19 08:36 rc3.d
drwxr-xr-x 2 root root    4096 Sep 19 07:35 rc4.d
drwxr-xr-x 2 root root    4096 Sep 19 07:35 rc5.d
drwxr-xr-x 2 root root    4096 Sep 19 07:35 rc6.d
drwxr-xr-x 2 root root    4096 Sep 11 18:00 rcS.d
...

分别代表不同的级别:

0: 关闭计算机
1: 单用户模式
2: 无网络多用户模式
3: 有网络多用户模式
4: 保留作自定义,否则同运行级 3
5: 同运行级 4,一般用于图形界面(GUI)登录(如 X的 xdm 或 KDE的 kdm)
6: 重启动计算机

sunseed@rpcsvr:~$ ls /etc/rc3.d -l
total 0
lrwxrwxrwx 1 root root 15 Sep 11 17:59 S01acpid -> ../init.d/acpid
...
lrwxrwxrwx 1 root root 15 Sep 11 17:59 S01uuidd -> ../init.d/uuidd
lrwxrwxrwx 1 root root 17 Sep 19 08:36 S20nginx -> /etc/init.d/nginx

里面一堆SXX开头的关联文件, S开头即 start的参数,数字从 00 到 99,越小越优先执行

增加Nginx启动

sudo ln -s /etc/init.d/nginx /etc/rc3.d/S20nginx
sudo reboot

重启测试

sunseed@rpcsvr:~$ curl --head 127.0.0.1
HTTP/1.1 200 OK
Server: nginx/1.14.0
Date: Wed, 19 Sep 2018 09:11:10 GMT
Content-Type: text/html
Content-Length: 612
Last-Modified: Wed, 19 Sep 2018 07:42:17 GMT
Connection: keep-alive
ETag: "5ba1fdd9-264"
Accept-Ranges: bytes