虚拟主机
配置虚拟主机
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,访问网页
状态页
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>
上图,是点击链接,从blog.com跳转的请求,被拒绝;不仅如此,直接访问也不行了,因为只定义了从bbs跳转的为合法referer,
上图,从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,浏览器访问,标签页上即有图标;
或直接取消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,访问测试,查看响应头部信息
压缩前:头部信息;
压缩后访问,多了gzip标识头部,多了vary字段,大小从280多k变为40多k
文件下载服务
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
启用缓存
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;
}
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;
}
存在/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链接,
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,而是当成文本;
}
3、last
location /2.txt {
return 666;
}
# location的顺序位置无所谓,都会从头再跟各个location比较一下;
location /1.txt {
rewrite /1.txt /2.txt last;
}
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
return、if
可以返回301永久重定向,或:302临时重定向;
1,pc虚拟配置,加一段location
location /return {
if ($scheme = http) {
return 302 https://www.baidu.com;
}
}
2,访问测试,访问return的uri时,会返回302状态码,返回百度的网址,然后浏览器会自己主动向百度发起请求;
eg:
访问http://www.taobao.com网址,会被重定向到https://www.taobao.com,实现全部https加密访问;
实现类型效果:
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;
}
}
}
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端口同时监听;