Skip to content
Open
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
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ In your `nginx.conf`,

1. At the top-level, load the module by adding the line `load_module ngx_ipscrub_module.so;` (NOTE: only if you built as a dynamic module).
1. Set `ipscrub_period_seconds <NUM SECONDS PER PERIOD>;` (optional).
1. In your `log_format` directives, replace `$remote_addr` with `$remote_addr_ipscrub`.
1. In your `log_format` directives, replace `$remote_addr` with `$remote_addr_ipscrub` and `$proxy_protocol_addr` with `$proxy_protocol_addr_ipscrub`.
1. Reload your nginx config.

**NOTE**: nginx may still leak IP addresses in the error log. If this is a concern, disable error logging or wipe the log regularly.
Expand Down
25 changes: 20 additions & 5 deletions ipscrub/src/ngx_ipscrub_module.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,15 @@ static char * ngx_ipscrub_conf(ngx_conf_t *cf, void *conf);

static ngx_int_t ngx_http_variable_remote_addr_ipscrub(ngx_http_request_t *r,
ngx_http_variable_value_t *v, uintptr_t data);
static ngx_int_t ngx_http_variable_proxy_protocol_addr_ipscrub(ngx_http_request_t *r,
ngx_http_variable_value_t *v, uintptr_t data);

static ngx_int_t ngx_ipscrub_init(ngx_conf_t *cf);
static ngx_int_t ngx_ipscrub_add_variables(ngx_conf_t *cf);

static ngx_http_variable_t ngx_http_ipscrub_vars[] = {
{ngx_string("remote_addr_ipscrub"), NULL, ngx_http_variable_remote_addr_ipscrub, 0, 0, 0},
{ngx_string("proxy_protocol_addr_ipscrub"), NULL, ngx_http_variable_proxy_protocol_addr_ipscrub, 0, 0, 0},
{ngx_string("ipscrub_hash_debug"), NULL, ngx_http_variable_remote_addr_ipscrub_debug, 0, 0, 0},
{ngx_string("ipscrub_salted_hash_debug"), NULL, ngx_http_variable_ipscrub_salted_hash_debug, 0, 0, 0},
{ngx_null_string, NULL, NULL, 0, 0, 0 }};
Expand Down Expand Up @@ -132,7 +135,7 @@ ngx_ipscrub_add_variables(ngx_conf_t *cf)
}

static ngx_int_t
ngx_http_variable_remote_addr_ipscrub(ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data)
real_ipscrub(ngx_str_t t, ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data)
{
ngx_int_t rc;
u_char *hashed;
Expand Down Expand Up @@ -160,7 +163,7 @@ ngx_http_variable_remote_addr_ipscrub(ngx_http_request_t *r, ngx_http_variable_v
salt.len = num_nonce_bytes;

// Although ngx_crypt provides a salted SHA function, specified by a salt beginning with {SSHA}, that function exposes the salt in its result. For our security model, this is inappropriate. Instead, we use the regular nginx SHA function specified by {SHA}, and manually combine the nonce and plaintext.
rc = concat(r->pool, r->connection->addr_text, salt, &combined);
rc = concat(r->pool, t, salt, &combined);
if (rc != NGX_OK) {
return NGX_HTTP_INTERNAL_SERVER_ERROR;
}
Expand All @@ -174,9 +177,9 @@ ngx_http_variable_remote_addr_ipscrub(ngx_http_request_t *r, ngx_http_variable_v
u_char *obscured = hashed + (sizeof("{SHA}") - 1);

// Compute number of bytes to represent hashed address.
if (r->connection->addr_text.data[3] == '.' ||
r->connection->addr_text.data[2] == '.' ||
r->connection->addr_text.data[1] == '.') {
if (t.data[3] == '.' ||
t.data[2] == '.' ||
t.data[1] == '.') {
// This is an IPv4 address.
// IPv4 has a 32-bit address space. Base64 is 6 bits-per-char. ceil(32/6) = 6.
len = 6;
Expand All @@ -194,3 +197,15 @@ ngx_http_variable_remote_addr_ipscrub(ngx_http_request_t *r, ngx_http_variable_v

return NGX_OK;
}

static ngx_int_t
ngx_http_variable_remote_addr_ipscrub(ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data)
{
return real_ipscrub(r->connection->addr_text, r, v, data);
}

static ngx_int_t
ngx_http_variable_proxy_protocol_addr_ipscrub(ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data)
{
return real_ipscrub(r->connection->proxy_protocol_addr, r, v, data);
}