ls0398 发表于 2018-11-8 10:32:21

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中
  

  
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 wgetunzip pcre-devel openssl-devel gcc-c++ pcre-devzlib-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 xvfnginx-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
  

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

  

  
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
  

  

  
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主配置文件说明
  结构:
  

usernginx   nginx;                                    #nginx运行时的用户及组  
worker_processesauto;               #当前主机物理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_typeapplication/octet-stream;          #默认八进制流
  

  log_formatmain'$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.logmain;      #日志路径
  server_tokens off;                                       #隐藏nginx版本信息
  sendfile      on;                                           #提高性能 打开sendfile机制
  tcp_nopush   on;         # 在sendfile模式下,是否启用TCP_CORK选项;(是否等待应用层合并一起发送)
  keepalive_timeout10;                               #保持连接10s
  open_file_cache max=1000 inactive=60;    #缓存文件最大多少杀,在60s内
  gzipon;                                 #开启压缩
  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 URL {
  ...
  if CONDITION {
  ...
  }
  }
  }
  }
  

  

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

server{  listen80 default_server;
  server_name vhost1.pkey.cn;
  root    /data1/web/vhost1;
  access_log /data1/log/nginx/vhost1_access.log;
  indexindex.html;
  
}
  

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

#nginx -t    #检查配置文件
  
#nginx -s>  
#本地hosts中添加 172.16.3.167vhost1.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{  listen80 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
  将用户请求的URI基于regex所描述的模式进行检查,匹配到时将其替换为replacement指定的新的URI;
  当用户匹配了URI的rewrite时再重新重新匹配一次 ,只要没有再匹配的 这时有可能 会有冲突
  注意:如果在同一级配置块中存在多个rewrite规则,那么会自下而下逐个检查;被某条件规则替换完成后,会重新一轮的替换检查,因此,隐含有循环机制;所表示的标志位用于控制此循环机制;
  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) : CN
  
State or Province Name (full name) []:ShangHai
  
Locality Name (eg, city) :ShangHai
  
Organization Name (eg, company) :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) :CN
  
State or Province Name (full name) []:ShangHai
  
Locality Name (eg, city) :ShangHai
  
Organization Name (eg, company) :pkey
  
Organizational Unit Name (eg, section) []:ziyao
  
Common Name (eg, your name or your server's hostname) []:vhost1.pkey.cn
  
Email Address []:webadmin@pkey.cn
  

  
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            = webadmin@pkey.cn
  X509v3 extensions:
  X509v3 Basic Constraints:
  CA:FALSE
  Netscape Comment:
  OpenSSL Generated Certificate

  X509v3 Subject Key>  4C:2A:AD:E3:70:D9:88:36:1A:6D:45:E9:92:05:E3:19:EB:8A:4C:88

  X509v3 Authority Key>  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
  

  
1 out of 1 certificate requests certified, commit? 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{  listen443 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_protocolsSSLv2 SSLv3 TLSv1 TLSv1.1 TLSv1.2;   #支持协议
  ssl_session_timeout2m;
  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>  访问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{  listen80 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).


页: [1]
查看完整版本: Nginx作为web服务器的http与https的初探