本章目录
[TOC]
前置基础知识学习
0x00 编译实践 描述:在企业线上生产环境中推荐进行Nginx编译安装,可以按照业务侧重点进行相应 Nginx 编译参数配置,所以编译参数不是功能加的越多越好,应该尽可能少编译模块不用的最好不要加入,本小结将以最新的Nginx版本以及依赖版本进行编译演示。
Nginx-1.21.6+OpenSSL-1.1.1n 最新源码构建安装整理,当前最新版本nginx-1.21.6,实践时间【2022年3月24日】 版本说明: pcre-8.45 、zlib-1.2.11、openssl-1.1.1n、nginx-1.21.6。
官方安装参考地址: https://docs.nginx.com/nginx/admin-guide/installing-nginx/installing-nginx-open-source/#downloading-the-sources
步骤 01.在从源代码编译 NGINX Open Source 之前,您需要为其依赖项安装库:
PCRE – 支持正则表达式,NGINX Core 和 Rewrite 模块需要。
1 2 3 4 5 6 wget -c https://nchc.dl.sourceforge.net/project/pcre/pcre/8.45/pcre-8.45.tar.bz2 tar -jxf pcre-8.45.tar.bz2 && cd pcre-8.45 ./configure make && sudo make install
zlib – 支持标头压缩, NGINX Gzip 模块需要。
1 2 3 4 5 wget -c http://zlib.net/zlib-1.2.11.tar.gz tar -zxf zlib-1.2.11.tar.gz && cd zlib-1.2.11 ./configure make && sudo make install
OpenSSL – 支持 HTTPS 协议, NGINX SSL 模块和其他模块需要。
1 2 3 4 5 6 7 8 9 10 11 wget -c http://www.openssl.org/source /openssl-1.1.1n.tar.gz tar -zxf openssl-1.1.1n.tar.gz && cd openssl-1.1.1n ./config --prefix=/usr/local /openssl make && sudo make install echo "/usr/local/openssl/lib" >> /etc/ld.so.conf.d/libc.confldconfig
步骤 02.从 nginx.org 下载稳定版和主线版本的源代码文件,要下载并解压最新主线版本的源代码,请运行:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 sudo mkdir -vp /usr/local /nginx/module /usr/lib/nginx/modules /var/cache/nginx/{client_temp,proxy_temp,fastcgi_temp,uwsgi_temp,scgi_temp} wget https://nginx.org/download/nginx-1.21.6.tar.gz tar zxf nginx-1.21.6.tar.gz && cd nginx-1.21.6 $ ./configure \ --prefix=/usr/local /nginx \ --with-pcre=../pcre-8.45 \ --with-zlib=../zlib-1.2.11 \ --with-openssl=../openssl-1.1.1n \ --user=ubuntu --group=ubuntu \ --sbin-path=/usr/sbin/nginx \ --conf-path=/usr/local /nginx/nginx.conf \ --pid-path=/usr/local /nginx/nginx.pid \ --error-log-path=/var/log /nginx/error.log \ --http-log-path=/var/log /nginx/access.log \ --lock-path=/var/run/nginx.lock \ --modules-path=/usr/lib/nginx/modules \ --http-client-body-temp-path=/var/cache/nginx/client_temp \ --http-proxy-temp-path=/var/cache/nginx/proxy_temp \ --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp \ --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp \ --http-scgi-temp-path=/var/cache/nginx/scgi_temp \ --with-stream --with-stream_realip_module --with-stream_ssl_module --with-stream_ssl_preread_module --with-stream_geoip_module \ --with-threads --with-mail --with-mail_ssl_module \ --with-http_addition_module --with-http_auth_request_module --with-http_dav_module --with-http_flv_module --with-http_gunzip_module \ --with-http_gzip_static_module --with-http_mp4_module --with-http_random_index_module --with-http_realip_module --with-http_secure_link_module \ --with-http_slice_module --with-http_ssl_module --with-http_stub_status_module --with-http_sub_module --with-http_v2_module \ --with-compat --with-file-aio \ --with-cc-opt='-Os -fomit-frame-pointer -g' --with-ld-opt=-Wl,--as-needed,-O1,--sort-common
Tips :请注意 geoip_module 模块, 如果需要使用则需要提前安装好 GeoIP library,例如在Ubuntu系统上执行apt-get install libgeoip-dev
如下命令。
Tips : 请注意 通过yum或者apt安装的nginx,通常会将nginx的配置文件放在/etc/nginx
,而手动编译构建的一般是在 /usr/local/nginx 目录中。
步骤 03.执行./configure
命令后的结果如下1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 Configuration summary + using threads + using PCRE library: ../pcre-8.45 + using system OpenSSL library + using zlib library: ../zlib-1.2.11 nginx path prefix: "/usr/local/nginx" nginx binary file: "/usr/sbin/nginx" nginx modules path: "/usr/lib/nginx/modules" nginx configuration prefix: "/usr/local/nginx" nginx configuration file: "/usr/local/nginx/nginx.conf" nginx pid file: "/usr/local/nginx/nginx.pid" nginx error log file: "/var/log/nginx/error.log" nginx http access log file: "/var/log/nginx/access.log" nginx http client request body temporary files: "/var/cache/nginx/client_temp" nginx http proxy temporary files: "/var/cache/nginx/proxy_temp" nginx http fastcgi temporary files: "/var/cache/nginx/fastcgi_temp" nginx http uwsgi temporary files: "/var/cache/nginx/uwsgi_temp" nginx http scgi temporary files: "/var/cache/nginx/scgi_temp"
步骤 04.执行构建安装后查看nginx版本以及构建参数等信息1 2 3 4 5 6 $ nginx -V nginx version: nginx/1.21.6 built by gcc 9.4.0 (Ubuntu 9.4.0-1ubuntu1~20.04) built with OpenSSL 1.1.1n 15 Mar 2022 TLS SNI support enabled configure arguments: --prefix=/usr/local /nginx --with-pcre=../pcre-8.45 --with-zlib=../zlib-1.2.11 --user=ubuntu --group=ubuntu --sbin-path=/usr/sbin/nginx --conf-path=/usr/local /nginx/nginx.conf --pid-path=/usr/local /nginx/nginx.pid --error-log-path=/var/log /nginx/error.log --http-log-path=/var/log /nginx/access.log --lock-path=/var/run/nginx.lock --modules-path=/usr/lib/nginx/modules --http-client-body-temp-path=/var/cache/nginx/client_temp --http-proxy-temp-path=/var/cache/nginx/proxy_temp --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp --http-scgi-temp-path=/var/cache/nginx/scgi_temp --with-stream --with-stream_realip_module --with-stream_ssl_module --with-stream_ssl_preread_module --with-stream_geoip_module --with-threads --with-mail --with-mail_ssl_module --with-http_addition_module --with-http_auth_request_module --with-http_dav_module --with-http_flv_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_mp4_module --with-http_random_index_module --with-http_realip_module --with-http_secure_link_module --with-http_slice_module --with-http_ssl_module --with-http_stub_status_module --with-http_sub_module --with-http_v2_module --with-compat --with-file-aio --with-cc-opt='-Os -fomit-frame-pointer -g' --with-ld-opt=-Wl,--as-needed,-O1,--sort-common
步骤 05.执行/usr/sbin/nginx
命令, 启用nginx服务并查看提供的服务。
1 2 3 $ ps -ef | grep nginx | grep -v "grep" | wc -l 3
描述: 我们可以执行./configure --help
便可以查看编译相关参数。1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 --prefix= --user= --group= --with-perl= --with-perl_modules_path= --with-pcre-opt= 在编译时为pcre库设置附加参数 --with-zlib= --with-zlib-opt= --with-zlib-asm= --with-openssl= --with-openssl-opt --with-http_ssl_module --with-cc-opt= --with-ld-opt= --with-cpu-opt= --conf-path= --error-log-path= --pid-path= --sbin-path= --lock-path= --builddir= --with-rtsig_module --with-select_module --with-poll_module --with-file-aio --with-ipv6 --with-http_realip_module --with-http_addition_module --with-http_xslt_module --with-http_image_filter_module --with-http_geoip_module --with-http_sub_module --with-http_dav_module --with-http_flv_module --with-http_gzip_static_module --with-http_random_index_module --with-http_secure_link_module --with-http_degradation_module --with-http_stub_status_module --without-http_charset_module --without-http_gzip_module --without-http_ssi_module --without-http_userid_module --without-http_access_module --without-http_auth_basic_module --without-http_autoindex_module --without-http_geo_module --without-http_map_module --without-http_split_clients_module --without-http_referer_module --without-http_rewrite_module --without-http_proxy_module --without-http_fastcgi_module --without-http_uwsgi_module --without-http_scgi_module --without-http_memcached_module -without-http_limit_zone_module --without-http_limit_req_module --without-http_empty_gif_module --without-http_browser_module --without-http_upstream_ip_hash_module --with-http_perl_module --http-log-path= --http-client-body-temp-path= --http-proxy-temp-path= --http-fastcgi-temp-path= --http-uwsgi-temp-path= --http-scgi-temp-path= -without-http --without-http-cache --with-mail --with-mail_ssl_module 启用ngx_mail_ssl_module支持 --without-mail_pop3_module --without-mail_imap_module --without-mail_smtp_module --with-google_perftools_module --with-cpp_test_module --add-module= --with-cc= --with-cpp= --without-pcre --with-md5= --with-md5-opt= --with-md5-asm --with-sha1= --with-sha1-opt= --with-sha1-asm --with-libatomic --with-libatomic= --with-debug
Shell脚本一键部署虚拟主机(附上关键性脚本): 完整代码:https://github.com/weiyigeek/SecOpsDev/Application/Web/Nginx/nginxVirtualHost-v1.sh 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 #!/bin/bash NGX_VER=1.16.1 NGX_URI="http://nginx.org/download/nginx-${NGX_VER} .tar.gz" NGX_SRC="nginx-${NGX_VER} .tar.gz" NGX_NAME=${NGX_SRC%.tar.gz} NGX_DIR="/usr/local/nginx/${NGX_VER} " NGX_ARGS="--prefix=${NGX_DIR} --user=nginx --group=nginx --with-http_stub_status_module" NGX_SRCCODE="${NGX_NAME} /src/core/nginx.h" NGX_VHDIR="${NGX_DIR} /conf/domains" FIREWALL_PORT=(80 8080) function nginx_install (){ echo -e "\e[32m1.核查安装依赖....... \e[0m" CHECK_SOFT=$(rpm -qa | grep -cE "^gcc|^pcre|^zlib" ) if [ $CHECK_SOFT -lt 2 ];then yum install -y gcc gcc-c++ pcre pcre-devel zlib-devel;fi echo -e "\e[32m2.检查nginx源码包是否存在....... \e[0m" if [ ! -f $NGX_SRC ];then wget -c $NGX_URI ;fi if [ ! -d $NGX_NAME ];then tar -zxf $NGX_SRC ;fi echo -e "\e[32m3.nginx安装陆军是否存在....... \e[0m" if [ ! -f $NGX_DIR /sbin/nginx ];then mkdir -vp $NGX_DIR ;fi echo -e "\e[32m3.验证nginx用户是否存在不存在则建立低权限用户....... \e[0m" CHECK_USER=$(getent passwd | grep -wc nginx) if [ $CHECK_USER -eq 0 ];then useradd -s /sbin/nologin nginx -M; fi echo -e "安全设置:Nginx版本隐藏......" sed -i "s/$NGX_VER //g" $NGX_SRCCODE sed -i 's/nginx\//JWS/g' $NGX_SRCCODE sed -i 's/"NGINX"/"JWS"/g' $NGX_SRCCODE echo -e "\e[32m4.进行nginx预编译及其编译安装....... \e[0m" cd $NGX_NAME && ./configure $NGX_ARGS if [ $? -eq 0 ];then make -j2 && make -j2 install else echo -e "\e[31m#Error: 预编译失败!终止安装,请检查软件依赖! \e[0m" exit fi if [ $? -ne 0 ];then echo -e "\e[31m#Error: 编译安装失败!终止安装 \e[0m" ;exit ;fi echo -e "\e[32m Nginx 成功安装....... \n安装目录:${NGX_DIR} \n 正在启动Nginx....\e[0m" $NGX_DIR /sbin/nginx } function nginx_vhost (){ NGX_VHOSTS=$1 firewall_config cd ${NGX_DIR} NGX_CNF="${NGX_DIR} /conf/nginx.conf" if [ ! -f $NGX_CONF ];then echo -e "Nginx-配置文件不存在请仔细检查!" ;exit ;fi grep "domains" ${NGX_CNF} >>/dev/null 2>&1 if [ $? -ne 0 ];then cp ${NGX_CNF} {,_$(date +%F_%H%M%S).bak} mkdir -vp ${NGX_VHDIR} sed -i "s/#user nobody/user nginx/g" ${NGX_CNF} sed -i "s/#gzip/gzip/g" ${NGX_CNF} grep -vE "#|^$" ${NGX_CNF} > ${NGX_CNF} .swp sed -i '/server/,$d' ${NGX_CNF} .swp cp ${NGX_CNF} .swp ${NGX_CNF} echo -e " include domains/*;\n}" >> ${NGX_CNF} fi cat>${NGX_VHDIR} /$NGX_VHOSTS .conf<<EOF server { listen 80; server_name $NGX_VHOSTS ; location / { root html/$NGX_VHOSTS ; index index.html index.htm; } location /nginxStatus { stub_status; } error_page 500 502 503 504 /50x.html; location = /50x.html { root html; } } EOF echo -e "\e[32m$NGX_VHOSTS 网站目录建立之中.....\e[0m" if [ ! -d $NGX_DIR /html/$NGX_VHOSTS / ];then mkdir -vp $NGX_DIR /html/$NGX_VHOSTS / cat>$NGX_DIR /html/$NGX_VHOSTS /index.html<<EOF <h1>$NGX_VHOSTS Test Pages. </h1> <p>By WeiyiGeek.top </p> <hr color=red> EOF fi echo -e "\e[32mNginx配置文件验证中.....\e[0m" $NGX_DIR /sbin/nginx -t if [ $? -ne 0 ];then echo -e "\e[31mNginx配置文件有误,请处理错误后重启Nginx服务器:\n ${NGX_DIR} /sbin/nginx -s reload" fi cat ${NGX_VHDIR} /$NGX_VHOSTS .conf echo -e "\e[32mNginx重启之中.....\e[0m" $NGX_DIR /sbin/nginx -s reload CHECK_STATUS=$(netstat -tlnp | grep -wc "nginx" ) if [ $CHECK_STATUS -ne 0 ];then echo -e "\e[32m#Nginx 启动成功.... \e[0m" else echo -e "\e[31m#Nginx 启动失败.... \e[0m" fi }
运行效果:
weiyigeek.top-运行效果
测试效果:
weiyigeek.top-测试效果
0x01 Nginx 配置最佳实践 Nginx 之 多配置文件配置 描述: Nginx配置文件中支持包含多个配置文件,比如下面的虚拟主机的配置将使用,在程序加载运行时候首先会读取nginx.conf 的配置文件,然后再读取 /etc/nginx/conf.d/
下面的配置文件;
例如,我们需要在/etc/nginx/nginx.conf
文件中,进行如下设置include /etc/nginx/conf.d/*.conf;
1 2 3 4 5 http { .... include conf.d/*.conf; .... }
weiyigeek.top-
Nginx 之 Server 侦听端口主机头配置浅析 描述:常规网站编译安装后运行只是单个网站访问,我们如何可以做到多网站同时运行到该Nginx服务器上,那我们便可使用Nginx提供的虚拟机主机方式, 使得一个服务端口可以访问不同的服务应用;
常规有三种方式:
1) 多端口
2) 多IP
3) 多域名:虚拟主机(VirtualHost)
环境准备: 1 2 3 cat >> /etc/hosts<<END 127.0.0.1 v1.weiyigeek.top v2.weiyigeek.top END
流程步骤:
1.修改移除Nginx.conf配置文件中的Server {...}
包含的参数添加include domains/*;
;
1 2 3 4 5 6 7 8 9 10 11 12 13 user nginx; worker_processes 1; events { worker_connections 1024; } http { include mime.types; default_type application/octet-stream; sendfile on; keepalive_timeout 65; gzip on; include domains/*; }
2.在Nginx的Conf目录中建立一个domains目录(注意这里不要建立到上级目录之中,否则会出现nginx master进程已经启动但是无监听端口),进入该目录中建立虚拟主机v1.weiyigeek.top.conf文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 server { listen 80; server_name v1.weiyigeek.top; #关键点 location / { #关键点 root html/v1.weiyigeek.top; index index.html index.htm; } #Nginx 监控模块启用 location /nginxStatus { stub_status; } error_page 500 502 503 504 /50x.html; location = /50x.html { root html; } }
3.在nginx安装目录中的html中建立一个与虚拟主机同名的文件夹(当然名字您可以任意取,但是必须和v1.weiyigeek.top.conf中指定路与的root一致)
1 2 3 4 [root@WeiyiGeek html] /usr/local /nginx/1.16.1/html [root@WeiyiGeek html] 50x.html index.html v1.weiyigeek.top v2.weiyigeek.top
配置示例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 server { listen 80; listen 443 ssl; listen 443 ssl http2; listen [::]:80; listen [::]:80 ipv6only=on; server_name weiyigeek.top; server_name weiyigeek.top www.weiyigeek.top; server_name *.weiyigeek.top; server_name weiyigeek.top.*; server_name "" ; server_name _; }
温馨提示: 当网站设置支持http2以后可以从请求响应头中看到如下字段 X-Firefox-Spdy:h2
weiyigeek.top-nginx-http/2
Nginx 之 Location 规则配置浅析 描述: Location 语法规则:location [=|~|~*|^~] /uri/ { … }
=
: 表示精确匹配.
/
: 表示通用匹配, 即任何请求都会匹配到。
~
: 表示区分大小写的正则匹配.
~*
: 表示不区分大小写的正则匹配.
!~
,!~*
: 分别标识为区分大小写不匹配及不区分大小写不匹配的正则
^~
: 表示URL以某个常规字符串开头,可以理解为匹配url路径即可,值得注意的是Nginx不对URL做编码,例如会将请求为/static/20%/aa被^~ /static/ /aa
规则匹配到。
默认情况下 location 的匹配顺序为精确匹配
(=) -> 开头匹配
(^~) -> 文件顺序中的正则匹配
(~*) -> 通用匹配
(/), 当有匹配成功的URL则停止匹配。
例如,有如下匹配规则:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 location = / { } location = /login { } location ^~ /static/ { } location ~ \.(gif|jpg|png|svg|js|css)$ { } location ~* \.(gif|jpg|png|svg|js|css)$ { } location ~* \.png$ { } location !~ \.xhtml$ { } location !~* \.xhtml$ { } location / { }
在实践过程中常见, 有如下几种匹配规则:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 location = / { root /usr/local /nginx/html proxy_pass http://tomcat:8080/index } location ^~ /static/ { root /webroot/static/; } location ~* \.(gif|jpg|jpeg|png|css|js|ico)$ { root /webroot/res/; } location / { proxy_pass http://tomcat:8080/ }
Nginx 之 规则判断表达式浅析 Nginx 常用判断表达式如下:
-f和!-f
: 用来判断是否存在文件
-d和!-d
:用来判断是否存在目录
-e和!-e
:用来判断是否存在文件或目录
-x和!-x
:用来判断文件是否可执行
除此之外我们还可以使用上一小节的正则匹配符进行判断。
nginx 全局变量一览: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 arg_PARAMETER args binary_remote_addr body_bytes_sent content_length content_type cookie_COOKIE document_root document_uri host hostname http_HEADER is_args http_user_agent http_cookie limit_rate query_string request_body_file request_method remote_addr remote_port remote_user request_completion request_method request_filename request_uri scheme server_protocol server_addr server_name server_port
Nginx 解析URL用作判断的全局变量,例如访问的URL为 http://weiyigeek.top:8080/test1/test2/test.php
1 2 3 4 5 6 $host :weiyigeek.top$server_port :8080$request_uri :http://weiyigeek.top:8080/test1/test2/test.php$document_uri :/test1/test2/test.php$document_root :/data/nginx/html$request_filename :/data/html/test1/test2/test.php
简单示例:
温馨提示: 此处以Nginx暴露给互联网, 所以利用 $remote_addr
变量获取访问者地址, 如果用了负载均衡的话此处应该是$http_x_forwarded_for
变量。
5.自定义变量封禁爬虫以及取消匹配到静态文件的日志记录。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 location ^~ /blog/ { # 防爬虫 if ( $http_user_agent ~* "Go-http-client|CriteoBot|YandexBot|PetalBot|BLEXBot|ReaddigBot|SemrushBot|DataForSeoBot|python|MJ12bot|AhrefsBot|AhrefsBot|hubspot|opensiteexplorer|leiki|webmeup|netEstate|Barkrowler|GrapeshotCrawler" ){ return 407; } if ( $request_uri ~* "css|js|ico|gif|jpg|jpeg|png" ){ # 关闭日志 access_log off; # 缓存时间7天 expires 7d; } alias /usr/local/app/weiyigeek.gitee.io/; index index.html; sub_filter_types application/html text/xml application/javascript; sub_filter 'src="/img/' 'src="/blog/img/'; ## 将响应内容中的域名替换成本站域名 sub_filter 'src="/js/' 'src="/blog/js/'; ## 将响应内容中的域名替换成本站域名 sub_filter 'href="/' 'href="/blog/'; ## 将响应内容中的域名替换成本站域名 sub_filter '"search.xml"' '"blog/search.xml"'; ## 将响应内容中的域名替换成本站域名 sub_filter '<loc>https://blog.weiyigeek.top/' '<loc>https://www.weiyigeek.top/blog/'; ## 将响应内容中的域名替换成本站域名 sub_filter_once off; ## 所有匹配到的都替换 expires 1d; }
Nginx 之 Redirect重定向与ReWrite重写 配置浅析 Redirect(重定向)语法示例 1 2 3 4 5 6 7 8 9 10 11 12 13 server { listen 80; server_name weiyigeek.top www.weiyigeek.top; return 301 https://$host $request_uri ; } server { listen 80; server_name weiyigeek.top www.weiyigeek.top; return 302 https://www.weiyigeek.top$request_uri ; }
ReWrite 重写语法示例 rewrite 正则表达式以及其可用参数:
last
: 本条重写规则匹配完成后,终止匹配后续重写规则,并重新发起请求继续匹配新的location URI规则;浏览器地址栏URL地址不变
break
: 本条重写规则匹配完成后,终止匹配后续重写规则; 浏览器地址栏URL地址不变
redirect
: 返回302临时重定向,浏览器地址会显示重写后的URL地址(爬虫不会收录)
permanent
: 返回301永久重定向,浏览器地址会显示重写后的URL地址 (爬虫会收录)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 server { listen 80; server_name weiyigeek.top www.weiyigeek.top; if ($http_host !~ "^www\.weiyigeek\.top$" { rewrite ^(.*) https://www.weiyigeek.top$1 permanent; } } location ~* \.(gif|jpg|png|svg|css|js)$ { valid_referers none blocked *.weiyigeek.top localhost 127.0.0.1 server_names ~\.google\. ~\.baidu\.; if ($invalid_referer ) { rewrite ^/ https://www.weiyigeek.top/403.jpg; } } if ( $document_uri ~* /([0-9]+)/([0-9]+)/([0-9]+)\.html$) { rewrite ^/ /index.html last; }
温馨提示:301 与 302 状态码的不同区别。
301 redirect: 301 代表永久性转移( Permanently Moved
) - 网站SEO推荐。
302 redirect: 302 代表暂时性转移( Temporarily Moved
)
Nginx 之 SSL 证书安全配置浅析 描述: 通常为了保证网站数据在传输过程中不被窃取和篡改,我们需要为其配置SSL证书,而在Nginx中配置方法是非常的简单的,不过最重要的还是你要生成私钥以及证书申请文件csr向证书颁发机构生成网站证书。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 # Permanent Redirect for HTTP to HTTPS server { listen 80; listen [::]:80; server_name weiyigeek.top; return 301 https://$host$request_uri; } server { listen 443 ssl http2; listen [::]:443 ssl http2; server_name weiyigeek.top; # HSTS (ngx_http_headers_module is required) 应该只使用 HTTPS 而不是使用 HTTP 通信 add_header Strict-Transport-Security "max-age=31536000;includeSubDomains;preload" always; # XXS-Protection add_header X-XSS-Protection "1; mode=block"; # MIME 模拟探测 add_header X-Content-Type-Options nosniff; # Frame 安全控制 add_header X-Frame-Options ALLOW-FROM music.163.com; # Spider Robots 爬取策略限制 add_header X-Robots-Tag none; # 开启 SSL ,如果想http 与 https 公用一个配置则可以将其注释( the "ssl" directive is deprecated ) # ssl on; # 配置证书链与证书密钥 ssl_certificate /etc/nginx/ssl/fullchain.cer; ssl_certificate_key /etc/nginx/ssl/weiyigeek.top.key; # ssl会话复用超时时间以及会话复用缓存大小 ssl_session_timeout 1d; ssl_session_cache shared:MozSSL:10m; # about 40000 sessions # 配置双证书时开启否则应该关闭 ssl_session_tickets off; ## OCSP stapling ssl_stapling on; ssl_stapling_verify on; # 使用根 CA 和中间证书验证 OCSP 响应的信任链 ssl_trusted_certificate /etc/nginx/ssl/ca.cer; # 仅使用ECDH是不用配置ssl_dhparam的否则你应该为它配置上 # curl https://ssl-config.mozilla.org/ffdhe2048.txt > /path/to/dhparam ssl_dhparam /path/to/dhparam; # 兼容性较为通用的SSL协议与加密算法套件 ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE:ECDH:AES:HIGH:EECDH+CHACHA20:EECDH+CHACHA20-draft:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:!NULL:!aNULL:!eNULL:!EXPORT:!PSK:!ADH:!DH:!DES:!MD5:!RC4; # 安全配置: ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4:!DH:!DHE; # 证书常规握手加密算法方式共十八个,ECDHE、DHE、AES开头分别6个 ; ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:HIGH:!NULL:!aNULL:!eNULL:!EXPORT:!PSK:!ADH:!DES:!MD5:!RC4; # 为了兼容性推荐服务器自动选择要使用的算法套件 ssl_prefer_server_ciphers on; # replace with the IP address of your resolver resolver 223.6.6.6 8.8.8.8 192.168.12.254; }
补充说明: 为Nginx服务器配置RSA与ECDSA双证书的两种方式。1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 ssl_certificate example.com.rsa.crt; ssl_certificate_key example.com.rsa.key; ssl_certificate example.com.ecdsa.crt; ssl_certificate_key example.com.ecdsa.key; ssl_ct on; ssl_ct_static_scts /path/to/sct/dir; ssl_ct on; ssl_certificate example.com.rsa.crt; ssl_certificate_key example.com.rsa.key; ssl_ct_static_scts xample.com.rsa.scts; ssl_certificate example.com.ecdsa.crt; ssl_certificate_key example.com.ecdsa.key; ssl_ct_static_scts example.com.ecdsa.scts;
Nginx 之 资源压缩配置浅析 描述: 为了降低服务器带宽压力以及优化响应速度, 通常我们需要在Nginx服务器配置中为其开启gzip压缩,
配置示例: 1 2 3 4 5 6 7 8 9 10 gzip on; gzip_min_length 2k; 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 font/ttf font/opentype image/svg+xml; gzip_vary on;
Nginx 之 静态资源expires缓存过期时间配置 描述: 在 Nginx 配置 expires 指令可以起到控制页面缓存的作用, 配置静态资源的 expires 可以有效的减少客户端对服务器的请求,该配置项适用于: http、server 以及 location 块中。
expires(过期时间语法)语法示例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 ; 语法: `expires [time|epoch|max|off]` * epoch:指定Expires的值为 1 January,1970,00:00:01 GMT * max: 指定Expires的值为31 December2037 23:59:59GMT,"Cache-Control"的值为10年。 * -1:指定Expires的值为当前服务器时间-1s,即永远过期。 * off:不修改Expires和"Cache-Control"的值 # location 块 ~ 使用正则匹配 location ~ \.(gif|jpg|jpeg|png|bmp|ico)$ { # 静态资源源路径必须配置否则,静态资源可能无法找到 root /var/www/img/; # 禁用404错误日志 log_not_found off; # 关闭access访问日志 access_log off; # 静态资源过期时间 expires 7d; }
该指令控制HTTP应答中的”Expires”和”Cache-Control”Header头部信息, 例如在配置后expires指令请求 https://blog.weiyigeek.top/img/avatar.jpg
URL:1 2 3 4 5 6 7 8 9 10 11 HTTP/1.1 304 Not Modified Server: nginx Date: Fri, 01 Apr 2022 09:19:09 GMT Last-Modified: Wed, 30 Mar 2022 15:42:30 GMT Connection: keep-alive ETag: "62447a66-35db" Expires: Fri, 08 Apr 2022 09:19:09 GMT Cache-Control: max-age=604800 Access-Control-Allow-Origin: *.weiyigeek.top Access-Control-Allow-Methods: GET,POST Access-Control-Allow-Headers: DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization
实践示例: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 # 网页资源缓存 location ~* \.(xml|html|htm)$ { # 资源决绝对目录设置 root /var/www/html; # 日志文件的相对路径或完整路径 access_log /path/to/file.log; # 开启日志记录 access_log on; # 设置过期时间 expires 24h; } # 样式、JS、图片资源缓存 location ~* \.(css|js|ico|gif|jpg|jpeg|png)$ { root /var/www/html/res; # 禁用404错误日志 log_not_found off; # 关闭日志 access_log off; # 缓存时间7天 expires 7d; } # 字体资源缓存 location ~* \.(eot|ttf|otf|woff|woff2|svg)$ { root /var/www/html/static; log_not_found off; access_log off; expires max; }
Nginx 之 反向代理资源基本缓存配置 描述: 在 Nginx 中往往我们会对指定站点进行反代(反向代理), 而在反代站点中存在动态资源与静态资源,我们可以使用下述指令开启简单的缓存配置。
首先我们需要了解一下三种缓存类型:
客户端缓存
代理缓存(Proxy Cache)
服务端缓存
这里主要讲解Nginx作为代理服务器进行代理缓存的配置采用的参数以及示例:
1.proxy_cache
:定义用于缓存的共享内存区域。同一个区域可以用于多个地方
1 2 3 Syntax: proxy_cache zone | off; Default: proxy_cache off; Context: http, server, location
2.proxy_cache_path
:设置缓存的路径和其他参数缓存数据存储在文件中,缓存中的文件名是将MD5函数应用于缓存键的结果
1 2 3 4 5 6 Context: http 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]; proxy_cache_path /data/nginx/cache levels=1:2 keys_zone=one:10m;
3.proxy_cache_valid
:设置缓存过期时间
1 2 3 4 5 6 7 8 9 10 Syntax: proxy_cache_valid [code ...] time; Context: http, server, location proxy_cache_valid 200 302 10m; proxy_cache_valid 404 1m; proxy_cache_valid 5m; proxy_cache_valid any 1m;
4.proxy_cache_key
:设置缓存维度
1 2 3 4 5 6 7 Syntax: proxy_cache_key string; Default: proxy_cache_key $scheme $proxy_host $request_uri ; Context: http, server, location proxy_cache_key "$host $request_uri $cookie_user " ; proxy_cache_key $scheme $proxy_host $uri $is_args $args ;
5.proxy_cache_purge
:定义将在何种条件下将请求视为缓存清除请求。如果字符串参数中至少有一个值不为空且不等于“0”,则删除具有相应缓存键的缓存项。通过返回204 (No Content)响应来指示操作成功的结果。
1 2 3 4 5 6 7 8 Syntax: proxy_cache_purge string ...; Context: http, server, location map $request_method $purge_method { PURGE 1; default 0; }
6.proxy_no_cache
:指定不缓存的部分页面,可以与proxy_cache_bypass指令一起使用。
1 2 3 4 5 6 Syntax: proxy_no_cache string ...; Context: http, server, location proxy_no_cache $cookie_nocache $arg_nocache $arg_comment ; proxy_no_cache $http_pragma $http_authorization ;
proxy_cache 相关指令集简述 描述: 其中proxy_cache_path指令
配置了缓存名称以及其存放地址、缓存大小等相关其它参数配置, 而proxy_cache指令
配置是为了启用创建的mycache名称的缓存。
proxy_no_cache : 该指令用于定义满足条件的响应不会被保存到缓存中,在条件字符串中至少有一个条件不为空或者0,符合这样条件的响应才不会被缓存, 其一般会配合proxy_cache_bypass
共同使用;
proxy_cache_bypass : 该指令用于定义哪些情况不从cache读取直接从backend获取资源配置同上。
proxy_cache_key : 该指令给缓存数据定义一个键。
proxy_cache_methods :该指令用于设置缓存哪些HTTP方法,默认缓存HTTP GET/HEAD方法不缓存POST方法。
proxy_cache_valid :该指令用于设置不同响应码的缓存时间。
proxy_cache_min_uses : 该指令用于设置缓存的最小使用次数,默认值为1
proxy_cache_use_stale : 该指令开启(增强)容错能力,即使用缓存内容来响应客户端的请求
示例演示: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 if ($request_uri ~ ^/(login|register|password\/reset)/) { set $cookie_nocache 1; }proxy_no_cache $cookie_nocache (0) $arg_nocache (1) $arg_comment (0) proxy_no_cache $http_pragma $http_authorization ; proxy_cache_key $scheme $proxy_host $uri $is_args $args ; proxy_cache_key $scheme $proxy_host $request_uri ; proxy_cache_methods GET HEAD; proxy_cache_valid 200 302 10m; proxy_cache_valid 301 1h; proxy_cache_valid 404 1m; proxy_cache_valid any 1m; proxy_cache_min_uses 1; proxy_cache_use_stale error timeout http_500 http_502 http_503 http_504;
实践配置: 多磁盘分割缓存,如果有多个硬盘则可以用来在多个硬盘之间分割缓存。1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 proxy_cache_path /mnt/disk1 levels=1:2 keys_zone=cache_1:256m max_size=1024G use_temp_path=off; proxy_cache_path /mnt/disk2 levels=1:2 keys_zone=cache_2:256m max_size=1024G use_temp_path=off; proxy_cache_path /mnt/disk3 levels=1:2 keys_zone=cache_3:256m max_size=1024G use_temp_path=off; split_clients $request_uri $disk { 33.3% 1; 33.3% 2; * 3; } location / { proxy_pass http://127.0.0.1:9090; proxy_cache_key $request_uri ; proxy_cache cache_$disk ; }
实践示例:
示例1.
1 2 3 4 5 6 7 8 9 10 11 proxy_cache_path /path/to/cache levels=1:2 keys_zone=mycache:10m max_size=10g inactive=60m use_temp_path=off; upstream my_upstream { server 192.168.1.20:8080 weight=5 max_fails=5 fail_timeout=30s; server 192.168.1.10:8080 weight=5 max_fails=5 fail_timeout=30s; } server { location / { proxy_cache mycache; proxy_pass http://my_upstream; } }
示例2:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 http { ... proxy_cache_path /opt/app levels:1:2 keys_zone=weiyigeek_cache:10m max_size=10g inactive=60m use_temp_path=off; map $request_method $purge_method { PURGE 1; default 0; } ... server { ... location / { proxy_cache weiyigeek_cache; proxy_pass http://weiyigeek; proxy_cache_valid 200 304 12h; proxy_cache_valid any 10m; proxy_cache_key $host $uri $is_args $args ; proxy_cache_purge $purge_method ; add_header Nginx-Cache "$upstream_cache_status " ; proxy_net_upstream error timeout invalid_header http_500 http_502; include proxy_params; } ... } }
温馨提示: 在proxy_cache_path
指令中的use_temp_path=off
参数,表示会将临时文件保存在缓存数据的同一目录中,此举避免在更新缓存时,磁盘之间互相复制响应数据,减少磁盘IO压力。
补充说明: 问: 如何清理指定缓存?1 2 > 1.rm -rf 删除缓存目录内容 > 2.第三方扩展模块ngx_cache_purge
Nginx 之 黑白名单限制与请求限流 描述: 通常为了防止黑客攻击以及恶意爬虫爬取, 我们需要针对Nginx服务器配置黑白名单和限流措施。
黑白名单之deny 与 allow 描述: 利用 include 指令添加黑白名单配置文件,该指令可以在http, server, location, limit_except
语句块,例如:1 2 3 4 5 6 7 8 9 10 include whiteip.conf; include blockip.conf;
温馨提示: 当被屏蔽的 IP 再次访问我们的nginx服务器网页是,将会显示 403 页面。
访问限制之并发连接与请求速率 描述: 我们可以分别利用Nginx提供的 limit_conn_zone 与 limit_req_zone 模块来限制每个IP的连接数以及请求数。$binary_remote_addr
是限制同一客户端ip地址(节约空间), 注意不是使用$remote_addr
变量;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 http { limit_conn_zone $binary_remote_addr zone=blogweiyigeektop:10m; limit_conn_zone $server_name zone=serverweiyigeektop:10m; limit_conn_log_level info; limit_req_zone $binary_remote_addr zone=weiyigeek_top:10m rate=1r/s; limit_req_zone $binary_remote_addr $uri zone=blog_weiyigeek_top:3m rate=1r/s; server { location ^~ /download1/ { limit_conn serverweiyigeektop 1000; limit_conn blogweiyigeektop 4; limit_rate 200k; alias /data/www.weiyigeek.top/download1/; } location ^~ /download2/ { limit_req zone=weiyigeek_top burst=5 nodelay; alias /data/blog.weiyigeek.top/download2/; } } }
动态屏蔽恶意IP Step 1.从logs目录下日志文件中安装指定规则查找要屏蔽的IP执行如下命令awk '{print $1}' access.log |sort |uniq -c|sort -n
即可,就可以统计出IP的访问次数。1 2 3 4 68 218.76.35.4 73 42.192.96.35 94 139.155.14.45 221 223.202.212.140
Step 2.自动化脚本简单实现访问请求次数多的IP将进行封禁,1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 #! /bin/bash log_nginx="/var/log/nginx" blockfile="/usr/local/nginx/conf.d" ip_tempfile="/tmp/nginx/ip.txt" grep "/atom.xml" $log_nginx /access.log | awk '{print $1}' | sort -rn |uniq -c |awk '{print $2}' > /tmp/nginx/ip.txt for ip in `cat /home/shell/ip.txt`;do result=$(grep $ip $blockfile /blockip.conf) if [ -z "$result " ]; then count=$(grep $ip $log_nginx /access.log|grep "app/user/getCode" |wc -l) if [ $count -ge 20 ]; then echo "deny $ip ;" >> $blockfile /blockip.conf fi fi done /usr/local /nginx/sbin/nginx -s reload
温馨提示: 上述并不是一个非常好的方式,此种方式误杀明显,建议与请求限制联合使用,于此同时我们可以利用Lua + redis
实现一个动态封禁与解封(这个后续在实现)。
白名单与限制联合使用: 描述: 如果 Nginx 前面有 lvs 或者 haproxy 之类的负载均衡或者反向代理,nginx 获取的都是来自负载均衡的连接或请求,此时是不应该限制负载均衡的连接和请求,这就需要 geo 和 map 模块设置白名单了;1 2 3 4 5 6 7 8 9 10 geo $whiteiplist { default 1; 10.11.15.161 0; } map $whiteiplist $limit { 1 $binary_remote_addr ; 0 "" ; } limit_req_zone $limit zone=one:10m rate=10r/s; limit_conn_zone $limit zone=addr:10m;