一、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编译安装成功;到此为至几种安装方式已经介绍完毕
三、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
访问如图:
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 如图
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如图:
首次访问时添加信任证书即可
基于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).