{"id":34063247,"url":"https://github.com/scottpeterman/secure_cartography","last_synced_at":"2026-04-07T15:33:08.314Z","repository":{"id":322167967,"uuid":"904002122","full_name":"scottpeterman/secure_cartography","owner":"scottpeterman","description":"A secure, Python-based network discovery and mapping tool that generates comprehensive network topology maps using SSH-based device interrogation.","archived":false,"fork":false,"pushed_at":"2026-01-31T11:42:51.000Z","size":97180,"stargazers_count":6,"open_issues_count":2,"forks_count":2,"subscribers_count":2,"default_branch":"main","last_synced_at":"2026-03-11T06:59:21.182Z","etag":null,"topics":["multi-vendor-support","network-automation","network-discovery","python-networking","topology-mapping"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/scottpeterman.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2024-12-16T04:09:08.000Z","updated_at":"2026-03-10T17:41:59.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/scottpeterman/secure_cartography","commit_stats":null,"previous_names":["scottpeterman/secure_cartography"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/scottpeterman/secure_cartography","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/scottpeterman%2Fsecure_cartography","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/scottpeterman%2Fsecure_cartography/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/scottpeterman%2Fsecure_cartography/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/scottpeterman%2Fsecure_cartography/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/scottpeterman","download_url":"https://codeload.github.com/scottpeterman/secure_cartography/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/scottpeterman%2Fsecure_cartography/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31518583,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-07T03:10:19.677Z","status":"ssl_error","status_checked_at":"2026-04-07T03:10:13.982Z","response_time":105,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["multi-vendor-support","network-automation","network-discovery","python-networking","topology-mapping"],"created_at":"2025-12-14T05:15:55.480Z","updated_at":"2026-04-07T15:33:08.307Z","avatar_url":"https://github.com/scottpeterman.png","language":"Python","readme":"# Secure Cartography v2\n\n**SSH \u0026 SNMP-Based Network Discovery and Topology Mapping**\n\n[![Python 3.9+](https://img.shields.io/badge/python-3.9+-blue.svg)](https://www.python.org/downloads/)\n[![License: GPL v3](https://img.shields.io/badge/License-GPLv3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0)\n[![PyQt6](https://img.shields.io/badge/GUI-PyQt6-green.svg)](https://www.riverbankcomputing.com/software/pyqt/)\n\nSecure Cartography is a network discovery tool that crawls your infrastructure via SNMP and SSH, collecting CDP/LLDP neighbor information to automatically generate topology maps. Built by a network engineer, for network engineers. \n\nIf you are interested in a non-python native application for network maps see [Secure Cartography  JS](https://github.com/scottpeterman/secure_cartography_js)\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"https://raw.githubusercontent.com/scottpeterman/secure_cartography/refs/heads/main/screenshots/slides2.gif\" alt=\"Secure Cartography - Cyber Theme\" width=\"800\"\u003e\n\u003c/p\u003e\n\n---\n\n## What's New in v2\n\nVersion 2 is a complete rewrite with a modernized architecture:\n\n| Feature | v1                           | v2                                                                     |\n|---------|------------------------------|------------------------------------------------------------------------|\n| Discovery Engine | Synchronous, single-threaded | **Async with configurable concurrency**                                |\n| Discovery Protocol | SSH only                     | **SNMP-first with SSH fallback**                                       |\n| Credential Storage | No credential persistance    | **SQLite vault with AES-256 encryption**                               |\n| CLI | Basic                        | **Full-featured with test/discover/crawl commands**                    |\n| Progress Reporting | Callbacks                    | **Structured events for GUI integration**                              |\n| SNMP Support | None                         | **v2c and v3 (authPriv)**                                              |\n| Vendor Support | Cisco, Arista                | **+ Cisco, Arista and Juniper, Others fingerprinted based on sysdesc** |\n| GUI | PyQt6                        | **PyQt6 with theme support (Cyber/Dark/Light)**                        |\n| Topology Viewer | External (yEd/Draw.io)       | **Embedded Cytoscape.js with vendor coloring, yEd \u0026 Draw.io export**   |\n| Security Analysis | None                         | **CVE vulnerability scanning via NIST NVD**                            |\n| Device Polling | None                         | **Interactive SNMP fingerprinting from map**                           |\n\n---\n\n## Features\n\n### Discovery Engine\n- **SNMP-first discovery** with automatic SSH fallback\n- **CDP and LLDP** neighbor detection across vendors\n- **Two-pass LLDP resolution** - correctly handles lldpLocPortNum vs ifIndex\n- **Bidirectional link validation** - only confirmed connections appear in topology\n- **Concurrent crawling** - discover 20+ devices simultaneously\n- **Depth-limited recursion** - control how far the crawler goes\n- **Exclusion patterns** - skip devices by hostname, sys_name, or sysDescr\n- **No-DNS mode** - use IPs directly from neighbor tables (home lab friendly)\n\n### Credential Management\n- **Encrypted SQLite vault** - AES-256-GCM encryption at rest\n- **Multiple credential types** - SSH (password + key), SNMPv2c, SNMPv3\n- **Priority ordering** - try credentials in sequence until one works\n- **Credential discovery** - auto-detect which credentials work on which devices\n\n### Security Analysis (CVE Vulnerability Scanning)\n- **Platform-to-CPE mapping** - automatically parses discovered platform strings\n- **NIST NVD integration** - queries National Vulnerability Database for CVEs\n- **Severity color-coding** - CRITICAL/HIGH/MEDIUM/LOW at a glance\n- **Local CVE cache** - SQLite cache avoids repeated API calls\n- **Export reports** - CSV export with affected devices per CVE\n- **Device-centric view** - \"Export by Device\" shows CVE counts per device\n- **Multi-vendor support** - Cisco IOS/IOS-XE/NX-OS, Arista EOS, Juniper JUNOS, Palo Alto, Fortinet\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"https://raw.githubusercontent.com/scottpeterman/secure_cartography/refs/heads/main/screenshots/sec_vuln.png\" alt=\"Security Analysis - CVE Vulnerability Scanning\" width=\"800\"\u003e\n\u003c/p\u003e\n\n### Live Topology Preview\n- **Embedded Cytoscape.js viewer** - interactive network visualization\n- **Real-time rendering** - topology displayed immediately after discovery\n- **Vendor-specific styling** - Cisco (blue), Arista (green), Juniper (orange) with distinct colors\n- **Undiscovered peer nodes** - referenced but unreachable devices shown with warning markers\n- **Theme-aware** - visualization adapts to Cyber/Dark/Light themes\n- **Interactive controls** - fit view, auto-layout, node selection with details popup\n\n### Draw.io Export\nOne-click export to Draw.io format for professional network documentation:\n\n- **Cisco mxgraph stencils** - native Draw.io shapes for switches, routers, firewalls, wireless\n- **Vendor coloring** - automatic fill colors match the embedded viewer (Cisco blue, Juniper orange, Arista green)\n- **Hierarchical layout** - tree algorithm positions devices by network tier\n- **Interface labels** - port-to-port connections preserved on edges\n- **Universal compatibility** - open in Draw.io desktop, web (diagrams.net), or VS Code extension\n- **Edit and annotate** - recipients can modify layouts, add notes, highlight paths\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"https://raw.githubusercontent.com/scottpeterman/secure_cartography/refs/heads/main/screenshots/drawio_multivendor.png\" alt=\"Draw.io Export - Multi-vendor topology\" width=\"800\"\u003e\n\u003c/p\u003e\n\n### Interactive Device Polling\nPoll individual devices directly from the Map Viewer for on-demand identification and inventory — no full discovery required.\n\n- **SNMP fingerprinting** - identifies vendor, model, OS version via Rapid7 Recog patterns\n- **Interface inventory** - collects ifTable with MAC addresses and OUI vendor lookup\n- **ARP table collection** - neighbor IP/MAC mappings with vendor identification\n- **Two operating modes**:\n  - **Local mode** - direct SNMP using pysnmp-lextudio (works on Windows/Linux/Mac)\n  - **Proxy mode** - for targets only reachable from a jump host ([SNMP Proxy](snmp_proxy/README.md))\n- **Export to Excel** - multi-sheet workbook with Summary, Interfaces, and ARP data\n\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"https://raw.githubusercontent.com/scottpeterman/secure_cartography/refs/heads/main/screenshots/snmp1.png\" alt=\"Device Poll - Interface Table\" width=\"600\"\u003e\n\u003c/p\u003e\n\n### Themed GUI\n- **Three themes** - Cyber (cyan), Dark (gold), Light (blue)\n- **Real-time progress** - live counters, depth tracking, log output\n- **Responsive design** - UI remains interactive during discovery\n- **Click-to-inspect** - node details (hostname, IP, platform) on selection\n\n### Supported Platforms\n| Vendor | SNMP | SSH | CVE Mapping |\n|--------|------|-----|-------------|\n| Cisco IOS/IOS-XE | ✓ | ✓ | ✓ |\n| Cisco NX-OS | ✓ | ✓ | ✓ |\n| Arista EOS | ✓ | ✓ | ✓ |\n| Juniper JUNOS | ✓ | ✓ | ✓ |\n\n* Others will likely appear but testing has been limited\n---\n\n## Screenshots\n\n\u003ctable\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003cimg src=\"https://raw.githubusercontent.com/scottpeterman/secure_cartography/refs/heads/main/screenshots/main_cyber.png\" alt=\"Cyber Theme\" width=\"280\"\u003e\u003c/td\u003e\n\u003ctd\u003e\u003cimg src=\"https://raw.githubusercontent.com/scottpeterman/secure_cartography/refs/heads/main/screenshots/main_dark.png\" alt=\"Dark Theme\" width=\"280\"\u003e\u003c/td\u003e\n\u003ctd\u003e\u003cimg src=\"https://raw.githubusercontent.com/scottpeterman/secure_cartography/refs/heads/main/screenshots/main_light.png\" alt=\"Light Theme\" width=\"280\"\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\u003cb\u003eCyber\u003c/b\u003e - Teal accents\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cb\u003eDark\u003c/b\u003e - Gold accents\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cb\u003eLight\u003c/b\u003e - Blue accents\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/table\u003e\n\n\u003ctable\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003cimg src=\"https://raw.githubusercontent.com/scottpeterman/secure_cartography/refs/heads/main/screenshots/full_run_preview_cyber.png\" alt=\"Topology - Cyber\" width=\"280\"\u003e\u003c/td\u003e\n\u003ctd\u003e\u003cimg src=\"https://raw.githubusercontent.com/scottpeterman/secure_cartography/refs/heads/main/screenshots/run_complete_dark.png\" alt=\"Topology - Dark\" width=\"280\"\u003e\u003c/td\u003e\n\u003ctd\u003e\u003cimg src=\"https://raw.githubusercontent.com/scottpeterman/secure_cartography/refs/heads/main/screenshots/full_run_preview_light.png\" alt=\"Topology - Light\" width=\"280\"\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003eTopology Preview - Cyber\u003c/td\u003e\n\u003ctd align=\"center\"\u003eTopology Preview - Dark\u003c/td\u003e\n\u003ctd align=\"center\"\u003eTopology Preview - Light\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/table\u003e\n\n\u003ctable\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003cimg src=\"https://raw.githubusercontent.com/scottpeterman/secure_cartography/refs/heads/main/screenshots/login_cyan.png\" alt=\"Login - Cyber\" width=\"280\"\u003e\u003c/td\u003e\n\u003ctd\u003e\u003cimg src=\"https://raw.githubusercontent.com/scottpeterman/secure_cartography/refs/heads/main/screenshots/login_amber.png\" alt=\"Login - Dark\" width=\"280\"\u003e\u003c/td\u003e\n\u003ctd\u003e\u003cimg src=\"https://raw.githubusercontent.com/scottpeterman/secure_cartography/refs/heads/main/screenshots/login_light.png\" alt=\"Login - Light\" width=\"280\"\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003eLogin - Cyber\u003c/td\u003e\n\u003ctd align=\"center\"\u003eLogin - Dark\u003c/td\u003e\n\u003ctd align=\"center\"\u003eLogin - Light\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/table\u003e\n\n---\n\n## Installation\n\n### Prerequisites\n- Python 3.10 or higher\n- pip\n\n### From Source\n```bash\ngit clone https://github.com/scottpeterman/secure_cartography.git\ncd secure_cartography\npip install -e .\n```\n\n### Dependencies\n```bash\n# Core\npip install pysnmp-lextudio paramiko cryptography textfsm aiofiles\n\n# GUI\npip install PyQt6 PyQt6-WebEngine\n```\n\n---\n\n## Quick Start\n\n### 1. Initialize the Credential Vault\n```bash\n# Create vault and set master password\npython -m sc2.scng.creds init\n\n# Add SNMP credential\npython -m sc2.scng.creds add snmpv2c snmp-readonly --community public\n\n# Add SSH credential  \npython -m sc2.scng.creds add ssh network-admin --username admin\n\n# List credentials\npython -m sc2.scng.creds list\n```\n\n### 2. Test Connectivity\n```bash\n# Quick SNMP test (no vault needed)\npython -m sc2.scng.discovery test 192.168.1.1 --community public\n\n# Test with vault credentials\npython -m sc2.scng.discovery device 192.168.1.1\n```\n\n### 3. Run Discovery\n```bash\n# Basic crawl\npython -m sc2.scng.discovery crawl 192.168.1.1 -d 3\n\n# With options\npython -m sc2.scng.discovery crawl 192.168.1.1 10.0.0.1 \\\n    -d 5 \\\n    --domain corp.example.com \\\n    --exclude \"phone,wireless,linux\" \\\n    --output ./network_maps\n```\n\n### 4. Launch GUI\n```bash\npython -m sc2.ui\n```\n\n### 5. Security Analysis\nAfter running discovery, click the **🔐 SECURITY** button in the header bar to open the Security Analysis window:\n\n1. **Load CSV** - Import the `devices.csv` from your discovery output\n2. **Review Mappings** - Verify auto-detected platform → CPE mappings\n3. **Sync Selected** - Query NIST NVD for CVEs (optional: add free API key for faster rate limits)\n4. **Analyze Results** - Review CVEs sorted by severity\n5. **Export Report** - Generate CSV with CVEs and affected devices\n\n---\n\n## Security Analysis Workflow\n\nThe Security Analysis module transforms your network inventory into an actionable vulnerability report.\n\n### Platform Recognition\nSecure Cartography automatically parses platform strings into CPE (Common Platform Enumeration) format:\n\n```\n\"Cisco IOS IOS 15.2(4.0.55)E\" → cpe:2.3:o:cisco:ios:15.2(4.0.55)e:*:*:*:*:*:*:*\n\"Arista vEOS-lab EOS 4.33.1F\" → cpe:2.3:o:arista:eos:4.33.1f:*:*:*:*:*:*:*\n```\n\n### CVE Lookup\nQueries the NIST National Vulnerability Database for known vulnerabilities:\n- Results cached locally in `~/.scng/cve_cache.db`\n- Free NVD API key increases rate limits (get one at [nvd.nist.gov](https://nvd.nist.gov/developers/request-an-api-key))\n\n### Export Options\nTwo export formats for different use cases:\n\n| Export | Format | Use Case |\n|--------|--------|----------|\n| **Export Report** | One row per CVE | Security team review, compliance audits |\n| **Export by Device** | One row per device | Remediation planning, patch prioritization |\n\n### Jump Host Workflow\nWhen your desktop doesn't have SNMP access:\n\n1. SSH to a jump host with network access\n2. Run discovery via CLI: `python -m sc2.scng.discovery crawl ...`\n3. Copy `devices.csv` back to your desktop\n4. Open in GUI → Security Analysis → Load CSV → Sync\n\n---\n\n## Architecture\n\n```\nsc2/\n├── scng/                      # Discovery engine\n│   ├── creds/                 # Credential vault\n│   │   ├── vault.py           # Encrypted SQLite storage\n│   │   ├── models.py          # SSH, SNMPv2c, SNMPv3 dataclasses\n│   │   ├── resolver.py        # Credential testing \u0026 discovery\n│   │   └── cli.py             # Credential management CLI\n│   │\n│   ├── discovery/             # Discovery engine\n│   │   ├── engine.py          # Async orchestration, crawl logic\n│   │   ├── models.py          # Device, Neighbor, Interface\n│   │   ├── cli.py             # Discovery CLI\n│   │   │\n│   │   ├── snmp/              # SNMP collection\n│   │   │   ├── walker.py      # Async GETBULK table walks\n│   │   │   └── collectors/    # system, interfaces, lldp, cdp, arp\n│   │   │\n│   │   └── ssh/               # SSH fallback\n│   │       ├── client.py      # Paramiko wrapper\n│   │       ├── collector.py   # Vendor detection, command execution\n│   │       └── parsers.py     # TextFSM integration\n│   │\n│   └── utils/\n│       └── tfsm_fire.py       # TextFSM auto-template selection\n│\n├── export/                    # Export modules\n│   ├── graphml_exporter.py    # yEd GraphML export\n│   └── drawio_exporter.py     # Draw.io export with vendor styling\n│\n└── ui/                        # PyQt6 GUI\n    ├── themes.py              # Theme system (Cyber/Dark/Light)\n    ├── login.py               # Vault unlock dialog\n    ├── main_window.py         # Main application window\n    ├── help_dialog.py         # Help system (GUI/CLI/Security docs)\n    │\n    ├── assets/\n    │   └── icons_lib/\n    │       └── platform_icon_drawio.json  # Draw.io icon mappings\n    │\n    └── widgets/               # Custom themed widgets\n        ├── panel.py               # Base panel with title bar\n        ├── connection_panel.py    # Seeds, domains, excludes\n        ├── credentials_panel.py   # Credential management UI\n        ├── discovery_options.py   # Depth, concurrency, toggles\n        ├── output_panel.py        # Output directory config\n        ├── progress_panel.py      # Stats, progress bar\n        ├── discovery_log.py       # Styled log output\n        ├── discovery_controller.py # Discovery↔UI bridge with throttled events\n        ├── topology_preview_panel.py  # Preview container (singleton)\n        ├── topology_viewer.py     # QWebEngineView + Cytoscape.js bridge\n        ├── topology_viewer.html   # Cytoscape.js visualization\n        ├── map_viewer_dialog.py   # Full-screen topology viewer\n        ├── security_widget.py     # CVE vulnerability analysis\n        ├── tag_input.py           # Tag/chip input widget\n        ├── toggle_switch.py       # iOS-style toggle\n        └── stat_box.py            # Counter display boxes\n```\n\n---\n\n## Topology Viewer\n\nThe embedded topology viewer uses [Cytoscape.js](https://js.cytoscape.org/) for interactive network visualization.\n\n### Features\n- **Automatic layout** - Dagre algorithm for hierarchical network arrangement\n- **Vendor coloring** - Platform-specific border and fill colors (Cisco blue, Juniper orange, Arista green)\n- **Undiscovered nodes** - Peers referenced but not crawled shown with dashed borders and ⚠ markers\n- **Edge labels** - Interface pairs displayed on connections\n- **Click inspection** - Select nodes to view device details\n- **Theme integration** - Colors adapt to current UI theme\n\n### Export Options\n| Format | Use Case |\n|--------|----------|\n| **Draw.io** | Editable diagrams with Cisco stencils for documentation, Confluence, SharePoint |\n| **yEd (GraphML)** | Professional diagrams with automatic layouts and port labels |\n| **PNG** | Quick image export for reports and presentations |\n| **CSV** | Device and connection lists for spreadsheet analysis |\n| **JSON** | Raw topology data for custom processing |\n\n### Data Flow\n```\nDiscovery Engine → map.json → Base64 encode → QWebChannel → JavaScript → Cytoscape.js\n```\n\nThe viewer uses base64 encoding for reliable Python→JavaScript data transfer, avoiding escaping issues with complex JSON payloads.\n\n---\n\n## CLI Reference\n\nSecure Cartography provides two CLI modules that can be used independently of the GUI:\n\n- `sc2.scng.creds` - Credential vault management\n- `sc2.scng.discovery` - Network discovery engine\n\nBoth CLIs support `--help` on all commands and subcommands.\n\n---\n\n### Credential Management (`sc2.scng.creds`)\n\n```\nusage: scng-creds [-h] [--vault-path VAULT_PATH] [--password PASSWORD]\n                  {init,unlock,add,list,show,remove,set-default,test,discover,change-password,deps} ...\n```\n\n#### Global Options\n\n| Option | Description |\n|--------|-------------|\n| `-v, --vault-path` | Path to vault database (default: `~/.scng/credentials.db`) |\n| `-p, --password` | Vault password (or set `SCNG_VAULT_PASSWORD` env var) |\n\n#### Commands\n\n##### `init` - Initialize a new vault\n```bash\npython -m sc2.scng.creds init\npython -m sc2.scng.creds init --vault-path /path/to/custom.db\n```\n\n##### `add` - Add credentials\n```bash\n# SSH with password (prompts for password)\npython -m sc2.scng.creds add ssh admin-cred --username admin --password\n\n# SSH with key file\npython -m sc2.scng.creds add ssh key-cred --username automation --key-file ~/.ssh/id_rsa\n\n# SNMPv2c\npython -m sc2.scng.creds add snmpv2c readonly --community public\n\n# SNMPv3 (authPriv)\npython -m sc2.scng.creds add snmpv3 snmpv3-cred \\\n    --username snmpuser \\\n    --auth-protocol sha256 \\\n    --auth-password authpass123 \\\n    --priv-protocol aes128 \\\n    --priv-password privpass123\n```\n\n##### `list` - List all credentials\n```bash\npython -m sc2.scng.creds list\n```\nOutput shows credential name, type, priority, and default status.\n\n##### `show` - Show credential details\n```bash\npython -m sc2.scng.creds show admin-cred\npython -m sc2.scng.creds show admin-cred --reveal  # Show passwords/communities\n```\n\n##### `remove` - Delete a credential\n```bash\npython -m sc2.scng.creds remove old-credential\n```\n\n##### `set-default` - Set credential as default for its type\n```bash\npython -m sc2.scng.creds set-default admin-cred\n```\n\n##### `test` - Test credential against a host\n```bash\npython -m sc2.scng.creds test admin-cred 192.168.1.1\npython -m sc2.scng.creds test readonly 10.0.0.1\n```\n\n##### `discover` - Find which credentials work on a host\n```bash\npython -m sc2.scng.creds discover 192.168.1.1\n```\nTests all credentials and reports which ones succeed.\n\n##### `change-password` - Change vault master password\n```bash\npython -m sc2.scng.creds change-password\n```\n\n##### `deps` - Check required dependencies\n```bash\npython -m sc2.scng.creds deps\n```\n\n---\n\n### Network Discovery (`sc2.scng.discovery`)\n\n```\nusage: scng.discovery [-h] {test,device,crawl} ...\n```\n\n#### Commands\n\n##### `test` - Quick SNMP connectivity test (no vault required)\n```bash\npython -m sc2.scng.discovery test 192.168.1.1 --community public\npython -m sc2.scng.discovery test 192.168.1.1 --community public --verbose\n```\n\n##### `device` - Discover a single device\n```bash\npython -m sc2.scng.discovery device 192.168.1.1\npython -m sc2.scng.discovery device core-switch.example.com --output ./results\n```\n\n##### `crawl` - Recursive network discovery\n```\nusage: scng.discovery crawl [-h] [-d DEPTH] [--domain DOMAINS] [--exclude EXCLUDE_PATTERNS]\n                            [-o OUTPUT] [-v] [--no-dns] [-c CONCURRENCY] [-t TIMEOUT]\n                            [--no-color] [--timestamps] [--json-events]\n                            seeds [seeds ...]\n```\n\n| Option | Description |\n|--------|-------------|\n| `seeds` | One or more seed IP addresses or hostnames |\n| `-d, --depth` | Maximum discovery depth (default: 3) |\n| `--domain` | Domain suffix for hostname resolution (repeatable) |\n| `--exclude` | Exclusion patterns for devices to skip (repeatable, comma-separated) |\n| `-o, --output` | Output directory for results |\n| `-v, --verbose` | Enable debug output |\n| `--no-dns` | Disable DNS lookups; use IPs from LLDP/CDP directly |\n| `-c, --concurrency` | Maximum parallel discoveries (default: 20) |\n| `-t, --timeout` | SNMP timeout in seconds (default: 5) |\n| `--no-color` | Disable colored terminal output |\n| `--timestamps` | Show timestamps in log output |\n| `--json-events` | Output events as JSON lines (for GUI/automation integration) |\n\n#### Crawl Examples\n\n```bash\n# Basic crawl from single seed\npython -m sc2.scng.discovery crawl 192.168.1.1\n\n# Multiple seeds with depth limit\npython -m sc2.scng.discovery crawl 10.1.1.1 10.2.1.1 --depth 5\n\n# With domain suffix for DNS resolution\npython -m sc2.scng.discovery crawl core-sw01 --domain corp.example.com --domain example.com\n\n# Exclude devices by pattern (matches hostname, sys_name, or sysDescr)\npython -m sc2.scng.discovery crawl 192.168.1.1 --exclude \"linux,vmware,phone\"\n\n# Multiple exclude flags also work\npython -m sc2.scng.discovery crawl 192.168.1.1 \\\n    --exclude \"linux\" \\\n    --exclude \"phone\" \\\n    --exclude \"wireless\"\n\n# Home lab mode (no DNS, faster)\npython -m sc2.scng.discovery crawl 192.168.1.1 --no-dns\n\n# High concurrency for large networks\npython -m sc2.scng.discovery crawl 10.0.0.1 -c 50 -d 10 -o ./enterprise_map\n\n# Full production example\npython -m sc2.scng.discovery crawl \\\n    core-rtr-01.dc1.example.com \\\n    core-rtr-01.dc2.example.com \\\n    --depth 8 \\\n    --domain dc1.example.com \\\n    --domain dc2.example.com \\\n    --exclude \"linux,esxi,vcenter,phone,wireless,ups\" \\\n    --concurrency 30 \\\n    --timeout 10 \\\n    --output ./network_discovery_$(date +%Y%m%d) \\\n    --verbose\n```\n\n#### Exclusion Patterns\n\nThe `--exclude` option filters devices from propagating the crawl. Patterns are:\n\n- **Case-insensitive** substring matches\n- **Comma-separated** for multiple patterns in one flag\n- Matched against **three fields**: `sysDescr`, `hostname`, and `sys_name`\n\nThis means exclusions work for both SNMP-discovered devices (via sysDescr) and SSH-discovered devices (via hostname).\n\n| Pattern | Matches |\n|---------|---------|\n| `linux` | Any device with \"linux\" in sysDescr, hostname, or sys_name |\n| `rtr-lab,sw-test` | Devices with \"rtr-lab\" OR \"sw-test\" in any field |\n| `phone,wireless,ap-` | Common patterns to skip IP phones and APs |\n\n**Note:** Excluded devices are still discovered (credentials tested, data collected), but their neighbors are not queued for further discovery. This prevents the crawl from expanding through non-network infrastructure.\n\n---\n\n## Output Format\n\nDiscovery creates per-device folders with JSON data:\n\n```\ndiscovery_output/\n├── core-switch-01/\n│   ├── device.json      # System info, interfaces\n│   ├── cdp.json         # CDP neighbors\n│   └── lldp.json        # LLDP neighbors\n├── dist-switch-01/\n│   └── ...\n├── devices.csv          # Device inventory (for Security Analysis)\n├── discovery_summary.json\n├── topology.graphml     # yEd-compatible graph\n└── map.json             # Topology with bidirectional validation\n```\n\n### map.json (Topology)\n```json\n{\n  \"core-switch-01\": {\n    \"node_details\": {\n      \"ip\": \"10.1.1.1\",\n      \"platform\": \"Arista vEOS-lab EOS 4.33.1F\"\n    },\n    \"peers\": {\n      \"dist-switch-01\": {\n        \"ip\": \"10.1.1.2\",\n        \"connections\": [\n          [\"Eth1/1\", \"Gi0/1\"],\n          [\"Eth1/2\", \"Gi0/2\"]\n        ]\n      }\n    }\n  }\n}\n```\n\n### devices.csv (Security Analysis Input)\n```csv\nhostname,ip,platform,vendor,model,serial\ncore-switch-01,10.1.1.1,Cisco IOS IOS 15.2(4.0.55)E,cisco,WS-C3850-24T,FCW2134L0NK\ndist-switch-01,10.1.1.2,Arista vEOS-lab EOS 4.33.1F,arista,vEOS,SN-VEOS-01\n```\n\n---\n\n## GUI Theme System\n\nThe GUI uses a comprehensive theme system with three built-in themes:\n\n| Theme | Primary | Accent | Use Case |\n|-------|---------|--------|----------|\n| **Cyber** | `#0a0a0f` | `#00ffff` (cyan) | SOC/NOC aesthetic |\n| **Dark** | `#000000` | `#d4af37` (gold) | Professional elegance |\n| **Light** | `#ffffff` | `#2563eb` (blue) | Bright environments |\n\nSee [README_Style_Guide.md](README_Style_Guide.md) for widget styling details.\n\n---\n\n## Documentation\n\n| Document | Description |\n|----------|-------------|\n| [README_Creds.md](README_Creds.md) | Credential vault API and CLI |\n| [README_scng.md](README_scng.md) | Discovery engine architecture |\n| [README_SNMP_Discovery.md](README_SNMP_Discovery.md) | SNMP collection details |\n| [README_SSH_Discovery.md](README_SSH_Discovery.md) | SSH fallback module |\n| [README_Progress_events.md](README_Progress_events.md) | GUI progress event reference |\n| [README_Style_Guide.md](README_Style_Guide.md) | PyQt6 widget theming guide |\n| [snmp_proxy/README.md](snmp_proxy/README.md) | SNMP proxy deployment for remote polling |\n\n---\n\n## Development Status\n\n### ✅ Complete\n- Credential vault with encryption\n- SNMP discovery (v2c, v3)\n- SSH fallback discovery\n- Async crawl engine with progress events\n- CLI for creds and discovery\n- Theme system (Cyber/Dark/Light)\n- Login dialog with vault unlock\n- Main window layout with all panels\n- Custom themed widgets\n- Discovery↔UI integration with throttled events\n- Live topology preview with Cytoscape.js\n- Vendor coloring in topology viewer\n- Undiscovered peer node visualization\n- Security Analysis with CVE vulnerability scanning\n- Export to yEd (GraphML with port labels)\n- Export to Draw.io with Cisco stencils and vendor coloring\n- Built-in help system\n- Interactive device polling (local + proxy modes)\n- Device fingerprinting via Rapid7 Recog patterns\n- OUI vendor lookup for MAC addresses\n\n### 📋 Planned\n- Map enhancement tools (manual node positioning, annotations)\n- Credential auto-discovery integration\n- Settings persistence\n- Export topology as PNG/SVG\n- Topology diff (compare discoveries)\n\n---\n\n## Technical Notes\n\n### Threading Architecture\nThe GUI uses a careful threading model to prevent UI lockups:\n\n- **Discovery runs in QThread** - async engine wrapped in worker thread\n- **Events throttled at source** - high-frequency events (stats, topology) rate-limited before emission\n- **QueuedConnection for all signals** - ensures slots execute on main thread\n- **WebView isolation** - no webview updates during active discovery; topology loads once at completion\n\n### Topology Data Transfer\nPython→JavaScript communication uses base64 encoding:\n```python\n# Python side\nb64_data = base64.b64encode(json.dumps(topology).encode()).decode()\nself._run_js(f\"TopologyViewer.loadTopologyB64('{b64_data}')\")\n```\n```javascript\n// JavaScript side  \nloadTopologyB64(b64String) {\n    const jsonString = atob(b64String);\n    this.loadTopology(jsonString);\n}\n```\nThis avoids JSON escaping issues with complex network data containing special characters.\n\n### Security Analysis Architecture\nThe Security Widget operates independently of the discovery engine:\n- **Platform parsing** - regex patterns extract vendor/product/version from sysDescr strings\n- **CPE generation** - converts parsed data to NIST CPE 2.3 format\n- **NVD API client** - async queries with rate limiting and caching\n- **SQLite cache** - `~/.scng/cve_cache.db` stores CVE data to avoid repeated API calls\n- **Device tracking** - maps CVEs back to specific hostnames/IPs from discovery CSV\n\n---\n\n## Security Considerations\n\n- **Master password** is never stored; derived key is held in memory only while vault is unlocked\n- **Credentials are encrypted** with AES-256-GCM before storage\n- **Salt** is randomly generated per installation\n- **No credentials in logs** - discovery output never includes passwords/communities\n- **Vault auto-locks** when application exits\n- **CVE cache is local** - no sensitive data sent to NVD (only CPE queries)\n\n---\n\n## Performance\n\nTypical discovery rates:\n- Single device (SNMP): 2-5 seconds\n- Single device (SSH fallback): 5-15 seconds\n- 100 devices: 3-8 minutes with 20 concurrent workers\n- 750+ devices: ~4-5 hours (production tested, 88%+ success rate)\n\nSecurity Analysis:\n- NVD API (no key): 5 requests per 30 seconds\n- NVD API (with key): 50 requests per 30 seconds\n- Cached lookups: instant\n\nGUI remains responsive during discovery due to throttled event architecture.\n\n---\n\n## License\n\nThis project is licensed under the **GNU General Public License v3.0** - see [LICENSE](LICENSE) for details.\n\n\n---\n\n## Author\n\n**Scott Peterman** - Network Engineer\n\n- GitHub: [@scottpeterman](https://github.com/scottpeterman)\n- Homepage: [scottpeterman](https://scottpeterman.github.io/)\n\n*Built by a network engineer who got tired of manually drawing topology diagrams.*\n\n---\n\n## Acknowledgments\n\n- Network visualization powered by [Cytoscape.js](https://js.cytoscape.org/)\n- SNMP operations via [pysnmp-lextudio](https://github.com/lextudio/pysnmp)\n- SSH via [Paramiko](https://www.paramiko.org/)\n- CLI parsing with [TextFSM](https://github.com/google/textfsm)\n- GUI powered by [PyQt6](https://www.riverbankcomputing.com/software/pyqt/)\n- Encryption via [cryptography](https://cryptography.io/)\n- CVE data from [NIST National Vulnerability Database](https://nvd.nist.gov/)\n- Device fingerprinting via [Rapid7 Recog](https://github.com/rapid7/recog)\n- OUI database from [Wireshark](https://www.wireshark.org/)\n- Draw.io stencils from [mxgraph Cisco library](https://github.com/jgraph/mxgraph)","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fscottpeterman%2Fsecure_cartography","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fscottpeterman%2Fsecure_cartography","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fscottpeterman%2Fsecure_cartography/lists"}