nginx 加工上游服务器返回的内容,并返回给客户端
禁用上游响应头部功能
1 2 3 | Syntax: proxy_ignore_headers field ...; Default: — Context: http, server, location |
功能介绍:某些响应头部可以改变nginx的行为,使用proxy_ignore_headers可以禁用他们生效;
可以禁用的头部功能
X-Accel-Redirect:由上游服务器指定在nginx内部重定向,控制请求的执行
X-Accel-Limit-Rate : 由上游设置发往客户端的速度限制,等同limit_rate指令
X-Accel-Buffering : 由上游控制是否缓存上游的响应
X-Accel-Charset : 由上游控制Content-Type中的Charset
缓存相关:
X-Accel-Expires : 设置响应在nginx的缓存时间,单位秒;@开头表示一天某时刻
Expires:控制nginx缓存时间,优先级低于X-Accel-Expires
Cache-Control:控制nginx缓存时间,优先级低于X-Accel-Expires
Set-Cookie:响应中出现Set-Cookie则不缓存,可通过proxy_ignore_headers禁止生效
Vary:响应中出现Vary:*则不缓存,同样可以禁止生效
转发上游响应指令
1 2 3 | Syntax: proxy_hide_header field; Default: — Context: http, server, location |
proxy_hide_header 功能:对上游响应中的某些头部,设置不向客户端转发
proxy_hide_header 功能默认不转发的响应包头:
Date :由ngx_http_header_filter_module过滤模块填写,值为nginx发送响应头部时的时间
server:由ngx_http_header_filter_module过滤模块过滤模块填写,值为nginx版本
X-Pad:通常是Apache为避免浏览器BUG生成的头部,默认忽略
X-Accel-:用于控制nginx行为的响应,不需要向客户端转发
proxy_pass_header : 对于已经被proxy-hide-header的头部,设置向客户端转发
配置
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 | [root@python vhast] # cat shangyou.conf server { listen 8011 ; default_type text / plain; return 200 '8011 server response.\n' ; } server { listen 8012 ; default_type text / plain; root html; location / { add_header aaa 'aaaa value' ; 添加aaa字段 } location / test { return 200 ' 8012 server response. uri: $uri method: $request_method requset: $request http_name: $http_name \n'; } } [root@python vhast] # cat upstream.conf upstream rrups{ #ip_hash; #hash user_$arg_username; #server 127.0.0.1:8011; server 127.0 . 0.1 : 8012 ; #keepalive 32; } server { #set_real_ip_from 192.168.183.4; #real_ip_recursive on; #real_ip_header X-Forwarded-For; server_name www.rrups.com; access_log logs / upstream.log main; error_log rrups_error.log info; location / { #proxy_pass http://rrups/addurl; proxy_pass http: / / rrups; #proxy_hide_header aaa; #没有屏蔽头部aaa字端 #proxy_method POST; #proxy_pass_request_headers off; #proxy_pass_request_body off; #proxy_set_body 'hello world'; #proxy_set_header name ''; proxy_http_version 1.1 ; proxy_set_header Connection ""; } } |
测试
1 2 3 4 5 6 7 8 9 10 11 | [root@python vhast] # curl www.rrups.com -I HTTP / 1.1 200 OK Server: nginx / 1.15 . 9 Date: Wed, 17 Jul 2019 06 : 41 : 13 GMT Content - Type : text / html Content - Length: 612 Connection: keep - alive Last - Modified: Wed, 10 Jul 2019 18 : 23 : 02 GMT ETag: "5d262d06-264" aaa: aaaa value # Accept - Ranges: bytes |
屏蔽后测试
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 | [root@python vhast] # cat upstream.conf upstream rrups{ #ip_hash; #hash user_$arg_username; #server 127.0.0.1:8011; server 127.0 . 0.1 : 8012 ; #keepalive 32; } server { #set_real_ip_from 192.168.183.4; #real_ip_recursive on; #real_ip_header X-Forwarded-For; server_name www.rrups.com; access_log logs / upstream.log main; error_log rrups_error.log info; location / { #proxy_pass http://rrups/addurl; proxy_pass http: / / rrups; proxy_hide_header aaa; #proxy_method POST; #proxy_pass_request_headers off; #proxy_pass_request_body off; #proxy_set_body 'hello world'; #proxy_set_header name ''; proxy_http_version 1.1 ; proxy_set_header Connection ""; } } [root@python vhast] # curl www.rrups.com -I HTTP / 1.1 200 OK Server: nginx / 1.15 . 9 Date: Wed, 17 Jul 2019 06 : 43 : 23 GMT Content - Type : text / html Content - Length: 612 Connection: keep - alive Last - Modified: Wed, 10 Jul 2019 18 : 23 : 02 GMT ETag: "5d262d06-264" Accept - Ranges: bytes |
上游服务器头部设置影响下游发送速率
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 | [root@python vhast] # cat shangyou.conf server { listen 8011 ; default_type text / plain; return 200 '8011 server response.\n' ; } server { listen 8012 ; default_type text / plain; root html; location / { add_header X - Accel - Limit - Rate 10 ; #在上游服务器,添加代理服务向客户端每秒发送的字节数 } location / test { return 200 ' 8012 server response. uri: $uri method: $request_method requset: $request http_name: $http_name \n'; } } |
测试
1 2 | [root@python vhast] # curl www.rrups.com -I HTTP / 1.1 200 OK |
1 2 3 | Syntax: proxy_pass_header field; Default: — Context: http, server, location |
修改返回的Set-Cookie头部
1 2 3 4 5 6 7 8 9 10 11 | Syntax: proxy_cookie_domain off; #修改上游服务器的Set-Cookie的指令;修改域名 proxy_cookie_domain domain replacement; Default: proxy_cookie_domain off; Context: http, server, location Syntax: proxy_cookie_path off; # 修改URI部分内容做替换 proxy_cookie_path path replacement; Default: proxy_cookie_path off; Context: http, server, location |
修改返回的Location头部
1 2 3 4 5 | Syntax: proxy_redirect default; proxy_redirect off; proxy_redirect redirect replacement; Default: proxy_redirect default; Context: http, server, location |
上游返回失败时的处理方法
1 2 3 4 | Syntax: proxy_next_upstream error | timeout | invalid_header | http_500 | http_502 | http_503 | http_504 | http_403 | http_404 | http_429 | non_idempotent | off ...; Default: proxy_next_upstream error timeout; Context: http, server, location |
前提:没有向客户端发送任何内容
配置: error(网络错误) 、timeout(超时后) 、invalid_header(不合法的header) 、http_ (返回http错误码)、non_idempotent (在上游服务器不能使用这个方法时)、off()
限制proxy_next_upstream的时间与次数
1 2 3 4 5 6 7 8 9 | Syntax: proxy_next_upstream_timeout time; #从请求开始选用上游服务的时间 Default: proxy_next_upstream_timeout 0 ; Context: http, server, location Syntax: proxy_next_upstream_tries number; # 重试次数 Default: proxy_next_upstream_tries 0 ; Context: http, server, location |
用error_page 拦截上游失败的响应;当上游响应码大于等于300时,将响应返回客户端还是按照error_page指令处理
1 2 3 | Syntax: proxy_intercept_errors on | off; Default: proxy_intercept_errors off; Context: http, server, location |
不做修改配置
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 | [root@python vhast] # cat shangyou.conf server { listen 8011 ; default_type text / plain; return 200 '8011 server response.\n' ; } server { listen 8012 ; default_type text / plain; root html; location / { add_header X - Accel - Limit - Rate 10 ; } location / test { return 200 ' 8012 server response. uri: $uri method: $request_method requset: $request http_name: $http_name \n'; } } server { listen 8013 ; default_type text / plain; return 500 '8013 server Internal Error.\n' ; } [root@python vhast] # cat proxy_next.conf upstream ps{ #ip_hash; #hash user_$arg_username; server 127.0 . 0.1 : 8011 ; server 127.0 . 0.1 : 8013 ; #keepalive 32; } server { #set_real_ip_from 192.168.183.4; #real_ip_recursive on; #real_ip_header X-Forwarded-For; server_name rrups.com; access_log logs / upstream.log main; error_log rrups_error.log info; location / { #proxy_pass http://rrups/addurl; proxy_pass http: / / ps; #proxy_hide_header aaa; #proxy_method POST; #proxy_pass_request_headers off; #proxy_pass_request_body off; #proxy_set_body 'hello world'; #proxy_set_header name ''; #proxy_http_version 1.1; #proxy_set_header Connection ""; } location / test { } location / error { proxy_pass http: / / ps; proxy_connect_timeout 1s ; proxy_next_upstream off; } location / intercept{ proxy_intercept_errors on; proxy_pass http: / / 127.0 . 0.1 : 8013 ; proxy_next_upstream off; } location / httperr { proxy_next_upstream http_500; proxy_pass http: / / ps; } } |
测试
1 2 3 4 5 6 7 8 | [root@python vhast] # curl rrups.com/error 8011 server response. [root@python vhast] # curl rrups.com/error 8013 server Internal Error. [root@python vhast] # curl rrups.com/error 8011 server response. [root@python vhast] # curl rrups.com/error 8013 server Internal Error. |
修改上游服务器一个端口
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 | [root@python vhast] # cat shangyou.conf server { listen 8011 ; default_type text / plain; return 200 '8011 server response.\n' ; } server { listen 8012 ; default_type text / plain; root html; location / { add_header X - Accel - Limit - Rate 10 ; } location / test { return 200 ' 8012 server response. uri: $uri method: $request_method requset: $request http_name: $http_name \n'; } } server { listen 8013 ; default_type text / plain; return 500 '8013 server Internal Error.\n' ; } [root@python vhast] # vim shangyou.conf [root@python vhast] # cat shangyou.conf server { listen 8011 ; default_type text / plain; return 200 '8011 server response.\n' ; } server { listen 8012 ; default_type text / plain; root html; location / { add_header X - Accel - Limit - Rate 10 ; } location / test { return 200 ' 8012 server response. uri: $uri method: $request_method requset: $request http_name: $http_name \n'; } } server { listen 8014 ;吧端口修改 default_type text / plain; return 500 '8013 server Internal Error.\n' ; } |
测试
1 2 3 4 5 6 7 8 9 10 11 | [root@python vhast] # curl rrups.com/error 8011 server response. [root@python vhast] # curl rrups.com/error <html> <head><title> 502 Bad Gateway< / title>< / head> <body> <center><h1> 502 Bad Gateway< / h1>< / center> <hr><center>nginx / 1.15 . 9 < / center> < / body> < / html> |
修改配置
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 | [root@python vhast] # cat proxy_next.conf upstream ps{ #ip_hash; #hash user_$arg_username; server 127.0 . 0.1 : 8011 ; server 127.0 . 0.1 : 8013 ; #keepalive 32; } server { #set_real_ip_from 192.168.183.4; #real_ip_recursive on; #real_ip_header X-Forwarded-For; server_name rrups.com; access_log logs / upstream.log main; error_log rrups_error.log info; location / { #proxy_pass http://rrups/addurl; proxy_pass http: / / ps; #proxy_hide_header aaa; #proxy_method POST; #proxy_pass_request_headers off; #proxy_pass_request_body off; #proxy_set_body 'hello world'; #proxy_set_header name ''; #proxy_http_version 1.1; #proxy_set_header Connection ""; } location / test { } location / error { proxy_pass http: / / ps; proxy_connect_timeout 1s ; proxy_next_upstream error; 从off改为error } location / intercept{ proxy_intercept_errors on; proxy_pass http: / / 127.0 . 0.1 : 8013 ; proxy_next_upstream off; } location / httperr { proxy_next_upstream http_500; proxy_pass http: / / ps; } } |
测试
1 2 3 4 5 6 7 8 | [root@python vhast] # curl rrups.com/error 8011 server response. [root@python vhast] # curl rrups.com/error 8011 server response. [root@python vhast] # curl rrups.com/error 8011 server response. [root@python vhast] # curl rrups.com/error 8011 server response. |
恢复上游服务器
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 | [root@python vhast] # cat shangyou.conf server { listen 8011 ; default_type text / plain; return 200 '8011 server response.\n' ; } server { listen 8012 ; default_type text / plain; root html; location / { add_header X - Accel - Limit - Rate 10 ; } location / test { return 200 ' 8012 server response. uri: $uri method: $request_method requset: $request http_name: $http_name \n'; } } server { listen 8013 ; default_type text / plain; return 500 '8013 server Internal Error.\n' ; } |
测试
1 2 3 4 5 6 7 8 | [root@python vhast] # curl rrups.com/error 8013 server Internal Error. [root@python vhast] # curl rrups.com/error 8011 server response. [root@python vhast] # curl rrups.com/error 8013 server Internal Error. [root@python vhast] # curl rrups.com/error 8011 server response. |
配置
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 | location / httperr { proxy_next_upstream http_500; proxy_pass http: / / ps; } [root@python vhast] # cat shangyou.conf server { listen 8011 ; default_type text / plain; return 200 '8011 server response.\n' ; } server { listen 8012 ; default_type text / plain; root html; location / { add_header X - Accel - Limit - Rate 10 ; } location / test { return 200 ' 8012 server response. uri: $uri method: $request_method requset: $request http_name: $http_name \n'; } } server { listen 8013 ; default_type text / plain; return 500 '8013 server Internal Error.\n' ; } |
测试
1 2 3 4 5 6 7 8 9 10 11 12 | [root@python vhast] # curl rrups.com/httperr 8011 server response. [root@python vhast] # curl rrups.com/httperr 8011 server response. [root@python vhast] # curl rrups.com/httperr 8011 server response. [root@python vhast] # curl rrups.com/httperr 8011 server response. [root@python vhast] # curl rrups.com/httperr 8011 server response. [root@python vhast] # curl rrups.com/httperr 8011 server response. |
修改上游服务器响应码
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 | [root@python vhast] # cat shangyou.conf server { listen 8011 ; default_type text / plain; return 200 '8011 server response.\n' ; } server { listen 8012 ; default_type text / plain; root html; location / { add_header X - Accel - Limit - Rate 10 ; } location / test { return 200 ' 8012 server response. uri: $uri method: $request_method requset: $request http_name: $http_name \n'; } } server { listen 8013 ; default_type text / plain; return 200 '8013 server Internal Error.\n' ; } |
测试
1 2 3 4 5 6 7 8 | [root@python vhast] # curl rrups.com/httperr 8011 server response. [root@python vhast] # curl rrups.com/httperr 8013 server Internal Error. [root@python vhast] # curl rrups.com/httperr 8011 server response. [root@python vhast] # curl rrups.com/httperr 8013 server Internal Error. |
配置
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 | server { listen 8013 ; default_type text / plain; return 500 '8013 server Internal Error.\n' ; } [root@python vhast] # cat proxy_next.conf upstream ps{ #ip_hash; #hash user_$arg_username; server 127.0 . 0.1 : 8011 ; server 127.0 . 0.1 : 8013 ; #keepalive 32; } server { #set_real_ip_from 192.168.183.4; #real_ip_recursive on; #real_ip_header X-Forwarded-For; server_name rrups.com; access_log logs / upstream.log main; error_log rrups_error.log info; location / { #proxy_pass http://rrups/addurl; proxy_pass http: / / ps; #proxy_hide_header aaa; #proxy_method POST; #proxy_pass_request_headers off; #proxy_pass_request_body off; #proxy_set_body 'hello world'; #proxy_set_header name ''; #proxy_http_version 1.1; #proxy_set_header Connection ""; } location / test { } location / error { proxy_pass http: / / ps; proxy_connect_timeout 1s ; #proxy_next_upstream error; } location / intercept{ proxy_intercept_errors off; proxy_pass http: / / 127.0 . 0.1 : 8013 ; proxy_next_upstream error; } location / httperr { proxy_next_upstream http_500; proxy_pass http: / / ps; } } |
测试
1 2 3 4 5 6 7 | [root@python vhast] # curl rrups.com/intercept -I HTTP / 1.1 500 Internal Server Error Server: nginx / 1.15 . 9 Date: Wed, 17 Jul 2019 08 : 10 : 13 GMT Content - Type : text / plain Content - Length: 28 Connection: keep - alive |
配置
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 | [root@python vhast] # cat shangyou.conf server { listen 8011 ; default_type text / plain; return 200 '8011 server response.\n' ; } server { listen 8012 ; default_type text / plain; root html; location / { add_header X - Accel - Limit - Rate 10 ; } location / test { return 200 ' 8012 server response. uri: $uri method: $request_method requset: $request http_name: $http_name \n'; } } server { listen 8013 ; default_type text / plain; return 500 '8013 server Internal Error.\n' ; } upstream ps{ #ip_hash; #hash user_$arg_username; server 127.0 . 0.1 : 8011 ; server 127.0 . 0.1 : 8013 ; #keepalive 32; } location / error { proxy_pass http: / / ps; proxy_connect_timeout 1s ; #proxy_next_upstream error; } error_page 500 / a.txt; 定义上游服务器返回 500 ,用a.txt文件内容返回 location / intercept{ proxy_intercept_errors on; proxy_pass http: / / 127.0 . 0.1 : 8013 ; #proxy_next_upstream error; } location / httperr { proxy_next_upstream http_500; proxy_pass http: / / ps; } } |
测试
1 2 3 4 5 6 7 8 9 10 | [root@python vhast] # curl rrups.com/intercept qwertyuopuughgbbvvbaaa [root@python vhast] # curl rrups.com/intercept -I HTTP / 1.1 500 Internal Server Error Server: nginx / 1.15 . 9 Date: Wed, 17 Jul 2019 08 : 23 : 49 GMT Content - Type : text / plain Content - Length: 23 Connection: close ETag: "5d28942d-17" |
双向认证时的指令
对下游使用证书
1 2 3 4 5 6 7 8 9 10 | Syntax: ssl_certificate file ; Default: — Context: http, server Syntax: ssl_certificate_key file ; Default: — Context: http, server |
验证下游证书
1 2 3 4 5 6 7 8 9 | Syntax: ssl_verify_client on | off | optional | optional_no_ca; Default: ssl_verify_client off; Context: http, server Syntax: ssl_client_certificate file ; Default: — Context: http, server |
对上游使用证书
1 2 3 4 5 6 7 8 9 10 | Syntax: proxy_ssl_certificate file ; Default: — Context: http, server, location Syntax: proxy_ssl_certificate_key file ; Default: — Context: http, server, location |
验证上游的证书
1 2 3 4 5 6 7 8 9 10 11 | Syntax: proxy_ssl_trusted_certificate file ; Default: — Context: http, server, location Syntax: proxy_ssl_verify on | off; Default: proxy_ssl_verify off; Context: http, server, location |
ssl 模块提供的变量
安全套件
ssl_cipher:本次通讯选用的安全套件,例如ECDHE-RSA-AES128-GCM-SHA256
ssl_ciphers:客户端支持的所有安全套件
ssl_protocol:本次通信选用TLS版本,例如TLS1.2
ssl_curves : 客户端支持的椭圆曲线,例如secp384rl:secp521r1
证书
ssl_client_raw_cert:原始客户端证书内容
ssl_client_escaped_cert:返回客户端证书做urlencode 编码后的内容
ssl_client_cert : 对客户端证书每一行内容前加tab制表符,增强可读性
ssl_client_fingerprint:客户端证书的SHA1指纹
证书结构化信息
ssl_server_name: 通过TLS插件SNI获取到的服务域名
ssl_client_i_dn:依据RFC2253获取到证书issuer dn信息,例如:CN=...,O=....,L=....,C=....
ssl_client_i_dn_legacy: 依据RFC2253获取到证书issuer dn信息例如:/C=…/L=…/O=…/CN=…
ssl_client_s_dn: 依据RFC2253获取到证书issuer dn信息例如:CN=…,OU=…,O=…,L=…,ST=…,C=…
ssl_client_s_dn_legacy:同样获取issuer dn信息,格式为:/C=…/ST=…/L=…/O=…/OU=…/CN=…
证书有效期
ssl_client_v_end: 返回客户端证书的过期时间;例如Dec 1 11:56:11 2028 GMT
ssl_client_v_remain: 返回还有多少天客户端证书过期,例如针对上面的ssl_client_v_end其值为3649
ssl_client_v_start : 客户端证书颁发日期;例如 Dec 4 11:56:11 2018 GMT
连接有效性
ssl_client_serial:返回连接客户端证书的序列号,例如8BE947674841BD44
ssl_early_data: 在TLS1.3协议中使用了early data且握手未返回1,则返回空字符串
ssl_client_verify:如果验证失败为FAILED:原因,如果没有验证证书则为NONE,验证成功则为SUCCESS
ssl_session_id:已建立连接的sessionid
ssl_session_reused:如果session被复用(参考session)则为r,否则为.
创建证书操作
创建根证书
创键CA私钥
1 | openssl genrsa - out ca.key 2048 |
制作CA公钥
1 | openssl req - new - x509 - days 3650 - key ca.key - out ca.crt |
签发证书
创建私钥
1 2 | openssl genrsa - out a.pem 1024 openssl rsa - in a.pem - out a.key |
生成签发证书请求
1 | openssl req - new - key a.pem - out a.csr |
使CA证书进行签发
1 | openssl x509 - req - sha256 - in a.csr - CA ca.crt - CAkey ca.key - CAcreateserial - days 3650 - out a.crt |
验证签发证书是否正确
1 | openssl verify - CAfile ca.crt a.crt |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· 葡萄城 AI 搜索升级:DeepSeek 加持,客户体验更智能
· 什么是nginx的强缓存和协商缓存
· 一文读懂知识蒸馏