目录
- location 正则匹配规则
- alias 定位到其他路径访问
- log_format
- allow/deny 访问控制
- expires 浏览器的缓存
- CSRF跨站攻击
- 防盗链
- 代理服务
- 通过文件引入参数
- 负载均衡调度器slb
- 代理缓存
- 分片请求
- 动静分离
- rewrite 重写
- secure_link_module
- ngx_http_geoip_module
- https加密
- CA证书生成
- HTTPS服务优化
location 正则匹配规则
正则前缀
=
严格匹配。如果这个查询匹配,那么将停止搜索并立即处理此请求。~
为区分大小写匹配(可用正则表达式)!~
为区分大小写不匹配~*
为不区分大小写匹配(可用正则表达式)!~*
为不区分大小写不匹配^~
如果把这个前缀用于一个常规字符串,那么告诉 nginx 如果路径匹配那么不再测试是否满足其他正则表达式。
location = / {
# 只匹配 / 查询。
}
location / {
# 匹配任何查询,因为所有请求都已 / 开头。但是正则表达式规则和长的块规则将被优先和查询匹配。
}
location ^~ /images/ {
# 匹配任何以 /images/ 开头的任何查询并且停止搜索。任何正则表达式将不会被测试。
}
location ~*.(gif|jpg|jpeg)$ {
# 匹配任何以 gif、jpg 或 jpeg 结尾的请求。
}
location ~*.(gif|jpg|swf)$ {
valid_referers none blocked start.igrow.cn sta.igrow.cn;
if ($invalid_referer) {
#防盗链
rewrite ^/ http://$host/logo.png;
}
}
A location can either be defined by a prefix string
, or by a regular expression
.
Regular expressions are specified with the preceding ~*
modifier (for case-insensitive matching), or the ~
modifier (for case-sensitive matching).
To find location matching a given request
- First checks locations defined using the prefix strings (prefix locations). Among them, the location with the longest matching prefix is selected and remembered.
- Then regular expressions are checked, in the order of their appearance in the configuration file. The search of regular expressions terminates on the first match, and the corresponding configuration is used.
If no match with a regular expression is found then the configuration of the prefix location remembered earlier is used.
If the longest matching prefix location has the ^~
modifier then regular expressions are not checked.
匹配规则
- 字符串优先,长的字符串更优先,符合的话会选中并记住。(这里只是记住哦,不是就是它了 还要看正则有没有符合的 正则没有才会选择它)
- 正则表达式按顺序检查, 有符合的就停止检查并使用。没有符合的话就选择之前被记住的字符串。
- 如果字符串有
^~
那么不再检查正则表达式
(总结就是:先查字符串,有最符合的做为候选。然后按照顺序检查正则,有符合的就选中 ,没有符合的就候选字符串上。)
规则实际案例详解
location = / {
[ configuration A ]
}
location / {
[ configuration B ]
}
location /documents/ {
[ configuration C ]
}
location ^~ /images/ {
[ configuration D ]
}
location ~* \.(gif|jpg|jpeg)$ {
[ configuration E ]
}
- The “/” request will match configuration A (
原因
:首先查字符串 有一个直接严格匹配=
的A 所以A) - the “/index.html” request will match configuration B, (
原因
:首先第一个严格字符串不满足, 第二个字符串优先 而第二个字符串满足了且没有其他满足的正则表达式 所以B) - the “/documents/document.html” request will match configuration C, (
原因
:字符串C是满足的 按顺序开始检查正则 没有满足的正则 所以C ) - the “/images/1.gif” request will match configuration D, (
原因
: 字符串B满足 字符串D满足 长字符串优先 所以D ) - the “/documents/1.jpg” request will match configuration E (
原因
:C满足 正则E也满足 所以E)
alias 定位到其他路径访问
定位到其他路径访问
Syntax: alias path;
Default: —
Context: location
Defines a replacement for the specified location. For example, with the following configuration
location /i/ {
alias /data/w3/images/;
}
on request of “/i/top.gif”, the file /data/w3/images/top.gif will be sent.
log_format
$http_ + 小写的key
空格进行分割每个变量- []
都会作为字符显示
示例如下:
log_format access '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" $http_x_forwarded_for $request_filename';
allow/deny 访问控制
Syntax: allow address | CIDR | unix: | all;
Default: —
Context: http, server, location, limit_except
Syntax: deny address | CIDR | unix: | all;
Default: —
Context: http, server, location, limit_except
location ~ ^/admin.html {
root /opt/app/code;
allow 222.128.189.0/24;
deny all;
index index.html index.htm;
}
expires 浏览器的缓存
ngx_http_headers_module
配置 response 添加Cache-Control: Expires Last-Modified:头,校验缓存向服务器进行校验,客户端发送 etag、last modify,服务端文件和客户端文件比对这两个是否一致
location ~* \.(js|css|gif|jpg|jpeg|png|bmp|swf)$
{
expires 30d;
break;
}
CSRF跨站攻击
ngx_http_headers_module
什么是跨站攻击:
- 用户访问
安全网站A
, 种下了cookie - 用户误访问
危险网站B
, B网站利用客户恶意访问安全网站A,那么A网站就会遭受到攻击
Access-Control-Allow-Origin
防盗链
valid_refers
模块利用 http_refer
进行防盗链但是效果有限
valid_refer none blocked 127.0.0.1 ~/google\./
if ($invalid_refer) {
return 403;
}
代理服务
ngx_http_proxy_module
客户端无法直接访问到服务端 通过代理实现
正向代理 (为客户端服务)
应用场景:翻墙,早期的办公室上网控制
location / {
if ( $http_x_forwarded_for !~* "^116\.62\.103\.228") {
return 403;
}
root /opt/app/code;
index index.html index.htm;
}
正向代理
listen 80;
server_name localhost test.com;
#charset koi8-r;
access_log /var/log/nginx/test_proxy.access.log main;
#定义DNS server
resolver 8.8.8.8;
location / {
proxy_pass http://$http_host$request_uri;
}
反向代理 (为服务端服务)
应用场景:访问新浪,但新浪那么多服务器 ,于是就请求代理,代理发送客户端请求
通过80代理到8080端口
listen 80;
server_name localhost test.com;
location ~ /test_proxy.html$ {
proxy_pass http://127.0.0.1:8080;
}
通过文件引入参数
location / {
proxy_pass http://127.0.0.1:8080;
include proxy_params;
}
File: proxy_params 文件
proxy_redirect default;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_connect_timeout 30;
proxy_send_timeout 60;
proxy_read_timeout 60;
proxy_buffer_size 32k;
proxy_buffering on;
proxy_buffers 4 128k;
proxy_busy_buffers_size 256k;
proxy_max_temp_file_size 256k;
负载均衡调度器slb
优势:可以提高容灾能力 。(配置在http下而不是server下)
gslb
全局负载均衡范围大:国家级,省级slb
普通的负载均衡
指令 | 释义 |
---|---|
down | 当前的server暂时不参与负载均衡 |
backup | 预留的备份服务器 |
max_fails | 允许请求失败的次数 |
fail_timeout | 经过mac_fails失败后,服务暂停的时间 |
max_conns | 限制最大的接受的连接数 |
#默认轮询配置的服务器
upstream anna {
server 116.62.103.228:8001 down;
server 116.62.103.228:8002 backup;
server 116.62.103.228:8003 max_fails=1 fail_timeout=10s;
}
轮询策略 - 调度算法
指令 | 释义 |
---|---|
轮询 | 按时间顺序逐一分配到不同的后端服务器 |
加权轮询 | weight值越大,分配到的访问几率越高 |
ip_hash | 按访问IP的hash结果分配,同一个IP的固定访问一个后端服务器 |
url_hash | 按访问的URL的hash结果分配,同一个URL的固定访问一个后端服务器 |
least_conn | 哪个服务器的连接数少就哪个机器 |
hash关键数值 | hash自定义的key |
1.加权轮询
upstream imooc {
server 116.62.103.228:8001;
server 116.62.103.228:8002 weight=5;
server 116.62.103.228:8003;
}
2.ip_hash
upstream anna {
ip_hash;
server 116.62.103.228:8001;
server 116.62.103.228:8002;
server 116.62.103.228:8003;
}
3.url_hash
upstream anna {
hash $request_uri;
server 116.62.103.228:8001;
server 116.62.103.228:8002;
server 116.62.103.228:8003;
}
代理缓存
http:
upstream imooc {
hash $request_uri;
server 116.62.103.228:8001;
server 116.62.103.228:8002;
server 116.62.103.228:8003;
}
proxy_cache_path /opt/app/cache levels=1:2 keys_zone=imooc_cache:10m max_size=10g inactive=60m use_temp_path=off;
server:
location / {
proxy_cache imooc;
proxy_pass http://imooc;
proxy_cache_valid 200 304 12h;
proxy_cache_valid any 10m; //200 304以外的 10分钟过期
proxy_cache_key $host$uri$is_args$args;
add_header Nginx-Cache "$upstream_cache_status";
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504; //遇到这些情况的话 自动到下一个服务器
include proxy_params;
}
分片请求
The ngx_http_slice_module module (1.9.8) is a filter that splits a request into subrequests, each returning a certain range of response. The filter provides more effective caching of big responses.
下载文件断掉的话还可以继续防止文件句柄消耗过多
动静分离
动态请求(php jsp)和静态请求(jpg png)进行分离
upstream java_api{
server 127.0.0.1:8080;
}
server {
listen 80;
server_name localhost;
#charset koi8-r;
access_log /var/log/nginx/log/host.access.log main;
root /opt/app/code;
//动态请求
location ~ \.jsp$ {
proxy_pass http://java_api; //这里的java_api 就是上面的upstream
index index.html index.htm;
}
//静态请求
location ~ \.(jpg|png|gif)$ {
expires 1h;
gzip on;
}
rewrite 重写
Syntax : rewrite regex replacement [flag];
Default: —
Context: server, location, if
rewrite优先级:server > location
Flag | 释义 | 具体 |
---|---|---|
last | 停止rewrite检测 | 重新建立新的请求,请求rewrite后的地址 |
break | 停止rewrite检测 | 直接在程序路径是否存在 |
redirect | 返回302临时重定向 | 客户端会记住重定向,下次访问时会直接访问重定向之后的地址 |
permanent | 返回301永久重定向 | 客户端仍然会访问原有地址,访问服务器,然后跳转都重定向的地址 |
location / {
rewrite ^/course-(\d+)-(\d+)-(\d+)\.html$ /course/$1/$2/course_$3.html break;
if ($http_user_agent ~* Chrome) {
rewrite ^/nginx http://anna.com/class/121.html redirect;
}
#$request_filename文件路径
if (!-f $request_filename) {
rewrite ^/(.*)$ http://www.baidu.com/$1 redirect;
}
index index.html index.htm;
}
secure_link_module
Syntax: secure_link expression;
Default: —
Context: http, server, location
Syntax: secure_link_md5 expression;
Default: —
Context: http, server, location
生成URL的脚本
#!/bin/sh
servername="jeson.t.imooc.io"
download_file="/download/file.img"
time_num=$(date -d "2018-10-18 00:00:00" +%s)
secret_num="imoocc"
res=$(echo -n "${time_num}${download_file} ${secret_num}"|openssl md5 -binary | openssl base64 | tr +/ -_ | tr -d =)
echo "http://${servername}${download_file}?md5=${res}&expires=${time_num}"
Nginx配置
location / {
secure_link $arg_md5,$arg_expires; //取参数名为md5 和 expires 的值
secure_link_md5 "$secure_link_expires$uri imooc"; //加密验证 imooc是加密字符串
if ($secure_link = "") {
return 403;
}
if ($secure_link = "0") {
return 410;
}
}
ngx_http_geoip_module
读取地域信息: 国内、国外区分,城市地域区分,对地域进行rewrite重写配置
geoip_country /etc/nginx/geoip/GeoIP.dat;
geoip_city /etc/nginx/geoip/GeoLiteCity.dat;
server {
location / {
if ($geoip_country_code != CN) {
return 403;
}
root /usr/share/nginx/html;
index index.html index.htm;
}
location /myip {
default_type text/plain;
return 200 "$remote_addr $geoip_country_name $geoip_country_code $geoip_city";
}
https
为什么需要HTTPS:
- HTTP不安全
- 传输数据被中间人盗用、信息泄露
- 数据内容劫持、篡改
名称 | 释义 |
---|---|
对称加密 | 加密秘钥、解密秘钥相同 |
非对称 | 加解密秘钥不同:发送方公钥,接收方私钥 |
CA证书生成
命令:openssl
- 生成key密钥
- 生成证书签名请求文件(csr文件)
- 生成证书签名文件(ca文件)
openssl genrsa -idea -out jesonc.key 1024
openssl req -new -key jesonc.key -out jesonc.csr
openssl x509 -req -days 3650 -in jesonc.csr -signkey jesonc.key -out jesonc.crt
server
{
listen 443;
server_name jeson.t.imooc.io;
ssl on;
ssl_certificate /etc/nginx/ssl_key/jesonc.crt;
ssl_certificate_key /etc/nginx/ssl_key/jesonc.key;
index index.html index.htm;
location / {
root /opt/app/code;
}
}
满足苹果要求的证书类型
openssl req -days 36500 -x509 -sha265 -nodes -newkey rsa:2048 -keyout jesonc.key -out jesonc_apple.crt
HTTPS服务优化
- 激活keepalive长连接
- 设置ssl session 缓存
server
{
listen 443;
server_name 116.62.103.228 jeson.t.imooc.io;
keepalive_timeout 100;
ssl on;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
#ssl_certificate /etc/nginx/ssl_key/jesonc.crt;
ssl_certificate /etc/nginx/ssl_key/jesonc_apple.crt;
ssl_certificate_key /etc/nginx/ssl_key/jesonc.key;
#ssl_certificate_key /etc/nginx/ssl_key/jesonc_nopass.key;
index index.html index.htm;
location / {
root /opt/app/code;
}
}
server{
#listen 443 ssl http2;
listen 443 ssl ;
server_name test.geagle.xx.com;
index index.html;
root /home/wwwroot/dist;
# ssl on;
ssl_certificate /usr/local/nginx/ssl/_.xx.com.crt;
ssl_certificate_key /usr/local/nginx/ssl/_.xx.com.key;
ssl_session_timeout 10m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_session_cache builtin:1000 shared:SSL:10m;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:AES256+EECDH:AES256+EDH;
location ~ /login {
proxy_pass http://localhost:8070;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location ~ /logout {
proxy_pass http://localhost:8070;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location ^~ /cdn {
proxy_pass https://oss-xx.cn/xxx-front/xx/xx/1.1.5;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location /home {
add_header Cache-Control no-cache;
add_header Pragma no-cache;
add_header Expires 0;
rewrite ^/home/(.*)/ /cdn/index.html permanent;
}
location /geagle/static {
add_header Cache-Control no-cache;
add_header Pragma no-cache;
add_header Expires 0;
proxy_pass https://oss-zz-zzt.yun.xx-inc.cn/geagle-front/ych/home/1.1.5;
#proxy_pass https://oss-zz-zzt.yun.xx-inc.cn/geagle-front/ych/home/hotfix;
#proxy_pass https://oss-sh-shyc3.yun.xx-inc.cn/geagle-front-online/ych/home/v1.1.3;
}
location / {
include /etc/nginx/conf.d/deny_spider.config;
add_header Cache-Control no-cache;
add_header Pragma no-cache;
add_header Expires 0;
rewrite / /cdn/index.html;
}
location = /api/search {
limit_req zone=perip_search;
limit_req_status 429;
rewrite /api(.*) /api/v1$1 break;
proxy_set_header X-real-ip $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
include uwsgi_params;
uwsgi_pass 127.0.0.1:8070;
proxy_pass http://127.0.0.1:8070;
}
location = /api/aggregate/statistical {
limit_req zone=perip_agg;
limit_req_status 429;
rewrite /api(.*) /api/v1$1 break;
proxy_set_header X-real-ip $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
include uwsgi_params;
uwsgi_pass 127.0.0.1:8070;
proxy_pass http://127.0.0.1:8070;
}
location ^~ /api/region {
rewrite /api(.*) /api/v1$1 break;
proxy_set_header X-real-ip $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
include uwsgi_params;
uwsgi_pass 127.0.0.1:8099;
proxy_pass http://127.0.0.1:8099;
}
location ~ /api {
include /etc/nginx/conf.d/deny_spider.config;
rewrite /api(.*) /api/v1$1 break;
proxy_set_header X-real-ip $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
include uwsgi_params;
uwsgi_pass 127.0.0.1:8070;
proxy_pass http://127.0.0.1:8070;
}
location ~ /openApi {
rewrite /openApi(.*) /openApi/v1$1 break;
proxy_set_header X-real-ip $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
include uwsgi_params;
uwsgi_pass 127.0.0.1:8070;
proxy_pass http://127.0.0.1:8070;
}
location /favicon.ico {
root /home/wwwroot/dist;
}
error_page 404 /404.html;
location = /40x.html {
root /opt/tip/web_test/dist/template;
index 404.html;
}
error_page 429 =200 /dealwith_429;
location = /dealwith_429{
set $ret_body '{"code": "429","msg": "Too Many Requests"}';
return 200 $ret_body;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
access_log /var/log/nginx/cc/access.log;
error_log /var/log/nginx/cc/error.log;
}