目录
(7)ssl_prefer_server_ciphers指令
7.proxy_temp_fifile_write_size指令
一、Rewrite基本使用
1.什么是Rewrite
Rewrite是Nginx服务器提供的一个重要基本功能,是Web服务器产品中几乎必备的功能。主要的作用是用来实现URL的重写。Nginx使用的是ngx_http_rewrite_module模块来解析和处理Rewrite功能的相关配置。
2.set指令
set:该指令用来设置一个新的变量。
#语法
#variable:变量的名称,该变量名称要用"$"作为变量的第一个字符,且不要与Nginx服务器预设的全局变量同名。
#value:变量的值,可以是字符串、其他变量或者变量的组合等。
set $variable value;
#位置
server、location、if
示例:
3.Rewrite常用全局变量
$args | 变量中存放了请求URL中的请求参数 |
$http_user_agent | 变量存储的是用户访问服务的代理信息(如果通过浏览器访问,记录的是浏览器的相关版本信息) |
$host | 变量存储的是访问服务器的server_name值 |
$document_uri | 变量存储的是当前访问地址的URI。 |
$document_root | 变量存储的是当前请求对应location的root值,如果未设置,默认指向Nginx自带html目录所在位置 |
$content_length | 变量存储的是请求头中的Content-Length的值 |
$content_type | 变量存储的是请求头中的Content-Type的值 |
$http_cookie | 变量存储的是客户端的cookie信息,可以通过add_header Set-Cookie 'cookieName=cookieValue'来添加cookie数 据 |
$limit_rate | 变量中存储的是Nginx服务器对网络连接速率 的限制,也就是Nginx配置中对limit_rate指令设置的值,默认是0,不限制。 |
$remote_addr | 变量中存储的是客户端的IP地址 |
$remote_port | 变量中存储了客户端与服务端建立连接的端口号 |
$remote_user | 变量中存储了客户端的用户名,需要有认证模块才能获取 |
$scheme | 变量中存储了访问协议 |
$server_addr | 变量中存储了服务端的地址 |
$server_name | 变量中存储了客户端请求到达的服务器的名称 |
$server_port | 变量中存储了客户端请求到达服务器的端口号 |
$server_protocol | 变量中存储了客户端请求协议的版本,比如"HTTP/1.1" |
$request_body_fifile | 变量中存储了发给后端服务器的本地文件资源的名称 |
$request_method | 变量中存储了客户端的请求方式,比如"GET","POST"等 |
$request_fifilename | 变量中存储了当前请求的资源文件的路径名 |
$request_uri | 变量中存储了当前请求的URI,并且携带请求参数 |
全局变量可以用在日志文件中,用到之前的log_format指令:
4.if指令
if:该指令用来支持条件判断,并根据条件判断结果选择不同的Nginx配置。
注意if后面需要一个空格
#语法,注意if后面需要一个空格
#condition为判定条件,可以支持以下写法:
#1. 变量名。如果变量名对应的值为空字符串或"0",if都判断为false,其他条件为true
#
#2. 使用"="和"!="比较变量和字符串是否相等,满足条件为true,不满足为false。注意:此处和Java不太一样#的地方是字符串不需要添加引号,并且等号和不等号前后都需要加空格。
#
#3. 使用正则表达式对变量进行匹配,匹配成功返回true,否则返回false。变量与正则表达式之间使用"~","~*","!~","!~*"来连接。
#"~"代表匹配正则表达式过程中区分大小写,
#"~*"代表匹配正则表达式过程中不区分大小写
#"!~"和"!~*"刚好和上面取相反值,如果匹配上返回false,匹配不上返回true
#
#4. 判断请求的文件是否存在使用"-f"和"!-f",
#5. 判断请求的目录是否存在使用"-d"和"!-d"
#6. 判断请求的目录或者文件是否存在使用"-e"和"!-e"
#7. 判断请求的文件是否可执行使用"-x"和"!-x"
if (condition){...}
#位置
server、location
5.break指令
break:
- 该指令用于中断当前相同作用域中的其他Nginx配置。与该指令处于同一作用域的Nginx配置中,位于它前面的指令配置生效,位于后面的指令配置无效。
- 终止当前的匹配并把当前的URI在本location进行重定向访问处理
#语法
break;
#位置
server,location,if
示例:
如果直接调用/testbreak,因为没有后缀,会跳过args,显示为tom:
如果调用/testbreak?1,因为有后缀,会进入if,username会变成nancy,并且中断if跳出来,并把后续的代码执行完。执行完成后,会去html这个默认目录下查找url(testbreak)对应的重定向资源。
6.return指令
return:该指令用于完成对请求的处理,直接向客户端返回。在return后的所有Nginx配置都是无效的。
#语法
#code:为返回给客户端的HTTP状态代理。可以返回的状态代码为0~999的任意HTTP状态代理
#text:为返回给客户端的响应体内容,支持变量的使用
#URL:为返回给客户端的URL地址
return code [text];
return code URL;
return URL;
#位置
server,location,if
7.rewrite指令
rewrite:该指令通过正则表达式的使用来改变URI。可以同时存在一个或者多个指令,按照顺序依次对URL进行匹配和处理
#语法
#regex:用来匹配URI的正则表达式
#replacement:匹配成功后,用于替换URI中被截取内容的字符串。如果该字符串是以"http://"或者"https://"开头的,则不会继续向下对URI进行其他处理,而是直接返回重写后的URI给客户端
rewrite regex replacement [flag];
#位置
http,server,if
flag:用来设置rewrite对URI的处理行为,可选值有如下:
- last:如果匹配成功后,就不往下走了,而是直接拿新的url在整个路径下找对应的方法
- break:将此处重写的URI作为一个新的URI,在本块中继续进行处理。即去/usr/local/nginx/html/你输入的url/index.html
- redirect:将重写后的URI返回给客户端,状态码为302,指明是临时重定向URI,主要用在replacement变量不是以"http://"或者"https://"开头的情况。
- permanent:将重写后的URI返回给客户端,状态码为301,指明是永久重定向URI,主要用在replacement变量不是以"http://"或者"https://"开头的情况。
实例:
8.rewrite_log指令
rewrite_log:该指令配置是否开启URL重写日志的输出功能。
开启后,URL重写的相关日志将以notice级别输出到error_log指令配置的日志文件汇总。
#语法
rewrite_log on|off;
#默认值
rewrite_log off;
#位置
http、server、location、if
使用:
rewrite_log on;
error_log logs/error.log notice;
二、Rewrite案例
1.域名跳转
输入jingdong,360buy,jd都会跳转到jd的页面。
(1)准备3个域名
vim /etc/hosts
(2)编辑配置文件
server {
listen 80;
server_name www.xupeng.com;
location /{
default_type text/html;
return 200 '<h1>welcome to xupeng!</h1>';
}
}
server {
listen 80;
server_name www.xupeng1.com www.xupeng2.com;
#将所有请求xupeng1的都重定向到xupeng
#此处的$1用于处理带参数的情况,如果带参数,原样带到xupeng处
rewrite ^(.*) http://www.xupeng.com$1;
}
(3)测试
注意,别在xshell上测试,需要在虚拟机内置浏览器测试,因为你的本地域名只在虚拟机起作用,在xshell的主机是不起作用的
2.域名镜像
对于上面的例子,我们不想把所有的内容都跳转,只有/user内容会跳转,怎么做?
server {
listen 80;
server_name www.xupeng.com;
location /{
default_type text/html;
return 200 '<h1>welcome to xupeng!</h1>';
}
}
server {
listen 80;
server_name www.xupeng1.com www.xupeng2.com;
#将所有请求xupeng1的都重定向到xupeng
#此处的$1用于处理带参数的情况,如果带参数,原样带到xupeng处
# rewrite ^(.*) http://www.xupeng.com$1;
#将/user开头的重定向,其他的不重定向
location /user {
rewrite ^/user(.*)$ http://www.xupeng.com$1;
}
location /emp {
default_type text/html;
return 200 '<h1>emp_success</h1>';
}
}
3.独立域名
我们怎么给每个模块设置一个独立的域名。
server{
listen 81;
server_name search.itcast.com;
rewrite ^(.*) http://www.itcast.cn/search$1;
}
server{
listen 82;
server_name item.itcast.com;
rewrite ^(.*) http://www.itcast.cn/item$1;
}
server{
listen 83;
server_name cart.itcast.com;
rewrite ^(.*) http://www.itcast.cn/cart$1;
}
4.目录自动添加/
我们在访问的时候,如果不加/会如下:
如果加了如下:
可以看到,nginx内部会自动做一次301重定向。
#如果为on,默认localhost。如果off,默认ip。
#新版本默认都是off,旧版本默认on
server_name_in_direct on|off;
对于旧版本,怎么在末尾自动加一个/:
server {
listen 8083;
server_name localhost;
#默认是off,即我们不需要关注/的问题
#如果是旧版本,默认是on
server_name_in_redirect on;
#对于旧版本,我们通过如下方式默认给他加/
location /xupeng {
if (-d $request_filename){
rewrite ^/(.*)([^/])$ http://$host/$1$2/permanent;
}
}
location / {
root html;
index index.html index.htm;
}
}
5.合并目录
我们想让我们网站被更多人搜到,一般目录层级不超过3层。但是随着项目复杂,静态资源往往大于3层,这就是矛盾。
我们先来做一个层级复杂的页面:
然后编写配置:
server {
listen 8084;
server_name localhost;
location /server {
root html;
index index.html;
rewrite ^/server-([0-9]+)-([0-9]+)-([0-9]+)-([0-9]+)-([0-9]+)\.html$ /server/$1/$2/$3/$4/$5.html last;
}
}
测试
6.防盗链
我们前面处理防盗链是返回403,现在返回一个图片:
location /images {
valid_referers none block www.baidu.com;
if ($invalid_referer){
return ^/ /images/forbidden.png break;
}
root html;
}
三、Nginx反向代理
1.反向代理和正向代理区别
Nginx即可以实现正向代理,也可以实现反向代理。
简而言之就是正向代理代理的对象是客户端,反向代理代理的是服务端,这是两者之间最大的区别。
2.正向代理的实现
我们windows本机,外加两台虚拟机146,150先准备好。配置好nginx。
146中只做日志打印,这个时候没有代理,直连成功:
在150中做如下配置:
配置windows主机:
然后windows再次访问146,可以看到ip变成了代理的150:
3.nginx反向代理语法
Nginx反向代理模块的指令是由ngx_http_proxy_module模块进行解析,该模块在安装Nginx的时候已经自己加装到Nginx中了。
(1)proxy_pass指令
proxy_pass:该指令用来设置被代理服务器地址,可以是主机名称、IP地址加端口号形式
#写法
proxy_pass url;
#位置
location
注:关于url要不要加/,如果我们以location /server{}为例:
- 如果不加/,在做代理的时候,会请求url/server/index.html
- 如果加了/,在做代理的时候,会请求url/index.html
即:如果不加/,会加上你的请求路径。如果加了/,不加你的请求路径。
示例:
我们在146服务器之前有一个代理服务器,如果访问146,其实默认会走到150。即交互为146,干活是150。
我们在146做如下配置:
然后我们访问146的8080会进入150的首页:
(2)proxy_set_header指令
proxy_set_header:该指令可以更改Nginx服务器接收到的客户端请求的请求头信息,然后将新的请求头发送给代理的服务器
#写法
proxy_set_header field value;
#默认值
proxy_set_header Host $proxy_host;
proxy_set_header Connection close;
#位置
http、server、location
实例:
我们设置被代理服务器为150,代理服务器为146:
150:
146:
(3)proxy_redirect指令
proxy_redirect:该指令是用来重置头信息中的"Location"和"Refresh"的值。
#写法
proxy_redirect redirect replacement;
proxy_redirect default;
proxy_redirect off;
#默认值
proxy_redirect default;
#位置
http、server、location
实例:
我们设置被代理服务器为150,代理服务器为146,访问过程如下:
客户端先去访问代理服务器146,146会跳到150,如果页面不存在,150会返回150的首页给146,因为proxy_redirect 指令,所以146服务器会吧150又重定向给146的location/,但是在location/中我们又做了一次重定向,所以,返回的值是150的index,而对应的ip是146(为了防止150真实服务器的ip暴露)
150:
146:
(4)反向代理实例
我们先声明:146为代理服务器,150为被代理服务器,以ip作为区分
*1)配置150
*2)配置146
四、Nginx的安全控制
1.安全隔离
通过代理分开了客户端到应用程序服务器端的连接,实现了安全措施。在反向代理之前设置防火墙,仅留一个入口供代理服务器访问。
2.使用ssl对流量进行加密
将我们常用的http请求转变成https请求,那么这两个之间的区别简单的来说两个都是HTTP协议,只不过https是身披SSL外壳的http。http协议是明文传输数据,存在安全问题,而https是加密传输,相当于http+ssl,并且可以防止流量劫持
HTTPS是一种通过计算机网络进行安全通信的传输协议。它经由HTTP进 行通信,利用SSL/TLS建立全通信,加密数据包,确保数据的安全性。
- SSL(Secure Sockets Layer)安全套接层
- TLS(Transport Layer Security)传输层安全
3.nginx添加ssl的支持
#获取之前的配置
cd /usr/local/nginx/sbin/
./nginx -V
##########将--prefix以及后面的拷贝下来
mv nginx nginxold
#生成nginx
cd /usr/local/nginx/core/nginx-1.16.1/
./configure --prefix=/usr/local/nginx --sbin-path=/usr/local/nginx/sbin/nginx --modules-path=/usr/local/nginx/modules --conf-path=/usr/local/nginx/conf/nginx.conf --error-log-path=/usr/local/nginx/logs/error.log --http-log-path=/usr/local/nginx/logs/access.log --pid-path=/usr/local/nginx/logs/nginx.pid --lock-path=/usr/local/nginx/logs/nginx.lock --with-http_gzip_static_module --with-http_ssl_module
cd objs/
cp nginx /usr/local/nginx/sbin/
#平滑升级或者直接编译
cd ../
make upgrade 或者 make && make install
#测试
cd /usr/local/nginx/sbin/
./nginx -V
4.ssl相关指令
(1)ssl指令
ssl:该指令用来在指定的服务器开启HTTPS,可以使用 listen 443 ssl,后面这种方式更通用些。
#语法
ssl on|off;
#默认值
ssl off;
#位置
http,server
#常用写法,默认监听443端口
server{
listen 443 ssl;
}
(2)ssl_certificate指令
ssl_certificate:为当前这个虚拟主机制定一个带有PEM格式证书的证书
#语法
ssl_certificate file;
#位置
http,server
(3)ssl_certificate_key指令
ssl_certificate_key:该指令用来指定PEM secret key文件的路径
#语法
ssl_certificate_key file;
#位置
http,server
(4)ssl_session_cache指令
ssl_session_cache:该指令用来配置用于SSL会话的缓存
#语法
ssl_session_cache off|none|[builtin[:size]][shared:name:size]
#默认值
ssl_session_cache none;
#位置
http,server
值得含义:
- off:禁用会话缓存,客户端不得重复使用会话
- none:禁止使用会话缓存,客户端可以重复使用,但是并没有在缓存中存储会话参数
- builtin:内置OpenSSL缓存,仅在一个工作进程中使用
- shared:所有工作进程之间共享缓存,缓存的相关信息用name和size来指定
(5)ssl_session_timeout指令
ssl_session_timeout:开启SSL会话功能后,设置客户端能够反复使用储存在缓存中的会话参数时间
#语法
ssl_session_timeout time;
#默认值
ssl_session_timeout 5m;
#位置
http,server
(6)ssl_ciphers指令
ssl_ciphers:指出允许的密码,密码指定为OpenSSL支持的格式
#语法
ssl_ciphers ciphers;
#默认值
ssl_ciphers HIGH:!aNULL:!MD5;
#位置
http,server
ssl的密码格式如下:
(7)ssl_prefer_server_ciphers指令
ssl_prefer_server_ciphers:该指令指定是否服务器密码优先客户端密码
#语法
ssl_prefer_server_ciphers on|off;
#默认值
ssl_prefer_server_ciphers off;
#位置
http,server
5.生成ssl证书
方式一:可以直接去阿里云买。(正式环境使用这种)
方拾二:使用openssl生成正式(学习使用这种)
#查看自己是否安装openssl
openssl version
#通过openssl生成证书,期间密码之类的随便输入即可
mkdir /root/cert
cd /root/cert
openssl genrsa -des3 -out server.key 1024
openssl req -new -key server.key -out server.csr
cp server.key server.key.org
openssl rsa -in server.key.org -out server.key
openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt
6.开启ssl支持实例配置
(1)编辑配置文件
配置文件默认最后一段就是ssl,我们把注释放开,可以手动删除,也可以:
光标放在#上,先按esc,然后ctrl+v,然后按下一个个选中#,然后按d。然后改一下路径即可
server {
#开启ssl
listen 443 ssl;
server_name localhost;
#配置文件,改成我们生成证书的目录
ssl_certificate /root/cert/server.crt;
ssl_certificate_key /root/cert/server.key;
#共享一个名字叫SSL的缓存,大小1M
ssl_session_cache shared:SSL:1m;
#这个缓存有效期5分钟
ssl_session_timeout 5m;
#允许的密码格式
ssl_ciphers HIGH:!aNULL:!MD5;
#服务器密码优于客户端密码
ssl_prefer_server_ciphers on;
location / {
root html;
index index.html index.htm;
}
}
(2)测试
重新用https访问,一开始我们是直接访问不到,现在页面变成如下:
我们点击高级,继续前往。就可以看到页面了。
如果不想看到这个页面直接跳转就通过阿里云生成的证书,然后将server_name改成对应域名,并且把证书文件的路径修改一下。
但是虽然可以跳转,如果不加https还是会显示不安全,需要手动添加https://
我们可以通过rewrite ^(.*) url$1;
五、反向代理调优
1.缓冲和缓存
反向代理值Buffffer和Cache
Buffffer翻译过来是"缓冲",Cache翻译过来是"缓存。
相同点:
两种方式都是用来提供IO吞吐效率,都是用来提升Nginx代理的性能。
不同点:
- 缓冲主要用来解决不同设备之间数据传递速度不一致导致的性能低的问题,缓冲中的数据一旦此次操作完成后,就可以删除。
- 缓存主要是备份,将被代理服务器的数据缓存一份到代理服务器,这样的话,客户端再次获取相同数据的时候,就只需要从代理服务器上获取,效率较高,缓存中的数据可以重复使用,只有满足特定条件才会删除.
2.proxy_buffering指令
proxy_buffering:该指令用来开启或者关闭代理服务器的缓冲区;
#语法
proxy_buffering on|off;
#默认值
proxy_buffering on;
#位置
http、server、location
3.proxy_buffffers指令
proxy_buffffers:该指令用来指定单个连接从代理服务器读取响应的缓存区的个数和大小。
#语法
#number:缓冲区的个数
#size:每个缓冲区的大小,缓冲区的总大小就是number*size
proxy_buffers number size;
#默认值
proxy_buffers 8 4k | 8K;(与系统平台有关)
#位置
http、server、location
4.proxy_buffffer_size指令
proxy_buffffer_size:该指令用来设置从被代理服务器获取的第一部分响应数据的大小。保持与proxy_buffffers中的size一致即可,当然也可以更小。
#语法
proxy_buffer_size size;
#默认值
proxy_buffer_size 4k | 8k;(与系统平台有关)
#位置
http、server、location
5.proxy_busy_buffffers_size指令
proxy_busy_buffffers_size:该指令用来限制同时处于BUSY状态的缓冲总大小。
#语法
proxy_busy_buffers_size size;
#默认值
proxy_busy_buffers_size 8k|16K;
#位置
http、server、location
6.proxy_temp_path指令
proxy_temp_path:当缓冲区存满后,仍未被Nginx服务器完全接受,响应数据就会被临时存放在磁盘文件上,该指令设置文件路径
#语法
#注意path最多设置三层。
proxy_temp_path path;
#默认值
proxy_temp_path proxy_temp;
#位置
http、server、location
7.proxy_temp_fifile_write_size指令
proxy_temp_fifile_write_size:该指令用来设置磁盘上缓冲文件的大小
#语法
#注意path最多设置三层。
proxy_temp_file_write_size size;
#默认值
proxy_temp_file_write_size 8K|16K;
#位置
http、server、location
8.网站通用配置
proxy_buffering on;
proxy_buffer_size 4 32k;
proxy_busy_buffers_size 64k;
proxy_temp_file_write_size 64k; 1234
六、打赏请求
如果本篇博客对您有所帮助,打赏一点呗,谢谢了呢~