From 6226ed3386ebdddc43edd1ad9dc589c7f6c37cdc Mon Sep 17 00:00:00 2001 From: agile6v Date: Sat, 8 Feb 2020 21:15:00 +0800 Subject: [PATCH 1/2] Add support for PROXY Protocol. --- README.md | 1 + README_CN.md | 1 + bin/apisix | 45 ++++++++++++++++++++++++++++++++++++++++++--- conf/config.yaml | 18 ++++++++++++++---- 4 files changed, 58 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 364bd105db13..312c2a04159a 100644 --- a/README.md +++ b/README.md @@ -58,6 +58,7 @@ A/B testing, canary release, blue-green deployment, limit rate, defense against - [gRPC proxy](doc/grpc-proxy.md): Proxying gRPC traffic. - [gRPC transcoding](doc/plugins/grpc-transcoding.md): Supports protocol transcoding so that clients can access your gRPC API by using HTTP/JSON. - Proxy Websocket + - Proxy Protocol - Proxy Dubbo: Dubbo Proxy based on Tengine. - HTTP(S) Forward Proxy - [SSL](doc/https.md): Dynamically load an SSL certificate. diff --git a/README_CN.md b/README_CN.md index 19e3acac41b9..abfe37b6f3f2 100644 --- a/README_CN.md +++ b/README_CN.md @@ -58,6 +58,7 @@ A/B 测试、金丝雀发布(灰度发布)、蓝绿部署、限流限速、抵 - [gRPC 代理](doc/grpc-proxy-cn.md):通过 APISIX 代理 gRPC 连接,并使用 APISIX 的大部分特性管理你的 gRPC 服务。 - [gRPC 协议转换](doc/plugins/grpc-transcoding-cn.md):支持协议的转换,这样客户端可以通过 HTTP/JSON 来访问你的 gRPC API。 - Websocket 代理 + - Proxy Protocol - Dubbo 代理:基于 Tengine,可以实现 Dubbo 请求的代理。 - HTTP(S) 反向代理 - [SSL](doc/https-cn.md):动态加载 SSL 证书。 diff --git a/bin/apisix b/bin/apisix index 69b745318d32..a0fb9b71f671 100755 --- a/bin/apisix +++ b/bin/apisix @@ -129,12 +129,16 @@ stream { server { {% for _, port in ipairs(stream_proxy.tcp or {}) do %} - listen {*port*}; + listen {*port*} {% if proxy_protocol and proxy_protocol.enable_tcp_pp then %} proxy_protocol {% end %}; {% end %} {% for _, port in ipairs(stream_proxy.udp or {}) do %} listen {*port*} udp; {% end %} + {% if proxy_protocol and proxy_protocol.enable_tcp_pp_to_upstream then %} + proxy_protocol on; + {% end %} + preread_by_lua_block { apisix.stream_preread_phase() } @@ -200,10 +204,14 @@ http { include mime.types; - real_ip_header {* real_ip_header *}; - {% for _, real_ip in ipairs(real_ip_from) do %} + {% if http.real_ip_header then %} + real_ip_header {* http.real_ip_header *}; + {%end%} + {% if http.real_ip_from then %} + {% for _, real_ip in ipairs(http.real_ip_from) do %} set_real_ip_from {*real_ip*}; {% end %} + {% end %} upstream apisix_backend { server 0.0.0.1; @@ -266,6 +274,13 @@ http { listen {* ssl.listen_port *} ssl {% if ssl.enable_http2 then %} http2 {% end %}; {% end %} + {% if proxy_protocol and proxy_protocol.listen_http_port then %} + listen {* proxy_protocol.listen_http_port *} proxy_protocol; + {% end %} + {% if proxy_protocol and proxy_protocol.listen_https_port then %} + listen {* proxy_protocol.listen_https_port *} ssl {% if ssl.enable_http2 then %} http2 {% end %} proxy_protocol; + {% end %} + {% if enable_ipv6 then %} listen [::]:{* node_listen *}; {% if ssl.enable then %} @@ -340,6 +355,30 @@ http { proxy_set_header X-Real-IP $remote_addr; proxy_pass_header Server; proxy_pass_header Date; + + set $var_x_forwarded_for $remote_addr; + set $var_x_forwarded_proto $scheme; + set $var_x_forwarded_host $host; + set $var_x_forwarded_port $server_port; + + if ($http_x_forwarded_for != "") { + set $var_x_forwarded_for "${http_x_forwarded_for}, ${realip_remote_addr}"; + } + if ($http_x_forwarded_proto != "") { + set $var_x_forwarded_proto $http_x_forwarded_proto; + } + if ($http_x_forwarded_host != "") { + set $var_x_forwarded_host $http_x_forwarded_host; + } + if ($http_x_forwarded_port != "") { + set $var_x_forwarded_port $http_x_forwarded_port; + } + + proxy_set_header X-Forwarded-For $var_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $var_x_forwarded_proto; + proxy_set_header X-Forwarded-Host $var_x_forwarded_host; + proxy_set_header X-Forwarded-Port $var_x_forwarded_port; + proxy_pass $upstream_scheme://apisix_backend$upstream_uri; header_filter_by_lua_block { diff --git a/conf/config.yaml b/conf/config.yaml index 57efc2abad9b..cdc0c2926f0d 100644 --- a/conf/config.yaml +++ b/conf/config.yaml @@ -24,14 +24,20 @@ apisix: enable_ipv6: true config_center: etcd # etcd: use etcd to store the config value # yaml: fetch the config value from local yaml file `/your_path/conf/apisix.yaml` + + #proxy_protocol: # Proxy Protocol configuration + # listen_http_port: 9181 # The port with proxy protocol for http, it differs from node_listen and port_admin. + # This port can only receive http request with proxy protocol, but node_listen & port_admin + # can only receive http request. If you enable proxy protocol, you must use this port to + # receive http request with proxy protocol + # listen_https_port: 9182 # The port with proxy protocol for https + # enable_tcp_pp: true # Enable the proxy protocol for tcp proxy, it works for stream_proxy.tcp option + # enable_tcp_pp_to_upstream: true # Enables the proxy protocol to the upstream server + # allow_admin: # http://nginx.org/en/docs/http/ngx_http_access_module.html#allow # - 127.0.0.0/24 # If we don't set any IP list, then any IP access is allowed by default. # - "::/64" # port_admin: 9180 # use a separate port - real_ip_header: "X-Real-IP" # http://nginx.org/en/docs/http/ngx_http_realip_module.html#real_ip_header - real_ip_from: # http://nginx.org/en/docs/http/ngx_http_realip_module.html#set_real_ip_from - - 127.0.0.1 - - 'unix:' router: http: 'radixtree_uri' # radixtree_uri: match route by uri(base on radixtree) # radixtree_host_uri: match route by host + uri(base on radixtree) @@ -69,6 +75,10 @@ nginx_config: # config for render the template to genarate n client_body_timeout: 60s # timeout for reading client request body, then 408 (Request Time-out) error is returned to the client send_timeout: 10s # timeout for transmitting a response to the client.then the connection is closed underscores_in_headers: "on" # default enables the use of underscores in client request header fields + real_ip_header: "X-Real-IP" # http://nginx.org/en/docs/http/ngx_http_realip_module.html#real_ip_header + real_ip_from: # http://nginx.org/en/docs/http/ngx_http_realip_module.html#set_real_ip_from + - 127.0.0.1 + - 'unix:' etcd: host: "http://127.0.0.1:2379" # etcd address From 818ac41ffb5934819322fe1af4741ad98be406e5 Mon Sep 17 00:00:00 2001 From: agile6v Date: Tue, 11 Feb 2020 21:35:21 +0800 Subject: [PATCH 2/2] Add deprecating message. --- bin/apisix | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/bin/apisix b/bin/apisix index a0fb9b71f671..d1a272fbb763 100755 --- a/bin/apisix +++ b/bin/apisix @@ -204,10 +204,19 @@ http { include mime.types; - {% if http.real_ip_header then %} + {% if real_ip_header then %} + real_ip_header {* real_ip_header *}; + {% print("\nDeprecated: apisix.real_ip_header has been moved to nginx_config.http.real_ip_header. apisix.real_ip_header will be removed in the future version. Please use nginx_config.http.real_ip_header first.\n\n") %} + {% elseif http.real_ip_header then %} real_ip_header {* http.real_ip_header *}; - {%end%} - {% if http.real_ip_from then %} + {% end %} + + {% if real_ip_from then %} + {% print("\nDeprecated: apisix.real_ip_from has been moved to nginx_config.http.real_ip_from. apisix.real_ip_from will be removed in the future version. Please use nginx_config.http.real_ip_from first.\n\n") %} + {% for _, real_ip in ipairs(real_ip_from) do %} + set_real_ip_from {*real_ip*}; + {% end %} + {% elseif http.real_ip_from then %} {% for _, real_ip in ipairs(http.real_ip_from) do %} set_real_ip_from {*real_ip*}; {% end %}