NAT Logging: Session Tracking for CGNAT and Compliance

An abuse complaint arrives: “IP 203.0.113.50 attacked our server at 14:32:15 UTC.” But 203.0.113.50 is your NAT gateway, used by 500 subscribers. Who was it?

Without NAT logging, you don’t know. With NAT logging, you can trace 203.0.113.50:32768 at 14:32:15 back to internal IP 10.0.15.42 — subscriber John Smith. Now you can respond to the complaint.

NAT logs are essential for troubleshooting and legal requirements.

Why Log NAT

Abuse Handling

Complaint: "Attack from 203.0.113.50:32768 to victim:80 at 14:32:15"
Without logs: "We use NAT, could be anyone"
With logs: "That was 10.0.15.42 (subscriber #12345)"

Many jurisdictions require ISPs to:

  • Log NAT translations
  • Retain logs for specified period
  • Provide data upon legal request

Troubleshooting

User: "My connection keeps dropping"
NAT logs show: Frequent connection resets, port exhaustion

Connection Tracking Logging

Enable Conntrack Logging

Terminal window
configure
# Log new connections
set system conntrack log new
# Log connection updates (optional, verbose)
set system conntrack log update
# Log connection destroy (useful for session duration)
set system conntrack log destroy
commit

Log Format

# Example log entries:
[NEW] tcp 6 120 SYN_SENT src=10.0.15.42 dst=93.184.216.34 sport=45678 dport=80 [UNREPLIED] src=93.184.216.34 dst=203.0.113.50 sport=80 dport=32768
[UPDATE] tcp 6 60 SYN_RECV src=10.0.15.42 dst=93.184.216.34 sport=45678 dport=80 src=93.184.216.34 dst=203.0.113.50 sport=80 dport=32768
[DESTROY] tcp 6 src=10.0.15.42 dst=93.184.216.34 sport=45678 dport=80 src=93.184.216.34 dst=203.0.113.50 sport=80 dport=32768

Key Fields

[NEW] - Connection start
[DESTROY] - Connection end
src=10.0.15.42 - Original source (internal)
dst=93.184.216.34 - Original destination
sport=45678 - Original source port
src=93.184.216.34 - Reply source
dst=203.0.113.50 - Reply destination (your NAT IP)
dport=32768 - NAT'd port (what abuse reports show)

Syslog Configuration

Send to Remote Syslog

Terminal window
configure
# Send logs to remote syslog server
set system syslog host 10.0.0.100 facility kern level debug
# Or specific file locally
set system syslog file nat-log facility kern level debug
commit

Log Rotation

/etc/logrotate.d/nat-logs
# Configure logrotate for NAT logs
/var/log/messages {
daily
rotate 90 # Keep 90 days for compliance
compress
delaycompress
notifempty
create 640 root adm
}

NAT Session Table

View Current Sessions

Terminal window
# Show all NAT sessions
show nat source translations
# Or via conntrack
sudo conntrack -L
# Filter for specific internal IP
sudo conntrack -L -s 10.0.15.42
# Filter for specific NAT IP
sudo conntrack -L -r 203.0.113.50

Real-Time Monitoring

Terminal window
# Watch new connections
sudo conntrack -E -e NEW
# Watch specific source
sudo conntrack -E -s 10.0.15.42

Log Analysis

Find Session by External Port

Terminal window
# Complaint: 203.0.113.50:32768 at 14:32:15
# Search logs
grep "dport=32768" /var/log/messages | grep "14:32"
# Output:
# Jan 8 14:32:15 router kernel: [NEW] tcp ... src=10.0.15.42 ... dport=32768

Find All Sessions for Internal IP

Terminal window
# Who was 10.0.15.42 talking to?
grep "src=10.0.15.42" /var/log/messages | grep "\[NEW\]"

Session Statistics

Terminal window
# Connections per internal IP
grep "\[NEW\]" /var/log/messages | grep -oP "src=\S+" | sort | uniq -c | sort -rn | head
# Destinations per internal IP
grep "src=10.0.15.42" /var/log/messages | grep "\[NEW\]" | grep -oP "dst=\S+" | sort | uniq -c | sort -rn

Log Storage and Retention

Requirements

GDPR (EU): Not specifically defined, but purpose limitation applies
Various ISP regulations: 6 months to 2 years typical
Calculate storage:
- ~200 bytes per session
- 1000 sessions/second = 200 KB/s = 17 GB/day
- 90 days retention = 1.5 TB

Efficient Storage

Terminal window
# Use structured logging
# Compress old logs
# Consider log aggregation (ELK stack, etc.)
# Example: rsyslog to Elasticsearch
# /etc/rsyslog.d/nat-to-elastic.conf
module(load="omelasticsearch")
if $programname == 'kernel' and $msg contains 'conntrack' then {
action(type="omelasticsearch"
server="elasticsearch.local"
serverport="9200"
template="nat-log-template")
}

CGNAT Specific Logging

Extended Port Blocks

For CGNAT, logging individual connections is expensive. Alternative: log port block assignments.

# Instead of logging every connection:
# [NEW] 10.0.15.42:12345 -> 93.184.216.34:80 via 203.0.113.50:32768
# Log port block assignment:
# 10.0.15.42 assigned ports 32768-34815 on 203.0.113.50 at 14:00:00
# 10.0.15.42 released ports 32768-34815 on 203.0.113.50 at 16:00:00
# Abuse lookup: 203.0.113.50:32768 at 14:32:15 was in 10.0.15.42's block

VyOS CGNAT Logging

Terminal window
configure
# If using deterministic NAT (fixed mapping)
# Logging is simpler - mapping is predictable
# For dynamic NAT, full connection logging required
commit

Responding to Abuse Complaints

Process

1. Receive complaint with:
- External IP (your NAT)
- External port
- Timestamp (UTC!)
- Destination IP/port
- Protocol
2. Convert timestamp to your timezone
3. Search logs:
grep "dport=<port>" /var/log/nat.log | grep "<timestamp>"
4. Identify internal IP
5. Map internal IP to subscriber (from DHCP logs, etc.)
6. Respond to complaint with internal reference

Response Template

Reference: ABUSE-2025-0108-001
Complaint received: 2025-01-08
External IP: 203.0.113.50
External Port: 32768
Timestamp: 2025-01-08 14:32:15 UTC
Destination: victim.example.com:80
Investigation:
NAT logs show this connection originated from internal IP 10.0.15.42.
This corresponds to subscriber account #12345.
Action taken:
[Your action - warning, suspension, etc.]

Performance Considerations

Log Volume

Terminal window
# Logging every connection has cost:
# - CPU for logging
# - Disk I/O
# - Storage space
# For high-throughput NAT:
# Consider sampling
# Use dedicated log server
# Aggregate logs

Log Only What’s Needed

Terminal window
# Log only NEW events (not UPDATE/DESTROY)
set system conntrack log new
# DELETE logs useful for session duration, but doubles volume

Security of Logs

Access Control

Terminal window
# NAT logs contain sensitive data
# - Who visited what
# - Privacy implications
# Restrict access
chmod 600 /var/log/nat.log
# Only authorized personnel
# Encrypt at rest
# Consider log integrity (signing)

Retention Policy

Terminal window
# Define retention period based on:
# - Legal requirements
# - Business needs
# - Privacy obligations
# Automatic purge after retention period
find /var/log/nat-archive -mtime +90 -delete

Best Practices

1. Log to Remote Server

Terminal window
# Don't rely on local storage
# Remote syslog or log aggregation
set system syslog host 10.0.0.100 facility kern level debug

2. Timestamp Accuracy

Terminal window
# Use NTP for accurate timestamps
set system ntp server pool.ntp.org
# Complaints reference specific times
# Accuracy matters for correlation
Terminal window
# Before you need it:
# - Generate test traffic
# - Verify logs captured
# - Practice searching
# - Measure search time

4. Document Process

# NAT Log Lookup Procedure
1. Receive complaint
2. Verify timestamp timezone
3. Search command: grep "dport=X" /path/to/logs
4. Identify internal IP
5. Cross-reference with DHCP/subscriber database
6. Document findings

The Lesson

NAT logs are essential for troubleshooting and legal requirements.

Without NAT logs:

  • Can’t respond to abuse complaints
  • Can’t troubleshoot user issues
  • May violate legal requirements
  • “It could be anyone”

With NAT logs:

  • Trace any connection to internal source
  • Respond to abuse with evidence
  • Meet compliance requirements
  • Debug NAT issues

The overhead of logging is real but necessary. Plan storage, plan retention, and practice lookup before you need it during an incident.

Your first abuse complaint is too late to set up logging.