verizon-router-client
Python client for Verizon Fios router APIs (focused on the CR1000A web UI endpoints).
Features
- Login/token helpers for the web UI.
- Fetch status details (uptime, WAN IPs, DNS servers).
- Read/write local DNS entries.
- Read/add/remove port forwarding rules.
- Parse known device lists.
- Bandwidth history and per-host traffic statistics.
- Settings from environment variables /
.env(pydantic-settings). vzroutercommand-line interface (click).
Install
Local editable install:
pip install -e .
Or with uv:
uv pip install -e .
Configuration
Settings are read from VZ_ROUTER_* environment variables and/or a .env
file in the working directory (environment variables win). Copy
.env.example to .env and fill in your values:
VZ_ROUTER_BASE_URL=https://192.168.1.1
VZ_ROUTER_USERNAME=admin
VZ_ROUTER_PASSWORD=your-admin-password
# Optional:
# VZ_ROUTER_VERIFY_TLS=false # or a path to a CA bundle
# VZ_ROUTER_TLS_HOSTNAME=mynetworksettings.com
# VZ_ROUTER_TIMEOUT_S=10.0
With that in place, connect() builds a client and logs in:
from verizon_router_client import connect
client = connect()
You can also construct settings explicitly with
RouterSettings(base_url=..., password=...) and pass them to connect() or
VerizonRouterClient.from_settings().
Quickstart
from verizon_router_client.cr1000a import VerizonRouterClient
client = VerizonRouterClient(
base_url="https://192.168.1.1",
# The router uses a hostname-bound TLS cert; this adapter handles it.
tls_hostname="mynetworksettings.com",
)
client.login("admin", "your-password")
print(client.get_uptime_seconds())
print(client.get_wan_ipv4())
print(client.get_wan_ipv6())
DNS entries
from verizon_router_client.cr1000a import VerizonRouterClient
client = VerizonRouterClient(
base_url="https://192.168.1.1",
# The router uses a hostname-bound TLS cert; this adapter handles it.
tls_hostname="mynetworksettings.com",
)
client.login("admin", "your-password")
print(client.get_dns_entries_v4())
slot = client.add_dns_ipv4("nas", "192.168.1.10")
client.clear_dns_ipv4_slot(slot)
Port forwarding
from verizon_router_client.cr1000a import VerizonRouterClient
client = VerizonRouterClient(
base_url="https://192.168.1.1",
# The router uses a hostname-bound TLS cert; this adapter handles it.
tls_hostname="mynetworksettings.com",
)
client.login("admin", "your-password")
rule_id = client.add_port_forward(
name="ssh",
private_ip="192.168.1.20",
forward_port=22,
dest_port=22,
)
client.remove_port_forward(rule_id=rule_id)
Known devices
from verizon_router_client.cr1000a import VerizonRouterClient
client = VerizonRouterClient(
base_url="https://192.168.1.1",
# The router uses a hostname-bound TLS cert; this adapter handles it.
tls_hostname="mynetworksettings.com",
)
devices = client.fetch_known_devices()
If you are not already logged in, pass a sysauth cookie value:
from verizon_router_client.cr1000a import VerizonRouterClient
client = VerizonRouterClient(
base_url="https://192.168.1.1",
# The router uses a hostname-bound TLS cert; this adapter handles it.
tls_hostname="mynetworksettings.com",
)
devices = client.fetch_known_devices(sysauth_cookie_value="...")
Bandwidth and traffic statistics
Parses /cgi/cgi_bandwith.js (the endpoint name is misspelled in firmware):
from verizon_router_client import connect
client = connect()
# Bandwidth history rate series (lists of ints, as reported by the router).
history = client.get_bandwidth_history_rates()
# Per-host traffic, keyed by aggregation period in seconds
# (3600, 43200, 86400, 604800, 2592000), then by MAC address.
stats = client.get_host_traffic_stats()
hour = stats[3600]
for mac, counters in hour.items():
print(mac, counters["bytes_tx"], counters["bytes_rx"])
# Raw addROD payloads (includes known_device_list, fsam_update, ...).
raw = client.fetch_bandwidth()
Command-line interface
Installing the package provides a vzrouter command. Connection options fall
back to the same VZ_ROUTER_* environment variables / .env file, and can be
overridden with flags (--base-url, --username, --password,
--verify-tls, --tls-hostname, --timeout). Structured output is JSON.
# Status: uptime, WAN IPs, WAN DNS servers
vzrouter status
# Known devices (summary; --full for all fields)
vzrouter devices --active
# Bandwidth
vzrouter bandwidth history
vzrouter bandwidth hosts --period 3600
# Local DNS entries
vzrouter dns list
vzrouter dns add nas 192.168.1.10
vzrouter dns remove nas
vzrouter dns remove 192.168.1.10 --by-ip --all
# Port forwarding
vzrouter forward list
vzrouter forward add --name ssh --private-ip 192.168.1.20 \
--forward-port 22 --dest-port 22
vzrouter forward remove 12345
TLS notes
By default the client uses the bundled Verizon Fios root CA (cert/Verizon Fios Root CA.pem)
and sets the TLS SNI/Host header to mynetworksettings.com when the base URL is an IP.
If your router uses different TLS settings, override verify_tls or tls_hostname.
Development
- Python: 3.10+
- Runtime dependencies:
requests,pydantic-settings,click
Testing
Run the suite with pytest:
uv run pytest
Unit tests (parsing, auth hashing, settings, CLI) never touch the network.
Integration tests run against a backend selected with --router:
uv run pytest --router=mock # in-process mock router service
uv run pytest --router=real # your real router, credentials from .env
uv run pytest # auto (default): real if .env has a password,
# mock otherwise
- Mock (
tests/mock_router.py): an in-process HTTP service emulating the CR1000A — hashed-credential login with asysauthcookie, auth-gatedcgi/*.jsendpoints, and stateful DNS / port-forwarding mutations. All fixture data uses RFC documentation values. - Real: reads credentials from the project
.env(--router=realskips if none). Mutating tests create uniquely named entries (pytest-vzr-*) and remove them afterwards. Tests that need deterministic state or are unsafe against real hardware (e.g. repeated failed logins) always run against the mock, whichever backend is selected.
Note: the router throttles rapid logins, so real-mode tests share a single login for the whole session. If the router is still throttling from recent attempts, the real-backend tests skip with an explanatory message — wait a few minutes and rerun.
Kubernetes Operator
The verizon-router-client can also be deployed as a Kubernetes operator using kopf.
The operator manages custom resources for DNS and Port Forwarding.
Helm
You can easily install the operator using the provided Helm chart.
# If you don't have an existing secret, you can pass the password directly
helm install verizon-router-operator ./charts/verizon-router-operator \
--set router.password='YOUR_ROUTER_PASSWORD'
# Or, if you've created a secret named `verizon-router-secret` with the `password` key:
helm install verizon-router-operator ./charts/verizon-router-operator
Setup
First, install the package with operator dependencies:
pip install -e ".[operator]"
Or build and use the provided Docker image:
docker build -t verizon-router-operator:latest .
Apply CRDs & RBAC
Apply the Custom Resource Definitions (CRDs) and Role-Based Access Control (RBAC):
kubectl apply -f k8s/crd-fiosdnsrecord.yaml
kubectl apply -f k8s/crd-fiosportforward.yaml
kubectl apply -f k8s/rbac.yaml
Configure Authentication
Create a secret with your router password:
kubectl create secret generic verizon-router-secret \
--from-literal=password='YOUR_ROUTER_PASSWORD'
Deploy the operator:
kubectl apply -f k8s/deployment.yaml
Custom Resources
You can now manage your router via standard Kubernetes manifests.
Add a DNS Record:
apiVersion: network.verizon.com/v1alpha1
kind: FiosDnsRecord
metadata:
name: nas-entry
spec:
hostname: nas
ip: 192.168.1.10
Add a Port Forwarding Rule:
apiVersion: network.verizon.com/v1alpha1
kind: FiosPortForward
metadata:
name: ssh-forward
spec:
name: ssh
private_ip: 192.168.1.20
forward_port: 22
dest_port: 22
Disclaimer
This project is not affiliated with Verizon. Use at your own risk.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file verizon_router_client-0.4.0.tar.gz.
File metadata
- Download URL: verizon_router_client-0.4.0.tar.gz
- Upload date:
- Size: 17.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ca1320b420b673f07ccb0db103ffe0d7bf1d34080db2a925c3c781112598e8a2
|
|
| MD5 |
f8d2e86fef436fe13d160584ae2b3985
|
|
| BLAKE2b-256 |
205fc8f7bca27afe4a82026f77a61be843d1e33dde15286258d67bf204af3f5f
|
Provenance
The following attestation bundles were made for verizon_router_client-0.4.0.tar.gz:
Publisher:
release.yml on Brishen/verizon_router_client
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
verizon_router_client-0.4.0.tar.gz -
Subject digest:
ca1320b420b673f07ccb0db103ffe0d7bf1d34080db2a925c3c781112598e8a2 - Sigstore transparency entry: 2303749255
- Sigstore integration time:
-
Permalink:
Brishen/verizon_router_client@52ebd44577b4f4b5b9ce10db69fa5a5b7422306e -
Branch / Tag:
refs/tags/v0.4.0 - Owner: https://github.com/Brishen
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@52ebd44577b4f4b5b9ce10db69fa5a5b7422306e -
Trigger Event:
push
-
Statement type:
File details
Details for the file verizon_router_client-0.4.0-py3-none-any.whl.
File metadata
- Download URL: verizon_router_client-0.4.0-py3-none-any.whl
- Upload date:
- Size: 20.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7bd48304a1873fb71e1f3c1c363f67953d6f19dd39734f870e2f5a746202fce2
|
|
| MD5 |
e2c7536228227451441cb26b42e2121e
|
|
| BLAKE2b-256 |
10e7fcd29cb2e5935fa32ccca02f240a5272ab4487f5d8f35ac7ff066b28eed8
|
Provenance
The following attestation bundles were made for verizon_router_client-0.4.0-py3-none-any.whl:
Publisher:
release.yml on Brishen/verizon_router_client
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
verizon_router_client-0.4.0-py3-none-any.whl -
Subject digest:
7bd48304a1873fb71e1f3c1c363f67953d6f19dd39734f870e2f5a746202fce2 - Sigstore transparency entry: 2303749282
- Sigstore integration time:
-
Permalink:
Brishen/verizon_router_client@52ebd44577b4f4b5b9ce10db69fa5a5b7422306e -
Branch / Tag:
refs/tags/v0.4.0 - Owner: https://github.com/Brishen
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@52ebd44577b4f4b5b9ce10db69fa5a5b7422306e -
Trigger Event:
push
-
Statement type: