一、Nginx模块分类
- 核心模块
- HTTP模块:处理HTTP请求和响应的核心功能。
- EVENT模块:处理网络事件,如连接请求和响应等。
- MAIL模块:提供邮件代理服务器的功能。
- 基础模块
- HTTP Access模块:控制对HTTP服务的访问权限。
- HTTP FastCGI模块:与FastCGI服务器交互,常用于PHP等脚本语言的执行。
- HTTP Proxy模块:实现HTTP请求的代理功能。
- HTTP Rewrite模块:根据规则重写请求的URI。
- 第三方模块:
这些模块由Nginx社区或其他开发者提供,用于扩展Nginx的功能。常见的第三方模块包括HTTP Upstream Request Hash模块、Notice模块、HTTP Access Key模块等。
常用模块
ngx_http_auth_basic module模块:实现网站的用户认证功能
ngx http_charset_module模块:可以自定义网页编码(如UTF-8)
ngx_htp_fastcgi_module模块:转发请求给PHP服务
ngx_http_gzip_module模块:实现网站数据压缩功能
ngx_http_log_module模块:记录用户请求的日志
ngx_http_rewrite_module模块:地址重写模块
ngx_http_ssl_module模块:实现HTTPS加密网站
ngx_http_stub_status module模块:显示Nginx服务状态
ngx_htp_upstream_module模块:定义集群服务器组模块,反向代理
ngx_stream_core module模块:定义4层调度(集群服务器组)模块
ngx_http_proxy_connect_module模块:正向代理,非官方模块
ngx_http_index_module
location / {
root html;
index index.html index.htm;
}
ngx_http_gzip_module
http{
gzip on; #开启压缩
gzip_min_length 1k; #1k以内字节的页面不压缩
gzip_comp_level 3; #压缩比例1~9等级
gzip_types text/xml image/png text/plain application/json; #压缩类型到 /etc/nginx/mime.types查看
}
ngx http_charset_module
server {
listen 80;
server_name localhost;
charset utf-8;
nginx -s reload
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title>简体中文标题</title>
</head>
<body>
<center>简体中文内容</center>
</body>
</html>
ngx_http_autoindex_module
默认关闭,在没有主页时会自动以目录的方式生成主页,如果在指定的默认站点目录下有index.html的文件会自动的被打开。
location / {
autoindex off; #是否开启
autoindex_exact_size on; #输出文件大小
autoindex_localtime off; #指定目录列表中的时间是否应以本地时区或 UTC 输出。
}
ngx_http_log_module
指定的格式写入请求日志。
log_format compression '$remote_addr - $remote_user [$time_local] '
'"$request" $status $bytes_sent '
'"$http_referer" "$http_user_agent" "$gzip_ratio"';
access_log /spool/logs/nginx-access.log compression buffer=32k;
# json日志格式
log_format log_json '{"@timestamp": "$time_local", '
'"remote_addr": "$remote_addr", '
'"referer": "$http_referer", '
'"request": "$request", '
'"status": $status, '
'"bytes": $body_bytes_sent, '
'"agent": "$http_user_agent", '
'"x_forwarded": "$http_x_forwarded_for", '
'"up_addr": "$upstream_addr",'
'"up_host": "$upstream_http_host",'
'"up_resp_time": "$upstream_response_time",'
'"request_time": "$request_time"'
' }';
access_log logs/access.log log_json; # 引用日志格式名称
access_log
access_log path [format [buffer=size] [gzip[=level]] [flush=time] [if=condition]];
- access_log off; # 关闭访问日志
- path 指定日志的存放位置。
- format 指定日志的格式。默认使用预定义的combined。
- buffer 用来指定日志写入时的缓存大小。默认是64k。
- gzip 日志写入前先进行压缩。压缩率可以指定,从1到9数值越大压缩比越高,同时压缩的速度也越慢。默认是1。
- flush 设置缓存的有效时间。如果超过flush指定的时间,缓存中的内容将被清空。
- if 条件判断。如果指定的条件计算为0或空字符串,那么该请求不会写入日志。
日志变量
$remote_addr:记录访问网站的客户端地址
$remote_user:远程客户端用户名称
$time_local:记录访问时间与时区
$request:表示request请求头的行
$status:http状态码,记录请求返回的状态,例如:200、404、301等
$body_bytes_sent:服务器发送给客户端的响应body字节数,发送给客户端的文件主体内容的大小,比如899,可以将日志每条记录中的这个值累加起来以粗略估计服务器吞吐量。
$http_referer:记录此次请求是从哪个链接访问过来的,可以根据refer进行防盗链设置
$http_user_agent:记录客户端访问信息,例如:浏览器,手机客户端等
$http_x_forwarded_for:客户端的真实ip,通常web服务器放在反向代理的后面,这样就不能获取到客户的IP地址了,通过$remote_add拿到的IP地址是反向代理服务器的iP地址。反向代理服务器在转发请求的http头信息中,可以增加x_forwarded_for信息,用以记录原有客户端的IP地址和原来客户端的请求的服务器地址。
$http_host 请求地址,即浏览器中你输入的地址(IP或域名)
$ssl_protocol:SSL协议版本
$ssl_cipher:交换数据中的算法
$upstream_status:upstream状态,比如成功是200
$upstream_addr:当ngnix做负载均衡时,可以查看后台提供真实服务的设备
$upstream_response_time:请求过程中,upstream响应时间
$request_time:整个请求的总时间,请求处理时间,单位为秒,精度毫秒; 从读入客户端的第一个字节开始,直到把最后一个字符发送给客户端后进行日志写入为止。
$args:这个变量等于请求行中的参数,同$query_string
$content_length:请求头中的Content-length字段。
$content_type:请求头中的Content-Type字段。
$document_root:当前请求在root指令中指定的值。
$host:请求主机头字段,否则为服务器名称。
$http_user_agent:客户端agent信息
$http_cookie:客户端cookie信息
$limit_rate:这个变量可以限制连接速率。
$request_method:客户端请求的动作,通常为GET或POST。
$remote_addr:客户端的IP地址。
$remote_port:客户端的端口。
$remote_user:已经经过Auth Basic Module验证的用户名。
$request_filename:当前请求的文件路径,由root或alias指令与URI请求生成。
$scheme:HTTP方法(如http,https)。
$server_protocol:请求使用的协议,通常是HTTP/1.0或HTTP/1.1。
$server_addr:服务器地址,在完成一次系统调用后可以确定这个值。
$server_name:服务器名称。
$server_port:请求到达服务器的端口号。
$request_uri:包含请求参数的原始URI,不包含主机名,如:”/foo/bar.php?arg=baz”。
$uri:不带请求参数的当前URI,$uri不包含主机名,如”/foo/bar.html”。
$document_uri:与$uri相同。
ngx_http_stub_status_module
模块提供对基本状态信息的访问, 该模块不是默认构建的需要--with-http_stub_status_module
configuration parameter.
location /basic_status {
stub_status;
}
输出如下
Active connections: 291
server accepts handled requests
16630948 16630948 31070465
Reading: 6 Writing: 179 Waiting: 106
ngx_http_auth_basic_module
允许通过使用“HTTP 基本身份验证”协议验证用户名和密码来限制对资源的访问。
认证信息不会自动失效。一旦设置了基本认证,并且用户输入了正确的用户名和密码,他们将永久保持有效,除非密码文件被更改或删除。
location / {
#认证时的提示
auth_basic "closed site";
auth_basic_user_file conf/htpasswd;
}
# 密码文件格式如下,必须使用密文,不能使用明文密码
name1:password1
name2:password2
name3:password3
密码支持以下类型:
- 使用crypt()函数加密。可以使用Apache Http Server发行版中的“htpasswd”实用程序或“openssl passwd”命令生成。 ·
- 使用基于MD5的密码算法(apr1)的Apache变体进行散列;可以使用相同的工具生成。 ·
- 由RFC2307中描述的”{scheme}data”语法(1.0.3+)指定。当前实现方案包括文本(用于示例,不应使用)、SHA(1.3.13)(SHA-1哈希文本,不应使用)、SSHA(SHA-1加盐哈希,被OpenLDAP、Dovecot等软件包使用)。
yum install httpd-tools -y
htpasswd
以下是一些常用选项的简要说明:
-c:创建一个新文件。如果文件已存在,则会被覆盖。通常用于首次创建密码文件。
-n:不更新文件,而是将结果输出到标准输出(stdout)。这可以用于测试或脚本中。
-b:从命令行直接提供密码,而不是提示用户输入。这适用于脚本自动化。
-i:从标准输入(stdin)读取密码,而不进行验证。这也适用于脚本自动化,但请注意安全性问题。
-m:强制使用MD5加密密码(默认选项)。
-2:强制使用SHA-256加密密码,这是一种更安全的加密方式。
-5:强制使用SHA-512加密密码,这是目前最安全的加密方式之一。
-B:强制使用bcrypt算法加密密码,这是一种非常安全的加密方式,但计算成本较高。
-C:设置bcrypt算法的计算成本(时间复杂度),值越高越安全但计算越慢。
-r:设置SHA-256或SHA-512算法使用的轮数,轮数越多越安全但计算越慢。
-d:强制使用传统的UNIX crypt()函数加密密码,但这种方式只支持最多8个字符的密码,且安全性较低。
-s:强制使用SHA-1加密密码,但SHA-1已被认为不够安全,不推荐使用。
-p:不加密密码(明文存储,非常不安全,仅用于测试)。
-D:从文件中删除指定的用户。
-v:验证指定用户的密码是否正确。
htpasswd -b /etc/nginx/htpasswd shadow 123456
Updating password for user shadow
cat /etc/nginx/htpasswd
shadow:$apr1$AEwCPzeg$7UAHOswybbpzjgFCjXcnV1
ngx_http_access_module
允许限制对某些客户端地址的访问。
location / {
deny 192.168.1.1;
allow 192.168.1.0/24;
allow 10.1.1.0/16;
allow 2001:0db8::/32;
deny all;
}
按顺序检查规则,直到找到第一个匹配项。在此示例中,仅允许访问 IPv4 网络 10.1.1.0/16 和 192.168.1.0/24(不包括地址 192.168.1.1)以及 IPv6 网络 2001:0db8::/32。如果规则很多,最好使用 ngx_http_geo_module 模块变量。
ngx_http_limit_conn_module
用于限制每个定义的键的连接数,特别是来自单个 IP 地址的连接数。 并非所有连接都被计算在内。仅当服务器处理了请求并且已读取整个请求标头时,才会对连接进行计数。
http {
# 开启一个内存空间,设置了一个变量addr设置内存空间大小10m(连接频率)
limit_conn_zone $binary_remote_addr zone=addr:10m;
...
server {
...
location /download/ {
# 调用,限制同时最高1个连接
limit_conn addr 1;
}
ngx_http_limit_req_module
限制每个定义的键的请求处理速率,特别是来自单个 IP 地址的请求的处理速率。
http {
# http标签段定义请求限制, rate限制速率,限制一秒钟最多一个IP请求
# zooe开启一个内存空间名字叫做one,大小10m
limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;
...
server {
...
location /search/ {
#zone指定共享内存空间的名字(perip),burst超过该配置的请求数,则返回503
limit_req zone=one burst=5;
#limit_req zone=one burst=5 nodelay;
nodelay # 不延迟处理burst规定的连接,瞬间处理,可能导致流量高峰 默认delay
}
设置共享内存区域和请求的最大突发大小。如果请求速率超过为区域配置的速率,则会延迟其处理,以便以定义的速率处理请求。过多的请求会被延迟,直到其数量超过最大突发大小,在这种情况下,请求会因错误 503(服务暂时不可用)而终止
ab -n 200 -c 100 http://127.0.0.1/index.html
Benchmarking 127.0.0.1 (be patient)
Completed 100 requests
Completed 200 requests
Finished 200 requests
Server Software: nginx/1.20.1
Server Hostname: 127.0.0.1
Server Port: 80
Document Path: /index.html
Document Length: 179 bytes
Concurrency Level: 100
Time taken for tests: 5.017 seconds
Complete requests: 200
Failed requests: 194
设置响应被拒绝的请求而返回的状态代码。
limit_req_status 503;
# 错误页实在默认站点目录的下去找。
error_page 503 /503_err.html
ngx_http_ssl_module
为 HTTPS 提供必要的支持。 该模块不是默认构建的,应该使用 –with-http_ssl_module 配置参数启用。
为了减少处理器负载,建议
- 将工作进程的数量设置为等于处理器的数量
- 启用保持活动连接
- 启用共享会话缓存
- 禁用内置会话缓存,
-
并可能增加会话生命周期(默认为 5 分钟)
worker_processes auto;
http {
...
server {
listen 443 ssl;
keepalive_timeout 70;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers AES128-SHA:AES256-SHA:RC4-SHA:DES-CBC3-SHA:RC4-MD5;
ssl_certificate /usr/local/nginx/conf/cert.pem;
ssl_certificate_key /usr/local/nginx/conf/cert.key;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
...
}
仅当使用 OpenSSL 1.0.1 或更高版本时,TLSv1.1 和 TLSv1.2 参数(1.1.13、1.0.12)才有效。
仅当使用使用 TLSv1.3 支持构建的 OpenSSL 1.1.1 时,TLSv1.3 参数 (1.13.0) 才有效。
缓存可以是以下任何类型:
- off : 严格禁止使用会话缓存:nginx 明确告诉客户端会话不能被重用。
- none: 温和地禁止使用会话缓存:nginx 告诉客户端会话可以重用,但实际上并不将会话参数存储在缓存中。
- builtin:内置 OpenSSL 中内置的缓存;仅由一个工作进程使用。缓存大小在会话中指定。如果未给出大小,则等于 20480 个会话。使用内置缓存可能会导致内存碎片。
- shared:所有工作进程之间共享的缓存。缓存大小以字节为单位指定; 1 MB 可以存储大约 4000 个会话。每个共享缓存应该有一个任意名称。具有相同名称的缓存可以在多个虚拟服务器中使用。
ssl_session_ticket_key current.key;
设置一个文件,其中包含用于加密和解密 TLS 会话票证的密钥。如果必须在多个服务器之间共享相同的密钥,则该指令是必需的。默认情况下,使用随机生成的密钥。
ssl_session_tickets on;
通过 TLS 会话票证启用或禁用会话恢复。
ssl_session_timeout 5m;
指定客户端可以重用会话参数的时间。
gx_http_ssl_module 模块支持的变量:
$ssl_cipher
:返回已建立的SSL连接所使用的加密套件字符串。$ssl_ciphers
(1.11.7+):返回客户端支持的加密套件列表,已知加密套件以名称列出,未知的以十六进制表示,例如:AES128-SHA:AES256-SHA:0x00ff
。此变量在OpenSSL 1.0.2或更高版本上完全支持。$ssl_client_cert
:返回已建立的SSL连接的客户端证书(PEM格式),每行(除第一行外)前加制表符,用于proxy_set_header
指令。$ssl_client_fingerprint
(1.7.1+):返回已建立的SSL连接的客户端证书的SHA1指纹。$ssl_client_i_dn
(1.11.6+):根据RFC 2253返回已建立的SSL连接的客户端证书的“颁发者DN”字符串。$ssl_client_i_dn_legacy
:在1.11.6版本之前,这是返回客户端证书“颁发者DN”的变量名,与$ssl_client_i_dn
相同。$ssl_client_raw_cert
:返回已建立的SSL连接的客户端证书的原始PEM格式。$ssl_client_s_dn
(1.11.6+):根据RFC 2253返回已建立的SSL连接的客户端证书的“主题DN”字符串。$ssl_client_s_dn_legacy
:在1.11.6版本之前,这是返回客户端证书“主题DN”的变量名,与$ssl_client_s_dn
相同。$ssl_client_serial
:返回已建立的SSL连接的客户端证书的序列号。$ssl_client_v_end
(1.11.7+):返回客户端证书的有效期结束日期。$ssl_client_v_remain
(1.11.7+):返回客户端证书剩余的有效天数。$ssl_client_v_start
(1.11.7+):返回客户端证书的有效期开始日期。$ssl_client_verify
:返回客户端证书验证的结果。如果证书存在并验证成功,返回“SUCCESS”;如果验证失败,返回“FAILED:reason”,其中“reason”是失败的具体原因;如果没有提供证书,则返回“NONE”。在1.11.7版本之前,“FAILED”结果不包含原因字符串。$ssl_curves
(1.11.7+):返回客户端支持的椭圆曲线列表。已知曲线以名称列出,未知的以十六进制表示,例如:0x001d:prime256v1:secp521r1:secp384r1
。此变量仅在使用OpenSSL 1.0.2或更高版本时受支持。在旧版本中,该变量的值将是一个空字符串。此变量仅对新会话可用。$ssl_protocol
:返回已建立的SSL连接的协议。$ssl_server_name
(1.7.0+):返回通过SNI(服务器名称指示)请求的服务器名称。$ssl_session_id
:返回已建立的SSL连接的会话标识符。$ssl_session_reused
(1.5.11+):如果SSL会话被重用,则返回“r”,否则返回“.”(点)。这有助于确定SSL会话是否被复用,从而优化性能。
生成有效期为一年的域名证书domain.crt和私钥domain.key
# 1. 生成私钥
openssl genpkey -algorithm RSA -out domain.key -pkeyopt rsa_keygen_bits:2048
# 2. 创建CSR
openssl req -new -key domain.key -out domain.csr -subj "/CN=domain.com"
# 3. 自签名证书
openssl x509 -req -days 365 -in domain.csr -signkey domain.key -out domain.crt
server {
listen 443 ssl;
server_name localhost;
ssl_certificate /etc/nginx/domain.crt;
ssl_certificate_key /etc/nginx/domain.key;
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
location / {
root html;
index index.html index.htm;
}
}
在Nginx上配置SSL证书的过程大致如下:
1、准备SSL证书和私钥。可以从信任的证书颁发机构购买或免费获取。确保将证书(通常为.crt或.pem格式)和私钥(通常为.key格式)保存在安全的位置。
2、在Nginx配置文件中添加SSL配置。这通常涉及编辑或创建nginx.conf文件。在server块中添加以下指令:
listen 443 ssl;:指定Nginx在443端口上监听HTTPS连接。
ssl_certificate /path/to/certificate.crt;:指定证书文件的路径。
ssl_certificate_key /path/to/private.key;:指定私钥文件的路径。
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;:指定支持的SSL协议版本。
ssl_ciphers ‘CipherSuite’;:指定加密算法套件,以增强安全性。
ssl_session_cache shared:SSL:10m;:设置SSL会话缓存的大小和时间。
ssl_session_timeout 5m;:设置SSL会话的超时时间。
3、重新加载Nginx配置。使用命令如sudo nginx -s reload来使新的配置生效。
验证配置。使用nginx -t命令来测试配置文件的正确性。
4、确保HTTP请求重定向到HTTPS。在server块中添加重定向规则,将所有HTTP请求自动重定向到HTTPS,例如,使用return 301 https://$host$request_uri;语句。
配置HTTPS严格传输安全(HSTS)。通过添加add_header Strict-Transport-Security “max-age=31536000; includeSubDomains”;到配置中,可以提高安全性。
HSTS
Web服务器通过在HTTPS响应头中设置Strict-Transport-Security
字段来启用HSTS策略。这个字段包含了一些指令,如max-age
(定义HSTS策略在浏览器中的缓存时间)、includeSubDomains
(表示该策略应用于当前域名的所有子域)和preload
(表示该域名同意申请加入浏览器发起的Preload List)。
- 浏览器行为:当浏览器接收到包含HSTS策略的HTTPS响应时,它会在缓存时间内(由
max-age
指定)自动将所有对该域名的HTTP请求转换为HTTPS请求。如果浏览器在缓存时间内尝试通过HTTP访问该域名,它将通过307重定向到HTTPS,并显示HSTS相关的响应头。 - 安全性提升:通过强制使用HTTPS连接,HSTS可以有效防止协议降级攻击、cookie劫持和中间人攻击等网络威胁。此外,它还可以确保用户无法忽略浏览器的不安全提示,从而进一步保证用户的数据安全。
location模块
正则须知
常用的正则表达式
^ :匹配输入字符串的起始位置
$ :匹配输入字符串的结束位置
* :匹配前面的字符零次或多次。如“ol*”能匹配“o”及“ol”、“oll”
+ :匹配前面的字符一次或多次。如“ol+”能匹配“ol”及“oll”、“olll”,但不能匹配“o”
? :匹配前面的字符零次或一次,例如“do(es)?”能匹配“do”或者“does”,”?”等效于”{0,1}”
. :匹配除“\n”之外的任何单个字符,若要匹配包括“\n”在内的任意字符,请使用诸如“[.\n]”之类的模式
\ :将后面接着的字符标记为一个特殊字符或一个原义字符或一个向后引用。如“\n”匹配一个换行符,而“\$”则匹配“$”
\d :匹配纯数字[0-9] \s :空白符 \w :任意单词字符包括下划线[A-Za-z0-9_]
{n} :重复 n 次
{n,} :重复 n 次或更多次
{n,m} :重复 n 到 m 次
[] :定义匹配的字符范围
[c] :匹配单个字符 c
[a-z] :匹配 a-z 小写字母的任意一个
[a-zA-Z0-9] :匹配所有大小写字母或数字
() :表达式的开始和结束位置
| :或运算符
匹配分为三种
精准匹配:location = / {…}
一般匹配:location / {…}
正则匹配:location ~ / {…}
location 常用的匹配规则:
= :进行普通字符精确匹配,也就是完全匹配。
^~ :表示普通字符匹配。使用前缀匹配,不匹配正则表达。
~ :区分大小写的匹配。
~* :不区分大小写的匹配。
!~ :区分大小写的匹配取非。
!~* :不区分大小写的匹配取非。
@ 用于内部跳转的命名location
合并连续的/符号 Merge_slashes on
Location匹配规则的优先级
优先级:具体文件路径 > 精准配置 = > 前缀匹配 ^~ > 正则匹配 ~,~,!~,!~ > 一般前缀匹配 /XXXX > 通用匹配 /
首先匹配具体文件路径例如/a/index.html,找不到文件的精确匹配,在找精确匹配,在没有精准匹配的时候,先看所有前缀的长度,取最长匹配的location;
如果最长的前缀匹配是带有^~的则不看其它的正则匹配,直接使用^~的location匹配用户的访问路径并跳转页面,然后匹配正则表达式。
虽然正则理论上优先级高于一般前缀匹配,但是匹配的顺序是先匹配一般前缀,再去匹配正则
正则匹配看上下顺序,根据配置文件的配置由上往下依次匹配,匹配到即停止
location / {
root /data/www/test;
index index.html index.htm;
}
location ^~ /test {
alias /data/www/location;
index index.html index.htm;
}
location /test/index.html {
return 200 "111";
}
location =/test/index.html {
return 200 "222";
}
以上配置, =/test/index.html 》 /test/index.html 》 ^~ /test 》 /
@内部重定向
#error_page 404 http://www.baidu.com # 直接这样是不允许的
error_page 404 = @fallback;
location @fallback {
proxy_pass http://www.baidu.com;
}
ngx_http_rewrite_module
根据请求 URI 搜索位置; 找到的位置内指定的该模块的指令将按顺序执行; 如果请求 URI 被重写,则重复循环,url重写不会超过10次
if ($http_user_agent ~ MSIE) {
rewrite ^(.*)$ /msie/$1 break;
}
这条规则检查请求中的User-Agent头部是否包含"MSIE"(这是Microsoft Internet Explorer浏览器的旧版标识符)。如果包含,Nginx将使用rewrite指令将请求的URI(统一资源标识符)重写为/msie/加上原始URI的路径。break标志意味着重写后的请求将停止进一步的处理,并直接以新的URI进行搜索或处理。这通常用于为旧版浏览器提供专门的页面或样式。
从Cookie中提取ID:
if ($http_cookie ~* "id=([^;]+)(?:;|$)") {
set $id $1;
}
~是区分大小写的匹配,~*是不区分大小写的匹配,!~和!~*是不匹配
这条规则使用正则表达式从请求的Cookie头部中提取名为id的值。如果找到,它将该值存储在Nginx变量$id中,供后续操作使用。正则表达式id=([^;]+)(?:;|$)匹配id=后跟任意非分号字符(这些字符被捕获到$1中),然后是一个分号或字符串的结束。
禁止POST请求:
if ($request_method = POST) {
return 405;
}
这条规则检查请求的HTTP方法是否为POST。如果是,Nginx将返回HTTP状态码405(Method Not Allowed),表示该资源不支持POST请求方法。这可以用于保护某些资源免受修改或确保仅通过特定方式(如GET请求)访问。
限制慢连接的速率:
if ($slow) {
limit_rate 10k;
}
这里的$slow变量通常不是Nginx内置的一部分,它可能是通过某种自定义方式(如通过Nginx的map指令或第三方模块)设置的。如果$slow为真(即,如果某个条件判断该连接为“慢”),则使用limit_rate指令将该连接的下载速率限制为每秒10KB。这有助于管理网络带宽或防止某些类型的滥用。
检查无效的Referer头部:
if ($invalid_referer) {
return 403;
}
这条规则检查变量$invalid_referer。这个变量通常通过Nginx的valid_referers指令或类似机制设置,用于确定请求的Referer头部是否有效或符合预期。如果$invalid_referer为真(即,如果Referer头部被认为无效),Nginx将返回HTTP状态码403(Forbidden),拒绝请求。这有助于防止某些类型的跨站请求伪造(CSRF)或确保请求来自预期的来源。
如果指定的正则表达式与请求 URI 匹配,则 URI 将按照替换字符串中的指定进行更改。重写指令按照它们在配置文件中出现的顺序依次执行。可以使用标志终止指令的进一步处理。如果替换字符串以“http://”、“https://”或“$scheme”开头,则处理停止并将重定向返回给客户端。如果正则表达式包含“}”或“;”字符,整个表达式应该用单引号或双引号引起来。
rewrite *regex*
*replacement*
[*flag*
];
flag参数:
- last : 停止处理当前的 ngx_http_rewrite_module 指令集并开始搜索与更改的 URI 匹配的新位置;
- break :与break指令一样,停止处理当前的ngx_http_rewrite_module指令集;
- redirect : 返回带有 302 代码的临时重定向;如果替换字符串不以“http://”、“https://”或“$scheme”开头,则使用;
- permanent : 返回带有 301 代码的永久重定向。
location /download/ {
rewrite ^(/download/.*)/media/(.*)\..*$ $1/mp3/$2.mp3 break;
rewrite ^(/download/.*)/audio/(.*)\..*$ $1/mp3/$2.ra break;
return 403;
}
最后一个标志应该用break替换,否则nginx将循环10次并返回500错误:
如果替换字符串包含新的请求参数,则先前的请求参数将附加在它们之后。如果不希望出现这种情况,请在替换字符串末尾放置问号以避免附加它们,例如:
rewrite ^/users/(.*)$ /show?user=$1? last;
将旧的域名永久重定向到新域名用到$host变量
permanent表示永久重定向
if ($host = "blog.shadowwu.club"){
rewrite /(.*)$ http://www.shadowwu.club/$1 permanent;
if判断重定向
if ($uri ~ ^/abc/123.html){
rewrite ^/ /;
}
^/表示匹配整个url 后面的重写一般与源url无关
$request_uri
:包含请求参数的原始URI,不包含主机名,如:http://www.kgc.com/abc/bbs/index.html?a=1&b=2 中的 /abc/bbs/index.php?a=1&b=2$uri
:这个变量指当前的请求URI,不包括任何参数,如:/abc/bbs/index.html$document_uri
:与$uri相同,这个变量指当前的请求URI,不包括任何传递参数,如:/abc/bbs/index.html$query_string
:请求参数Parameter
if条件判断
1、直接判断变量
if ($slow) {}
如果变量值是空字符串或者"0"时,判定为false;否则,判定为true。
1.0.1版本前,任何以"0"开头的字符串,判定为false。
2、字符串相等
使用 “=” 和 “!=” 操作符判断是否等于字符串
if ($request_method = POST) {}
3、正则匹配
~:判断时区分字符大小写
~*:判断时不区分字符大小写
!~:判断时区分字符大小写
!~*:判断时不区分字符大小写
4、文件及目录判断
“-f”, “!-f”:判断指定的路径是否为存在且为文件;
“-d”, “!-d”:判断指定的路径是否为存在且为目录;
“-e”, “!-e”:判断指定的路径是否存在,文件或目录均可;
“-x”, “!-x”:判断指定路径的文件是否存在且可执行;
if (!-f "$document_root/index.html") {}
ngx_http_proxy_module
反向代理的优点
1、保护服务安全
- 隐藏服务节点的IP
- 将服务节点置于防火墙之后,避免直接攻击业务节点服务器
2、服务节点更专注于业务,同时提升性能
由于有反向代理的存在,可以让反向代理服务器去实现比如https、gzip压缩等与业务无关的功能
提供动静态分离,将静态文件发往静态服务器或本地文件系统,避免业务节点处理这些与业务无关的请求
提供缓存机制,将一些短时间内不会变化的动态内容,在反向代理服务器这层增加缓存,降低业务服务器的请求量
由于控制权在代理服务这边,完全可以根据服务节点的性能动态分配请求,做到服务节点性能最佳
正是由于Ngxin引入了反向代理的特性,让请求和响应都要经过Nginx,因此给Nginx带来了非常多的可能。比如负载均衡、HTTP缓存等。
- 基本语法:
proxy_pass URL;
,其中URL可以是后端服务器的协议(如http、https)、域名、IP地址和端口,以及可选的URI。 - 配置位置:
proxy_pass
指令通常配置在Nginx的location
块中,也可以在if
语句(位于location
块内)或limit_except
块中使用。 - 转发规则
- 当
proxy_pass
后面的URL以/
结尾时,表示将请求转发到后端服务器的根路径,并且不会将location
块中匹配的路径部分包含在内。 - 当
proxy_pass
后面的URL不以/
结尾时,Nginx会将location
块中匹配的路径部分附加到后端服务器的URL上。
- 当
location / {
proxy_pass http://localhost:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
#后端服务器获取远程客户端真实ip地址
}
# 设置Nginx与后端服务器建立连接的超时时间
# 如果在这个时间内无法建立连接,则Nginx会返回错误
proxy_connect_timeout 30;
# 设置Nginx向后端服务器发送请求的超时时间
# 如果在这个时间内后端服务器没有接收到完整的请求,则连接将被关闭
proxy_send_timeout 60;
# 设置Nginx从后端服务器读取响应的超时时间
# 如果在这个时间内Nginx没有从后端服务器读取到任何数据,则连接将被关闭
proxy_read_timeout 60;
# 设置Nginx读取后端服务器响应的初始缓冲区大小
# 这个缓冲区用于存储从后端服务器读取的响应头部信息
proxy_buffer_size 32k;
# 开启或关闭Nginx的响应缓冲功能
# 当设置为on时,Nginx会等待后端服务器发送完整的响应后再发送给客户端
# 这可以减少发送到客户端的数据包数量,但可能会增加内存使用
proxy_buffering on;
# 设置Nginx用于读取后端服务器响应的缓冲区数量和大小
# 这里设置为4个缓冲区,每个缓冲区的大小为128k
# Nginx会根据需要分配这些缓冲区来存储从后端服务器读取的响应数据
proxy_buffers 4 128k;
# 设置在读取响应时,Nginx可以使用的“忙”缓冲区的大小
# 当Nginx需要将响应数据发送给客户端时,它会优先使用这些“忙”缓冲区
# 如果这些缓冲区中的数据不足以满足客户端的请求,Nginx会尝试从其他缓冲区中获取数据
# 这个设置可以帮助Nginx更高效地处理响应数据的传输
proxy_busy_buffers_size 256k;
# 设置Nginx可以将响应数据写入临时文件的最大大小
# 如果Nginx的缓冲区不足以存储整个响应,并且响应的大小超过了这个值,
# 则Nginx会将响应数据写入临时文件,然后再发送给客户端
# 这个设置有助于防止Nginx因为内存不足而崩溃
proxy_max_temp_file_size 256k;
ngx_http_upstream_module
模块用于定义可由 proxy_pass、fastcgi_pass、uwsgi_pass、scgi_pass 和 memcached_pass 指令引用的服务器组。
负载均衡
upstream backend {
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;
}
server {
location / {
proxy_pass http://backend;
}
}
ip_hash 分配固定ip
默认轮询,不固定ip,轮回访问多个server
参数:
1、weight可以设置后台服务器的权重值,默认为1
2、max_fails可以设置后台服务器的最大连接失败次数
3、fail_timeout可以设置后台服务器的失败超时时间,单位为秒
4、down标记服务器已关机,不参与集群调度
注意upstream在http模块下,server模块上
ngx_http_proxy_connect_module
正向代理需要第三方模块,正向代理隐藏客户端
server {
##代理端口
listen 3100;
resolver 192.168.125.21 114.114.114.114 valid=300s;
resolver_timeout 10s;
#server_name localhost;
proxy_connect;
proxy_connect_allow 443 80;
proxy_connect_connect_timeout 10s;
proxy_connect_read_timeout 10s;
proxy_connect_send_timeout 10s;
location / {
proxy_set_header Host $host;
#代理到请求的地址
proxy_pass $scheme://$http_host$request_uri;
proxy_buffers 256 4k;
proxy_max_temp_file_size 0k;
proxy_connect_timeout 30;
proxy_send_timeout 60;
proxy_read_timeout 60;
proxy_next_upstream error timeout invalid_header http_502;
}
# 启用日志记录
access_log /usr/local/nginx/logs/proxy.log;
}
stream
Nginx从1.9.0版本开始引入了Stream模块(ngx_stream_core_module),这个模块主要用来处理四层网络协议(即网络层和传输层协议,如TCP和UDP)的流量。与Nginx的HTTP模块不同,Stream模块不处理HTTP请求,而是直接操作TCP或UDP数据包。
- 转发和代理:Stream模块可以将接收到的TCP或UDP流量转发到后端服务器,实现代理功能。这对于需要代理数据库连接、SMTP服务、DNS查询等场景非常有用。
- 负载均衡:Stream模块支持负载均衡功能,可以将请求分发到多个后端服务器,提高系统的可用性和性能。它支持多种负载均衡算法,如轮询、最小连接数、IP哈希等。
- 配置灵活:Stream模块的配置语法与HTTP模块类似,但专注于四层协议的处理。它允许用户定义监听端口、设置代理目标、配置负载均衡策略等。
cat > /usr/local/nginx/conf/mynginx.conf << EOF
stream {
upstream sshserver {
server 192.168.125.21:22;
}
server {
listen 220;
proxy_pass sshserver;
}
}
EOF
以上是SSL代理,通过192.168.125.20的220端口对192.168.125.21进行了ssh访问
ngx_http_fastcgi_module
允许将请求传递到 FastCGI 服务器。
PHP-FPM(FastCGI Process Manager:FastCGI 进程管理器
location / {
fastcgi_pass localhost:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /home/www/scripts/php$fastcgi_script_name;
fastcgi_param QUERY_STRING $query_string;
fastcgi_param REQUEST_METHOD $request_method;
fastcgi_param CONTENT_TYPE $content_type;
fastcgi_param CONTENT_LENGTH $content_length;
}
fastcgi_pass localhost:9000;
- 这行指令告诉Nginx将请求传递给哪个FastCGI服务器。在这个例子中,它指向
localhost
的9000
端口,这通常是PHP-FPM监听的默认端口。这意味着Nginx将作为前端服务器,接收客户端的请求,并将它们转发到运行在相同服务器上的PHP-FPM进程进行处理。
- 这行指令告诉Nginx将请求传递给哪个FastCGI服务器。在这个例子中,它指向
fastcgi_index index.php;
- 当请求是一个目录时,这行指令指定了Nginx应该尝试作为脚本执行的默认文件名。在这个例子中,如果请求的是一个目录(且该目录中存在
index.php
文件),Nginx将尝试执行该目录下的index.php
文件。
- 当请求是一个目录时,这行指令指定了Nginx应该尝试作为脚本执行的默认文件名。在这个例子中,如果请求的是一个目录(且该目录中存在
fastcgi_param ...;
- 这些指令用于设置传递给FastCGI进程的参数。每个
fastcgi_param
指令都定义了一个环境变量,这些环境变量在PHP脚本执行时是可见的。 SCRIPT_FILENAME /home/www/scripts/php$fastcgi_script_name;
:这指定了PHP脚本的完整路径。$fastcgi_script_name
是一个Nginx变量,包含了请求的URI(不包括查询字符串)。这个指令告诉PHP-FPM哪个文件应该被执行。注意这里的路径/home/www/scripts/php
可能需要根据你的实际文件结构进行调整。QUERY_STRING $query_string;
:将请求的查询字符串(URL中?
后面的部分)传递给PHP脚本。REQUEST_METHOD $request_method;
:将HTTP请求方法(如GET、POST等)传递给PHP脚本。CONTENT_TYPE $content_type;
和CONTENT_LENGTH $content_length;
:分别将请求的内容类型和长度传递给PHP脚本。这对于处理POST请求特别有用,因为POST请求体可能包含表单数据或文件上传。
- 这些指令用于设置传递给FastCGI进程的参数。每个
server {
listen 80;
listen 801;
server_name testnginx.org
test.testnginx.org
www.testnginx.org;
root /data/www/test;
location / {
index index.html index.htm;
}
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000;
#fastcgi_pass unix:/app/php74/var/run/php-fpm.sock;
fastcgi_index index.php;
#fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
$document_root:这是一个Nginx变量,它代表了当前请求的根目录。这个变量通常在server块或location块中通过root指令设置。例如,root /var/www/html; 会将$document_root设置为/var/www/html。
$fastcgi_script_name:这是另一个Nginx变量,它包含了请求的URI(统一资源标识符),但不包括任何查询字符串(即URL中?后面的部分)。这个变量是Nginx在内部处理请求时构建的,它反映了请求的URI路径。
将这两个变量组合起来,$document_root$fastcgi_script_name就构成了要执行的PHP脚本的完整路径。例如,如果$document_root是/var/www/html,且请求的URI是/index.php,那么$document_root$fastcgi_script_name就会是/var/www/html/index.php。
参考
nginx 的常用模块 – Gshelldon – 博客园 (cnblogs.com)