Last active
November 10, 2022 23:40
-
-
Save nginx-gists/8202a6872e9ec784ce14b1a63564a39d to your computer and use it in GitHub Desktop.
Data Masking for User Privacy with the NGINX JavaScript Module
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
log_format masked '$remote_addr_masked - $remote_user [$time_local] ' | |
'"$request" $status $body_bytes_sent ' | |
'"$http_referer" "$http_user_agent"'; | |
js_import mask_ip_uri.js; | |
js_set $remote_addr_masked mask_ip_uri.maskRemoteAddress; | |
server { | |
listen 80; | |
access_log /var/log/nginx/access.log; | |
access_log /var/log/nginx/access_masked.log masked; | |
location / { | |
return 200 "$remote_addr -> $remote_addr_masked\n"; # For testing only | |
} | |
} | |
# vim: syntax=nginx |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function fnv32a(str) { | |
var hval = 2166136261; | |
for (var i = 0; i < str.length; ++i ) { | |
hval ^= str.charCodeAt(i); | |
hval += (hval << 1) + (hval << 4) + (hval << 7) + (hval << 8) + (hval << 24); | |
} | |
return hval >>> 0; | |
} | |
function i2ipv4(i) { | |
var octet1 = (i >> 24) & 255; | |
var octet2 = (i >> 16) & 255; | |
var octet3 = (i >> 8) & 255; | |
var octet4 = i & 255; | |
return octet1 + "." + octet2 + "." + octet3 + "." + octet4; | |
} | |
function maskRemoteAddress(req) { | |
return i2ipv4(fnv32a(req.remoteAddress)); | |
} | |
function maskRequestURI(req) { | |
var query_string = req.variables.query_string; | |
if (query_string.length) { // Proceed if we have query string | |
var kvpairs = query_string.split('&'); // Convert to array of key=value | |
for (var i = 0; i < kvpairs.length; i++) { // Iterate through each KV pair | |
var kvpair = kvpairs[i].split('='); // Split KV pair into new array | |
if (kvpair[0] == "zip") { // Mask zip | |
// Use first 5 digits of masked value | |
kvpairs[i] = kvpair[0] + "=" + fnv32a(kvpair[1]).toString().substr(0,5); | |
} else if (kvpair[0] == "email") { // Mask email | |
// Use hash as prefix for a single domain | |
kvpairs[i] = kvpair[0] + "=" + fnv32a(kvpair[1]) + "@example.com"; | |
} | |
} | |
return req.uri + "?" + kvpairs.join('&'); // Construct masked URI | |
} | |
return req.uri; // No query string, return URI | |
} | |
export default { maskRemoteAddress maskRequestURI } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
log_format masked '$remote_addr_masked - $remote_user [$time_local] ' | |
'"$request_method $request_uri_masked $server_protocol" ' | |
'$status $body_bytes_sent "$http_referer" "$http_user_agent"'; | |
js_import mask_ip_uri.js; | |
js_set $request_uri_masked mask_ip_uri.maskRequestURI; | |
server { | |
listen 80; | |
access_log /var/log/nginx/access.log; | |
access_log /var/log/nginx/access_masked.log masked; | |
location / { | |
return 200 "$remote_addr -> $remote_addr_masked\n"; # For testing only | |
} | |
} | |
# vim: syntax=nginx |
i suggest adding
add_header Content-Type "text/plain";
before your text return
my javascript is lacking. is it possible to reverse the mask done by maskRemoteAddress?
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
For a discussion of these files, see Data Masking for User Privacy with the NGINX JavaScript Module