pynetworkintel 1.3.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pynetworkintel-1.3.0/LICENSE +22 -0
- pynetworkintel-1.3.0/PKG-INFO +269 -0
- pynetworkintel-1.3.0/README.md +214 -0
- pynetworkintel-1.3.0/pynetworkintel/__init__.py +98 -0
- pynetworkintel-1.3.0/pynetworkintel/_mcp_connector.py +141 -0
- pynetworkintel-1.3.0/pynetworkintel/_mcp_tools.py +368 -0
- pynetworkintel-1.3.0/pynetworkintel/alerts.py +276 -0
- pynetworkintel-1.3.0/pynetworkintel/analysis/__init__.py +7 -0
- pynetworkintel-1.3.0/pynetworkintel/analysis/cve.py +189 -0
- pynetworkintel-1.3.0/pynetworkintel/analysis/llm.py +183 -0
- pynetworkintel-1.3.0/pynetworkintel/analysis/rules.py +247 -0
- pynetworkintel-1.3.0/pynetworkintel/changes.py +221 -0
- pynetworkintel-1.3.0/pynetworkintel/cli.py +569 -0
- pynetworkintel-1.3.0/pynetworkintel/cloud/__init__.py +24 -0
- pynetworkintel-1.3.0/pynetworkintel/cloud/aws.py +327 -0
- pynetworkintel-1.3.0/pynetworkintel/cloud/azure.py +278 -0
- pynetworkintel-1.3.0/pynetworkintel/cloud/correlation.py +273 -0
- pynetworkintel-1.3.0/pynetworkintel/cloud/credentials.py +248 -0
- pynetworkintel-1.3.0/pynetworkintel/cloud/gcp.py +283 -0
- pynetworkintel-1.3.0/pynetworkintel/config.py +216 -0
- pynetworkintel-1.3.0/pynetworkintel/core.py +221 -0
- pynetworkintel-1.3.0/pynetworkintel/dashboard.py +532 -0
- pynetworkintel-1.3.0/pynetworkintel/db.py +218 -0
- pynetworkintel-1.3.0/pynetworkintel/devops/__init__.py +21 -0
- pynetworkintel-1.3.0/pynetworkintel/devops/cicd_scanner.py +208 -0
- pynetworkintel-1.3.0/pynetworkintel/devops/compliance.py +272 -0
- pynetworkintel-1.3.0/pynetworkintel/devops/iac_validator.py +297 -0
- pynetworkintel-1.3.0/pynetworkintel/devops/siem_integrator.py +189 -0
- pynetworkintel-1.3.0/pynetworkintel/discovery/__init__.py +6 -0
- pynetworkintel-1.3.0/pynetworkintel/discovery/scanner.py +307 -0
- pynetworkintel-1.3.0/pynetworkintel/discovery/ssh_config.py +138 -0
- pynetworkintel-1.3.0/pynetworkintel/iot/__init__.py +19 -0
- pynetworkintel-1.3.0/pynetworkintel/iot/discovery.py +329 -0
- pynetworkintel-1.3.0/pynetworkintel/iot/protocols.py +240 -0
- pynetworkintel-1.3.0/pynetworkintel/iot/vulnerabilities.py +319 -0
- pynetworkintel-1.3.0/pynetworkintel/kubernetes/__init__.py +22 -0
- pynetworkintel-1.3.0/pynetworkintel/kubernetes/discovery.py +341 -0
- pynetworkintel-1.3.0/pynetworkintel/kubernetes/network_policy.py +241 -0
- pynetworkintel-1.3.0/pynetworkintel/kubernetes/rbac.py +270 -0
- pynetworkintel-1.3.0/pynetworkintel/kubernetes/security.py +285 -0
- pynetworkintel-1.3.0/pynetworkintel/ml/__init__.py +19 -0
- pynetworkintel-1.3.0/pynetworkintel/ml/anomaly.py +282 -0
- pynetworkintel-1.3.0/pynetworkintel/ml/behavioral.py +290 -0
- pynetworkintel-1.3.0/pynetworkintel/ml/predictive.py +309 -0
- pynetworkintel-1.3.0/pynetworkintel/models.py +140 -0
- pynetworkintel-1.3.0/pynetworkintel/progress.py +169 -0
- pynetworkintel-1.3.0/pynetworkintel/reporting.py +262 -0
- pynetworkintel-1.3.0/pynetworkintel/scheduler.py +237 -0
- pynetworkintel-1.3.0/pynetworkintel/topology.py +179 -0
- pynetworkintel-1.3.0/pynetworkintel.egg-info/PKG-INFO +269 -0
- pynetworkintel-1.3.0/pynetworkintel.egg-info/SOURCES.txt +68 -0
- pynetworkintel-1.3.0/pynetworkintel.egg-info/dependency_links.txt +1 -0
- pynetworkintel-1.3.0/pynetworkintel.egg-info/entry_points.txt +2 -0
- pynetworkintel-1.3.0/pynetworkintel.egg-info/requires.txt +30 -0
- pynetworkintel-1.3.0/pynetworkintel.egg-info/top_level.txt +1 -0
- pynetworkintel-1.3.0/pyproject.toml +110 -0
- pynetworkintel-1.3.0/setup.cfg +4 -0
- pynetworkintel-1.3.0/tests/test_analysis.py +99 -0
- pynetworkintel-1.3.0/tests/test_cloud.py +65 -0
- pynetworkintel-1.3.0/tests/test_cve.py +227 -0
- pynetworkintel-1.3.0/tests/test_dashboard.py +161 -0
- pynetworkintel-1.3.0/tests/test_devops.py +77 -0
- pynetworkintel-1.3.0/tests/test_integration.py +93 -0
- pynetworkintel-1.3.0/tests/test_iot.py +49 -0
- pynetworkintel-1.3.0/tests/test_kubernetes.py +41 -0
- pynetworkintel-1.3.0/tests/test_ml.py +83 -0
- pynetworkintel-1.3.0/tests/test_models.py +106 -0
- pynetworkintel-1.3.0/tests/test_scanner.py +196 -0
- pynetworkintel-1.3.0/tests/test_security.py +207 -0
- pynetworkintel-1.3.0/tests/test_topology.py +156 -0
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
Proprietary License — Free to use with explicit attribution
|
|
2
|
+
|
|
3
|
+
Copyright © 2026 Georgi Mammen Mullassery
|
|
4
|
+
|
|
5
|
+
Permission is granted to any person obtaining a copy of this software to use,
|
|
6
|
+
copy, modify, and distribute this software and its documentation, provided that:
|
|
7
|
+
|
|
8
|
+
1. The above copyright notice and this permission notice appear in all copies
|
|
9
|
+
or substantial portions of the software.
|
|
10
|
+
|
|
11
|
+
2. Explicit attribution to the original author (Georgi Mammen Mullassery) is
|
|
12
|
+
provided in any project documentation and significant code comments where
|
|
13
|
+
this software is used.
|
|
14
|
+
|
|
15
|
+
3. The software is provided "AS IS" without warranty of any kind, express or
|
|
16
|
+
implied, including but not limited to the warranties of merchantability,
|
|
17
|
+
fitness for a particular purpose, or non-infringement.
|
|
18
|
+
|
|
19
|
+
4. In no event shall the author be liable for any claim, damages, or other
|
|
20
|
+
liability arising from the use of this software.
|
|
21
|
+
|
|
22
|
+
For more information, visit: https://github.com/Mullassery
|
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: pynetworkintel
|
|
3
|
+
Version: 1.3.0
|
|
4
|
+
Summary: AI-powered network intelligence and vulnerability discovery platform
|
|
5
|
+
Author-email: Georgi Mullassery <mullassery@gmail.com>
|
|
6
|
+
License: Proprietary
|
|
7
|
+
Project-URL: Homepage, https://github.com/Mullassery/PyNetworkIntel
|
|
8
|
+
Project-URL: Documentation, https://github.com/Mullassery/PyNetworkIntel/blob/main/README.md
|
|
9
|
+
Project-URL: Source Code, https://github.com/Mullassery/PyNetworkIntel
|
|
10
|
+
Project-URL: Bug Tracker, https://github.com/Mullassery/PyNetworkIntel/issues
|
|
11
|
+
Keywords: network,security,vulnerability,scanning,discovery,monitoring,artificial-intelligence
|
|
12
|
+
Classifier: Development Status :: 4 - Beta
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: Intended Audience :: System Administrators
|
|
15
|
+
Classifier: License :: Other/Proprietary License
|
|
16
|
+
Classifier: Operating System :: OS Independent
|
|
17
|
+
Classifier: Programming Language :: Python :: 3
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
21
|
+
Classifier: Topic :: System :: Monitoring
|
|
22
|
+
Classifier: Topic :: System :: Networking
|
|
23
|
+
Classifier: Topic :: Security
|
|
24
|
+
Requires-Python: >=3.10
|
|
25
|
+
Description-Content-Type: text/markdown
|
|
26
|
+
License-File: LICENSE
|
|
27
|
+
Requires-Dist: paramiko<4.0,>=3.0
|
|
28
|
+
Requires-Dist: netaddr<1.4,>=0.9
|
|
29
|
+
Requires-Dist: pyyaml<7.0,>=6.0
|
|
30
|
+
Requires-Dist: requests<3.0,>=2.31
|
|
31
|
+
Requires-Dist: anthropic<1.0,>=0.25
|
|
32
|
+
Requires-Dist: rich<14.0,>=13.0
|
|
33
|
+
Requires-Dist: sqlalchemy<3.0,>=2.0
|
|
34
|
+
Requires-Dist: apscheduler<4.0,>=3.10
|
|
35
|
+
Provides-Extra: dev
|
|
36
|
+
Requires-Dist: pytest<9.0,>=7.4; extra == "dev"
|
|
37
|
+
Requires-Dist: pytest-cov<7.0,>=4.1; extra == "dev"
|
|
38
|
+
Requires-Dist: black<25.0,>=23.7; extra == "dev"
|
|
39
|
+
Requires-Dist: ruff<0.9,>=0.0.280; extra == "dev"
|
|
40
|
+
Requires-Dist: build<2.0,>=0.10; extra == "dev"
|
|
41
|
+
Requires-Dist: twine<7.0,>=4.0; extra == "dev"
|
|
42
|
+
Provides-Extra: cloud
|
|
43
|
+
Requires-Dist: boto3<2.0,>=1.28; extra == "cloud"
|
|
44
|
+
Requires-Dist: azure-identity<2.0,>=1.14; extra == "cloud"
|
|
45
|
+
Requires-Dist: azure-mgmt-compute<32.0,>=30.0; extra == "cloud"
|
|
46
|
+
Requires-Dist: azure-mgmt-network<27.0,>=25.0; extra == "cloud"
|
|
47
|
+
Requires-Dist: azure-mgmt-storage<23.0,>=21.0; extra == "cloud"
|
|
48
|
+
Requires-Dist: azure-mgmt-resource<24.0,>=23.0; extra == "cloud"
|
|
49
|
+
Requires-Dist: azure-mgmt-rdbms<11.0,>=10.1; extra == "cloud"
|
|
50
|
+
Requires-Dist: google-cloud-compute<2.0,>=1.14; extra == "cloud"
|
|
51
|
+
Requires-Dist: google-cloud-storage<3.0,>=2.10; extra == "cloud"
|
|
52
|
+
Provides-Extra: kubernetes
|
|
53
|
+
Requires-Dist: kubernetes<32.0,>=27.0; extra == "kubernetes"
|
|
54
|
+
Dynamic: license-file
|
|
55
|
+
|
|
56
|
+
# PyNetworkIntel
|
|
57
|
+
|
|
58
|
+
**Discover what's on your network. Map how it's connected. Find what's vulnerable.**
|
|
59
|
+
|
|
60
|
+
PyNetworkIntel scans a network target with `nmap`, optionally pulls
|
|
61
|
+
configuration from reachable devices over SSH, checks discovered services
|
|
62
|
+
against known vulnerability rules and the NVD CVE database, and derives a
|
|
63
|
+
subnet/gateway topology graph from the results - in plain Python, with no
|
|
64
|
+
hidden network calls beyond nmap/SSH/NVD/(optional) Anthropic.
|
|
65
|
+
|
|
66
|
+
[](https://pypi.org/project/pynetworkintel)
|
|
67
|
+
[](https://www.python.org)
|
|
68
|
+
[](./LICENSE)
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
|
|
72
|
+
## Before you scan anything
|
|
73
|
+
|
|
74
|
+
This tool actively probes network hosts. **Only scan networks and devices
|
|
75
|
+
you own or have explicit written permission to test.** Unauthorized network
|
|
76
|
+
scanning may be illegal in your jurisdiction. Both the CLI and the
|
|
77
|
+
underlying commands require you to confirm authorization before a scan
|
|
78
|
+
runs (see [Security](#security) below) - this isn't a formality, it's there
|
|
79
|
+
so the tool never scans a target silently just because it was handed one.
|
|
80
|
+
|
|
81
|
+
---
|
|
82
|
+
|
|
83
|
+
## 30-Second Start
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
pip install pynetworkintel
|
|
87
|
+
# nmap must also be installed and on PATH (brew install nmap / apt install nmap / etc.)
|
|
88
|
+
|
|
89
|
+
pynetworkintel scan 192.168.1.0/24
|
|
90
|
+
# -> prompts to confirm you're authorized to scan this target, then runs
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
```python
|
|
94
|
+
from pynetworkintel import Scanner
|
|
95
|
+
|
|
96
|
+
scanner = Scanner() # no SSH by default - see "SSH config grabbing" below
|
|
97
|
+
result = scanner.scan("192.168.1.0/24")
|
|
98
|
+
|
|
99
|
+
for device in result.devices:
|
|
100
|
+
print(f"{device.ip} ({device.hostname or 'unknown'})")
|
|
101
|
+
for service in device.services:
|
|
102
|
+
print(f" - {service.name} {service.version or ''} on port {service.port}")
|
|
103
|
+
|
|
104
|
+
print(result.topology().to_dict()) # subnet groupings + inferred gateway edges
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
---
|
|
108
|
+
|
|
109
|
+
## Key Features
|
|
110
|
+
|
|
111
|
+
- **Device discovery** - `nmap -sV` based host/port/service discovery
|
|
112
|
+
(`pynetworkintel.discovery`)
|
|
113
|
+
- **Topology mapping** - a real graph (nodes/edges), not just a flat device
|
|
114
|
+
list: devices are grouped into inferred subnets, with gateway-style edges
|
|
115
|
+
derived from IP addressing (`pynetworkintel.topology`)
|
|
116
|
+
- **Vulnerability detection** - config-based rule checks (weak SSH settings,
|
|
117
|
+
telnet exposure, etc.) plus live NVD CVE lookups by service/version
|
|
118
|
+
(`pynetworkintel.analysis`)
|
|
119
|
+
- **Optional SSH config grabbing** - pulls `sshd_config`, firewall rules,
|
|
120
|
+
etc. from devices you have credentials for, concurrently across devices
|
|
121
|
+
- **Change tracking** - detects new/removed devices across scans, backed by
|
|
122
|
+
a local SQLite/SQLAlchemy history (`pynetworkintel.changes`, `pynetworkintel.db`)
|
|
123
|
+
- **Reports & alerts** - Markdown/JSON reports, Slack/email/webhook alert
|
|
124
|
+
channels (`pynetworkintel.reporting`, `pynetworkintel.alerts`)
|
|
125
|
+
- **Optional AI summary** - plain-English findings summary via the
|
|
126
|
+
Anthropic API, only when `--summarize` / `summarize=True` is used
|
|
127
|
+
|
|
128
|
+
---
|
|
129
|
+
|
|
130
|
+
## Installation
|
|
131
|
+
|
|
132
|
+
```bash
|
|
133
|
+
pip install pynetworkintel
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
Requires the `nmap` binary to be installed separately and on `PATH`
|
|
137
|
+
(the Python package wraps it via `subprocess`; without it, discovery
|
|
138
|
+
returns no results but the rest of the API still works, e.g. for testing).
|
|
139
|
+
|
|
140
|
+
Optional extras for the lighter-tested cloud/kubernetes asset-discovery
|
|
141
|
+
modules (see [Module status](#module-status)):
|
|
142
|
+
|
|
143
|
+
```bash
|
|
144
|
+
pip install "pynetworkintel[cloud]" # boto3, azure-mgmt-*, google-cloud-*
|
|
145
|
+
pip install "pynetworkintel[kubernetes]" # kubernetes python client
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
---
|
|
149
|
+
|
|
150
|
+
## CLI Usage
|
|
151
|
+
|
|
152
|
+
```bash
|
|
153
|
+
# Scan a subnet (prompts for scan authorization the first time)
|
|
154
|
+
pynetworkintel scan 192.168.1.0/24
|
|
155
|
+
|
|
156
|
+
# Scan and grab SSH config from reachable devices (explicit --ssh-user required;
|
|
157
|
+
# there is no default user, on purpose - see Security below)
|
|
158
|
+
pynetworkintel scan 192.168.1.0/24 --ssh-user admin --ssh-key ~/.ssh/id_rsa
|
|
159
|
+
|
|
160
|
+
# Non-interactive / CI use: skip the confirmation prompt explicitly
|
|
161
|
+
pynetworkintel scan 192.168.1.0/24 --i-am-authorized
|
|
162
|
+
|
|
163
|
+
# Full pipeline: scan + vulnerability analysis + AI summary
|
|
164
|
+
pynetworkintel analyze 192.168.1.0/24 --summarize
|
|
165
|
+
|
|
166
|
+
# JSON output (includes devices, findings, and the topology graph)
|
|
167
|
+
pynetworkintel scan 192.168.1.0/24 --output json
|
|
168
|
+
|
|
169
|
+
# Save results to a file
|
|
170
|
+
pynetworkintel analyze 192.168.1.0/24 --output-file results.json
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
SSH passwords are **never** accepted as a CLI flag (they'd end up in shell
|
|
174
|
+
history and process listings). Use `--ssh-key` or set
|
|
175
|
+
`PYNETWORKINTEL_SSH_PASSWORD` in the environment instead.
|
|
176
|
+
|
|
177
|
+
---
|
|
178
|
+
|
|
179
|
+
## Python API
|
|
180
|
+
|
|
181
|
+
```python
|
|
182
|
+
from pynetworkintel import Pipeline
|
|
183
|
+
|
|
184
|
+
pipeline = Pipeline(
|
|
185
|
+
ssh_username="admin", # optional; omit to skip SSH config grabbing
|
|
186
|
+
ssh_key_path="~/.ssh/id_rsa",
|
|
187
|
+
)
|
|
188
|
+
result = pipeline.run("192.168.1.0/24", summarize=False)
|
|
189
|
+
|
|
190
|
+
print(result["summary"]) # counts: devices, findings by severity, subnets
|
|
191
|
+
print(result["topology"]) # {"nodes": [...], "edges": [...], "subnets": [...]}
|
|
192
|
+
for finding in result["findings"]:
|
|
193
|
+
print(finding["severity"], finding["title"])
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
---
|
|
197
|
+
|
|
198
|
+
## Security
|
|
199
|
+
|
|
200
|
+
PyNetworkIntel is a dual-use network scanning tool, and the security
|
|
201
|
+
posture of the tool itself is treated as a first-class concern, not an
|
|
202
|
+
afterthought:
|
|
203
|
+
|
|
204
|
+
- **Scan authorization is required.** `scan`/`analyze` will not run without
|
|
205
|
+
`--i-am-authorized`, `PYNETWORKINTEL_I_AM_AUTHORIZED=1`, or an interactive
|
|
206
|
+
confirmation.
|
|
207
|
+
- **No default SSH user.** You must pass `--ssh-user` explicitly; the tool
|
|
208
|
+
will not assume `root` (or anything else) on your behalf.
|
|
209
|
+
- **No `--ssh-password` flag.** Use `--ssh-key` or the
|
|
210
|
+
`PYNETWORKINTEL_SSH_PASSWORD` environment variable.
|
|
211
|
+
- **SSH passwords are never written to disk**, including in the persisted
|
|
212
|
+
config file (`~/.pynetworkintel/config.yaml`, which is chmod'd `0600`).
|
|
213
|
+
- **SSH host key verification** uses `paramiko.WarningPolicy` (logs loudly
|
|
214
|
+
on an unknown/changed host key rather than silently trusting it). See
|
|
215
|
+
`pynetworkintel/discovery/ssh_config.py` for the documented tradeoff -
|
|
216
|
+
first-contact scanning of arbitrary devices is fundamentally in tension
|
|
217
|
+
with strict known-hosts verification.
|
|
218
|
+
- **Scan targets are validated** before reaching the `nmap` command line,
|
|
219
|
+
rejecting anything that isn't a plausible IP/CIDR/hostname (in particular
|
|
220
|
+
anything starting with `-`, which would otherwise be parsed as an nmap
|
|
221
|
+
flag).
|
|
222
|
+
- Dependency versions are pinned with upper bounds in `pyproject.toml`.
|
|
223
|
+
|
|
224
|
+
See [SECURITY.md](SECURITY.md) for how to report a vulnerability.
|
|
225
|
+
|
|
226
|
+
---
|
|
227
|
+
|
|
228
|
+
## Module status
|
|
229
|
+
|
|
230
|
+
Being direct about what's tested and what's real-but-lighter-tested vs. not
|
|
231
|
+
shipped at all:
|
|
232
|
+
|
|
233
|
+
| Module | Status | Notes |
|
|
234
|
+
|---|---|---|
|
|
235
|
+
| `discovery`, `analysis`, `models`, `topology`, `core`, `cli`, `config` | **Core, tested** | The scan -> analyze -> topology path; primary test coverage lives here |
|
|
236
|
+
| `reporting`, `alerts`, `changes`, `dashboard`, `scheduler`, `db` | **Core, tested** | Report generation, change tracking, live terminal dashboard |
|
|
237
|
+
| `cloud` (AWS/Azure/GCP asset discovery) | Shipped, lighter-tested | Real code, lazy-imports SDKs via the `cloud` extra |
|
|
238
|
+
| `kubernetes` (cluster/RBAC/pod security) | Shipped, lighter-tested | Real code, lazy-imports the `kubernetes` client via the `kubernetes` extra |
|
|
239
|
+
| `iot` (MQTT/CoAP/Modbus/S7comm discovery) | Shipped, lighter-tested | Real socket-based probing; arguably core to "everything connected to your network," just less exercised |
|
|
240
|
+
| `ml` (statistical baselines/anomaly detection) | Shipped, lighter-tested | Real `statistics`-based logic, not a trained model - "ML" in the name overstates it |
|
|
241
|
+
| `devops` (CI/CD & IaC static scanning) | Shipped, lighter-tested | Real regex-based Terraform/GitHub Actions scanning, self-contained |
|
|
242
|
+
| `enterprise` (multitenancy, HA, auth, REST API) | **Not shipped** | Excluded from the package entirely - enterprise-platform scope, unrelated to network discovery, untested |
|
|
243
|
+
| `architect` (conversational architecture advisor) | **Not shipped** | Excluded from the package entirely - unrelated to network discovery |
|
|
244
|
+
|
|
245
|
+
---
|
|
246
|
+
|
|
247
|
+
## Requirements
|
|
248
|
+
|
|
249
|
+
- Python 3.10+
|
|
250
|
+
- `nmap` installed and on `PATH` for live scanning
|
|
251
|
+
- SSH access (key or password) to a device, only if you want config grabbing
|
|
252
|
+
- An Anthropic API key, only if you use `--summarize`
|
|
253
|
+
|
|
254
|
+
---
|
|
255
|
+
|
|
256
|
+
## Documentation
|
|
257
|
+
|
|
258
|
+
- [Dashboard](docs/DASHBOARD.md) - the live terminal stats viewer (`--dashboard`)
|
|
259
|
+
|
|
260
|
+
`docs/ARCHITECTURE.md`, `docs/PRODUCT_VISION.md`, and `docs/ROADMAP.md` are
|
|
261
|
+
stale/placeholder documents from earlier planning and are not kept in sync
|
|
262
|
+
with the implementation; refer to [CLAUDE.md](CLAUDE.md) for an accurate
|
|
263
|
+
architecture description instead.
|
|
264
|
+
|
|
265
|
+
---
|
|
266
|
+
|
|
267
|
+
## License
|
|
268
|
+
|
|
269
|
+
Proprietary License - free to use with explicit attribution. See [LICENSE](LICENSE).
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
# PyNetworkIntel
|
|
2
|
+
|
|
3
|
+
**Discover what's on your network. Map how it's connected. Find what's vulnerable.**
|
|
4
|
+
|
|
5
|
+
PyNetworkIntel scans a network target with `nmap`, optionally pulls
|
|
6
|
+
configuration from reachable devices over SSH, checks discovered services
|
|
7
|
+
against known vulnerability rules and the NVD CVE database, and derives a
|
|
8
|
+
subnet/gateway topology graph from the results - in plain Python, with no
|
|
9
|
+
hidden network calls beyond nmap/SSH/NVD/(optional) Anthropic.
|
|
10
|
+
|
|
11
|
+
[](https://pypi.org/project/pynetworkintel)
|
|
12
|
+
[](https://www.python.org)
|
|
13
|
+
[](./LICENSE)
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## Before you scan anything
|
|
18
|
+
|
|
19
|
+
This tool actively probes network hosts. **Only scan networks and devices
|
|
20
|
+
you own or have explicit written permission to test.** Unauthorized network
|
|
21
|
+
scanning may be illegal in your jurisdiction. Both the CLI and the
|
|
22
|
+
underlying commands require you to confirm authorization before a scan
|
|
23
|
+
runs (see [Security](#security) below) - this isn't a formality, it's there
|
|
24
|
+
so the tool never scans a target silently just because it was handed one.
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## 30-Second Start
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
pip install pynetworkintel
|
|
32
|
+
# nmap must also be installed and on PATH (brew install nmap / apt install nmap / etc.)
|
|
33
|
+
|
|
34
|
+
pynetworkintel scan 192.168.1.0/24
|
|
35
|
+
# -> prompts to confirm you're authorized to scan this target, then runs
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
```python
|
|
39
|
+
from pynetworkintel import Scanner
|
|
40
|
+
|
|
41
|
+
scanner = Scanner() # no SSH by default - see "SSH config grabbing" below
|
|
42
|
+
result = scanner.scan("192.168.1.0/24")
|
|
43
|
+
|
|
44
|
+
for device in result.devices:
|
|
45
|
+
print(f"{device.ip} ({device.hostname or 'unknown'})")
|
|
46
|
+
for service in device.services:
|
|
47
|
+
print(f" - {service.name} {service.version or ''} on port {service.port}")
|
|
48
|
+
|
|
49
|
+
print(result.topology().to_dict()) # subnet groupings + inferred gateway edges
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
## Key Features
|
|
55
|
+
|
|
56
|
+
- **Device discovery** - `nmap -sV` based host/port/service discovery
|
|
57
|
+
(`pynetworkintel.discovery`)
|
|
58
|
+
- **Topology mapping** - a real graph (nodes/edges), not just a flat device
|
|
59
|
+
list: devices are grouped into inferred subnets, with gateway-style edges
|
|
60
|
+
derived from IP addressing (`pynetworkintel.topology`)
|
|
61
|
+
- **Vulnerability detection** - config-based rule checks (weak SSH settings,
|
|
62
|
+
telnet exposure, etc.) plus live NVD CVE lookups by service/version
|
|
63
|
+
(`pynetworkintel.analysis`)
|
|
64
|
+
- **Optional SSH config grabbing** - pulls `sshd_config`, firewall rules,
|
|
65
|
+
etc. from devices you have credentials for, concurrently across devices
|
|
66
|
+
- **Change tracking** - detects new/removed devices across scans, backed by
|
|
67
|
+
a local SQLite/SQLAlchemy history (`pynetworkintel.changes`, `pynetworkintel.db`)
|
|
68
|
+
- **Reports & alerts** - Markdown/JSON reports, Slack/email/webhook alert
|
|
69
|
+
channels (`pynetworkintel.reporting`, `pynetworkintel.alerts`)
|
|
70
|
+
- **Optional AI summary** - plain-English findings summary via the
|
|
71
|
+
Anthropic API, only when `--summarize` / `summarize=True` is used
|
|
72
|
+
|
|
73
|
+
---
|
|
74
|
+
|
|
75
|
+
## Installation
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
pip install pynetworkintel
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Requires the `nmap` binary to be installed separately and on `PATH`
|
|
82
|
+
(the Python package wraps it via `subprocess`; without it, discovery
|
|
83
|
+
returns no results but the rest of the API still works, e.g. for testing).
|
|
84
|
+
|
|
85
|
+
Optional extras for the lighter-tested cloud/kubernetes asset-discovery
|
|
86
|
+
modules (see [Module status](#module-status)):
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
pip install "pynetworkintel[cloud]" # boto3, azure-mgmt-*, google-cloud-*
|
|
90
|
+
pip install "pynetworkintel[kubernetes]" # kubernetes python client
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
---
|
|
94
|
+
|
|
95
|
+
## CLI Usage
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
# Scan a subnet (prompts for scan authorization the first time)
|
|
99
|
+
pynetworkintel scan 192.168.1.0/24
|
|
100
|
+
|
|
101
|
+
# Scan and grab SSH config from reachable devices (explicit --ssh-user required;
|
|
102
|
+
# there is no default user, on purpose - see Security below)
|
|
103
|
+
pynetworkintel scan 192.168.1.0/24 --ssh-user admin --ssh-key ~/.ssh/id_rsa
|
|
104
|
+
|
|
105
|
+
# Non-interactive / CI use: skip the confirmation prompt explicitly
|
|
106
|
+
pynetworkintel scan 192.168.1.0/24 --i-am-authorized
|
|
107
|
+
|
|
108
|
+
# Full pipeline: scan + vulnerability analysis + AI summary
|
|
109
|
+
pynetworkintel analyze 192.168.1.0/24 --summarize
|
|
110
|
+
|
|
111
|
+
# JSON output (includes devices, findings, and the topology graph)
|
|
112
|
+
pynetworkintel scan 192.168.1.0/24 --output json
|
|
113
|
+
|
|
114
|
+
# Save results to a file
|
|
115
|
+
pynetworkintel analyze 192.168.1.0/24 --output-file results.json
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
SSH passwords are **never** accepted as a CLI flag (they'd end up in shell
|
|
119
|
+
history and process listings). Use `--ssh-key` or set
|
|
120
|
+
`PYNETWORKINTEL_SSH_PASSWORD` in the environment instead.
|
|
121
|
+
|
|
122
|
+
---
|
|
123
|
+
|
|
124
|
+
## Python API
|
|
125
|
+
|
|
126
|
+
```python
|
|
127
|
+
from pynetworkintel import Pipeline
|
|
128
|
+
|
|
129
|
+
pipeline = Pipeline(
|
|
130
|
+
ssh_username="admin", # optional; omit to skip SSH config grabbing
|
|
131
|
+
ssh_key_path="~/.ssh/id_rsa",
|
|
132
|
+
)
|
|
133
|
+
result = pipeline.run("192.168.1.0/24", summarize=False)
|
|
134
|
+
|
|
135
|
+
print(result["summary"]) # counts: devices, findings by severity, subnets
|
|
136
|
+
print(result["topology"]) # {"nodes": [...], "edges": [...], "subnets": [...]}
|
|
137
|
+
for finding in result["findings"]:
|
|
138
|
+
print(finding["severity"], finding["title"])
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
---
|
|
142
|
+
|
|
143
|
+
## Security
|
|
144
|
+
|
|
145
|
+
PyNetworkIntel is a dual-use network scanning tool, and the security
|
|
146
|
+
posture of the tool itself is treated as a first-class concern, not an
|
|
147
|
+
afterthought:
|
|
148
|
+
|
|
149
|
+
- **Scan authorization is required.** `scan`/`analyze` will not run without
|
|
150
|
+
`--i-am-authorized`, `PYNETWORKINTEL_I_AM_AUTHORIZED=1`, or an interactive
|
|
151
|
+
confirmation.
|
|
152
|
+
- **No default SSH user.** You must pass `--ssh-user` explicitly; the tool
|
|
153
|
+
will not assume `root` (or anything else) on your behalf.
|
|
154
|
+
- **No `--ssh-password` flag.** Use `--ssh-key` or the
|
|
155
|
+
`PYNETWORKINTEL_SSH_PASSWORD` environment variable.
|
|
156
|
+
- **SSH passwords are never written to disk**, including in the persisted
|
|
157
|
+
config file (`~/.pynetworkintel/config.yaml`, which is chmod'd `0600`).
|
|
158
|
+
- **SSH host key verification** uses `paramiko.WarningPolicy` (logs loudly
|
|
159
|
+
on an unknown/changed host key rather than silently trusting it). See
|
|
160
|
+
`pynetworkintel/discovery/ssh_config.py` for the documented tradeoff -
|
|
161
|
+
first-contact scanning of arbitrary devices is fundamentally in tension
|
|
162
|
+
with strict known-hosts verification.
|
|
163
|
+
- **Scan targets are validated** before reaching the `nmap` command line,
|
|
164
|
+
rejecting anything that isn't a plausible IP/CIDR/hostname (in particular
|
|
165
|
+
anything starting with `-`, which would otherwise be parsed as an nmap
|
|
166
|
+
flag).
|
|
167
|
+
- Dependency versions are pinned with upper bounds in `pyproject.toml`.
|
|
168
|
+
|
|
169
|
+
See [SECURITY.md](SECURITY.md) for how to report a vulnerability.
|
|
170
|
+
|
|
171
|
+
---
|
|
172
|
+
|
|
173
|
+
## Module status
|
|
174
|
+
|
|
175
|
+
Being direct about what's tested and what's real-but-lighter-tested vs. not
|
|
176
|
+
shipped at all:
|
|
177
|
+
|
|
178
|
+
| Module | Status | Notes |
|
|
179
|
+
|---|---|---|
|
|
180
|
+
| `discovery`, `analysis`, `models`, `topology`, `core`, `cli`, `config` | **Core, tested** | The scan -> analyze -> topology path; primary test coverage lives here |
|
|
181
|
+
| `reporting`, `alerts`, `changes`, `dashboard`, `scheduler`, `db` | **Core, tested** | Report generation, change tracking, live terminal dashboard |
|
|
182
|
+
| `cloud` (AWS/Azure/GCP asset discovery) | Shipped, lighter-tested | Real code, lazy-imports SDKs via the `cloud` extra |
|
|
183
|
+
| `kubernetes` (cluster/RBAC/pod security) | Shipped, lighter-tested | Real code, lazy-imports the `kubernetes` client via the `kubernetes` extra |
|
|
184
|
+
| `iot` (MQTT/CoAP/Modbus/S7comm discovery) | Shipped, lighter-tested | Real socket-based probing; arguably core to "everything connected to your network," just less exercised |
|
|
185
|
+
| `ml` (statistical baselines/anomaly detection) | Shipped, lighter-tested | Real `statistics`-based logic, not a trained model - "ML" in the name overstates it |
|
|
186
|
+
| `devops` (CI/CD & IaC static scanning) | Shipped, lighter-tested | Real regex-based Terraform/GitHub Actions scanning, self-contained |
|
|
187
|
+
| `enterprise` (multitenancy, HA, auth, REST API) | **Not shipped** | Excluded from the package entirely - enterprise-platform scope, unrelated to network discovery, untested |
|
|
188
|
+
| `architect` (conversational architecture advisor) | **Not shipped** | Excluded from the package entirely - unrelated to network discovery |
|
|
189
|
+
|
|
190
|
+
---
|
|
191
|
+
|
|
192
|
+
## Requirements
|
|
193
|
+
|
|
194
|
+
- Python 3.10+
|
|
195
|
+
- `nmap` installed and on `PATH` for live scanning
|
|
196
|
+
- SSH access (key or password) to a device, only if you want config grabbing
|
|
197
|
+
- An Anthropic API key, only if you use `--summarize`
|
|
198
|
+
|
|
199
|
+
---
|
|
200
|
+
|
|
201
|
+
## Documentation
|
|
202
|
+
|
|
203
|
+
- [Dashboard](docs/DASHBOARD.md) - the live terminal stats viewer (`--dashboard`)
|
|
204
|
+
|
|
205
|
+
`docs/ARCHITECTURE.md`, `docs/PRODUCT_VISION.md`, and `docs/ROADMAP.md` are
|
|
206
|
+
stale/placeholder documents from earlier planning and are not kept in sync
|
|
207
|
+
with the implementation; refer to [CLAUDE.md](CLAUDE.md) for an accurate
|
|
208
|
+
architecture description instead.
|
|
209
|
+
|
|
210
|
+
---
|
|
211
|
+
|
|
212
|
+
## License
|
|
213
|
+
|
|
214
|
+
Proprietary License - free to use with explicit attribution. See [LICENSE](LICENSE).
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
"""PyNetworkIntel: AI-powered network intelligence platform."""
|
|
2
|
+
|
|
3
|
+
__version__ = "1.3.0"
|
|
4
|
+
|
|
5
|
+
# Core scanning and analysis
|
|
6
|
+
from pynetworkintel.core import Scanner, Analyzer, Pipeline
|
|
7
|
+
|
|
8
|
+
# Models and data structures
|
|
9
|
+
from pynetworkintel.models import (
|
|
10
|
+
Severity,
|
|
11
|
+
FindingType,
|
|
12
|
+
Service,
|
|
13
|
+
ConfigFile,
|
|
14
|
+
Device,
|
|
15
|
+
ScanResult,
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
# Configuration
|
|
19
|
+
from pynetworkintel.config import (
|
|
20
|
+
SSHConfig,
|
|
21
|
+
ScanConfig,
|
|
22
|
+
AnalysisConfig,
|
|
23
|
+
OutputConfig,
|
|
24
|
+
AppConfig,
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
# Alerting
|
|
28
|
+
from pynetworkintel.alerts import (
|
|
29
|
+
AlertChannel,
|
|
30
|
+
SlackAlertChannel,
|
|
31
|
+
EmailAlertChannel,
|
|
32
|
+
WebhookAlertChannel,
|
|
33
|
+
AlertManager,
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
# Change detection and reporting
|
|
37
|
+
from pynetworkintel.changes import ChangeDetector, ChangeReporter
|
|
38
|
+
from pynetworkintel.reporting import ReportGenerator
|
|
39
|
+
|
|
40
|
+
# Topology mapping
|
|
41
|
+
from pynetworkintel.topology import TopologyMapper, NetworkTopology, TopologyNode, TopologyEdge
|
|
42
|
+
|
|
43
|
+
# Dashboard and monitoring
|
|
44
|
+
from pynetworkintel.dashboard import Dashboard, DashboardServer, DashboardClient
|
|
45
|
+
from pynetworkintel.scheduler import MonitoringScheduler
|
|
46
|
+
|
|
47
|
+
# Utilities
|
|
48
|
+
from pynetworkintel.progress import ProgressIndicator, OutputFormatter
|
|
49
|
+
|
|
50
|
+
# MCP 2.0 Support — Network security intelligence
|
|
51
|
+
from pynetworkintel._mcp_connector import NetworkIntelligence
|
|
52
|
+
|
|
53
|
+
__all__ = [
|
|
54
|
+
# Core
|
|
55
|
+
"Scanner",
|
|
56
|
+
"Analyzer",
|
|
57
|
+
"Pipeline",
|
|
58
|
+
# Models
|
|
59
|
+
"Severity",
|
|
60
|
+
"FindingType",
|
|
61
|
+
"Service",
|
|
62
|
+
"ConfigFile",
|
|
63
|
+
"Device",
|
|
64
|
+
"ScanResult",
|
|
65
|
+
# Config
|
|
66
|
+
"SSHConfig",
|
|
67
|
+
"ScanConfig",
|
|
68
|
+
"AnalysisConfig",
|
|
69
|
+
"OutputConfig",
|
|
70
|
+
"AppConfig",
|
|
71
|
+
# Alerts
|
|
72
|
+
"AlertChannel",
|
|
73
|
+
"SlackAlertChannel",
|
|
74
|
+
"EmailAlertChannel",
|
|
75
|
+
"WebhookAlertChannel",
|
|
76
|
+
"AlertManager",
|
|
77
|
+
# Change detection
|
|
78
|
+
"ChangeDetector",
|
|
79
|
+
"ChangeReporter",
|
|
80
|
+
# Reporting
|
|
81
|
+
"ReportGenerator",
|
|
82
|
+
# Topology
|
|
83
|
+
"TopologyMapper",
|
|
84
|
+
"NetworkTopology",
|
|
85
|
+
"TopologyNode",
|
|
86
|
+
"TopologyEdge",
|
|
87
|
+
# Dashboard
|
|
88
|
+
"Dashboard",
|
|
89
|
+
"DashboardServer",
|
|
90
|
+
"DashboardClient",
|
|
91
|
+
# Scheduler
|
|
92
|
+
"MonitoringScheduler",
|
|
93
|
+
# Utilities
|
|
94
|
+
"ProgressIndicator",
|
|
95
|
+
"OutputFormatter",
|
|
96
|
+
# MCP
|
|
97
|
+
"NetworkIntelligence",
|
|
98
|
+
]
|