Bootstrap

Nginx作为web服务器的http与https的初探

一、nginx简介

1、概述:
NGINX 是免费, 开源, 高性能HTTP服务和反向代理服务,也是一款可以做IMAP/POP3 代理服务器.Nginx以其高性能、稳定性、丰富的功能设置,配置简单,低资源消耗。单台就能解决C10K并发连接.Nginx不依赖于线程来处理请求。相反,它使用了更具伸缩性的事件驱动(异步)体系结构。这种体系结构使用了较小但更重要的是负载下可预测的内存量。即使你不想同时处理数千个请求,你仍然可以体会Nginx的高性能和内存占用小的利益。从单台到最小的VPS一直到大型服务器集群都可使用.

2、nginx程序架构
nginx采用master/worker模型
master进程:负责加载和分析配置文件,管理worker进程,达到平滑升级.
一个或多个worker进程 :
处理并响应用户名请求.其中cache loader进程用于载入缓存对象,cache manager管理缓存对象
3 、nginx特性
异步,事件驱动和非阻塞;通过epoll/select实现并发请求处理,通过AIO,sendfile,mmap,异步 实现文件IO
nginx高度模块化,早期不支持DSO机制,近期版本支持动态装载和御载模块

4、nginx模块分类与功能
核心模块(core module),标准模块和第三方模块;
nginx可用来做静态web服务器(图片服务器,或js/css/html/txt等静态资源服务器);
结合FastCGI/uwSGI/SCGI等协议与程序语言,反代动态资源请求;
http/https协议的反向代理;
imap4/pop3协议的反向代理;
tcp/udp协议的请求转发;

二、nginx安装

以下实验均基于CentOS7 
1、yum安装
参考官方文档:
http://nginx.org/en/linux_packages.html
a,官方库安装
把以下的库放到/etc/yum.repos.d/nginx.repo中

[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/centos/7/x86_64/
gpgcheck=0
enabled=1
#yum clean all
#yum install nginx

b,EPEL扩展库中安装
#yum install epel-release -y
#yum install nginx -y
以上两种yum安装 可自动解决包依赖关系.但可定制性差!
启动nginx
#systemctl enable nginx
#systemctl start nginx
官方库和epel库中安装的 默认首页不太一样!但最终可以访问,表示nginx基本安装完成.
2、编译安装
安装依赖包:

#yum install vim gcc wget  unzip pcre-devel openssl-devel gcc-c++ pcre-dev  zlib-devel -y

下载源码

#wget http://101.96.10.63/nginx.org/download/nginx-1.12.1.tar.gz   (不要问我这个链接怎么是ip,官方就是这样的)

添加nginx账号与组

#groupadd -g 108 -r nginx
#useradd -u 108 -r -g 108 nginx

编译安装

#tar xvf  nginx-1.12.1.tar.gz
#cd nginx-1.12.1
 #./configure --prefix=/usr/local/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/run/nginx.pid --lock-path=/var/run/nginx.lock --user=nginx --group=nginx --with-http_ssl_module --with-http_v2_module --with-http_dav_module --with-http_stub_status_module --with-threads --with-file-aio
 #make && make install

为编译安装nginx添加systemctl服务
cat /usr/lib/systemd/system/nginx.service

[Unit]
Description=The nginx HTTP and reverse proxy server
After=network.target remote-fs.target nss-lookup.target

[Service]
Type=forking
PIDFile=/var/run/nginx.pid
# Nginx will fail to start if /run/nginx.pid already exists but has the wrong
# SELinux context. This might happen when running `nginx -t` from the cmdline.
# https://bugzilla.redhat.com/show_bug.cgi?id=1268621
ExecStartPre=/usr/bin/rm -f /run/nginx.pid
ExecStartPre=/usr/local/nginx/sbin/nginx -t
ExecStart=/usr/local/nginx/sbin/nginx
ExecReload=/bin/kill -s HUP $MAINPID
KillSignal=SIGQUIT
TimeoutStopSec=5
KillMode=process
PrivateTmp=true

[Install]
WantedBy=multi-user.target

#添加开机启动
#systemctl enable nginx
防火墙头配置添加开放80端口或关闭
#systemctl disable firewalld 
#systemctl mask firewalld 关闭默认firewalld防火墙
http://172.16.3.167 如图:
Nginx作为web服务器的http与https的初探

nginx编译安装成功;到此为至几种安装方式已经介绍完毕

三、nginx程序环境与配置文件结构简介

1、配置文件组成:
主配置文件: nginx.conf (默认在/etc/nginx/目录下)include conf.d/*.conf
主程序文件:/usr/sbin/nginx (默认) 编译时可指定
系统服务文件: nginx.service (/usr/lib/systemd/system/)
2、nginx.conf主配置文件说明
结构:

user  nginx   nginx;                                    #nginx运行时的用户及组
worker_processes  auto;               #当前主机物理cpu核心数,auto表示自动
#worker_cpu_affinity 1000 0100;    #绑定worker进程在指定cpu核心上运行
worker_priority -5;                         #worker运行优先级 [-20,20]
error_log  /data1/log/nginx/error.log warn;             #错误日志路径 
pid        /var/run/nginx.pid;                                 #pid文件路径 

events {                                                          #事件驱动
    worker_connections 1024;                      #单worker并发处理连接数
}

http {                                                              #http协议块
    include       /etc/nginx/mime.types;            #包含处理文件类型
    default_type  application/octet-stream;          #默认八进制流

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request"     #日志格式
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /data1/log/nginx/access.log  main;      #日志路径
    server_tokens off;                                       #隐藏nginx版本信息
    sendfile        on;                                           #提高性能 打开sendfile机制
    tcp_nopush     on;         # 在sendfile模式下,是否启用TCP_CORK选项;(是否等待应用层合并一起发送)
    keepalive_timeout  10;                               #保持连接10s
    open_file_cache max=1000 inactive=60;    #缓存文件最大多少杀,在60s内
    gzip  on;                                   #开启压缩
    gzip_comp_level 5;                 #压缩级别
    gzip_types *;                          #指定压缩类型,*表示所有文件均压缩

    include /etc/nginx/conf.d/*.conf;                      #配置子目录
}

主配置段,也叫全局配置段;
event{}:事件驱动相关配置;
http{}:http/https协议相关配置;
mail{}:邮件相关
stream {}:协议层流代理

3、http协议配置结构

http {
                    ...
                    ...:各server虚拟主机的公共配置
                    server {
                        ...
                    }:每个server用于定义一个虚拟主机;  没有中心主机的概念都是server虚拟主机
                    server {
                        ...
                        listen   port #侦听端口  default_server:设定为默认虚拟主机;ssl:限制仅能够通过ssl连接提供服务;
                        server_name        #主机访问ip或域名(url)
                        root                      #网站根路径
                        alias
                        location [OPERATOR] URL {
                            ...
                            if CONDITION {
                                ...
                            }
                        }
                    }
                }

nginx基本配置及与性能相关的基本配置大致就这些,如需要更详细的配置信息请参考官方文档
4、配置一个虚拟主机
#cat /etc/nginx/conf.d/
#cat vhost1.conf
#mkdir -pv /data1/web/vhost1;

server{
    listen  80 default_server;
    server_name vhost1.pkey.cn;
    root    /data1/web/vhost1;
    access_log /data1/log/nginx/vhost1_access.log;
    index  index.html;
}

#cat /data1/web/vhost1/index.html
<h1> Vhost1 web!</h1>

#nginx -t    #检查配置文件
#nginx -s reload      #重新加载配置文件
#本地hosts中添加 172.16.3.167  vhost1.pkey.cn

访问如图:
Nginx作为web服务器的http与https的初探

5、开启nginx运行状态
nginx web虚拟主机也有了,得看看nginx状态啊!
#cat /etc/nginx/conf.d/nginxstatus.conf

server{
    listen   80;
    server_name localhost;
    location  /basic_status {
        stub_status;
        }
}

在另一台机器上安装httpd-tools
ab -n 10000 -c 100 http://172.16.3.167/index.html
#查看nginx状态

]# curl -s http://127.0.0.1/basic_status
Active connections: 1 
server accepts handled requests
 10057 10057 10007 
Reading: 0 Writing: 1 Waiting: 0 

状态说明: 
Active connections: 活动状态的连接数;
accepts:已经接受的客户端请求的总数;
handled:已经处理完成的客户端请求的总数;
requests:客户端发来的总的请求数;
Reading:处于读取客户端请求报文首部的连接的连接数;
Writing:处于向客户端发送响应报文过程中的连接数;
Waiting:处于等待客户端发出请求的空闲连接数;

四、nginx location的匹配规则

1、应用范围场景
location [ = | ~ | ~ | ^~ ] uri { ... }
Sets configuration depending on a request URI.( 所设置的是根据所请求的URI配置的)
在一个server中location配置段可存在多个,用于实现从uri到文件系统的路径映射;ngnix会根据用户请求的URI来检查定义的所有location,并找出一个最佳匹配,而后应用其配置;
2、location语法
=:对URI做精确匹配;例如, http://vhost1.pkey.cn/http://vhost1.pkey.cn/index.html
ocation = / {
...
}
~:对URI做正则表达式模式匹配,区分字符大小写;
~
:对URI做正则表达式模式匹配,不区分字符大小写;
^~:对URI的左半部分做匹配检查,不区分字符大小写;
不带符号:匹配起始于此uri的所有的url;

3、匹配优先级 
从高到低依次:"= " > "^~ " > "~/~*" > 不带符号;
实例:

location = / {
    [ configuration A ]
}

location / {
    [ configuration B ]
}

location /documents/ {
    [ configuration C ]
}

location ^~ /images/ {
    [ configuration D ]
}

location ~* \.(gif|jpg|jpeg)$ {
    [ configuration E ]
}

如是"/"结尾的请求则匹配A区域,"/index.html"请求刚是匹配B区域,"/documents/doc.html"匹配C区域,"/images/1.gif"匹配D区域,而"/documents/1.jpg"请求匹配的是E区域.

结合匹配规则和location做一个小实例,基于之前的例子
只需要修改vhos1.conf为以下:

server{
        listen  80 default_server;
        server_name     vhost1.pkey.cn;
        root    /data1/web/vhost1;
        access_log /data1/log/nginx/vhost1_access.log;
        index index.html index.htm;
        location ~* .(jpg|png)$ {        #不区分大小写,URI以jpg或png接尾,路径跳到 /data1/web/admin下
                root /data1/web/admin/;
        }
}

创建/data1/web/admin 
放入一张cover.png
原根目录 /data1/web/vhost1下并没有 任何图片 
访问:http://vhost1.pkey.cn/cover.png 如图
Nginx作为web服务器的http与https的初探

4、别名路径(alias path)
定义路径别名,文档映射的另一种机制;仅能用于location上下文;
注意:location中使用root指令和alias指令的意义不同;
(a) root,给定的路径对应于location中的/uri/左侧的/;
(b) alias,给定的路径对应于location中的/uri/右侧的/;
例如:

location /imgs/ {

root /data1/web/pictures/;
allow all;
}    
此时访问http://vhost1.pkey.cn/imgs/top.jpg时   网站的要目录/data1/web/pictures/下要有imgs目录及top.jpg
而换成alias时  访问 http://vhost1.pkey.cn/imgs      /data1/web/pictures不需要imgs目录只需要该目录下有top.jpg就行.

五、nginx rewrite重写

rewrite是通过ngx_http_rewrite_module模块实现;
1、作用与配置规则
rewrite regex replacement [flag]
将用户请求的URI基于regex所描述的模式进行检查,匹配到时将其替换为replacement指定的新的URI;
当用户匹配了URI的rewrite时再重新重新匹配一次 ,只要没有再匹配的 这时有可能 会有冲突
注意:如果在同一级配置块中存在多个rewrite规则,那么会自下而下逐个检查;被某条件规则替换完成后,会重新一轮的替换检查,因此,隐含有循环机制;[flag]所表示的标志位用于控制此循环机制;

2、匹配机制flag
last:重写完成后停止对当前URI在当前location中后续的其它重写操作,而后对新的URI启动新一轮重写检查;提前重启新一轮循环;重头再检查 
break:重写完成后停止对当前URI在当前location中后续的其它重写操作,而后直接跳转至重写规则配置块之后的其它配置;结束循环;
redirect:重写完成后以临时重定向方式直接返回重写后生成的新URI给客户端,由客户端重新发起请求;不能以http://或https://开头; #浏览器中的响应状态是 302即临时重定向.
permanent:重写完成后以永久重定向方式直接返回重写后生成的新URI给客户端,由客户端重新发起请求;浏览器中的响应状态码为301即永久重定向.

六、nginx搭建基于ssl的安全https站点

基于ngx_http_ssl_module模块
环境说明:
两台CentOS7,其中 172.16.3.152用于做CA服务器,172.16.3.167做web服务器
1、自建立CA服务器
创建私钥证书

cd /etc/pki/CA/
]# (umask 077;openssl genrsa -out private/cakey.pem 2048)
创建自签证书有效期365天
]#openssl req -new -x509 -key private/cakey.pem -out cacert.pem -days 365
出现以下信息需要填写一些相关信息
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]: CN
State or Province Name (full name) []:ShangHai
Locality Name (eg, city) [Default City]:ShangHai
Organization Name (eg, company) [Default Company Ltd]:pkey
Organizational Unit Name (eg, section) []:ziyao
Common Name (eg, your name or your server's hostname) []:cahost.pkey.cn
Email Address []:

#创建索引文件

# touch index.txt
#echo 01 > serial

2、为nginx申请一个证书

#mkdir /etc/nginx/ssl
#cd /etc/nginx/ssl

#创建私钥
#(umask 077;openssl genrsa -out nginx.key 2048)
#创建csr证书

#openssl req -new -key nginx.key -out nginx.csr
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:CN
State or Province Name (full name) []:ShangHai
Locality Name (eg, city) [Default City]:ShangHai
Organization Name (eg, company) [Default Company Ltd]:pkey
Organizational Unit Name (eg, section) []:ziyao
Common Name (eg, your name or your server's hostname) []:vhost1.pkey.cn
Email Address []:[email protected]

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:

3、生成好的证书发给CA签署

#scp nginx.csr 172.16.3.152:/tmp
root@172.16.3.152's password: 
nginx.csr                                                          100% 1054     1.0KB/s   00:00

4、到CA服务器上进行签署

# openssl ca -in /tmp/nginx.csr -out /etc/pki/CA/certs/nginx.crt -days 365
Using configuration from /etc/pki/tls/openssl.cnf
Check that the request matches the signature
Signature ok
Certificate Details:
        Serial Number: 1 (0x1)
        Validity
            Not Before: Dec 21 08:39:08 2017 GMT
            Not After : Dec 21 08:39:08 2018 GMT
        Subject:
            countryName               = CN
            stateOrProvinceName       = ShangHai
            organizationName          = pkey
            organizationalUnitName    = ziyao
            commonName                = vhost1.pkey.cn
            emailAddress              = [email protected]
        X509v3 extensions:
            X509v3 Basic Constraints: 
                CA:FALSE
            Netscape Comment: 
                OpenSSL Generated Certificate
            X509v3 Subject Key Identifier: 
                4C:2A:AD:E3:70:D9:88:36:1A:6D:45:E9:92:05:E3:19:EB:8A:4C:88
            X509v3 Authority Key Identifier: 
                keyid:0A:CD:81:8E:E4:42:BC:DF:67:87:C3:2C:57:D1:CA:ED:80:A4:EA:AE

Certificate is to be certified until Dec 21 08:39:08 2018 GMT (365 days)
Sign the certificate? [y/n]:y

1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated

签署完成生成在/etc/pki/CA/certs下生成nginx.csr签名证书
再发送回给nginx服务器

# scp nginx.crt 172.16.3.167:/etc/nginx/ssl
Warning: Permanently added '172.16.3.167' (ECDSA) to the list of known hosts.
root@172.16.3.167's password: 
nginx.crt                                                          100% 4541    69.5KB/s   00:00

5、到nginx上配置https站点
#cd /etc/nginx/conf.d
#cp vhost1.conf vhost1_ssl.conf
#cat vhost1_ssl.conf

server{
        listen  443 ssl;
        server_name     vhost1.pkey.cn;
        root    /data1/web/vhost1;
        access_log /data1/log/nginx/vhost1_ssl_access.log;
        ssl on;
        ssl_certificate /etc/nginx/ssl/nginx.crt;        #签名证书
        ssl_certificate_key /etc/nginx/ssl/nginx.key;    #私钥证书
        ssl_protocols  SSLv2 SSLv3 TLSv1 TLSv1.1 TLSv1.2;     #支持协议
        ssl_session_timeout  2m;
        ssl_session_cache shared:sslcache:5m;    #各worker共享缓存模式;1m大约缓存4000条
        index index.html index.htm;
        location ~* .(jpg|png)$ {
                root /data1/web/admin/;
        }
}

检查nginx配置并reload,此时如果开了防火墙记得开放tcp 443端口
#ngix -t
#nginx -s reload
访问https://vhost1.pkey.cn如图:
首次访问时添加信任证书即可

Nginx作为web服务器的http与https的初探
Nginx作为web服务器的http与https的初探
基于https的web已经搭建成功,这是一个私有证书搭建的https所以才有信任问题,或把nginx.csr转换成大多数浏览器识别的证书格式:

#openssl pkcs12 -export -clcerts -in nginx.crt -inkey nginx.key -out nginx.p12
Enter Export Password:
Verifying - Enter Export Password:

导入到浏览器即可

6、结合rewrite让访问http的转向https
cat vhost1.conf

 server{
        listen  80 default_server;
        server_name     vhost1.pkey.cn;
        root    /data1/web/vhost1;
        access_log /data1/log/nginx/vhost1_access.log;
        index index.html index.htm;
        location ~* .(jpg|png)$ {
                root /data1/web/admin/;
        }
       ** rewrite /(.*)$ https://vhost1.pkey.cn/$1;**      #添加重写
}

此时访问http://vhost1.pkey.cn时自动跳转到https://vhost1.peky.cn有点像你输入www.baidu.com自动跳转到
https://www.baidu.com
至此粗略的介绍完nginx的特性,安装,配置文件说明,location及匹配,rewrite alias路径,并作为web服务器时的基本配置(http,https).










本文转自 dyc2005 51CTO博客,原文链接:http://blog.51cto.com/dyc2005/2053027,如需转载请自行联系原作者
;