Anonymizing Network Configurations with Netconan
Using netconan to strip passwords, IPs, and sensitive strings from Cisco and Juniper configs before sharing them — deterministic, reversible, and prefix-preserving.
Contents
The Problem
You need to share a network config. Maybe it is for a vendor RCA, an LLD for a customer, a Batfish analysis, or a Stack Overflow question. The config has passwords, SNMP communities, real IP addresses, and internal hostnames baked in.
Manual redaction is tedious and error-prone. You will miss something. I have seen sanitized configs with TACACS keys still in them more than once.
Netconan
Netconan (network configuration anonymizer) solves this properly. It is an open-source Python CLI that anonymizes sensitive data in network configuration files. It is maintained by the same team behind Batfish.
Install it:
$ pip install netconan
That is it. No containers, no dependencies beyond Python.
Basic Usage
Given a sensitive config:
! router-core-01 configuration
username admin password 7 122A001901
enable secret 5 $1$wtHI$0rN7R8PKwC30AsCGA77vy.
!
tacacs-server host 10.1.100.5 key s3cr3tK3y
ip address 10.10.20.30/24
ip address 2001:db8::9d3b:1
!
route-map NYC-to-LAX permit 10
route-map NYC-to-ATL permit 10
Run netconan against it:
$ netconan \
-i sensitive/ \
-o anonymized/ \
--anonymize-passwords \
--anonymize-ips \
--sensitive-words NYC,LAX,ATL
Output:
! db1792 configuration
username admin password 7 09424B1D1A0A1913053E012724322D3765
enable secret 5 $1$0000$EhfXcDfB7iiakW6mwMy1i.
!
tacacs-server host 10.72.218.183 key netconanRemoved2
ip address 10.72.218.183/24
ip address cd7e:83e:1eaf:2ada:7535:591e:6d47:a4b8
!
route-map e69ceb-to-880ac2 permit 10
route-map e69ceb-to-5d37ad permit 10
Passwords are replaced with format-compliant substitutes (Type 7, Type 5, Juniper Type 9 all handled). IPs are anonymized. Sensitive keywords are hashed. The config remains structurally valid.
What It Anonymizes
- Passwords and community strings (
-p) — recognizes standard formats across Cisco, Juniper, Arista, and other vendors - IPv4 and IPv6 addresses (
-a) — prefix-preserving anonymization - Sensitive keywords (
-w) — replaces any occurrence of specified words (hostnames, site codes, customer names) - AS numbers (
-n) — anonymizes specified AS numbers while preserving public/private ranges
Prefix-Preserving IP Anonymization
This is the clever part. Netconan does not just randomize IPs. It uses prefix-preserving anonymization based on Xu et al. (2001). Two IPs that share a common prefix in the original config will share the same prefix length after anonymization. Your routing topology stays readable.
Additional controls:
--preserve-host-bits 8— preserves the last 8 bits by default, so /30 point-to-point links and NAT pools keep their structure--preserve-prefixes 10.0.0.0/8— keeps specified prefixes intact, anonymizes only the host portion--preserve-addresses 192.168.1.1— skips anonymization entirely for specific addresses--preserve-private-addresses— leaves RFC 1918 space untouched
Deterministic and Reversible
With a consistent salt, anonymization is deterministic:
$ netconan -i configs/ -o anonymized/ \
--anonymize-ips \
--anonymize-passwords \
--salt "my-project-salt-2026"
Files processed with the same salt produce identical anonymized output. This means you can anonymize configs from different devices separately and they remain consistent — the same real IP always maps to the same anonymized IP.
Even better, IP anonymization is reversible:
$ netconan -i anonymized/ -o deanonymized/ \
--undo \
--salt "my-project-salt-2026"
Store the salt securely and you can always recover the original IPs. You can also dump the full IP mapping for reference:
$ netconan -i configs/ -o anonymized/ \
--anonymize-ips \
--salt "my-project-salt-2026" \
--dump-ip-map ip-mapping.txt
Config File for Repeatable Runs
For repeatable anonymization across a team, use a config file instead of CLI flags:
# netconan.cfg
anonymize_ips = true
anonymize_passwords = true
sensitive_words = [NYC,LAX,ATL,ACME]
salt = my-project-salt-2026
preserve_host_bits = 8
preserve_private_addresses = true
$ netconan -c netconan.cfg -i configs/ -o anonymized/
Check this into your repo (without the salt, obviously) and everyone on the team gets consistent results.
When to Use This
- Sharing configs with vendors — strip customer data before sending to TAC
- Documentation — LLDs and SLDs with realistic but sanitized configs
- Open-source contributions — share real-world configs for Batfish snapshots or test cases
- Compliance — PCI DSS and similar frameworks that require masking of network addressing in shared documents
- Troubleshooting posts — sanitized configs for forums without exposing your network
Netconan handles the tedious part. Use it instead of find-and-replace.