Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: Add support for PROXY Protocol. #1113

Merged
merged 3 commits into from
Feb 12, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
1 change: 1 addition & 0 deletions README_CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 证书。
Expand Down
50 changes: 49 additions & 1 deletion bin/apisix
Original file line number Diff line number Diff line change
Expand Up @@ -130,12 +130,16 @@ stream {

server {
{% for _, port in ipairs(stream_proxy.tcp or {}) do %}
listen {*port*} {% if enable_reuseport then %} reuseport {% end %};
listen {*port*} {% if enable_reuseport then %} reuseport {% end %} {% 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 {% if enable_reuseport then %} reuseport {% end %};
{% 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()
}
Expand Down Expand Up @@ -202,10 +206,23 @@ http {

include mime.types;

{% 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 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 %}
{% end %}

upstream apisix_backend {
server 0.0.0.1;
Expand Down Expand Up @@ -268,6 +285,13 @@ http {
listen {* ssl.listen_port *} ssl {% if ssl.enable_http2 then %} http2 {% end %} {% if enable_reuseport then %} reuseport {% 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 enable_reuseport then %} reuseport {% end %};
{% if ssl.enable then %}
Expand Down Expand Up @@ -342,6 +366,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 {
Expand Down
18 changes: 14 additions & 4 deletions conf/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,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)
Expand Down Expand Up @@ -70,6 +76,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
Expand Down