1.Nginx默认虚拟主机

①编辑Nginx的主配置文件文件,删除Server相关的配置,并在http部分加入一下内容

•include vhost/*.conf;

②创建如下目录以及文件

[root@test_02 conf]# mkdir vhost
[root@test_02 vhost]# vim aaa.com.conf

在文件中写入如下内容

server
{
    listen 80 default_server;  // 有这个标记的就是默认虚拟主机
    server_name aaa.com;
    index index.html index.htm index.php;
    root /data/wwwroot/default;
}

③创建虚拟主机目录

[root@test_02 vhost]# mkdir -p /data/wwwroot/default/

④测重启服务后,测试发现成功解析到了定义好的index.php文件内容

[root@test_02 conf]# /usr/local/nginx/sbin/nginx -t
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
[root@test_02 conf]# /usr/local/nginx/sbin/nginx -s reload
[root@test_02 conf]# curl localhost
This is default site.

2.Nginx用户认证

①创建虚拟主机配置文件,并写入配置内容

[root@test_02 vhost]# vim test.com.con

写入如下配置内容

server
{
    listen 80;
    server_name test.com;
    index index.html index.htm index.php;
    root /data/wwwroot/test.com;

location  /
    {
        auth_basic              "Auth";     //定义认证用户
        auth_basic_user_file   /usr/local/nginx/conf/htpasswd;   //定义密码文件
}
}

②创建密码文件

此处生成密码文件使用了与LAMP相同的htpasswd工具

[root@test_02 vhost]# htpasswd -cm /usr/local/nginx/conf/htpasswd wennan
New password:
Re-type new password:
Adding password for user wennan
[root@test_02 vhost]# cat !$
cat wennan
cat: wennan: 没有那个文件或目录
[root@test_02 vhost]# cat /usr/local/nginx/conf/htpasswd
wennan:$apr1$BdrSuQwn$dHpJWOgYC0v8xYpFq4gXC.

③-u选项带用户名密码测试

[root@test_02 vhost]# curl -uwennan:wennan19930825 -x127.0.0.1:80 test.com
hello

3.重定向

①在虚拟主机配置文件中计入重定向相关的配置内容

server
{
    listen 80;
    server_name test.com test1.com test2.com test3.com;
    index index.html index.htm index.php;
    root /data/wwwroot/test.com;
    if ($host != 'test.com' ) {
        rewrite  ^/(.*)$  http://test.com/$1  permanent;
    }

}

域名非test.com的时候,永久重定向至test.com

②测试

[root@test_02 vhost]# curl -x127.0.0.1:80 test2.com/index.html
<html>
<head><title>301 Moved Permanently</title></head>
<body bgcolor="white">
<center><h1>301 Moved Permanently</h1></center>
<hr><center>nginx/1.12.1</center>
</body>
</html>

4.Nginx访问日志

①使用vim打开nginx的主配置文件,搜索log_format的内容

[root@test_02 ~]# vim /usr/local/nginx/conf/nginx.conf
 log_format wennan '$remote_addr $http_x_forwarded_for [$time_local]'
    ' $host "$request_uri" $status'
    ' "$http_referer" "$http_user_agent"';

$remote_addr:客户端公网IP

$http_x_forwarded_for:代理服务器的IP

$time_local:本地服务器时间

$host:访问主机名

$request_uri:访问的url地址

$status:状态码

$http_referer:referer

$http_user_agent:用户代理

②在虚拟主机配置文件中增加如下内容

[root@test_02 ~]# vim /usr/local/nginx/conf/vhost/test.com.conf
server
{
    listen 80;
    server_name test.com test1.com test2.com test3.com;
    index index.html index.htm index.php;
    root /data/wwwroot/test.com;
    if ($host != 'test.com' ) {
        rewrite  ^/(.*)$  http://test.com/$1  permanent;
    }
    access_log /tmp/test.com.log wennan;

}

③重启服务后,多次curl访问测试,得到如下的访问日志

[root@test_02 ~]# curl -x127.0.0.1:80 test2.com -I
HTTP/1.1 301 Moved Permanently
Server: nginx/1.12.1
Date: Fri, 05 Jan 2018 00:37:28 GMT
Content-Type: text/html
Content-Length: 185
Connection: keep-alive
Location: http://test.com/

[root@test_02 ~]# cat /tmp/test.com.log
127.0.0.1 - [05/Jan/2018:08:37:13 +0800] test.com "/" 200 "-" "curl/7.29.0"
127.0.0.1 - [05/Jan/2018:08:37:16 +0800] test.com "/" 200 "-" "curl/7.29.0"
127.0.0.1 - [05/Jan/2018:08:37:24 +0800] test3.com "/" 301 "-" "curl/7.29.0"
127.0.0.1 - [05/Jan/2018:08:37:28 +0800] test2.com "/" 301 "-" "curl/7.29.0"

5.Nginx日志切割

Mginx与Apache不通,自身没有集成日志的切割工具,因此此处借助日至切割脚本来实现。

[root@test_02 ~]# vim /usr/local/sbin/nginx_log_rotate.sh
# /bin/bash
## 假设nginx的日志存放路径为/data/logs/
d=`date -d "-1 day" +%Y%m%d`
logdir="/data/logs"
nginx_pid="/usr/local/nginx/logs/nginx.pid"
cd $logdir
for log in `ls *.log`
do
    mv $log $log-$d
done
/bin/kill -HUP `cat $nginx_pid`

脚本内容解释:

d=`date -d "-1 day" +%Y%m%d` :定义日志时间

nginx_pid="/usr/local/nginx/logs/nginx.pid":重新加载pid以创建新的日志文件

logdir="/tmp/":定义日志路径

此处使用for循环,对ls所列出的项目进行循环,将日至文件名称加上定义好的时间信息

for log in `ls *.log`
do
    mv $log $log-$d
done

运行脚本,并查看日志文件

[root@test_02 ~]# sh -x /usr/local/sbin/nginx_log_rotate.sh
++ date -d '-1 day' +%Y%m%d
+ d=20180104
+ logdir=/tmp/
+ nginx_pid=/usr/local/nginx/logs/nginx.pid
+ cd /tmp/
++ ls test.com.log
+ for log in '`ls *.log`'
+ mv test.com.log test.com.log-20180104
++ cat /usr/local/nginx/logs/nginx.pid
+ /bin/kill -HUP 22748
[root@test_02 ~]# ls /tmp
1.txt      mysql.sock     systemd-private-eace50d630df44208a369fc2b33d6e8f-vmtoolsd.service-jR4oK6
2.txt      pear           test.com.log
aming.txt  php-fcgi.sock  test.com.log-20180104
[root@test_02 ~]# vim /usr/local/sbin/nginx_log_rotate.sh

6.静态元素不记录日志

在虚拟主机配置文件中加入如下内容

此处设置不记录图片类型文件的访问日志,且js或者css格式文件永不过期

 location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$
    {
          expires      7d;
          access_log off;
    }
    location ~ .*\.(js|css)$
    {
          access_log off;
    }

借助curl命令进行测试,日至并未记录1.gif文件的访问日志

[root@test_02 test.com]# curl -x127.0.0.1:80 test.com/index.html
hello
[root@test_02 test.com]# curl -x127.0.0.1:80 test.com/1.gif
qweqweqwe
[root@test_02 test.com]# cat /tmp/test.com.log
127.0.0.1 - [05/Jan/2018:09:31:02 +0800] test.com "/index.html" 200 "-" "curl/7.29.0"
127.0.0.1 - [05/Jan/2018:09:31:43 +0800] test.com "/index.html" 200 "-" "curl/7.29.0"

再次使用curl命令,分别访问1.gif与2.js两个文件。

由于js文件未设置expires,所以在反馈信息中没有max-age这一项

[root@test_02 test.com]# curl -x127.0.0.1:80 test.com/1.gif -I
HTTP/1.1 200 OK
Server: nginx/1.12.1
Date: Fri, 05 Jan 2018 01:38:57 GMT
Content-Type: image/gif
Content-Length: 10
Last-Modified: Fri, 05 Jan 2018 01:33:25 GMT
Connection: keep-alive
ETag: "5a4ed5e5-a"
Expires: Fri, 12 Jan 2018 01:38:57 GMT
Cache-Control: max-age=604800
Accept-Ranges: bytes

[root@test_02 test.com]# curl -x127.0.0.1:80 test.com/2.js -I
HTTP/1.1 200 OK
Server: nginx/1.12.1
Date: Fri, 05 Jan 2018 01:39:05 GMT
Content-Type: application/javascript
Content-Length: 5
Last-Modified: Fri, 05 Jan 2018 01:37:46 GMT
Connection: keep-alive
ETag: "5a4ed6ea-5"
Accept-Ranges: bytes

7.Nginx防盗链

①编辑虚拟主机配置文件/usr/local/nginx/sbin/nginx/conf/vhost/test.com.conf

加入以下防盗链相关的配置:

location ~* ^.+\.(gif|jpg|png|swf|flv|rar|zip|doc|pdf|gz|bz2|jpeg|bmp|xls)$  \\匹配以.gif等结尾的文件
{
    expires 7d;  \\过期时间设置为7天
    valid_referers none blocked server_names  *.test.com ;  \\设置域名白名单:refer为.test.com跳转
    if ($invalid_referer) {
        return 403;
    }
    access_log off;
}

②分别将referer设置为www.baidu.com/1.txt和test.com/1.txt后访问1.gif文件,得到如下反馈。

8.访问控制

需求:在test.com/admin下有1.txt文件,该文件只允许127.0.0.1的IP源访问,而不允许其他IP源访问:

①在虚拟主机配置文件中加入如下设置:

location /admin/
{
    allow 127.0.0.1;
    deny all;
}

②测试结果

nginx中的匹配规则为从上至下一次匹配,匹配到合适的条件后则不再继续匹配。

因此分别以127.0.0.1和192.168.231.131两个IP访问1.txt文件会得到如下的反馈结果

[root@test_02 ~]# curl -x127.0.0.1:80 test.com/admin/1.txt -I
HTTP/1.1 200 OK
Server: nginx/1.12.1
Date: Sun, 07 Jan 2018 12:06:24 GMT
Content-Type: text/plain
Content-Length: 7
Last-Modified: Sun, 07 Jan 2018 12:06:19 GMT
Connection: keep-alive
ETag: "5a520d3b-7"
Accept-Ranges: bytes

[root@test_02 ~]# curl -x192.168.231.131:80 test.com/admin/1.txt -I
HTTP/1.1 403 Forbidden
Server: nginx/1.12.1
Date: Sun, 07 Jan 2018 12:06:53 GMT
Content-Type: text/html
Content-Length: 169
Connection: keep-alive

③访问控制中也可以针对useragent做限制。

在虚拟主机配置文件中加入如下配置:

if ($http_user_agent ~* 'Spider/3.0|YoudaoBot|Tomato')
{
      return 403;

该段配置表示当useragent为youdaobot或者tomato的事后禁止访问。

匹配符号“~”之后的“*”表示不区分大小写

vim /usr/local/nginx/conf/vhost/test.com.conf
[root@test_02 ~]# curl -A "Tomatoasdasd" -x127.0.0.1:80 test.com/admin/1.txt -I
HTTP/1.1 403 Forbidden
Server: nginx/1.12.1
Date: Sun, 07 Jan 2018 14:13:49 GMT
Content-Type: text/html
Content-Length: 169
Connection: keep-alive

[root@test_02 ~]# curl -A "aomatoasdasd" -x127.0.0.1:80 test.com/admin/1.txt -I
HTTP/1.1 200 OK
Server: nginx/1.12.1
Date: Sun, 07 Jan 2018 14:13:59 GMT
Content-Type: text/plain
Content-Length: 7
Last-Modified: Sun, 07 Jan 2018 12:06:19 GMT
Connection: keep-alive
ETag: "5a520d3b-7"
Accept-Ranges: bytes

9.Nginx代理

用户访问非直连网络环境的服务器时,可以间接通过代理服务器。

Nginx代理设置文件为/usr/local/nginx/conf/vhost/proxy.conf

在该配置文件中写入如下配置内容:

server
{
    listen 80;
    server_name ask.apelearn.com;

    location /
    {
        proxy_pass      http://121.201.9.155/;
        proxy_set_header Host   $host;
        proxy_set_header X-Real-IP      $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

代理前通过本机访问ask.apelearn.com的返回如下:

[root@test_02 vhost]# curl ask.apelearn.com/robots.txt
#
# robots.txt for MiWen
#

User-agent: *

Disallow: /?/admin/
Disallow: /?/people/
Disallow: /?/question/
Disallow: /account/
Disallow: /app/
Disallow: /cache/
Disallow: /install/
Disallow: /models/
Disallow: /crond/run/
Disallow: /search/
Disallow: /static/
Disallow: /setting/
Disallow: /system/
Disallow: /tmp/
Disallow: /themes/
Disallow: /uploads/
Disallow: /url-*
[root@tes-x127.0.0.1:80 ask.apelearn.com/robots.txttxt
<html>
<head><title>404 Not Found</title></head>
<body bgcolor="white">
<center><h1>404 Not Found</h1></center>
<hr><center>nginx/1.12.1</center>
</body>
</html>

启用代理后:

[root@test_02 vhost]# curl -x127.0.0.1:80 ask.apelearn.com/robots.txt
#
# robots.txt for MiWen
#

User-agent: *

Disallow: /?/admin/
Disallow: /?/people/
Disallow: /?/question/
Disallow: /account/
Disallow: /app/
Disallow: /cache/
Disallow: /install/
Disallow: /models/
Disallow: /crond/run/
Disallow: /search/
Disallow: /static/
Disallow: /setting/
Disallow: /system/
Disallow: /tmp/
Disallow: /themes/
Disallow: /uploads/
Disallow: /url-*
Disallow: /views/

10.Nginx负载均衡

当一台Nginx服务器为后台多个Web服务器做代理的时候,则为Nginx的负载均衡。

①编辑新的配置文件/usr/local/nginx/conf/vhost/load.conf

upstream qq
{
    ip_hash;
    server 61.135.157.156:80;
    server 125.39.240.113:80;
}
server
{
    listen 80;
    server_name www.qq.com;
    location /
    {
        proxy_pass      http://qq;
        proxy_set_header Host   $host;
        proxy_set_header X-Real-IP      $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

由于Nginx不支持直接在Porxy_pass部分输入多个IP,因此需要借助upstream工具来分流。

upstream部分的 Server为多台Web服务器的IP地址,ip_hash则是为了让每个用户固定访问一台Web服务器。

②测试

在重新加载服务之前,使用curl工具访问www.qq.com,访问到了默认页面

[root@test_02 vhost]# curl -x127.0.0.1:80 www.qq.com
This is default site.

重新加载服务后,则成功访问到了qq的主页代码。

11.生成ssl密钥对

①使用openssl工具生成密钥 ,加密方式为rsa,长度为2048

[root@test_02 conf]# openssl genrsa -des3 -out tmp.key 2048
Generating RSA private key, 2048 bit long modulus
....................................+++
.....................................+++
e is 65537 (0x10001)
Enter pass phrase for tmp.key:
Verifying - Enter pass phrase for tmp.key:

②由于此处生成的密钥是需要加密的,为了方便使用,需要将密钥文件转化为不需要密码的私钥文件

[root@test_02 conf]# openssl rsa -in tmp.key -out wennan.key
Enter pass phrase for tmp.key:
writing RSA key
[root@test_02 conf]# ls
fastcgi.conf            htpasswd    mime.types.default  scgi_params          uwsgi_params.default
fastcgi.conf.default    koi-utf     nginx.conf          scgi_params.default  vhost
fastcgi_params          koi-win     nginx.conf.1        tmp.key              wennan.key
fastcgi_params.default  mime.types  nginx.conf.default  uwsgi_params         win-utf

③生成用于生成公钥的请求文件

[root@test_02 conf]# openssl req -new -key wennan.key -out wennan.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) []:gd
Locality Name (eg, city) [Default City]:gz
Organization Name (eg, company) [Default Company Ltd]:kch
Organizational Unit Name (eg, section) []:kch
Common Name (eg, your name or your server's hostname) []:test_02
Email Address []:wennan_zhou@kelchina.com.cn

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

④生成公钥文件

[root@test_02 conf]# openssl x509 -req -days 365 -in wennan.csr -signkey wennan.key -out wennan.crt
Signature ok
subject=/C=cn/ST=gd/L=gz/O=kch/OU=kch/CN=test_02/emailAddress=wennan_zhou@kelchina.com.cn
Getting Private key

12.Nginx配置ssl

①由于Nginx安装编译的过程中未做过ssl相关的配置,因此需要先重新编译nginx

[root@test_02 nginx-1.12.1]# ./configure --prefix=/usr/local/nginx/ --with-http_ssl_module
[root@test_02 nginx-1.12.1]# make&&make install

②编辑配置文件/usr/local/nginx/conf/vhost/ssl.conf

[root@test_02 nginx-1.12.1]# vim /usr/local/nginx/conf/vhost/ssl.conf
server
{
    listen 443;
    server_name test.com;
    index index.html index.php;
    root /data/wwwroot/test.com;
    ssl on;                               \\开启ssl功能
    ssl_certificate wennan.crt;           \\公钥
    ssl_certificate_key wennan.key;       \\私钥
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
}

③重启服务查看监听端口信息

[root@test_02 nginx-1.12.1]# /etc/init.d/nginx restart
Restarting nginx (via systemctl):                          [  确定  ]
[root@test_02 nginx-1.12.1]# netstat -lntp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      38069/nginx: master
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      1173/sshd
tcp        0      0 127.0.0.1:25            0.0.0.0:*               LISTEN      1837/master
tcp        0      0 0.0.0.0:443             0.0.0.0:*               LISTEN      38069/nginx: master
tcp6       0      0 :::3306                 :::*                    LISTEN      3965/mysqld
tcp6       0      0 :::22                   :::*                    LISTEN      1173/sshd
tcp6       0      0 ::1:25                  :::*                    LISTEN      1837/master

④在/etc/hosts文件中加入test.com后使用curl测试成功

提示信息为证书不可信。

[root@test_02 test.com]# curl https://test.com
curl: (60) Peer's certificate issuer has been marked as not trusted by the user.
More details here: http://curl.haxx.se/docs/sslcerts.html

curl performs SSL certificate verification by default, using a "bundle"
 of Certificate Authority (CA) public keys (CA certs). If the default
 bundle file isn't adequate, you can specify an alternate file
 using the --cacert option.
If this HTTPS server uses a certificate signed by a CA represented in
 the bundle, the certificate verification probably failed due to a
 problem with the certificate (it might be expired, or the name might
 not match the domain name in the URL).
If you'd like to turn off curl's verification of the certificate, use
 the -k (or --insecure) option.