HAOJX

nginx中的http反向代理流程及proxy模块

字数统计: 1.4k阅读时长: 6 min
2018/10/10 Share
  1. 处理proxy_pass指令
  2. cache命中则发生响应头部 , 没有命中则根据指令生成发往上游http头部和包体
  3. 指令proxy_request_buffering如果是on的话, 则读取请求完整包体, 如果为off则根据负载均衡选择上游服务器
  4. 发送请求(边读包体边发)
  5. 上游接收处理响应头部
  6. 如果proxy_buffering是on的话 ,则接受完整的响应包体再发送,如果为off的话 , 则先发送响应头部,响应包体则边读边发
  7. 如果开启cache则包体加入缓存

proxy模块

对上游使用http/https协议进行反向代理

1
2
3
Syntax:  proxy_pass URL;
Default: —
Context: location, if in location, limit_except

其中url的参数规则为:

  • URL必须以http://或者https://开头
  • 当URL中携带URI时 , 则将location匹配上的一段替换成该URI, 如果不携带URI,则直接转发给上游

##根据指令生成请求头部和包体

生成发往上游的请求行

1
2
3
4
5
6
7
Syntax:  proxy_method method;
Default: —
Context: http, server, location

Syntax: proxy_http_version 1.0 | 1.1;
Default: proxy_http_version 1.0;
Context: http, server, location

生成发往上游的请求头部

1
2
3
4
5
6
7
8
9
Syntax:  proxy_set_header field value;
Default:
proxy_set_header Host $proxy_host;
proxy_set_header Connection close;
Context: http, server, location

Syntax: proxy_pass_request_headers on | off;
Default: proxy_pass_request_headers on;
Context: http, server, location

若value的值为空 ,则整个haeder都不会向上游发送

生成发往上游的包体

1
2
3
4
5
6
Syntax:  proxy_pass_request_body on | off;
Default: proxy_pass_request_body on;
Context: http, server, location
Syntax: proxy_set_body value;
Default: —
Context: http, server, location

接收客户端请求的包体

1
2
3
Syntax:  proxy_request_buffering on | off;
Default: proxy_request_buffering on;
Context: http, server, location

客户端接收的包体

1
2
3
4
5
6
Syntax:  client_body_buffer_size size;
Default: client_body_buffer_size 8k|16k;
Context: http, server, location
Syntax: client_body_in_single_buffer on | off;
Default: client_body_in_single_buffer off;
Context: http, server, location

接收包体所分配的内存

最大包体长度限制

1
2
3
Syntax:  client_max_body_size size;
Default: client_max_body_size 1m;
Context: http, server, location

仅对请求头部中含有Content-Length有效 , 超出最大长度后, 返回413

临时文件路径

1
2
3
4
5
6
Syntax:  client_body_temp_path path [level1 [level2 [level3]]];
Default: client_body_temp_path client_body_temp;
Context: http, server, location
Syntax: client_body_in_file_only on | clean | off;
Default: client_body_in_file_only off;
Context: http, server, location

读取包体超时

1
2
3
Syntax:  client_body_timeout time;
Default: client_body_timeout 60s;
Context: http, server, location

读取包体超时, 返回408

向上游服务建立连接

1
2
3
Syntax:  proxy_connect_timeout time;
Default: proxy_connect_timeout 60s;
Context: http, server, location

响应超时则返回502

如果超时则再选择一个上游服务器

1
2
3
Syntax:  proxy_next_upstream http_502 | ..;
Default: proxy_next_upstream error timeout;
Context: http, server, location

上游连接启用tcp keepalive

1
2
3
Syntax:  proxy_socket_keepalive on | off;
Default: proxy_socket_keepalive off;
Context: http, server, location

上游启用http keepalive

1
2
3
4
5
6
7
Syntax:  keepalive connections;
Default: —
Context: upstream

Syntax: keepalive_requests number;
Default: keepalive_requests 100;
Context: upstream

接收上游响应

向上游发送http响应

1
2
3
Syntax:  proxy_send_timeout time;
Default: proxy_send_timeout 60s;
Context: http, server, location

接收上游响应头部

1
2
3
Syntax:  proxy_buffer_size size;
Default: proxy_buffer_size 4k|8k;
Context: http, server, location

接收上游响应包体

1
2
3
Syntax:  proxy_buffers number size;
Default: proxy_buffers 8 4k|8k;
Context: http, server, location
1
2
3
4
5
6
7
8
9
10
11
12
Syntax:  proxy_buffering on | off;
Default: proxy_buffering on;
Context: http, server, location
Syntax: proxy_max_temp_file_size size;
Default: proxy_max_temp_file_size 1024m;
Context: http, server, location
Syntax: proxy_temp_file_write_size size;
Default: proxy_temp_file_write_size 8k|16k;
Context: http, server, location
Syntax: proxy_temp_path path [level1 [level2 [level3]]];
Default: proxy_temp_path proxy_temp;
Context: http, server, location

及时转发包体

1
2
3
Syntax:  proxy_busy_buffers_size size;
Default: proxy_busy_buffers_size 8k|16k;
Context: http, server, location

接收上游时网络速度

1
2
3
4
5
6
Syntax:  proxy_read_timeout time;
Default: proxy_read_timeout 60s;
Context: http, server, location
Syntax: proxy_limit_rate rate;
Default: proxy_limit_rate 0;
Context: http, server, location

上游包体持久化

1
2
3
4
5
6
Syntax:  proxy_store_access users:permissions ...;
Default: proxy_store_access user:rw;
Context: http, server, location
Syntax: proxy_store on | off | string;
Default: proxy_store off;
Context: http, server, location

禁用上游响应头部

1
2
3
Syntax:  proxy_ignore_headers field ...;
Default: —
Context: http, server, location

可以禁用的的头部功能:

  • X-Accel-Redirect: 上游指定在nginx内部重定向
  • X-Accel-Limit-Rate: 上游设置发往客户端的速度限制 , 等同limit_rate指令
  • X-Accel-Buffering : 由上游控制是否控制缓存上游响应
  • X-Accel-Charset 由上游控制Content-Type中的charset
  • X-Accel-Expires , Expires,Cache-Control 控制nginx缓存时间 , 优先级由高到低
  • Set-Cookie 出现Set-Cookie则不缓存, 通过proxy_ignore_headers禁止生效
  • Vary

转发上游响应

对于某些上游响应的头部, 设置不向客户端转发

1
2
3
Syntax:  proxy_hide_header field;
Default: —
Context: http, server, location

proxy_hide_header默认不转发的有:Date,server,X-Pad , X-Accel-

对于已经被proxy_hide_header的头部, 设置向上游转发 , 则用

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;
proxy_cookie_domain domain replacement;
Default: proxy_cookie_domain off;
Context: http, server, location

Syntax:
proxy_cookie_path off;
proxy_cookie_path path replacement;
Default: proxy_cookie_path off;
Context: http, server, location

修改返回的location头部

1
2
3
4
5
6
Syntax:
proxy_redirect default;
proxy_redirect off;
proxy_redirect redirect replacement;
Default: proxy_redirect default;
Context: http, server, location

上游返回失败时的处理方法

1
2
3
4
5
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

限制proxy_next_upstream的次数和时间

1
2
3
4
5
6
7
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

ssl证书认证

作为上游自己使用的证书

1
2
3
4
5
6
7
Syntax:  ssl_certificate file;
Default: —
Context: http, server

Syntax: ssl_certificate_key file;
Default: —
Context: http, server

做完上游验证下游证书

1
2
3
4
5
6
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
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
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

创建证书示例:

1
2
3
4
5
6
7
8
9
10
11
openssl genrsa -out ca.key 2048    #创建根证书CA私钥
openssl req -new -x509 -days 3650 -key ca.key -out ca.crt 创建根证书CA公钥

签发证书:
openssl genrsa -out a.pem 1024
openssl rsa -in a.pem -out a.key

openssl req -new -key a.pem -out a.csr #生成签发请求
openssl x509 -req -sha256 -in a.csr -CA ca.crt -CAkey ca.key -CAcreateserial -days 3650 -out a.crt #用CA证书进行签发

openssl verify -CAfile ca.crt a.crt #验证签发是否正确
CATALOG
  1. 1. proxy模块
    1. 1.1. 生成发往上游的请求行
    2. 1.2. 生成发往上游的请求头部
    3. 1.3. 生成发往上游的包体
    4. 1.4. 接收客户端请求的包体
    5. 1.5. 客户端接收的包体
    6. 1.6. 最大包体长度限制
    7. 1.7. 临时文件路径
    8. 1.8. 读取包体超时
  2. 2. 向上游服务建立连接
    1. 2.1. 上游连接启用tcp keepalive
    2. 2.2. 上游启用http keepalive
  3. 3. 接收上游响应
    1. 3.1. 接收上游响应头部
    2. 3.2. 接收上游响应包体
    3. 3.3. 及时转发包体
    4. 3.4. 接收上游时网络速度
    5. 3.5. 上游包体持久化
    6. 3.6. 禁用上游响应头部
    7. 3.7. 转发上游响应
    8. 3.8. 修改返回的set-cookie头部
    9. 3.9. 修改返回的location头部
    10. 3.10. 上游返回失败时的处理方法
    11. 3.11. 限制proxy_next_upstream的次数和时间
    12. 3.12. 用error_page拦截上游失败响应
    13. 3.13. ssl证书认证