1
0
mirror of synced 2024-12-05 00:55:42 +01:00

Generate salt using 128bits from arc4random_buf

This commit is contained in:
Mason Simon 2018-05-27 19:19:09 -07:00
parent 44ccc14540
commit fa8830b003
6 changed files with 35 additions and 22 deletions

View File

@ -2,7 +2,7 @@ FROM ubuntu:latest
WORKDIR . WORKDIR .
RUN apt-get update && apt-get install -y curl gcc make git libpcre3-dev zlib1g-dev RUN apt-get update && apt-get install -y curl gcc make git libpcre3-dev zlib1g-dev libbsd-dev
ADD ipscrub /ipscrub/ ADD ipscrub /ipscrub/
ADD Makefile / ADD Makefile /

View File

@ -15,7 +15,7 @@
## Security Model ## Security Model
1. On initialization, and again every `PERIOD`, generate `salt` as `HASH(ngx_random() ++ timestamp)`. 1. On initialization, and again every `PERIOD`, generate `salt` using 128bits from `arc4random_buf()`.
2. On each request, generate masked IP address as `HASH(salt ++ IP address)`. 2. On each request, generate masked IP address as `HASH(salt ++ IP address)`.
3. Log masked IP address. 3. Log masked IP address.

View File

@ -4,7 +4,13 @@ ngx_module_type=HTTP
ngx_module_name=ngx_ipscrub_module ngx_module_name=ngx_ipscrub_module
ngx_module_deps="$ngx_addon_dir/src/ngx_ipscrub_support.h $ngx_addon_dir/src/ngx_ipscrub_debug.h" ngx_module_deps="$ngx_addon_dir/src/ngx_ipscrub_support.h $ngx_addon_dir/src/ngx_ipscrub_debug.h"
ngx_module_srcs="$ngx_addon_dir/src/ngx_ipscrub_module.c $ngx_addon_dir/src/ngx_ipscrub_support.c $ngx_addon_dir/src/ngx_ipscrub_debug.c" ngx_module_srcs="$ngx_addon_dir/src/ngx_ipscrub_module.c $ngx_addon_dir/src/ngx_ipscrub_support.c $ngx_addon_dir/src/ngx_ipscrub_debug.c"
ngx_module_libs=SHA1
# On Linux, link with libbsd, to get arc4random.
if [ `uname` = Linux ]; then
ngx_module_libs="SHA1 -lbsd"
else
ngx_module_libs="SHA1"
fi
. auto/module . auto/module

View File

@ -42,7 +42,8 @@ static ngx_command_t ngx_ipscrub_commands[] = {
// Globals. // Globals.
const int default_period_seconds = 10 * 60; // Period between salt changes. const int default_period_seconds = 10 * 60; // Period between salt changes.
time_t period_start = -1; time_t period_start = -1;
long nonce = -1; // Input to salt generation. #define num_nonce_bytes 16
u_char nonce[num_nonce_bytes]; // Input to salt generation.
static ngx_http_module_t ngx_ipscrub_module_ctx = { static ngx_http_module_t ngx_ipscrub_module_ctx = {
@ -146,7 +147,7 @@ ngx_http_variable_remote_addr_ipscrub(ngx_http_request_t *r, ngx_http_variable_v
// Regenerate salt if past end of period. // Regenerate salt if past end of period.
time_t now = time(NULL); time_t now = time(NULL);
if (period_start == -1 || now - period_start > icf->period_seconds) { if (period_start == -1 || now - period_start > icf->period_seconds) {
rc = randlong(&nonce); rc = randbytes((u_char *) &nonce, num_nonce_bytes);
if (rc != NGX_OK) { if (rc != NGX_OK) {
return NGX_HTTP_INTERNAL_SERVER_ERROR; return NGX_HTTP_INTERNAL_SERVER_ERROR;
} }
@ -156,7 +157,7 @@ ngx_http_variable_remote_addr_ipscrub(ngx_http_request_t *r, ngx_http_variable_v
} }
salt.data = (u_char *) &nonce; salt.data = (u_char *) &nonce;
salt.len = sizeof(nonce); 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. // 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, r->connection->addr_text, salt, &combined);

View File

@ -3,6 +3,15 @@
#include "ngx_ipscrub_support.h" #include "ngx_ipscrub_support.h"
#if (NGX_FREEBSD || NGX_SOLARIS || NGX_DARWIN)
// arc4random is built-in on these platforms.
#elif (NGX_LINUX)
#include <bsd/stdlib.h>
#else
// TODO: test using libbsd on Windows.
#error ipscrub requires arc4random_buf.
#endif
// null_terminate allocates a new, null-terminated string based on input. // null_terminate allocates a new, null-terminated string based on input.
ngx_int_t null_terminate(ngx_pool_t *pool, ngx_str_t input, u_char **out) ngx_int_t null_terminate(ngx_pool_t *pool, ngx_str_t input, u_char **out)
{ {
@ -37,23 +46,20 @@ ngx_int_t concat(ngx_pool_t *pool, ngx_str_t prefix, ngx_str_t suffix, u_char **
return NGX_OK; return NGX_OK;
} }
// randlong fills out with secure random bytes and returns NGX_OK iff successful. // randbytes fills out with secure random bytes.
ngx_int_t randlong(long *out) { // Return value of NGX_OK indicates success.
#if !(NGX_DARWIN || NGX_SOLARIS || NGX_FREEBSD || NGX_LINUX) // Return value of NGX_ERROR indicates error.
// Windows not supported a.t.m. ngx_int_t randbytes(u_char *out, int num_bytes) {
// TODO: support Windows (https://msdn.microsoft.com/en-us/library/sxtz2fa8.aspx). if (out == NULL) {
return -1; return NGX_ERROR;
#endif }
if (num_bytes < 1 || num_bytes > 64) {
int rand = open("/dev/urandom", O_RDONLY); // Values outside these bounds may indicate parameter usage mistake.
if (rand < 0) { return NGX_ERROR;
return -1;
} }
ssize_t ret = read(rand, out, sizeof(long));
if (ret != sizeof(long)) { arc4random_buf(out, num_bytes);
return -1;
}
return NGX_OK; return NGX_OK;
} }

View File

@ -8,6 +8,6 @@
ngx_int_t null_terminate(ngx_pool_t *pool, ngx_str_t input, u_char **hashed); ngx_int_t null_terminate(ngx_pool_t *pool, ngx_str_t input, u_char **hashed);
ngx_int_t concat(ngx_pool_t *pool, ngx_str_t prefix, ngx_str_t suffix, u_char **out); ngx_int_t concat(ngx_pool_t *pool, ngx_str_t prefix, ngx_str_t suffix, u_char **out);
ngx_int_t randlong(long *out); ngx_int_t randbytes(u_char *out, int num_bytes);
#endif /* _IPSCRUB_SUPPORT_H_INCLUDED_ */ #endif /* _IPSCRUB_SUPPORT_H_INCLUDED_ */