写在最开始的话,转载请标明出处:创客花园( http://www.ourgarden.cn/慕课网nginx视频学习笔记/ ),谢谢
视频中的代码下载: 慕课网Nginx视频代码
基于Nginx的中间件架构
第一章 课程前言
总体来说就是能获得能多东西,值得学习,也都配套带有实际的演示,在这里,我尽力保存了视频中所有演示的配置信息和扩展的内容,以期能够做到事无巨细
基于centos7学习nginx的慕课网视频教学的笔记总结,内容尽可能详细,涵盖了常用的nginx配置与系统安全配置相关的内容,主要用于运维服务相关,安全和web application firewall(Lua)的内容,后期会不断做出实践的文章整理出来
环境
- 确认系统网络
- 确认yum可用
- 确认关闭iptables规则
- 确认停用selinux
安装
yum -y install gcc gcc-c++ autoconf pcre pre-devel make automake
yum -y install wget httpd-tools vim
初始化
cd /opt;
mkdir app download logs work backup
iptables
iptables -F
iptables -L
iptable -t nat -L
iptable -t nat -F
getenforce
setenforce 0
第二章 基础篇
- 快速安装
- 配置语法
- 默认模块
- Nginx的log
- 访问限制
- Http的请求
- 请求限制与连接限制
- access模块配置语法
- 请求限制局限性
- 基本安全认证
- auth模块配置语法
- 安全认证局限性
Nginx的特点
- IO多路复用epoll
- 轻量级
- CPU亲和(affinity)
- sendfile
Nginx搭建
- Mainline version 开发版
- Stable version 稳定版
- Legacy version 历史版
目录
- 安装目录
rpm -ql nginx
/etc/lograte.d/nginx 日志
/etc/nginx 目录、配置文件
/etc/nginx/fastcgi_params cgi配置
/etc/nginx/mime.types 配置文件,类型扩展
/var/cache/nginx 缓存目录
/var/log/nginx 日志目录
- 编译参数
nginv -V
--user=nginx
--group=nginx
--with-cc-opt=parameters
--with-ld-opt=parameters
- 基本配置语法
/etc/nginx/nginx.conf
/etc/nginx/conf.d/*.conf
user # 设置nginx服务的系统使用用户
worker_processes # 工作进程数
error_log # nginx的错误日志
pid # nginx服务启动时候pid
events # worker_connects 每个进程允许最大连接数
events use # 工作进程数
http {
server {
listen 80;
server_name localhost;
location / {
root path;
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root path;
}
}
}
默认配置与默认站点启动
可以寻找相关的配置介绍文档
Http请求
request 请求行、请求头部请求数据
response 状态行、消息报头、响应正文
日志
error_log
access_log
log_format:
syntax: log_format name [escape=default|json] string ...;
Default: log_format combined "...";
Context:http
变量:
HTTP请求变量 - arg_PARAMETER、http_HEADER、sent_http_HEADER
内置变量 - Nginx内置变量 nginx.org
自定义变量 - 自定义
常用内置变量
$remote_addr
$remote_user
$time_local
$request
$status
$body_bytes_sent
$http_referer
$http_user_agent
$http_x_forwarded_for
Nginx模块讲解
Nginx官方模块
第三方模块
http_stub_status_module
Nginx的客户端状态
Syntax : stub_status;
Default : -
Context : server, location
random_index
目录中选择一个随机主页
Syntax : random_index on|off;
Default : random_index off;
Context : location
sub
HTTP内容替换
Syntax : sub_filter string replacement;
Default : -;
Context : http, server, location
Syntax : sub_filter_last_modified on | off;
Default : sub_filter_last_modified off;
Context : http, server, location
Syntax : sub_filter_once on | off;
Default : sub_filter_once on;
Context : http, server, location
Nginx请求限制
连接频率限制 - limit_conn_module
Syntax : limit_conn_zone key
zone=name:size;
Default : -
Context : http
Syntax : limit_conn zone number;
Default : -
Context : http, server, location
请求频率限制 - limit_req_module
Syntax : limit_req_zone key
zone=name:size rate=rate;
Default : -
Context : http
Syntax : limit_req zone=name [burst=number] [nodelay];
Default : -
Context : http, server, location
demo:
limit_conn_zone $binary_remote_addr zone=conn_zone:1m;
limit_req_zone $binary_remote_addr zone=req_zone:1m rate=1r/s;
location / {
root path;
#limit_conn conn_zone 1;
#limit_req zone=req_zone burst=3 nodelay;
#limit_req zone=req_zone burst=3;
#limit_req zone=req_zone;
}
Nginx的访问控制
基于IP的访问控制 - http_access_module
Syntax : allow address | CIDR | unin: | all;
Default : -
Context : http, server, location, limit_except
Syntax : deny address | CIDR | unin: | all;
Default : -
Context : http, server, location, limit_except
demo:
location ~ ^/admin.html {
root path;
deny ipaddress/24;
allow all;
index index.html index.htm;
}
问题:http_access_module的局限性,限制是基于IP的,如果是通过代理就没办法限制了,可通过http_x_forwarded_for,结合geo模块,通过http自定义变量传递来处理
http_x_forwarded_for = Client IP, proxy(1) IP, proxy(2) IP
基于用户的信任登录 - http_auth_basic_module
Syntax : auth_basic string | off;
Default : auth_basic off;
Context : http, server, location, limit_except
Syntax : auth_basic_user_file file;
Default : -
Context : http, server, location, limit_except
file方式可以采用 htpasswd (在httpd-tools安装包中) 的方式进行加密
htpasswd -c ../auth_conf username
demo:
location ~ ^/admin.html {
root path;
auth_basic "pls input you auth!";
auth_basic_user_file /etc/nginx/auth_conf;
index index.html index.htm;
}
问题:http_auth_basic_module存在用户信息依赖文件方式、操作管理机械效率低下的局限性,可通过Nginx结合Lua实现高效验证、Nginx和LDAP打通,利用Nginx-auth_ldap模块
第三章 场景实践篇
- 静态资源web服务
- 什么是静态资源
- 静态资源服务场景
- 静态资源服务配置
- 客户端缓存
- 静态资源压缩
- 防盗链
- 跨域访问
- 代理服务
- 负载均衡调度器SLB
- 动态缓存服务
静态资源web服务
静态资源类型
类型 | 种类 |
---|---|
浏览器端渲染 | html css js |
图片 | jpeg gif png |
视频 | flv mpeg mp4 |
文件 | txt 其他后缀文件 |
静态资源服务场景-CDN
配置语法--文件读取
Syntax : sendfile on | off;
Default : sendfile off;
Context : http, server, location, if in location
深入拓展: --with-file-aio 异步文件读取
配置语法 - tcp_nopush
Syntax : tcp_nopush on | off;
Default : tcp_nopush off;
Context : http, server, location
作用: sendfile开启的情况下,提高网络包的传输效率
配置语法- tcp_nodelay
Syntax : tcp_nodelay on | off;
Default : tcp_nodelay on;
Context : http, server, location
作用: keepalive连接下,提高网络包的传输实时性
配置语法 - 压缩
Syntax : gzip on | off;
Default : gzip off;
Context : http, server, location, if in location
Syntax : gzip_comp_level level;
Default : gzip_comp_level 1;
Context : http, server, location
Syntax : gzip_http_version 1.0 | 1.1;
Default : gzip_http_version 1.1;
Context : http, server, location
扩展Nginx压缩模块
- http_gzip_static_module - 预读gzip功能
- http_gunzip_module - 应用支持gunzip的压缩方式
demo:
sendfile on;
location ~ .*\.(jpg|gif|png)$ {
gzip on;
gzip_http_version 1.1;
gzip_comp_level 2;
gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png;
root path;
}
location ~ .*\.(txt|html)$ {
gzip on;
gzip_http_version 1.1;
gzip_comp_level 2;
gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png;
root path;
}
location ~ ^/download {
gzip_static on;
tcp_nopush on;
root path;
}
浏览器缓存
http协议定义的缓存机制(如: Expires ; Cache-control等)
浏览器无缓存
客户端有缓存
客户端校验过期机制
校验是否过期 | Expires、Cache-Control (max-age) |
---|---|
协议中Etag头信息校验 | Etag |
Last-Modified头信息校验 | Last-Modified |
浏览器缓存配置语法 - Expires
添加Cache-Control、Expires头
Syntax : expires [modified] time;
expires epoch | max | off;
Default : expires off;
Context : http, server, location, if in location
demo:
location ~ .*\.(html|htm)$ {
expires 24h;
root path;
}
跨站访问
Access-Control-Allow-Origin
Syntax : add_header name value [always];
Default : -
Context : http, server, location, if in location
demo:
location ~ .*\.(html|htm) {
add_header Access-Control-Allow-Origin http://domain;
add_header Access-Control-Allow-Methods GET,POST,PATCH,PUT,DELETE,OPTIONS;
}
防盗链
http_refer 防盗链配置模块
Syntax : valid_referers none | blocked | server_names | string ...;
Default : -
Context : server, location
demo:
location ~ .*\.(jpg|jpeg|png)$ {
# ip可用正则匹配 ~/google\./
valid_referers none blocked ip;
if ($invalid_referer) {
return 403;
}
root path;
}
代理服务
代理简图
正向代理
通过代理去访问外网,对象是客户端
反向代理
通过代理去访问对应的服务,对象是服务端
代理配置语法
Syntax : proxy_pass URL;
Default : -
Context : location, if in location, limit_except
demo:
# 反向代理
location ~ /test.html$ {
proxy_pass http://ip:8080/test.html;
}
# 正向代理
location / {
if ($http_x_forwarded_for !~* "^116\.62\.103\.228") {
return 403;
}
root path;
index index.html index.htm;
}
# 在指定机器上的配置
resolver 8.8.8.8;
location / {
proxy_pass http://$http_host$request_uri;
}
代理缓冲区的配置
Syntax : proxy_buffering on | off;
Default : proxy_buffering on;
Context : http, server, location
扩展: proxy_buffer_size、 proxy_buffers、 proxy_busy_buffers_size
跳转重定向
Syntax : proxy_redirect default;
proxy_redirect off;
proxy_redirect redirect replacement;
Default : proxy_redirect default;
Context : http, server, location
代理头信息
Syntax : proxy_set_header field value;
Default : proxy_set_header Host $proxy_host;
proxy_set_header Connection close;
Context : http, server, location
扩展: proxy_hide_header、proxy_set_body
超时
Syntax : proxy_connection_timeout time;
Default : proxy_connect_timeout 60s;
Context : http, server, location
扩展: proxy_read_timeout、 proxy_send_timeout
demo:
location / {
proxy_pass http://127.0.0.1:8080;
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;
# include proxy_params;
}
扩展: 可采用include的方式包含进去proxy_params
负载均衡
调度中心和应用服务中心
GSLB和SLB
SLB分为四层负载均衡和七层负载均衡
配置负载均衡语法 upstream server
Syntax : upstream name {...};
Default : -
Context : http
demo:
upstream imooc {
server ip1:port;
server ip2:port;
server ip3:port;
}
server {
...
location / {
# imooc为上面配置的upstream name
proxy_pass http://imooc;
include proxy_params;
}
}
扩展延申:iptables
upstream扩展延申
upstream name {
server backend1.example.com weight=5;
server backend2.example.com:8080;
server unix:/tmp/backend3;
server backup1.example.com:8080 backup;
server backup2.example.com:8080 backup;
}
upstream后面的关键字
关键字 | 内容 |
---|---|
down | 当前的server暂时不参与负载均衡 |
backup | 预留的备份服务器 |
max_fails | 允许请求失败的次数 |
fail_timeout | 经过max_fails失败后,服务暂停的时间 |
max_conns | 限制最大的接收的连接数 |
backup状态
demo:
upstream back {
server ip1:port down;
server ip2:port backup;
server ip3:port max_fails=1 fail_timeout=30;
}
轮询策略与加权轮询
调度算法
轮询方式 | 轮询内容 |
---|---|
轮询 | 按时间顺序逐一分配到不同的后端服务器 |
加权轮询 | weight值越大,分配到的访问几率越大 |
ip_hash | 每个请求按访问IP的hash结果分配,这样来自同一个IP的固定访问一个后端服务器 |
least_conn | 最少连接数,哪个机器的连接数少就分发 |
url_hash | 按照访问的URL的hash结果来分配请求,是每个URL定向到同一个后端服务器 |
hash关键数值 | hash自定义的key |
url_hash/hash关键字
This directive appeared in version 1.7.2
Syntax : hash key [consistent];
Default : -
Context : upstream
demo:
upstream name {
hash $request_uri;
server ip1:port;
server ip2:port;
server ip3:port;
}
Nginx做缓存服务
服务端缓存 memcache/redis
代理缓存 Nginx
客户端缓存 浏览器缓存
缓存配置 proxy_cache
Syntax : proxy_cache_path path [levels=levels] [use_temp_path=on|off] keys_zone=name:size [inactive=time] [max_size=size] [manager_files=number] [manager_sleep=time] [manager_threshold=time] [loader_files=number] [loader_sleep=time] [loader_threshold=time] [purger=on|off] [purger_files=number] [purger_sleep=time] [purger_threshold=time];
Default : -
Context : http
Syntax : proxy_cache zone | off;
Default : proxy_cache off;
Context : http, server, location
缓存过期周期和缓存维度配置
Syntax : proxy_cache_valid [CODE ...] time;
Default : -
Context : http, server, location
Syntax : proxy_cache_key string;
Default : proxy_cache_key $scheme$proxy_host$request_uri;
Context : http, server, location
demo:
proxy_cache_path path levels=1:2 keys_zone=imooc_cache:10m max_size=10g inactive=60m use_temp_path=off;
server {
...
location / {
proxy_cache imooc_cache;
proxy_pass http://upstreamname;
proxy_cache_valid 200 304 12h;
proxy_cache_valid any 10m;
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;
}
}
如何清理指定缓存
rm -rf 缓存目录内容
第三方扩展模块ngx_cache_module
如何让部分页面不缓存
Syntax : proxy_no_cache string ...;
Default : -
Context : http, server, location
demo:
proxy_cache_path path levels=1:2 keys_zone=imooc_cache:10m max_size=10g inactive=60m use_temp_path=off;
server {
...
# 增加的部分
if ($request_uri ~ ^/(url3|login|register|password\/reset)) {
set $cookie_nocache 1;
}
location / {
proxy_cache imooc_cache;
proxy_pass http://upstreamname;
proxy_cache_valid 200 304 12h;
proxy_cache_valid any 10m;
proxy_cache_key $host$uri$is_args$args;
# 增加的部分
proxy_no_cache $cookie_nocache $arg_nocache $arg_comment;
proxy_no_cache $http_pragma $http_authorization;
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;
}
}
分片请求
大文件分片请求的优势:每个子请求收到的数据都会形成一个独立文件,一个请求断了,其他请求不受影响
缺点:当文件很大或者slice很小的时候,可能会导致文件描述符耗尽等情况
Syntax : slice size;
Default : slice 0;
Context : http, server, location
第四章 深度学习篇
- 动静分离
- rewrite规则
- 进阶模块配置
- Https服务
- Https协议
- 配置语法
- Nginx的Https服务
- 苹果要求的https服务
- Nginx与Lua开发
动静分离
通过中间件将动态请求和静态请求分离
分离资源,减少不必要的请求消耗,减少请求延时
demo:
upstream php_api {
server ip:port;
}
server {
...
location ~ \.php$ {
proxy_pass http://php_api;
index index.html index.htm;
}
location ~ \.(jpg|png|gif) {
expires 1h;
gzip on;
}
}
rewrite规则
- url 访问跳转,支持开发设计
- SEO优化
- 维护
- 安全
rewrite 配置语法
Syntax : rewrite regex replacement [flag];
Default : -
Context : server, location, if
demo:
# 重定向维护页面
rewrite ^(.*)$ /pages/maintain.html break;
正则表达式
转移字符 \
rewrite index\.php$ /pages/maintain.html break;
小括号,用于匹配括号之间的内容,通过$1, $2调用
if ($http_user_agent ~ MSIE) {
rewrite ^(.*)$ /msie/$1 break;
}
正则表达式终端测试命令 pcretest
demo:
/(\d+)\.(\d+)\.(\d+).(\d+)/
flag 标签
demo:
location ~ ^/break {
rewrite ^/break /test/ break;
}
location ~ ^/last {
#rewrite ^/last /test/ last;
rewrite ^/last /test/ redirect;
rewrite ^/last /test/ perganment;
}
location /test/ {
default_type application/json;
return 200 '{"status":"success"}';
}
location / {
rewrite ^/course-(\d+)-(\d+)-(\d+)\.html$ /course/$1/$2/course_$3.html break;
if ($http_user_agent ~* Chrome) {
rewrite ^/nginx http://domain/class/code.html break;
}
if (!-f $request_filename) {
rewrite ^/(.*)$ http://domain/$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
验证流程
demo:
location / {
secure_link $arg_md5,$arg_expires;
secure_link_md5 "$secure_link_expires$uri imooc";
if ($secure_link = "") {
return 403;
}
if ($secure_link = "0") {
return 410;
}
}
geoip_module模块
基于IP地址匹配MaxMind GeoIP 二进制文件,读取IP所在地域信息
yum install nginx-module-geoip在nginx.conf中加载
load_module "modules/ngx_http_geoip_module.so";
load_module "modules/ngx_stream_geoip_module.so";去maxmind下载Country/City的数据并解压到 /etc/nginx/geoip目录下
在http的配置模块下加载下面的信息
geoip_country /etc/nginx/geoip/GeoIP.dat;
geoip_city /etc/nginx/geoip/GeoLiteCity.dat;
http_geoip_module
- 区别国内国外的请求
- 区别国内城市的请求
demo:
location / {
if ($geoip_country_code != CN) {
return 403;
}
root path;
index index.html index.htm;
}
location /myip {
default_type text/plain;
return 200 "$remote_addr $geoip_country_name $geoip_country_code $geoip_city";
}
扩展,maxmind是否可以使用其他语言来进行二次开发?那网上那些获得IP的sdk岂不是很容易实现?可以尝试
HTTPS原理和作用
对称加密和非对称加密
证书签名生成CA证书
- openssl version
- nginx -v ( --with-http_ssl_module )
- 生成 key 密钥
- 生成证书签名请求文件( csr文件 )
- 生成证书签名文件( CA文件 )
# create a director ssl_key to save files
mkdir /etc/nginx/ssl_key
cd /etc/nginx/ssl_key
# generate a key file with phrase
openssl genrsa -idea -out name.key 1024
# input phrase: **** get name.key
# generate a csr file with name.key by phrase
openssl req -new -key name.key -out name.csr
# input phrase: ****
# input some message for u
# get CA file
# 3650 is expires time
openssl x509 -req -days 3650 -in name.csr -signkey name.key -out name.crt
Syntax : ssl on | off;
Default : ssl off;
Context : http, server
Syntax : ssl_certificate file;
Default : -
Context : http, server
Syntax : ssl_certificate_key file;
Default : -
Context : http, server
demo:
server {
listen 443;
server_name domain;
ssl on;
ssl_certificate /etc/nginx/ssl_key/name.crt;
ssl_certificate_key /etc/nginx/ssl_key/name.key;
location / {
root path;
index index.html index.htm;
}
}
苹果要求的openssl后台https服务
- 服务器所有的连接使用TLS1.2以上版本
- HTTPS证书必须使用SHA256以上哈希算法签名
- HTTPS证书必须使用RSA 2048位或ECC 256位以上公钥算法
- 使用前向加密技术
# get openssl version to TLS1.2
openssl version
# update openssl version
# ...
# check the crt file
openssl x509 -noout -text -in ./name.crt
# enter the dir
cd /etc/nginx/ssl_key
# generate the key and crt file
openssl req -days 36500 -x509 -sha256 -nodes -newkey rsa:2048 -keyout name.key -out name.crt
HTTPS服务优化
- 激活keepalive长连接
- 设置ssl session缓存
demo:
server {
listen 443;
server_name domain;
keepalive 100;
ssl on;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
ssl_certificate /etc/nginx/ssl_key/name.crt;
ssl_certificate_key /etc/nginx/ssl_key/name.key;
location / {
root path;
index index.html index.htm;
}
}
Nginx与Lua开发
充分的结合Nginx的并发处理epoll优势和Lua的轻量实现简单的功能切高并发的场景
很激动啊,学过几年的Lua,终于有好地方使用了
Lua及基础语法
安装
yum install lua
demo:
#!/usr/bin/lua
print("I'm json")
-- 行注释
--[[
块注释
]]
-- 变量是弱变量类型的
-- 布尔类型只有nil和false是false,数字0、空字符串"",'\0',都是true
-- lua中的变量如果没有特殊说明,全是全局变量
-- while
while num 60 and sex ~= "Female" then
print("非女人而且大于60")
else
local age = io.read()
print("your age is "..age)
end
Nginx与Lua环境
LuaJIT是Lua解释器
ngx_devel_kit 和 lua-nginx-module
重新编译Nginx
https://www.imooc.com/article/19597
Nginx调用Lua模块指令
Nginx Lua API
灰度发布
按照一定的关系区别,分部分的代码进行上线,使代码的发布能平滑过度上线
- 用户的信息cookie等信息区别
- 根据用户的IP地址
memcached -p 11211 -u nobody -d
demo:
location /hello {
default_type 'text/plain';
content_by_lua 'ngx.say("hello,lua")'
}
location /myip {
default_type 'text/plain';
content_by_lua '
clientIP = ngx.req.get_headers()["x_forwarded_for"]
ngx.say("IP:",clientIP)
';
}
location / {
default_type "text/html";
content_by_lua_file /opt/app/lua/dep.lua;
add_after_body "$http_x_forwarded_for";
}
location @server {
proxy_pass http://server:port;
}
location @server_test {
proxy_pass http://server_test:port;
}
-- /opt/app/lua/dep.lua
clientIP = ngx.req.get_headers()["X-Real-IP"]
if clientIP == nil then
clientIP = ngx.req.get_headers()["x_forwarded_for"]
end
if clientIP == nil then
clientIP = ngx.var.remote_addr
end
local memcached = require "restry.memcached"
local memc,err = memcached:new()
if not memc then
ngx.say("failed to instantiate memc:",err)
return
end
local ok,err = memc:connect("127.0.0.1",11211)
if not ok then
ngx.say("failed to connect:",err)
return
end
local res,flags,err = memc:get(clientIP)
ngx.say("value key:",res,clientIP)
if err then
ngx.say("failed to get clientIP",err)
return
end
if res == "1" then
ngx.exec("@server_test")
return
end
ngx.exec("@server")
第五章 Nginx架构篇
- 常见问题
- Nginx中间件性能优化
- 如何调适性能优化
- 性能优化影响因素
- 操作系统性能优化
- Nginx性能优化
- Nginx与安全
- 新版本特性
- 中间件架构设计
Nginx常见问题
- 相同server_name多个虚拟主机优先级访问
优先读取的配置作为优先级判定条件 -
location匹配优先级(根据匹配精确度)
= 进行普通字符精确匹配,也就是完全匹配
^~ 表示普通字符匹配,使用前缀匹配
~ \ ~* 表示执行一个正则匹配()
demo:
location = /code1/ {
rewrite ^(.*)$ /code1/index.html break;
}
location ~ /code.* {
rewrite ^(.*)$ /code3/index.html break;
}
location ^~ /code {
rewrite ^(.*)$ /code2/index.html break;
}
- try_files使用
按顺序检查文件是否存在
Syntax:
location / {
try_files $uri $uri/ /index.php;
}
demo:
location / {
root path;
try_files $uri $uri/ @java_page;
}
location @java_page {
proxy_pass http://domain:port;
}
- Nginx的alias和root区别
demo:
location /request_path/image/ {
root /local_path/image/;
}
# 假设访问 http://domain/request_path/image/image.png
# 实际访问 /local_path/image/request_path/image/image.png
# 即为 rootpath + requestpath
location /request_path/image/ {
alias /local_path/image/;
}
# 假设访问 http://domain/request_path/image/image.png
# 实际访问 /local_path/image/image.png
# 即为 aliaspath + filename
- 用什么方法传递用户的真实IP
set x_real_ip = $remote_addr;
- 其他
Nginx : 413 Request Entity Too Large ----> 用户上传文件限制 clinet_max_body_size
502 bad gateway ----> 后端服务无响应
504 Gateway Time-out ----> 后端服务执行超时
Nginx性能优化
- 性能优化考虑点
- 当前系统结构瓶颈:观察指标、压力测试
- 了解业务模型: 接口业务类型、系统层次化结构
- 性能与安全
- 压测工具ab
- 安装: yum install httpd-tools
- 使用: ab -n 总的请求数 -c 并发数 [-k 是否开启长连接] http://domain:port
- 系统与Nginx性能优化
网络、系统(负载、磁盘、稳定性)、服务(http请求的优化)、程序、数据库、底层服务
3.1 文件句柄,linux\unix一切皆文件,文件句柄就是一个索引
3.2 设置方式,系统全局修改,用户局部性修改,进程局部修改
修改/etc/security/limits.conf
root soft nofile 65535(一万左右比较合理)
root hard nofile 65535(一万左右比较合理)
* soft nofile 25535
* hard nofile 25535
nginx.conf中 worker_rlimit_nofile 35535;
3.3 CPU的亲和
worker_processes 2; # cpu核心数
worker_cpu_affinity 01 10; #这个后面的数据是跟核心有关的,有几个就有几位,假设有三个就是 001 010 100;以此类推
可以通过 ps -eo pid,args,psr | grep [n]ginx 查看CPU哪一个
worker_cpu_affinity 10 01;
worker_cpu_affinity auto; # 自动
nginx.conf详解
user nginx; # 设置程序使用用户
worker_processes 16; # 使用的CPU核心数
worker_cpu_affinity auto; # 自动分配进程所处核心
error_log /var/log/nginx/error.log warn; # 日志位置和级别
pid /var/run/nginx.pid; # 进程文件
worker_rlimit_nofile 35535;# 文件句柄数,一般在一万左右就可以了,要求高的可以设置高一点,不超过65535
events {
use epoll; # linux连接模型
worker_connects 10240; # 每个进程使用工作连接
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
#########
# Charset
charset utf-8; # 字符集
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "http_referer"'
'"$http_user_agent" "$http_x_forwarded_for" "$request_uri"';
# access_log off; # 关闭日志
access_log /var/log/nginx/access.log main;
##########
# Core module
sendfile on;
# tcp_nopush on; # 静态服务器建议打开
# tcp_nodeny on; # 动态接口建议打开,需要配合keepalive打开才行
keepalive_timeout 65;
###########
# Gzip module
gzip on;
gzip_disable "MSIE [1-6]\."; # 兼容IE6
gzip_http_version 1.1;
##########
# Virtual Host Server
include /etc/nginx/conf.d/*.conf;
}
Nginx安全篇
- 常见的恶意行为
- 常见的应用层攻击手段
- Nginx防攻击策略
- 场景: Nginx + Lua的安全waf防火墙
恶意行为
恶意行为主要是爬虫行为和恶意抓取、资源盗用
基础防盗链功能 - 目的不让恶意用户轻易的爬取网站对外数据
secure_link_module - 对数据安全性提高加密验证和失效性,适合核心重要数据
access_module - 对后台、部分用户服务的数据提供IP防控
攻击手段
- 后台密码撞库 - 通过猜测密码字典不断对后台系统登陆性尝试,获取后台登录密码
方法一:后台登录密码复杂度
方法二:access_module - 对后台提供IP防控
方法三:预警机制 -
文件上传漏洞 - 利用这些可以上传的接口将恶意代码植入到服务器中,再通过url去访问以执行代码
服务端要验证文件名,再配合nginx校验
location ^~ /upload {
root path;
if ($request_filename ~* (.*)\.php) {
return 403;
}
}
- SQL注入 - 利用未过滤/未审核用户输入的攻击方法,让应用运行本不应该运行的SQL代码
Nginx + Lua防火墙
参考代码
https://github.com/loveshell/ngx_lua_waf
Nginx版本更新和本身漏洞
- 查看版本更新描述
- 漏洞问题查看
Nginx中间件架构
- 了解需求: 静态资源服务、代理服务、动静分离
静态资源:浏览器缓存、类型分类、防盗链、流量限制、防资源盗用、压缩....
代理服务:协议类型、正向代理、反向代理、负载均衡、代理缓存、头信息处理、LNMP、分片请求、Proxypass... - 设计评估:硬件、系统、关联服务
硬件:CPU、内存、硬盘
系统:用户权限、日志目录存放
关联服务:LVS、keepalive、syslog、fastcgi - 配置注意事项:合理配置、了解原理、关注日志