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

(WIP) PROXY protocol support #110

Open
wants to merge 11 commits into
base: master
Choose a base branch
from
71 changes: 54 additions & 17 deletions modules/ngx_tcp_generic_proxy_module.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,10 @@ typedef struct ngx_tcp_proxy_conf_s {
} ngx_tcp_proxy_conf_t;


static void ngx_tcp_proxy_init_session(ngx_tcp_session_t *s);
static void ngx_tcp_proxy_init_upstream(ngx_connection_t *c,
static void ngx_tcp_proxy_init_session(ngx_tcp_session_t *s);
static void ngx_tcp_proxy_init_upstream(ngx_connection_t *c,
ngx_tcp_session_t *s);
static void ngx_tcp_upstream_init_proxy_handler(ngx_tcp_session_t *s,
static void ngx_tcp_upstream_init_proxy_handler(ngx_tcp_session_t *s,
ngx_tcp_upstream_t *u);
static char *ngx_tcp_proxy_pass(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
static void ngx_tcp_proxy_dummy_read_handler(ngx_event_t *ev);
Expand Down Expand Up @@ -114,8 +114,8 @@ ngx_module_t ngx_tcp_proxy_module = {
};


static void
ngx_tcp_proxy_init_session(ngx_tcp_session_t *s)
static void
ngx_tcp_proxy_init_session(ngx_tcp_session_t *s)
{
ngx_connection_t *c;
ngx_tcp_proxy_conf_t *pcf;
Expand Down Expand Up @@ -149,7 +149,7 @@ ngx_tcp_proxy_init_session(ngx_tcp_session_t *s)


static void
ngx_tcp_proxy_dummy_write_handler(ngx_event_t *wev)
ngx_tcp_proxy_dummy_write_handler(ngx_event_t *wev)
{
ngx_connection_t *c;
ngx_tcp_session_t *s;
Expand All @@ -167,7 +167,7 @@ ngx_tcp_proxy_dummy_write_handler(ngx_event_t *wev)


static void
ngx_tcp_proxy_dummy_read_handler(ngx_event_t *rev)
ngx_tcp_proxy_dummy_read_handler(ngx_event_t *rev)
{
ngx_connection_t *c;
ngx_tcp_session_t *s;
Expand Down Expand Up @@ -233,7 +233,42 @@ ngx_tcp_proxy_init_upstream(ngx_connection_t *c, ngx_tcp_session_t *s)
}


static void
static void
ngx_tcp_proxy_send_proxy_protocol(ngx_tcp_session_t *s, ngx_tcp_upstream_t *u)
{
ngx_connection_t *c;
ngx_str_t proxy_line;
struct sockaddr_in *client, *listener;
u_char *src_addr, *dst_addr;

c = u->peer.connection;
c->log->action = "ngx_tcp_proxy_send_proxy_protocol";

client = (struct sockaddr_in*)s->connection->sockaddr;
listener = (struct sockaddr_in*)s->connection->listening->sockaddr; // doesn't appear to be correct
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Try the s->connection->local_sockaddr, it should store the destination address.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I gave it a go, doesn't seem to return the correct values either. IP is 0.0.0.0 and the port is not the port defined in the configuration. Not that important anyway IMO

src_addr = (u_char *)&client->sin_addr;
dst_addr = (u_char *)&listener->sin_addr;


ngx_log_debug0(NGX_LOG_DEBUG_TCP, c->log, 0, "sending proxy protocol");

// PROXY TCP4 <src ip> <dst ip> <src port> <dst port>\r\n
proxy_line.data = ngx_pnalloc(c->pool, 56); // maximum length for TCP4
proxy_line.len = ngx_sprintf(proxy_line.data,
// "PROXY TCP4 %V %V %d %d\r\n",
"PROXY TCP4 %ud.%ud.%ud.%ud %ud.%ud.%ud.%ud %d %d\r\n",
// s->connection->addr_text,
src_addr[0], src_addr[1], src_addr[2], src_addr[3],
dst_addr[0], dst_addr[1], dst_addr[2], dst_addr[3],
client->sin_port,
listener->sin_port
) - proxy_line.data;

c->send(c, proxy_line.data, proxy_line.len);
}


static void
ngx_tcp_upstream_init_proxy_handler(ngx_tcp_session_t *s, ngx_tcp_upstream_t *u)
{
ngx_connection_t *c;
Expand Down Expand Up @@ -284,30 +319,32 @@ ngx_tcp_upstream_init_proxy_handler(ngx_tcp_session_t *s, ngx_tcp_upstream_t *u)

#if (NGX_TCP_SSL)

/*
/*
* The ssl connection with client may not trigger the read event again,
* So I trigger it in this function.
* */
if (s->connection->ssl) {
ngx_tcp_proxy_handler(s->connection->read);
ngx_tcp_proxy_handler(s->connection->read);
}

#endif

if (s->upstream->conf->upstream->accept_proxy) {
ngx_tcp_proxy_send_proxy_protocol(s, u);
}
return;
}


static void
ngx_tcp_proxy_handler(ngx_event_t *ev)
ngx_tcp_proxy_handler(ngx_event_t *ev)
{
char *action, *recv_action, *send_action;
off_t *read_bytes, *write_bytes;
size_t size;
ssize_t n;
ngx_buf_t *b;
ngx_err_t err;
ngx_uint_t do_write, first_read;
ngx_uint_t do_write, first_read = 0;
ngx_connection_t *c, *src, *dst;
ngx_tcp_session_t *s;
ngx_tcp_proxy_conf_t *pcf;
Expand Down Expand Up @@ -431,7 +468,7 @@ ngx_tcp_proxy_handler(ngx_event_t *ev)
size = b->end - b->last;

if (size) {
if (src->read->ready || first_read) {
if (src->read->ready || first_read) {

first_read = 0;
c->log->action = recv_action;
Expand Down Expand Up @@ -522,7 +559,7 @@ ngx_tcp_proxy_handler(ngx_event_t *ev)


static char *
ngx_tcp_proxy_pass(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
ngx_tcp_proxy_pass(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
ngx_tcp_proxy_conf_t *pcf = conf;

Expand Down Expand Up @@ -570,7 +607,7 @@ ngx_tcp_proxy_pass(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)


static void *
ngx_tcp_proxy_create_conf(ngx_conf_t *cf)
ngx_tcp_proxy_create_conf(ngx_conf_t *cf)
{
ngx_tcp_proxy_conf_t *pcf;

Expand All @@ -590,7 +627,7 @@ ngx_tcp_proxy_create_conf(ngx_conf_t *cf)


static char *
ngx_tcp_proxy_merge_conf(ngx_conf_t *cf, void *parent, void *child)
ngx_tcp_proxy_merge_conf(ngx_conf_t *cf, void *parent, void *child)
{
ngx_tcp_proxy_conf_t *prev = parent;
ngx_tcp_proxy_conf_t *conf = child;
Expand Down
7 changes: 7 additions & 0 deletions ngx_tcp_upstream.c
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,12 @@ static ngx_command_t ngx_tcp_upstream_commands[] = {
offsetof(ngx_tcp_upstream_main_conf_t, check_shm_size),
NULL },

{ ngx_string("accept_proxy"),
NGX_TCP_UPS_CONF|NGX_CONF_FLAG,
ngx_conf_set_flag_slot,
NGX_TCP_SRV_CONF_OFFSET,
offsetof(ngx_tcp_upstream_srv_conf_t, accept_proxy),
NULL },
ngx_null_command
};

Expand Down Expand Up @@ -691,6 +697,7 @@ ngx_tcp_upstream_add(ngx_conf_t *cf, ngx_url_t *u, ngx_uint_t flags)
uscf->line = cf->conf_file->line;
uscf->port = u->port;
uscf->default_port = u->default_port;
uscf->accept_proxy = NGX_CONF_UNSET;
#if (nginx_version) >= 1003011
uscf->no_port = u->no_port;
#endif
Expand Down
1 change: 1 addition & 0 deletions ngx_tcp_upstream.h
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ struct ngx_tcp_upstream_srv_conf_s {

check_conf_t *check_type_conf;
ngx_str_t send;
ngx_flag_t accept_proxy;

union {
ngx_uint_t return_code;
Expand Down
Loading