← ikonstas70.github.io

Network Automation Stack Functional

Programmatic HTTP-to-Telnet Gateway for Network Device Fleets

Author: Ioannis Alexander Konstas
Organization: IT Solutions USA
Date: February 17, 2026
Repository: github.com/ikonstas70/network-automation-stack

ⓘ  Accuracy Disclaimer

Technical content in this article was researched and compiled with AI assistance under the direct supervision of the author. While every effort has been made to ensure accuracy, errors may still be present. If you spot an inaccuracy or have a correction, the author welcomes feedback — please reach out at github@it-solutionsusa.com or open an issue at github.com/ikonstas70.

Overview

This project establishes a high-security, automated management layer for network device fleets. By layering a Flask API Gateway over a socat transport bridge, it converts any Telnet-accessible device into a RESTful endpoint — transforming 10–20 Cisco CSR1000v routers into a programmatically managed fleet with zero external exposure.

Platform-agnostic: No hypervisor required. The stack works with any appliance reachable via Telnet on a forwarded port — physical hardware, virtual machines, console servers, or any platform that maps devices to TCP ports.

Architecture Diagram

curl / AI Agent / Automation Script | HTTPS (outbound-only) | +-----------+-----------+ | Cloudflare Edge | WAF + Zero Trust +-----------+-----------+ | Cloudflare Tunnel | v +-----------------------------------------------------+ | MAC MINI (Management Host) | | | | +---------------+----------------+ | | | Flask API :8080 | | | | csr_api_secure.py | | | | - X-API-KEY validation | | | | - ALLOWED_PORTS check | | | | - Timing controller | | | | - scrub_output() regex | | | +---------------+----------------+ | | | localhost | | +---------------+----------------+ | | | socat Gateway (telnet.sh) | | | | Ports 2301-2310 | | | | - fork (concurrent) | | | | - nohup (persistent) | | | +---------------+----------------+ | | | L3 Point-to-Point | +---------------------+-------------------------------+ | (No default gateway) v +-----------------------------------------------------+ | NETWORK DEVICE LAYER | | (any Telnet-accessible appliance) | | | | +------+ +------+ +------+ +------+ +------+ | | | R1 | | R2 | | R3 | | R4 |...| R10 | | | | 2301 | | 2302 | | 2303 | | 2304 | | 2310 | | | +------+ +------+ +------+ +------+ +------+ | | Cisco CSR1000v Fleet (current) | +-----------------------------------------------------+ OUT-OF-BAND ACCESS (Tailscale WireGuard): [ Engineer ] ----------------------------------------> [ Mac Mini :2301-2310 ]

Stack Layers

EDGE
Cloudflare Tunnel + WAF Global HTTPS access, Web Application Firewall, Zero Trust policy enforcement. No inbound ports open on the host.
API
Flask API — csr_api_secure.py (:8080) X-API-KEY authentication, ALLOWED_PORTS validation, timing controller, scrub_output() regex sanitization.
TCP
socat Gateway — telnet.sh (Ports 2301–2310) TCP relay from management host to target device. Fork mode for concurrent sessions. nohup for persistence.
DEV
Network Device Layer Any Telnet-accessible appliance. Current deployment: Cisco CSR1000v fleet on isolated L3 point-to-point (no default gateway).
VPN
Tailscale / WireGuard — Out-of-Band Access Private mesh VPN for direct engineer access to console ports, independent of the Cloudflare path.

Data Flow

1
Triggercurl POST /telnet {"port": 2301, "command": "show ip int brief"}
2
Ingress — Cloudflare Tunnel forwards request to localhost:8080
3
Validate — Flask checks X-API-KEY header and ALLOWED_PORTS list
4
Execute — Python subshell with timed printf/telnet sequence
5
Relay — socat forwards localhost:2301 → target-host:2301
6
Execution — Device receives command via Telnet on the forwarded port
7
Return — Output scrubbed and returned as structured JSON

Security Posture

FeatureMechanismPurpose
AuthenticationX-API-KEY headerBlocks unauthenticated API access
Port restrictionALLOWED_PORTS listLimits access to ports 2301–2310 only
Network isolationL3 Point-to-Point, no default gatewayDevices unreachable from internet
Output sanitizationscrub_output() regexStrips Telnet banners and escape chars
Transport encryptionTailscale WireGuardPrivate mesh VPN for engineer access
Application firewallCloudflare WAFFilters malicious inbound requests
Defense-in-depth: Two independent access paths — Cloudflare (public API) and Tailscale (private console) — operate at different stack layers and do not share configuration.

Quick Start

# Install dependencies
python3 -m venv ~/csr_env && source ~/csr_env/bin/activate
pip install -r requirements.txt

# Start socat transport bridge
sh src/telnet.sh

# Start Flask API
sh src/start_csr_api.sh

# Open Cloudflare tunnel
cloudflared tunnel --url http://localhost:8080

# Send a command
curl -X POST http://127.0.0.1:8080/telnet \
     -H "X-API-KEY: YOUR_SECRET_KEY_HERE" \
     -H "Content-Type: application/json" \
     -d '{"port": 2301, "command": "show ip interface brief"}'

Future Roadmap