GDPR合规:Nginx中实现IP匿名化(最后八位组取偶)
Absolutely, you can implement your exact desired IP anonymization logic using Nginx's map module—no need for overly aggressive C-class stripping. Let’s walk through the step-by-step configuration to round the last octet to the nearest even number (divide by 2, floor, multiply by 2).
Step 1: Split the IP into Octets
First, create map blocks to extract each of the four octets from the client IP ($remote_addr):
# Extract first three octets of IPv4 addresses map $remote_addr $ip_octet1 { ~^(\d+)\.(\d+)\.(\d+)\.(\d+)$ $1; } map $remote_addr $ip_octet2 { ~^(\d+)\.(\d+)\.(\d+)\.(\d+)$ $2; } map $remote_addr $ip_octet3 { ~^(\d+)\.(\d+)\.(\d+)\.(\d+)$ $3; } # Extract the fourth octet for processing map $remote_addr $ip_octet4 { ~^(\d+)\.(\d+)\.(\d+)\.(\d+)$ $4; }
Step 2: Anonymize the Fourth Octet
Next, use another map to apply your rounding logic. This relies on Nginx's arithmetic expression support (available in Nginx 1.11.10+):
map $ip_octet4 $ip_octet4_anonymized { # Default to empty if the octet isn't a valid number default ""; # Apply: (octet // 2) * 2 ~^(\d+)$ $((($1 // 2) * 2)); }
Step 3: Reconstruct the Anonymized IP
Combine the first three octets with the processed fourth octet to form the final anonymized IP:
map $remote_addr $anonymized_ip { # For valid IPv4 addresses, assemble the anonymized string ~^(\d+)\.(\d+)\.(\d+)\.(\d+)$ "$ip_octet1.$ip_octet2.$ip_octet3.$ip_octet4_anonymized"; # For non-IPv4 addresses (e.g., IPv6), keep the original or customize as needed default $remote_addr; }
Step 4: Update Your Log Format
Replace $remote_addr with $anonymized_ip in your log format definition:
log_format custom '$anonymized_ip - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; # Apply the custom log format to your access log access_log /var/log/nginx/access.log custom;
Key Notes
- Version Requirement: Ensure you’re running Nginx 1.11.10 or newer to use the
$((...))arithmetic syntax. If you’re on an older version, you can achieve similar results withsetandifblocks, butmapis cleaner and more efficient. - Example Output: An IP like
192.168.1.123becomes192.168.1.122, while192.168.1.124stays192.168.1.124—perfect for balancing GDPR compliance with retaining useful subnet context. - IPv6 Handling: The configuration above leaves IPv6 addresses unchanged. If you need to anonymize IPv6, you’d need to adjust the regex and logic to target the appropriate segments (feel free to ask if you need help with that!).
内容的提问来源于stack exchange,提问作者Adam

