nginx之web服务

nginx做web服务时相关配置实验笔记...

虚拟主机

配置虚拟主机

1,定义虚拟主机文件,主配置中引入

[root@host2 conf]# cat vhosts/bbs.conf 
server {
	listen 80;
	server_name www.bbs.com;
	
	root /data/nginx/bbs;
	index index.html;

	location / {
		root /data/nginx/bbs;
		
	}
}
# 写入网页文件
[root@host2 conf]# cat /data/nginx/bbs/index.html 
bbs-index

# nginx.conf中引入,注意位置,和默认的localhost的server同级别,在http内部
http {
...
include vhosts/*.conf;
...
}

# nginx -t ; nginx -s reload

2,访问

注意:默认虚拟主机是配置文件排位置第一的虚拟,所以为避免影响,include放在http段最下方,在主配置文件中最上方定义一个默认虚拟主机;

[root@host1 ~]# curl www.bbs.com
nginx-default-html
# 没reload时,nginx还没启用bbs虚机,此时访问,默认的虚拟主机会匹配到处理
# nginx默认虚拟主机,的默认首页
[root@host2 conf]# cat /usr/local/nginx/html/index.html
nginx-default-html

# 重启后,
[root@host1 ~]# curl www.bbs.com
bbs-index
[root@host1 ~]# cat /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.80.101 www.pc.com www.bbs.com www.load1.com

三种虚拟主机

# 三种定义方式
[root@host2 conf]# cat vhosts/*
server {
	listen 80;
	server_name www.bbs.com;
	
	root /data/nginx/bbs;
	index index.html;

	location / {
		root /data/nginx/bbs;
		
	}
}
基于主机头
server {
	listen 8080;
	root /data/nginx/blog;
	index index.html;
}
基于端口
server {
	listen 192.168.10.101:80;
	root /data/nginx/mobile;
	index index.html;
}
基于不同ip的
server {
	listen 80;
	server_name www.pc.com;
	root /data/nginx/pc;
	index index.html;

	location / {
		
	}

}
基于主机头

# 写入主页
-----------------
[root@host2 conf]# ll /data/nginx/
total 0
drwxr-xr-x 2 root root 24 Aug 28 15:22 bbs
drwxr-xr-x 2 root root 24 Aug 28 17:59 blog
drwxr-xr-x 2 root root 24 Aug 28 17:59 mobile
drwxr-xr-x 2 root root 24 Aug 28 17:15 pc
[root@host2 conf]# cat /data/nginx/*/index.html
bbs-index
blog-index
mobile-index
pc-index

# 访问测试
------------------
[root@host1 ~]# curl 192.168.10.101
mobile-index
[root@host1 ~]# curl 192.168.80.101:8080
blog-index
[root@host1 ~]# curl www.pc.com
pc-index
[root@host1 ~]# curl www.bbs.com
bbs-index
[root@host1 ~]# 

网页访问控制

模块:http_access:https://nginx.org/en/docs/http/ngx_http_access_module.html

可基于ip,cidr的ip形式,unix socket做访问控制,一般先allow需要的小范围,最后deny大范围;

基于ip的

server {
        listen 80;
        server_name www.bbs.com;

        root /data/nginx/bbs;
        index index.html;
        allow 192.168.80.100;
        deny all;
...
对bbs做限制配置


[root@host3 ~]# curl www.bbs.com
bbs-index
[root@host3 ~]# curl www.bbs.com
<html>
<head><title>403 Forbidden</title></head>
<body bgcolor="white">
<center><h1>403 Forbidden</h1></center>
<hr><center>nginx/1.14.2</center>
</body>
</html>
# 只有100可以正常访问,其余ip不行

网页认证

https://nginx.org/en/docs/http/ngx_http_auth_basic_module.html

利用htpasswd工具,生成用户名,及密码;在需要的context配置,启用网页认证和用户密码文件,

1,下载httpd-tools包

[root@host2 conf]# rpm -ql httpd-tools
/usr/bin/ab
/usr/bin/htdbm
/usr/bin/htdigest
/usr/bin/htpasswd
...
[root@host2 conf]# yum install -y httpd-tools

2,生成用户密码文件

htpasswd -h
查看用法

[root@host2 conf]# htpasswd -cb nginx.user wang wang
Adding password for user wang
[root@host2 conf]# htpasswd -b nginx.user li li
Adding password for user li
[root@host2 conf]# cat nginx.user 
wang:$apr1$kQLDR3lH$IxgAN1BpoCms8Q2iWjFyz0
li:$apr1$SjOumK8J$vPIPEMN4CY3lBgED9Uwst/

3,在context中引用

 location /stat {
        auth_basic           "need auth!";
        auth_basic_user_file nginx.user;
        stub_status;
#       access_log logs/bbs-stat.log log1;
        }

4,访问网页

image-20200829135432750

状态页

https://nginx.org/en/docs/http/ngx_http_stub_status_module.html

eg:

  location /stat {
                stub_status;
        }
# 加一个stat的location,启用stub_status指令;

[root@host1 ~]# curl www.bbs.com/stat
Active connections: 1 
server accepts handled requests
 7 7 7 
Reading: 0 Writing: 1 Waiting: 0 
# 访问

日志格式定义

https://nginx.org/en/docs/http/ngx_http_log_module.html

官方eg

log_format compression '$remote_addr - $remote_user [$time_local] '
                       '"$request" $status $bytes_sent '
                       '"$http_referer" "$http_user_agent" "$gzip_ratio"';

access_log /spool/logs/nginx-access.log compression buffer=32k;

日志格式一般在http段定义,用名字标识,默认全局生效,下级范围如server,location默认继承http段日志的格式和路径,亦可以自定义格式和路径;日志组成一般是内建变量,

在需要的上下文,如server,location,都可以引用http中定义的格式,自定义位置;

默认的main日志格式和access.log日志位置对http下所有server,location等生效,当然可以被覆盖;

1,定义格式

http {
...
    log_format log1 '$remote_addr $remote_user'
			'$status "$http_referer"'
			'"$http_user_agent" "$http_x_forwarded_for"';
			
注意写多行时,两边用''引起来			
...
}

2,引用

# 在bbs虚拟主机的stat的location引用,注意要先建立对应日志存放目录,
# 此后只有访问bbs的stat的请求,会被单独记录到bbs-stat.log,
# 其他虚拟主机的访问,包括bbs其他location的访问,仍是记录在默认的access.log中

	location /stat {
		stub_status;
	access_log logs/bbs-stat.log log1;
	}

json格式日志

​ 定义log_format时,自拼凑为json格式日志,即自定义key,然后value是引用的内建变量,自然日志就为json格式了;

http段定义:
【注意:1,json的key和值都用双引号引起来;2、每一对key-value后的逗号,除了最后一个;3,换行写时,每一行都用单引号引起来;】

    log_format myjsonlog '{"@timestamp":"$time_iso8601",'
        '"clientip":"$remote_addr",'
        '"host":"$server_addr",'

        '"status":"$status"}';
...
虚拟主机pc 的 upload的location引用

        location /upload {
                root /data/html/pc/;
                index index.html;
                access_log  logs/pc-json-upload.log myjsonlog;
...
重载
nginx -t ; nginx -s reload

查看
[root@host2 ~]# cat /usr/local/nginx/logs/pc-json-upload.log 
{"@timestamp":"2020-08-25T11:18:49+08:00","clientip":"192.168.80.100","host":"192.168.80.101","status":"200"}
{"@timestamp":"2020-08-25T11:18:49+08:00","clientip":"192.168.80.100","host":"192.168.80.101","status":"200"}
{"@timestamp":"2020-08-25T11:18:50+08:00","clientip":"192.168.80.100","host":"192.168.80.101","status":"200"}

json格式日志:
	方便:elk处理,脚本统计处理等;

防盗链

用户每个请求的请求头,一般都有referers字段,表示是从哪个网址跳转过来的, 一般网站图片等资源都要做放盗链,禁止小网站直接链接自己的资源,消耗自己带宽;

valid_referers定义合法的来源目标,如谷歌,百度等搜索引擎,自己网站内部的跳转,其余的一般都禁止;

eg:

1,pc上定义合法的referer,只有bbs

[root@host2 conf]# cat vhosts/pc.conf 
server {
	listen 80;
	server_name www.pc.com;
	root /data/nginx/pc;
	index index.html;
valid_referers *.bbs.com;
	location / {
		if ($invalid_referer) {
			return 403;
		}
	}

}

2,bbs和blog上写入网页,链接到pc.com

[root@host2 conf]# cat /data/nginx/bbs/index.html 
bbs-index
<a href="http://www.pc.com" target="_blank">pc.com</a>

[root@host2 conf]# cat /data/nginx/blog/index.html 
blog-index
<a href="http://www.pc.com" target="_blank">pc.com</a>

image-20200829125930510

image-20200829130706120

上图,是点击链接,从blog.com跳转的请求,被拒绝;不仅如此,直接访问也不行了,因为只定义了从bbs跳转的为合法referer,

image-20200829130050689

image-20200829130620762

上图,从bbs.com跳转的请求可以;

配置favicon.ico

真实浏览器访问网站首页时,会自动请求favicon.ico图标,若没有,日志会记录一条404;

192.168.80.1 - - [29/Aug/2020:13:13:48 +0800] "GET / HTTP/1.1" 200 66 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.135 Safari/537.36"
192.168.80.1 - - [29/Aug/2020:13:13:48 +0800] "GET /favicon.ico HTTP/1.1" 404 571 "http://www.bbs.com/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.135 Safari/537.36"

配置一个favicon.ico

加个favicon.ico的location
    location = /favicon.ico {
                root /data/nginx/bbs;
        }


[root@host2 conf]# cp /usr/share/backgrounds/day.jpg /data/nginx/bbs/
[root@host2 conf]# mv /data/nginx/bbs/day.jpg /data/nginx/bbs/favicon.ico
[root@host2 conf]# nginx -t
nginx: the configuration file /usr/local/nginx-1.14/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx-1.14/conf/nginx.conf test is successful
[root@host2 conf]# nginx -s reload


reload,浏览器访问,标签页上即有图标;

image-20200829131811128

或直接取消favicon找不到的报错;并不记录该日志

location = /favicon.ico {
	log_not_found off;
	access_log off;
}

gzip压缩

https://nginx.org/en/docs/http/ngx_http_gzip_module.html

1,准备稍大文件做网页文件

[root@host2 conf]# cp /var/log/messages /data/nginx/bbs/mess.html
[root@host2 conf]# ll -h !$
ll -h /data/nginx/bbs/mess.html
-rw------- 1 root root 279K Aug 29 13:28 /data/nginx/bbs/mess.html

注意nginx用户的读权限
[root@host2 conf]# chmod a+r /data/nginx/bbs/mess.html

2,在需要的上下文配置启用压缩,及压缩比等属性

 location / {
                root /data/nginx/bbs;
#       access_log logs/bbs-json.log myjsonlog;

        gzip on;
        gzip_comp_level 3;
        gzip_disable "fire";
        gzip_min_length 200;
        gzip_vary on;

        }

3,访问测试,查看响应头部信息

压缩前:头部信息;

image-20200829133155082

压缩后访问,多了gzip标识头部,多了vary字段,大小从280多k变为40多k

image-20200829133249076

文件下载服务

https://nginx.org/en/docs/http/ngx_http_autoindex_module.html

利用autoindex指令可以在找不到默认的index.html情况下,展示该目录下所有文件,并可以提供下载;

1,配置download的loaction

  location /download {
                root /data/nginx/bbs; 
                autoindex on;
                autoindex_exact_size on;
                autoindex_localtime on;
                autoindex_format html;
        }  

2,放入文件,注意:一定不能有index.html,否则刷出的是首页文件,只有不存在首页文件时,才会显示目录,提供下载功能

[root@host2 conf]# ll /data/nginx/bbs/download
total 8
-rw-r--r-- 1 root root 1077 Aug 29 18:06 fastcgi.conf
-rw-r--r-- 1 root root 3099 Aug 29 18:06 nginx.conf

image-20200829181353322

启用缓存

Syntax:	open_file_cache off;
open_file_cache max=N [inactive=time];
Default:	
open_file_cache off;
Context:	http, server, location

eg:
open_file_cache          max=1000 inactive=20s;
open_file_cache_valid    30s;
open_file_cache_min_uses 2;
open_file_cache_errors   on;

客户端限制

速率限制

https://nginx.org/en/docs/http/ngx_http_limit_req_module.html

The ngx_http_limit_req_module module (0.7.21) is used to limit the request processing rate per a defined key, in particular, the processing rate of requests coming from a single IP address. The limitation is done using the “leaky bucket” method.

并发限制

https://nginx.org/en/docs/http/ngx_http_limit_req_module.html

The ngx_http_limit_conn_module module is used to limit the number of connections per the defined key, in particular, the number of connections from a single IP address.

URL重写

https://nginx.org/en/docs/http/ngx_http_rewrite_module.html#rewrite

rewrite、last、break

rewrite有四种标志;permanent类似return加301;redirect类似return加302;last表示匹配到继续执行匹配循环;break表示匹配到就跳出匹配循环;

last配置不当容易造成死循环,但nginx默认限制了最大循环10次,然后返回500error;

Syntax:	rewrite regex replacement [flag];
Default:	—
Context:	server, location, if

1、rewrite做http到https跳转

   if ($scheme = http) {
        #       return 301 https://www.pc.com;
                rewrite / https://www.pc.com break;
        }

image-20200829204455962

2、break

2者对比发现:break是做了rewrite之后,不再理会其他的location,直接在本机找rewrite后的文件,本例中是找/2.txt,由于没有该文件,所以返回是404;

而last,是做了rewrite之后,用rewrite后新的uri和各个location的配置再匹配一遍,如果匹配到了,就用匹配到后的配置处理,此例中:1.txt改写后变为2.txt,改写后的2.txt又匹配到了另外的2.txt的location,所以执行里面的指令,返回666给客户端;

 location /1.txt {
                rewrite /1.txt /2.txt break;
        }
        location /2.txt {
                return 666;
        }

image-20200829205736810

存在/2.txt文件的情况下,会直接得到相应页面;注意:调试窗口,只有一个发起1.txt的请求,并无发起2.txt的请求,也就是说,是nginx内部完成重写,nginx找到改写后文件直接返回客户端,不需要客户端得到改写后的uri并重新发起请求!

下图为rewrite情况,return不同!见下方对比;

 location /1.txt {
                rewrite /1.txt /2.txt break;
        }
break标记位,在改成为2.txt后,直接找到本地的2.txt返回客户端;
改写后的uri不会再和其他location做再次比较;
不会返回客户端新的url或uri链接,

image-20200829211730744

return和rewrite区别

  • return
    • return主要使用于外部完整url链接的重定向
    • 服务器会返回客户端新的url,浏览器会对返回的url重新发起请求,地址栏url会变
    • code不可以随意写,一般是301,302,写的随便的如233,后面的url会被当初return的文本参数返回,而不是被当作url对待
  • rewrite
    • rewrite主要适用于内部部分uri变更的重定向,如video路径改成了mp4路径
    • 服务端不会返回客户端新的url,浏览器不会得到url并发新请求,地址栏地址不会变
    • nginx内部完成路径的重写,并找到重写后的文件,直接返回给客户端;

下图为return情况:

  location /1.txt {
                return 301 http://www.pc.com/3.txt;
                301的code不能随便写,一开始写的233,后面的url不会当成url,而是当成文本;
        }

image-20200829212910994

3、last

        location /2.txt {
                return 666;
        }
        # location的顺序位置无所谓,都会从头再跟各个location比较一下;
         location /1.txt {
                rewrite /1.txt /2.txt last;
        }

image-20200829205629478

4、last的死循环

    location /2.txt {
                rewrite /2.txt /1.txt last;
        }
        location /1.txt {
                rewrite /1.txt /2.txt last;
        }
        
        
 # error.log给出了明显的报错;  
2020/08/29 21:12:45 [error] 2334#2334: *210 rewrite or internal redirection cycle while processing "/2.txt", client: 192.168.80.1, server: www.pc.com, request: "GET /1.txt HTTP/1.1", host: "www.pc.com

image-20200829211127225

return、if

可以返回301永久重定向,或:302临时重定向;

1,pc虚拟配置,加一段location

 location /return {
                if ($scheme = http) {
                        return 302 https://www.baidu.com;
                }
        }

2,访问测试,访问return的uri时,会返回302状态码,返回百度的网址,然后浏览器会自己主动向百度发起请求;

image-20200829201719078

eg:

访问http://www.taobao.com网址,会被重定向到https://www.taobao.com,实现全部https加密访问;

image-20200829202206145

实现类型效果:

1,同时配置http和https监听

2,然后,对http的请求做return重定向到https;

server {
        listen 80;
        listen 443 ssl;
        server_name www.pc.com;
        root /data/nginx/pc;
        index index.html;

        ssl_certificate_key ssl/bbs.key;
        ssl_certificate     ssl/bbs.crt;
        ssl_session_cache shared:sslcache:20m;
        ssl_session_timeout 10m;

        if ($scheme = http) {
                return 301 https://www.pc.com;
        }
        location /return {
                if ($scheme = http) {
                        return 302 https://www.baidu.com;
                }
        }
}

image-20200829202917980

https加密

https://nginx.org/en/docs/http/ngx_http_ssl_module.html

真实公网证书,需到证书提供商申请,有单一域名、和通配域名,如*.gitee.io就是通配域名证书,所有gitee.io结尾的网站都可以被同一套证书加密;

1,生成自签名ca,然后给需要的虚拟主机或这个nginx实例生成证书和key

openssl genrsa -out bbs.key 1024
openssl req -new -x509 -days 365 -key bbs.key -out bbs.crt
# 生成key,然后直接自签名;

mkdir /usr/local/nginx/conf/ssl
[root@host2 ssl]# pwd
/usr/local/nginx/conf/ssl
[root@host2 ssl]# ll
total 8
-rw-r--r-- 1 root root 1001 Aug 29 17:43 bbs.crt
-rw-r--r-- 1 root root  891 Aug 29 17:40 bbs.key

2,配置到bbs上

server {
        listen 80;
        listen 443 ssl;
        server_name www.bbs.com;

        ssl_certificate_key ssl/bbs.key; # 采用的是conf的相对路径
        ssl_certificate     ssl/bbs.crt;
        ssl_session_cache shared:sslcache:20m;
        ssl_session_timeout 10m;

...

3,重载访问

已经完成了https的访问,然后将根证书导入浏览器信任的根列表,再次访问显示证书无问题,但仍有红色警告

[root@host2 ssl]# ss -lnt
State      Recv-Q Send-Q Local Address:Port                Peer Address:Port              
LISTEN     0      128                *:80                             *:*                  
LISTEN     0      128                *:22                             *:*                  
LISTEN     0      100        127.0.0.1:25                             *:*                  
LISTEN     0      128                *:443                            *:*   
# 443端口同时监听;

image-20200829174851967

updatedupdated2020-10-192020-10-19
加载评论