nginx配置进阶(三)
==============================================================================
概述:
本章我们将会继续介绍Nginx中http段的配置,内容主要包括:
==============================================================================
1.The ngx_http_fastcgi_module module allows passing requests to a FastCGI server.
★作用:
附图: lnmp
★fastcgi_pass address;
示例: fastcgi_pass localhost:9000; ★fastcgi_index name;
★fastcgi_param parameter value [if_not_empty];
[root@centos7 nginx]# cat fastcgi_params
fastcgi_param QUERY_STRING $query_string;
fastcgi_param REQUEST_METHOD $request_method;
fastcgi_param CONTENT_TYPE $content_type;
fastcgi_param CONTENT_LENGTH $content_length;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
fastcgi_param REQUEST_URI $request_uri;
fastcgi_param DOCUMENT_URI $document_uri;
fastcgi_param DOCUMENT_ROOT $document_root;
fastcgi_param SERVER_PROTOCOL $server_protocol;
fastcgi_param REQUEST_SCHEME $scheme;
fastcgi_param HTTPS $https if_not_empty;
fastcgi_param GATEWAY_INTERFACE CGI/1.1;
fastcgi_param SERVER_SOFTWARE nginx/$nginx_version;
fastcgi_param REMOTE_ADDR $remote_addr;
fastcgi_param REMOTE_PORT $remote_port;
fastcgi_param SERVER_ADDR $server_addr;
fastcgi_param SERVER_PORT $server_port;
fastcgi_param SERVER_NAME $server_name;
# PHP only, required if PHP was built with --enable-force-cgi-redirect
fastcgi_param REDIRECT_STATUS 200;
⊙配置lnmp示例1
⊙配置示例2:通过/pm_status和/ping来获取fpm server状态信息;
1.首先安装相关的部署程序包
# yum install php-fpm php-mysql mariadb-server php-gd php-mbstring php-mcrypt
2.php-fpm默认系统用户和组为apache,因为这里要使nginx与php-fpm相结合,所以我们需要修改php-fpm的配置文件/etc/php-fpm.d/www.conf 修改用户和组为nginx
[root@localhost ~]# cd /etc/php-fpm.d/
[root@localhost php-fpm.d]# ls
www.conf
[root@localhost php-fpm.d]# vim www.conf # 修改配置文件
user = nginx
group = nginx
pm.status_path = /pm-status # 启用状态页
ping.path = /ping # 启用ping和pong接口
ping.response = pong
3.创建/var/lib/php/session,并修改其属主和属组为nginx
[root@localhost ~]# mkdir /var/lib/php/session
[root@localhost ~]# chown -R nginx:nginx /var/lib/php/session
[root@localhost ~]# ll -d /var/lib/php/session
drwxr-xr-x 2 nginx nginx 4096 10月 27 21:56 /var/lib/php/session
4.启动服务,并查看其对应端口,nginx/80,mairadb/3306,php-fpm/9000
[root@localhost ~]# systemctl start nginx
[root@localhost ~]# systemctl start php-fpm
[root@localhost ~]# systemctl start mariadb
[root@localhost ~]# ss -tnl
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 128 127.0.0.1:9000 *:*
LISTEN 0 50 *:3306 *:*
LISTEN 0 128 *:80 *:*
LISTEN 0 128 *:22 *:*
LISTEN 0 128 127.0.0.1:631 *:*
LISTEN 0 100 127.0.0.1:25 *:*
LISTEN 0 128 127.0.0.1:6010 *:*
LISTEN 0 128 :::22 :::*
LISTEN 0 128 ::1:631 :::*
LISTEN 0 100 ::1:25 :::*
LISTEN 0 128 ::1:6010 :::*
5.接下来我们就可以配置nginx使用php-fpm了,配置如下:
1)/etc/nginx/conf.d/default.conf中自带有fastcgi的定义,我们直接启用就可以,然后稍作修改
2)修改如下:
location ~* \.php$ { # 上图匹配所有以.php结尾的文件区分大小写,这里改为不区分大小写
root /usr/share/nginx/html; # 默认为相对路径,这里最好改为绝对路径
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php; # 默认的主页面
# 请求时传递的脚本参数到后端,这里我们要给它一个真正的root路径下的url
# 这里的url一定要转换成对应的后端服务器的网页文件的位置
fastcgi_param SCRIPT_FILENAME /usr/share/nginx/html/$fastcgi_script_name;
include fastcgi_params; # 包含的另外一个配置文件
}
3)修改完成之后,检测语法,并重载nginx服务,然后提供页面文件
[root@localhost conf.d]# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
[root@localhost conf.d]# nginx -s reload
[root@localhost conf.d]# cat << eof > /usr/share/nginx/html/phpinfo.php # 提供测试页
> <?php
> phpinfo();
> ?>
> eof
[root@localhost conf.d]# cat /usr/share/nginx/html/phpinfo.php
<?php
phpinfo();
?>
用浏览器访问如下:
6.接下来我们部署一个php的应用程序phpMyadmin,因为只是测试一下,所以我把之前部署在lamp上的phpMyadmin复制过来,如下:
[root@localhost ~]# ls /vhosts/www/
index.html index.php phpMyAdmin-4.0.5-all-languages pma test.html
[root@localhost ~]# cp /vhosts/www/phpMyAdmin-4.0.5-all-languages/ /usr/share/nginx/html/
[root@localhost ~]# cd /usr/share/nginx/html/
[root@localhost html]# ln -sv phpMyAdmin-4.0.5-all-languages/ PMA
"PMA" -> "phpMyAdmin-4.0.5-all-languages/"
[root@localhost html]# ls
50x.html index.html phpinfo.php phpMyAdmin-4.0.5-all-languages PMA
使用浏览器访问如下:
提示客户端错误,原因为我们这里的默认主页面index.php虽然已经在location中定义,但是没有在server中定义,所以再次修改nginx的配置文件如下:
修改好之后,保存退出,检测语法重载之后,再次刷新页面,可以正常访问,如下图:
后面基于mysql的认证登录等就不在这里做演示了可以参考之前的文档;
7.接下来,我们使用ab命令来对文件中压测,看一下nginx接受并发响应的性能;
[root@localhost ~]# ab -c 100 -n 2000 http://192.168.1.17/PMA/index.php
This is ApacheBench, Version 2.3 <$Revision: 1430300 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking 192.168.1.17 (be patient)
Completed 200 requests
Completed 400 requests
Completed 600 requests
Completed 800 requests
Completed 1000 requests
Completed 1200 requests
Completed 1400 requests
Completed 1600 requests
Completed 1800 requests
Completed 2000 requests
Finished 2000 requests
Server Software: nginx/1.10.0
Server Hostname: 192.168.1.17
Server Port: 80
Document Path: /PMA/index.php
Document Length: 8141 bytes
Concurrency Level: 100
Time taken for tests: 121.663 seconds
Complete requests: 2000
Failed requests: 0
Write errors: 0
Total transferred: 18691104 bytes
HTML transferred: 16282000 bytes
Requests per second: 16.44 [#/sec] (mean)
Time per request: 6083.133 [ms] (mean)
Time per request: 60.831 [ms] (mean, across all concurrent requests)
Transfer rate: 150.03 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 0 0.6 0 4
Processing: 1020 5982 644.2 6032 9814
Waiting: 79 5896 649.1 5984 9814
Total: 1020 5982 643.8 6032 9815
Percentage of the requests served within a certain time (ms)
50% 6032
66% 6149
75% 6225
80% 6285
90% 6489
95% 6638
98% 6838
99% 7106
100% 9815 (longest request)
8.我们在php-fpm的配置文件中开启了测试功能(ping/pong)和状态页status,之前我们在httpd中是通过添加单独的匹配条件代理至后端的,那在nginx中我们应该怎样设置呢?如下:
然后我们使用浏览器访问如下:
如上,就为简单部署成功了一个lnmp环境了。。。
2.fastcgi的缓存
★fastcgi_cache_path path ☉格式和适用位置: # Syntax: fastcgi_cache_path path [levels=levels] [use_temp_path=on|off] keys_zone=name:size [inactive=time] [max_size=size] [manager_files=number] [manager_sleep=time] [manager_threshold=time] [loader_files=number] [loader_sleep=time] [loader_threshold=time] [purger=on|off] [purger_files=number] [purger_sleep=time] [purger_threshold=time]; Default:— Context:http # 只能定义在http中 ☉作用:
☉参数: ◆levels=levels:缓存目录的层级数量,以及每一级的目录数量;
◆keys_zone=name:size
◆inactive=time:非活动时长; ◆max_size=size:磁盘上用于缓存数据的缓存空间上限; ★fastcgi_cache zone | off;
★fastcgi_cache_key string;
★fastcgi_cache_methods GET | HEAD | POST ...;
★fastcgi_cache_min_uses number;
★fastcgi_cache_valid [code ...] time;
定义使用缓存:
1.首先要创建一个缓存的文件目录,实际生产环境中可以放在固态磁盘上或者Raid0上,这样I/O能力很强;(注意文可能需要修改属主和属组为nginx)
[root@localhost ~]# ls /var/cache/
abrt-di fontconfig httpd krb5rcache libvirt nginx realmd
cups gdm ibus ldconfig man PackageKit yum
[root@localhost ~]# ls /var/cache/nginx/
client_temp fastcgi_temp proxy_temp scgi_temp uwsgi_temp
[root@localhost ~]# mkdir /var/cache/nginx/fastcgi_cache
2.因为缓存只能定义在http配置段,所以编辑主配置文件/etc/nginx/nginx.conf
3.如上,已经定义好了,但是要想调用,要定义在在server或者location中,因为我们这里针对的是fastcgi协议所以定义在php的location中,如下:
4.定义好之后保存退出,检测语法,重载;然后用浏览器访问PMA,查看缓存如下
[root@localhost ~]# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
[root@localhost ~]# nginx -s reload
[root@localhost ~]# tree /var/cache/nginx/fastcgi_cache/
/var/cache/nginx/fastcgi_cache/
└── 9
└── 0e
└── 3
└── 9092aafd46eba60f9dd7f9eee97d30e9
3 directories, 1 file
再访问http://192.168.1.17/phpinfo.php,查看缓存如下:
[root@localhost ~]# tree /var/cache/nginx/fastcgi_cache/
/var/cache/nginx/fastcgi_cache/
├── 0
│ └── 15
│ └── 4
│ └── 918e9e96dec978b2ec01d531bef84150
├── 9
│ └── 0e
│ └── 3
├── e
│ └── fd
│ └── 5
│ └── 98413616be76ca2adb60d2de52405fde
└── f
└── a6
└── 5
└── f507ec3769c639b6261e1eb529305a6f
3.fastcgi 的保持连接
★fastcgi_keep_conn on | off;
☉作用:
1.支持nginx能够运行为https服务
★ssl on | off;
★ssl_certificate file;
★ssl_certificate_key file;
★ssl_protocols [SSLv2] [SSLv3] [TLSv1] [TLSv1.1] [TLSv1.2];
★ssl_session_cache off | none | [builtin[:size]] [shared:name:size];
★ssl_session_timeout time;
配置示例:
把80端口重定向到443上,然后关闭80服务;
配置使ngins支持https协议:
1.在rpm包安装的nginx的配置文件中没有对ssl的相关配置,所以这里我们在/etc/nginx/conf.d下新定义一个虚拟主机使其支持ssl,配置如下:
[root@localhost conf.d]# pwd
/etc/nginx/conf.d
[root@localhost conf.d]# vim ssl.conf
1 server {
2 listen 443 ssl; # 指明ssl监听的端口443,和ssl协议
3 server_name # 主机名
4 root /vnhosts/ssl/htdocs; # ssl的路径
5 ssl on # 开启ssl功能
6 ssl_certificate /etc/nginx/ssl/nginx.crt; # 虚拟机使用的证书文件的路径
7 ssl_certificate_key /etc/nginx/ssl/nginx.key; # 与其证书匹配的私钥文件路径
8 ssl_session_cache shared:sslcache:20m; # 定义使用共享缓存,名字为sslcache,大小为20M
9 }
2.为了测试,首先在自己的主机上创建私有CA,但是在互联网上公开使用时,一定要找公共CA去签署
1)生成私钥文件
[root@localhost ~]# cd /etc/pki/CA
[root@localhost CA]# ls
certs crl newcerts private
[root@localhost CA]# ls private/
[root@localhost CA]# (umask 077;openssl genrsa -out private/cakey.pem 4096)
Generating RSA private key, 4096 bit long modulus
......++
........................................................................................................................................................................................................................................................................................................................................................................................................................................................................................++
e is 65537 (0x10001)
[root@localhost CA]# ls private/
cakey.pem
2)生成自签证书
[root@localhost CA]# openssl req -new -x509 -key private/cakey.pem -out cacert.pem
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) []:Beijing
Locality Name (eg, city) [Default City]:Beijing
Organization Name (eg, company) [Default Company Ltd]:MageEdu
Organizational Unit Name (eg, section) []:taotao.com
Common Name (eg, your name or your server's hostname) []:ca.taotao.com
Email Address []:
[root@localhost CA]# ll
总用量 20
-rw-r--r-- 1 root root 2037 10月 28 21:14 cacert.pem
drwxr-xr-x. 2 root root 4096 6月 29 2015 certs
drwxr-xr-x. 2 root root 4096 6月 29 2015 crl
drwxr-xr-x. 2 root root 4096 6月 29 2015 newcerts
drwx------. 2 root root 4096 10月 28 21:05 private
3)为CA提供目录和文件
[root@localhost CA]# touch index.txt
[root@localhost CA]# echo 01 > serial
[root@localhost CA]# ls
cacert.pem certs crl index.txt newcerts private serial
3.如上,创建CA完成,接下来要为nginx服务器签署CA请求
1)创建用于httpd通信时的私钥
[root@localhost CA]# cd /etc/nginx/
[root@localhost nginx]# ls
conf.d koi-utf mime.types nginx.conf scgi_params win-utf
fastcgi_params koi-win modules nginx.conf.bak uwsgi_params
[root@localhost nginx]# mkdir ssl
[root@localhost nginx]# cd ssl
[root@localhost ssl]# (umask 077;openssl genrsa -out nginx,key 2048)
Generating RSA private key, 2048 bit long modulus
......................+++
.................................................+++
e is 65537 (0x10001)
[root@localhost ssl]# ls
nginx,key # 创建成功
2)利用生成的私钥生成证书签署请求:
[root@localhost ssl]# 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) []:Beijing
Locality Name (eg, city) [Default City]:Beijing
Organization Name (eg, company) [Default Company Ltd]:MageEdu
Organizational Unit Name (eg, section) []:taotao.com
Common Name (eg, your name or your server's hostname) []:www.taotao.com
Email Address []:
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
4.接下来CA要为nginx签发证书(因为这里都是在本地主机生成的CA和httpd服务,所以不需要传送)
[root@localhost ssl]# openssl ca -in nginx.csr -out nginx.crt
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: Oct 28 13:29:07 2016 GMT
Not After : Oct 28 13:29:07 2017 GMT
Subject:
countryName = CN
stateOrProvinceName = Beijing
organizationName = MageEdu
organizationalUnitName = taotao.com
commonName = www.taotao.com
X509v3 extensions:
X509v3 Basic Constraints:
CA:FALSE
Netscape Comment:
OpenSSL Generated Certificate
X509v3 Subject Key Identifier:
8C:6E:F0:D0:2E:DF:52:22:6D:10:A9:25:74:BC:17:A5:2F:9C:42:DD
X509v3 Authority Key Identifier:
keyid:79:9F:37:3C:86:41:08:6D:1F:85:09:2B:59:C6:B6:0D:63:CC:5A:57
Certificate is to be certified until Oct 28 13:29:07 2017 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
[root@localhost ssl]# ls
nginx.crt # 签署的证书 nginx.csr nginx.key
5.如上,证书签署完成我们只需把生成的证书nginx.crt发送给客户端即可,现在我们检测语法nginx的语法,重载,查看ssl的443端口是否监听;
[root@localhost ssl]# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
[root@localhost ssl]# nginx -s reload
[root@localhost ssl]# ss -tnl
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 128 127.0.0.1:9000 *:*
LISTEN 0 50 *:3306 *:*
LISTEN 0 128 *:80 *:*
LISTEN 0 128 *:22 *:*
LISTEN 0 128 127.0.0.1:631 *:*
LISTEN 0 100 127.0.0.1:25 *:*
LISTEN 0 128 127.0.0.1:6010 *:*
LISTEN 0 128 *:443 *:*
LISTEN 0 128 127.0.0.1:6011 *:*
LISTEN 0 128 :::22 :::*
LISTEN 0 128 ::1:631 :::*
LISTEN 0 100 ::1:25 :::*
LISTEN 0 128 ::1:6010 :::*
LISTEN 0 128 ::1:6011 :::*
6.接下来我们为在nginx中定义的虚拟主机创建root的路径,并提供测试页面
[root@localhost ssl]# mkdir /vnhosts/ssl/htdocs -pv
mkdir: 已创建目录 "/vnhosts"
mkdir: 已创建目录 "/vnhosts/ssl"
mkdir: 已创建目录 "/vnhosts/ssl/htdocs"
[root@localhost ssl]# vim /vnhosts/ssl/htdocs/index.html
<h1>SSL Host</h1>
在浏览器中访问如下:
由上图可知:有两点错误:
7.修改本地hosts文件,使其能够解析
[root@localhost ssl]# vim /etc/hosts
1 127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
2 ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
3 10.1.252.37 # 添加ip的解析
8.导入CA机构的自签证书
再次访问,可以正常访问,如下:
因为我们现在在配置文件中定义了多个server,所以,如果不基于https协议访问,而使用http访问,还是会访问默认的主页面,如下:
8.处于安全考虑,如果我想让用户访问网站都是通过https协议访问(即实现从80端口跳转到443端口)的话,就需要在另一个server添加rewritw重写uri,如下:
现在我们再去访问http://192.168.1.17,如下
这就是,为什么我们在平时访问网站时,明明使用的是http协议,但它会自动跳转使用到https协议,只不过是用到了rewrite重写罢了!!!
1.用于阻挡来源非法的域名请求(防盗链)
★valid_referers none | blocked | server_names | string ...; ☉作用:
☉参数: ◆none:请求报文首部没有referer首部(也就是从浏览器中直接输入的); ◆blocked:请求报文的referer首部没有值; ◆server_names:参数,其可以有值作为主机名或主机名模式;
示例: valid_referers none blocked server_names *.example.com example.* www.example.org/galleries/ ~\.google\.; if ($invalid_referer) { return 403; }
演示:
解析:
测试:
使用curl命令模拟从tao.com magedu.com 和baidu.com跳转而来,结果发现前两个跳转都可以正常访问到内容,而从baidu跳转过来的则不能访问
[root@localhost conf.d]# curl -k -e "http://www.tao.com" "https://www.taotao.com/index.html"
<h1>SSL Host</h1>
[root@localhost conf.d]# curl -k -e "http://www.magedu.com" "https://www.taotao.com/index.html"
<h1>SSL Host</h1>
[root@localhost conf.d]# curl -k -e "http://www.baidu.com" "https://www.taotao.com/index.html"
<html>
<head><title>403 Forbidden</title></head>
<body bgcolor="white">
<center><h1>403 Forbidden</h1></center> # 不能正常访问返回结果为403 Forbidden
<hr><center>nginx/1.10.0</center>
</body>
</html>