内容大纲
nginx(web服务)与TCP/IP,HTTP协议的关系与实现
Nginx(Web服务)与TCP/IP,HTTP的关系与实现
参考资料
http://www.cnblogs.com/f-ck-need-u/p/7683027.html
相关协议/Nginx自身特色 需求 Nginx指令实现 作用位置 TCP/IP IP,端口 listen 10.0.0.1 80 default_server HTTP 站点 http,server HTTP1.1 虚拟主机 server_name www.cnblogs.com blog.cnblogs.com HTTP1.1 持久连接 keepalive_timeout 65 HTTP 资源URI(URL) (资源定位) locatoin 资源路径匹配(正则方式 | 路径方式),root(对应服务器的具体目录),index(默认的起始页)
资源路径匹配(正则方式)优先级: =(精确) > ^~(非正则匹配类似fgrep) > ~(区分大小写) > ~*(不区分大小写) > / (路径方式)
(资源重定向) rewrite perl正则 替换的内容 标志[ last | permanet | break | redirect ] HTTP MIME(媒体类型) include /path/mime.types HTTP 程序打开或接收媒体方式 default_type application/octet-stream Nginx 处理连接的总进程数 worker_processes 数值 # 数值一般等于CPU的总核数 Nginx 每个进程处理总连接数 work_connections 数值 Nginx 日志 error_log,acces_log,log_format Nginx IP地址过滤 allow,deny # allow 10.0.0.0/24,allow 10.0.0.8,deny all Nginx 显示目录结构 autoindex on Nginx 运行状态 stub_status Nginx 错误代码跳转 error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /www/error/error.html;
}
Nginx 文件高效传输 sendfile on
Nginx 用户验证 location /admin {
auth_basic "closed site"; # auth_basic strng|off #提示
auth_basic_user_file conf/htpasswd; # 验证的账号与密码所在的文件
}
# ------ 账号与密码的生成,及在htpasswd的格式
user:password
user2:password2
# ------ 密码生成方式 htpasswd 是 httpd-tools包的命令
shell>htpasswd -bcm /Application/nginx/conf/htpasswd WillLee 123456
shell>htpasswd -bm /Application/nginx/conf/htpasswd tony 123456
或
openssl passwd -apr1 123456 # 将密码放入 htpasswd 文件内,与账号放在一起。-apr1 兼容MD5个密钥格式
Nginx内置变量 (top)
官方变量文档:Alphabetical index of variables
这些变量可以在配置文件中使用,方便实现各种nginx页面代理,转换,重写,重定向等操作;而且还可以对nginx日志做自定义的日志配置,方便你对nginx日志的收集和分析。
变量 说明 $args 请求中的参数部分:www.cnblogs.com/1.php?uid=1&cid=10 ,其中$args就是 uid=1&b=2 $content_length http请求报文里面的“content-length” $conten_type http请求报文里面的“content-type” $document_root nginx配置文件中的 root 参数对应的值 $document_uri 当前的请求中的路径(不含域名,及参数),如 www.cnblogs.com/1.php?uid=1 ,其中$document_uri 就是 1.php $uri 与 $document_uri 相同 $host http请求报文中的域名,也是nginx配置文件中的 server_name $request 是 $request_method,$request_url,$server_protocol的组合 $http_user_agent 客户端的代理,也是浏览器的功能之一,描述客户的详细信息,用curl -A 指定 $http_cookie 客户端的cookie信息 $limit_rate nginx服务器指定limit_rate配置了显示网络速率,则会显示,如果没有设置,则显示 0 $remote_addr 客户端的公网IP(客户端路由器的上网IP,ISP分配的公网IP) $remote_port 客户端的端口 $remote_user 如果nginx有配置认证,该变量表示客户端认证的用户名 $request_body_file 做反向代理时发给后端服务器的本地资源的名称 $request_method http协议中的资源请求方法:get,put,post等 $request_filename 当请求的资源文件的真实路径名称(注意没有参数部分),相当于是$document_root/$document_uri $request_uri 相当于$document_uri 和 $args $scheme 请求的协议,https,http,ftp等 $server_port 服务器的端口 $server_addr 服务器的ip $server_name 服务器的主机名 $http_referer 客户端通过那个链接跳转到当前的页面,curl -e 可以指定 $http_x_forwarded_for 不算nginx内置变量,作用:记录代理的IP和客户的真实IP,
Uri与Nginx的配置文件 (top)
根据域名跳转
server { listen 80; server_name www.cnblogs.com cnblogs.com;
location / {
root /Server/data/html/www;
index index.html index.htm; if ( $host != www.cnblogs.com ) { # 当用户访问 cnblogs.com 时,进行跳转。 rewrite /(.*)$ https://www.cnblogs.com/$1 permanent; # 域名跳转用 301,网站跳转用302,解决搜索引擎对两个相同域名访问的内容一样,而降低权重,导致排名降低。 }
}
}
根据资源跳转
server { listen 80; server_name bbs.cblogs.com;
location / { root /Server/data/html/bbs; index index.html index.htm; } location /download/ { # 当用户访问 http://bbs.cblogs.com/dowload/ 时,进行跳转。 rewrite /.* https://bbs.cblogs.com redirect; } }
日志交割与过滤 (top)
交割脚本(核心的两个命令mv,nginx -s )
#!/bin/bash
# -- Description: nginx log daily delivery
# -- date/version/who: 2018-12-12/v1/lbc
# define dir BASE_DIR=/Application/nginx LOG_DIR=${BASE_DIR}/log LOG_DIR_BACKUP=/Server/log/http
# define file name LOG_FILE_NAME=access.log DOMAIN_NAME='www.cnblogs.com' LOG_FILE_NAME_BACKUP=${DOMAIN_NAME}_$(date -d "-1 day" +%Y%m%d).log
# define file full path LOG_FILE=${LOG_DIR}/${LOG_FILE_NAME} LOG_FILE_BACKUP=${LOG_DIR_BACKUP}/${LOG_FILE_NAME_BACKUP} [ -f "$LOG_FILE" ] || exit 1
/bin/mkdir -p ${LOG_DIR_BACKUP} /bin/mv $LOG_FILE $LOG_FILE_BACKUP $BASE_DIR/sbin/nginx -s reopen另外:nginx -s reopen 等效 nginx -t && nginx -s reload 等效 kill -s USR1 nginx_pid 等效 kill -HUP nginx_pid
将脚本加入定时任务
crontab -e
# 2018-12-12/v1/lbc 00 00 * * * /bin/sh /Server/script/web_log_delivery.sh &>/dev/null
过滤
当客户端访问量很大的时候,日志会对磁盘的IO造成不小性能的损耗,所以可以对某些资源进行过滤。
server {
listen 10.0.0.8 80 default_server;
server_name www.cnblogs.com;
root /Server/data/html/www;
index index.html index.php;
location ~* .*\.(jgp|gif|jpeg|png|bmp|swf|js|css)$ { access_log off; }
}
防盗链 (top)
盗链:网站的资源被其它网站拿走,如:A站点的图片被B站点引用,却耗费了A站点的宽带。
必须理解:根据Referer的定义,它的作用是指示一个请求是从哪里链接过来,那么当一个请求并不是由链接触发产生的,那么自然也就不需要指定这个请求的链接来源。
指令:valid_referers none | blocked | server_names | arbitrary string | ;
指令解释:valid_referers 定义白名单'referer', 决定了内置变量$invalid_referer的值,如果referer头部包含在这个合法网址里面,这个变量被设置为0,否则设置为1。
通俗的理解:vaild_referers 对 referer 里面的值,按条件(也就是该命令的参数 none,blocked,arbitrary string ,server_names)满足则对其放行。
配置端:server,location
参数解释:
none:表示“referer”的来源为空,即客户端在浏览器直接输入 url 进行访问,则referer为空。
blocked:表示"referer" 的值被代理或防火墙删除或伪装的情况,在这情况下,referer 的值是不以http://或https:// 开头的。
server_names:“referer”包含当前域名
arbitrary string :自定义url
server { listen 10.0.0.8 80 default_server; server_name www.cnblogs.com; root /Server/data/html/www; index index.html index.php; location ~* .*\.(jgp|gif|jpeg|png|bmp|swf|js|css)$ {
# valid_referers none *.cbblogs.com ; # 只允许 https://www.cnblogs.com/1.jpg 或 http://www.cnblogs.com/1.jpg 访问,对 www.cnblogs/1.jpg 不允许访问。 valid_referers none blocked *.cnblogs.com *.cnblogs.cn ; # https://www.cnblogs.cn/1.jgp 或 www.cnblogs.cn/1.jgp 都不受限制。 if ($invalid_referer) { return 403; } access_log off; } }参考:https://www.cnblogs.com/limeng951/p/5833790.html
https://blog.csdn.net/u011250882/article/details/49679535/
https://blog.csdn.net/shenqueying/article/details/79426884
官网:http://nginx.org/en/docs/http/ngx_http_referer_module.html
静态文件过期时间 (top)
浏览器缓存:将服务器上的某些静态资源(图片,js,css等)缓存在本地客户端的浏览器中,使得再次访问时无需再去服务器下载。
好处:缩短了用户访问网页的时间,也节省了服务器的宽带。
缺点:服务端的资源更新了,而客户端的缓存的资源没有更新。
nginx 服务端解决办法
location ~* .*\.(gif|jpg|png|jpeg)$ { expires 7d; # d 指天数,h 指小时,m 指分钟,s 指秒。 }
列如:
#date +%F\ %T 2019-01-15 16:02:50 #curl -I www.sina.com HTTP/1.1 301 Moved Permanently Server: nginx Date: Tue, 15 Jan 2019 07:59:56 GMT Content-Type: text/html Content-Length: 178 Connection: keep-alive Location: http://www.sina.com.cn/ Expires: Tue, 15 Jan 2019 08:01:11 GMT # 过期的时间 Cache-Control: max-age=120 # 被缓存的时间,单位秒 Age: 45 Via: http/1.1 cnc.jinan.ha2ts4.50 (ApacheTrafficServer/6.2.1 [cRs f ]), http/1.1 cnc.ningbo.ha2ts4.26 (ApacheTrafficServer/6.2.1 [cRs f ]) X-Via-Edge: 1547539196821a00f5ab67b64476510c68c60 X-Cache: HIT.26 X-Via-CDN: f=edge,s=cnc.ningbo.ha2ts4.26.nb.sinaedge.com,c=182.90.15.160;f=Edge,s=cnc.ningbo.ha2ts4.26,c=101.71.100.26
访问控制 (top)
实现的模块:ngx_http_access_module,目的就是控制指定的IP是否可以访问
默认的location / 方式
server { listen 80; server_name www.cnblogs.com; ... location / { allow 10.0.0.0/24; #允许访问 allow 10.0.0.1; #允许访问 deny all; # 除了上面允许的ip外,其他都不能访问 } }
正则方式
server { listen 80; server_name www.cnblogs.com; ... # location ~(data|image|cache).*\php$ location ~ "admin" { allow 10.0.0.0/24; #允许访问 allow 10.0.0.1; #允许访问 deny all; # 除了上面允许的ip外,其他都不能访问 } }
基于变量
server { listen 80; server_name www.cnblogs.com; ... location / { # if ($request_uri ~ "uid=\d{1,10}" if ( $document_uri ~ "admin") { return 403; } } }
基于链接
server { listen 80; server_name www.cnblogs.com; ... location / { # 当在百度链接过来的,就跳转到自定义的站点上 if ($http_referer ~ "baidu.com") { rewrite /.* http://www.cnblogs.com redirect; # return http://bbs.cnblogs.com; } } }
基于客户端的agent (通过观察访问日志,找出不友好(频繁访问)的搜索引擎蜘蛛,或一些非正常的访问都给返回403,减少服务器的压力)
server { listen 80; server_name www.cnblogs.com; ... location / { if ($user_agent ~ '.*Spider|.*Bot|Tomato') { return 403; } } }
HTTPS 配置 (top)
SSL即HTTPS,服务端使用443端口,是在http的基础上增加了加密,解密的过程,数据在传输的过程中处于加密状态,保证数据在传输中不被篡改或获取。
由于增加了加密与解密,与http相比自然要耗时更多。
SSL需要一个合法的CA证书,可以在https://freessl.cn/ 中获取免费的CA证书(有效期一年),企业可直接购买。
server { listen 443 ssl; server_name www.myyf.xyz; index index.html index.php; root /Server/data/www.myyf.xyz; ssl on ; ssl_certificate server.crt; # crt文件所在的路径 ssl_certificate_key server.key; # key文件所在的路径 ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # ssl的协议版本 ssl_ciphers ALL:!DH:!EXPORT:!RC4:+HIGH:+MEDIUM:!eNULL; # 加密算法, : 分隔,!不启用,+ 该算法排到最后 ssl_prefer_server_ciphers on ; # 默认为off,当为on时,在使用 sslv3与tls协议时,服务器加密算法优于客户端加密算法 }
限速 (top)
限制下载及限制并发数针对的是TCP连接
官网参考:http://nginx.org/en/docs/http/ngx_http_limit_conn_module.html
对下载限速
server { location ~ /download/ { # 针对每个请求的限速 limit_rate_after 512k; # 当文件下载到512k大小时,开始限速 limit_rate 150k; # 满足限速功能后,的下载速率为150k/s } }
并发连接数的限制
http { ......
# limit_comm_zone 必须在 http 标签中 limit_conn_zone $binary_remote_addr zone=xxxx:10m; # 定义一个内存块索引名为:xxxx,大小为10m,以$bianry_remote_addr 作为 key 值。 server { ...... limit_conn xxxx 10; # limit_conn 针对 xxxx 这个内存块,并发为10个,这里的10是指单个 ip 的并发最多为10个。 } }
针对 http 请求进行限制
官网参考:http://nginx.org/en/docs/http/ngx_http_limit_req_module.html
http { ... limit_req_zone $binary_remote_addr zone=xxxx:10m rate=1r/s; # 设置一块共享内存区域,保存键值状态,键值就是客户端ip,rate=1r/s表示限制客户端每一个ip平均处理请求的频率为1秒1次,若需要每2秒处理一次,则使用 30r/m server { ... location /download/ { limit_req zone=xxxx burst=5; #burst=5,意为前5个请求需要排队,每秒处理1个。而后面来的请求就会直接拒绝(显示503)。在生产中可以设置大一点,比如200,其实它针对单个IP,单个ip能并发200已经是很棒了。 } } }
对白名单以外的IP进行限速
官网参考:
http://nginx.org/en/docs/http/ngx_http_geo_module.html
http://nginx.org/en/docs/http/ngx_http_map_module.html
geo $good_ip { # geo 操作的对象时候ip或ip段。,可以理解 $good_id 是一个数组 good_id[1]=default,good_id=[0]='127.0.0.1/31,192.168.100.0/23' defalut 1; # 其他的ip 归类到 1 里 127.0.0.1/32 0; # 将 127.0.0.1 单个IP 及 192.168.100.0网段归类到 0 里。 192.168.100.0/23 0; } map $good_id $limit { # map 操作的对象是变量,作用就是将两个变量所代表的的关系进行映射,可以理解为 $limit[1]=$binary_remtoe_addr 映射到 $good_id[1]=defalut 1 $binary_remote_addr; # $good_id 中的 1 与 &bianry_remote_addr 关联。 0 ""; # $good_id 中的 0 暂无关联 }
limit_req_zone $limit zone=xxxx:10m rate=1r/s; # 调用$limit的映射关系
server {
location /download/ {
limit_req zone=xxxx burst=5;
}
}
状态信息 (top)
官网参考:http://nginx.org/en/docs/http/ngx_http_stub_status_module.html
开启nginx 的状态页,需要在编译时加参数 --with-http_stub_status_module
server { listen 80; server_name www.myyf.xyz; location /status/ { # 也可以使用用户验证 stub_status on; access_log off; allow 127.0.0.1; allow 192.168.6.0/24; deny all; } }
curl -x www.myyf.xyz/status/
active connections:当前的连接数量。可以每一分钟获取该值,可以得到一分钟的并发数连接数量。
accepts :共处理的连接数,accepts - requests = 失败的连接数
handled:成功创建3次握手的次数
requests:总共处理请求的次数
reading:正在处理客户端的数量(处理客户端的请求报文)
writing:正在响应客户端的数量(处理响应报文给客户端)
waiting:正在等待处理下一次请求指令的驻留连接,该数值在keep-alive开启下才会出现大于0
编译参数
依赖包
yum install -y gcc-c++ pcre pcre-devel openssl openssl-devel gd-devel libxml2 libxml2-devel bzip2-devel
编译参数
View Codenginx code dir >./configure --prefix=/Application/nginx-1.14.2 \ --user=www \ --group=www \ --with-http_ssl_module \ --with-http_flv_module \ --with-http_mp4_module \ --with-http_stub_status_module \ --with-http_gzip_static_module \ --with-pcre \ --with-threads \ --with-http_realip_module \ --with-http_image_filter_module \ --with-file-aio \ --with-http_sub_module \ --with-http_dav_module \ --with-http_degradation_module shell>make -j 4 shell>make install