Skip to main content
Glama
ooples

MCP Console Automation Server

telnet.md24.7 kB
# Telnet Protocol Documentation ## Overview The Telnet Protocol provides comprehensive support for Telnet connections to network devices, servers, and legacy systems. This implementation includes full RFC 854 compliance, device-specific patterns for major network equipment vendors, automatic option negotiation, and robust error handling with reconnection capabilities. ## Features - **RFC 854 Compliance**: Full Telnet protocol implementation with command interpretation - **Device Recognition**: Built-in patterns for Cisco, Juniper, Huawei, and generic devices - **Option Negotiation**: Automatic handling of Telnet options (ECHO, NAWS, Terminal Type, etc.) - **Connection Management**: Automatic reconnection, keep-alive, and timeout handling - **Prompt Detection**: Smart prompt recognition for different device types and modes - **Command Queuing**: Asynchronous command execution with timeout and retry support - **Privileged Mode**: Automatic elevation to enable/config mode for network devices - **Binary Mode**: Support for binary data transfer when needed - **ANSI Processing**: Optional ANSI color code stripping and processing ## Configuration ### Basic Configuration ```javascript const telnetOptions = { // Connection settings host: '192.168.1.1', port: 23, timeout: 30000, // Authentication username: 'admin', password: 'password', // Device type (affects prompt detection and commands) deviceType: 'cisco', // 'cisco', 'juniper', 'huawei', 'generic' // Terminal settings terminalType: 'VT100', windowSize: { width: 80, height: 24 }, // Protocol options negotiateOptions: true, stripAnsiColors: true, encoding: 'utf8' }; ``` ### Advanced Configuration ```javascript const advancedOptions = { // Connection resilience maxReconnectAttempts: 5, keepAlive: true, keepAliveInterval: 30000, // Command execution execTimeout: 10000, sendTimeout: 5000, maxBuffer: 2048 * 1024, // 2MB buffer // Device-specific settings enableMode: true, enablePassword: 'enable_secret', // Custom prompts (overrides device patterns) shellPrompt: /[\w\-_.]+[>#]\s*$/, loginPrompt: /Username:/i, passwordPrompt: /Password:/i, // Protocol fine-tuning initialLFCR: true, echoLines: 1, stripShellPrompt: true, binaryMode: false, // Error handling failedLoginMatch: /Login incorrect|Authentication failed/i, pageSeparator: '--More--', // Debugging debug: true }; ``` ### Device-Specific Configuration ```javascript // Cisco device configuration const ciscoConfig = { host: '192.168.1.10', deviceType: 'cisco', username: 'admin', password: 'cisco123', enableMode: true, enablePassword: 'enable_secret', execTimeout: 15000 }; // Juniper device configuration const juniperConfig = { host: '192.168.1.20', deviceType: 'juniper', username: 'root', password: 'juniper123', shellPrompt: /[\w\-_.]+[@%>]\s*$/, configPrompt: /[\w\-_.]+#\s*$/ }; // Huawei device configuration const huaweiConfig = { host: '192.168.1.30', deviceType: 'huawei', username: 'admin', password: 'huawei123', enableMode: true, shellPrompt: /<[\w\-_.]+>/ }; ``` ## Usage Examples ### Basic Telnet Connection ```javascript import { TelnetProtocol } from './protocols/TelnetProtocol.js'; const telnet = new TelnetProtocol({ host: '192.168.1.1', username: 'admin', password: 'password', deviceType: 'cisco' }); // Listen for connection events telnet.on('connected', () => { console.log('Telnet connection established'); }); telnet.on('output', (output) => { console.log(`Output: ${output.data}`); }); telnet.on('error', (error) => { console.error(`Error: ${error.message}`); }); // Connect and execute commands await telnet.connect(); // Execute basic commands const version = await telnet.send('show version'); console.log('Device version:', version); const interfaces = await telnet.send('show interfaces'); console.log('Interface status:', interfaces); await telnet.disconnect(); ``` ### Network Device Configuration ```javascript // Cisco router configuration example const ciscoRouter = new TelnetProtocol({ host: '192.168.1.1', username: 'admin', password: 'cisco123', deviceType: 'cisco', enableMode: true, enablePassword: 'enable_secret' }); await ciscoRouter.connect(); // Enter privileged mode await ciscoRouter.enablePrivilegedMode(); // Enter configuration mode await ciscoRouter.enterConfigMode(); // Configure interface await ciscoRouter.send('interface FastEthernet0/1'); await ciscoRouter.send('ip address 192.168.100.1 255.255.255.0'); await ciscoRouter.send('no shutdown'); await ciscoRouter.send('exit'); // Configure OSPF await ciscoRouter.send('router ospf 1'); await ciscoRouter.send('network 192.168.100.0 0.0.0.255 area 0'); await ciscoRouter.send('exit'); // Save configuration await ciscoRouter.saveConfiguration(); await ciscoRouter.disconnect(); ``` ### Batch Device Management ```javascript // Manage multiple network devices class NetworkDeviceManager { constructor() { this.devices = new Map(); } async connectToDevices(deviceList) { const connections = deviceList.map(device => this.connectDevice(device) ); await Promise.all(connections); } async connectDevice(device) { const telnet = new TelnetProtocol({ host: device.ip, username: device.username, password: device.password, deviceType: device.type, enablePassword: device.enablePassword }); telnet.on('error', (error) => { console.error(`Device ${device.name} error:`, error.message); }); try { await telnet.connect(); await telnet.enablePrivilegedMode(); this.devices.set(device.name, telnet); console.log(`Connected to ${device.name}`); } catch (error) { console.error(`Failed to connect to ${device.name}:`, error.message); } } async executeOnAllDevices(command) { const results = new Map(); for (const [name, telnet] of this.devices) { try { const output = await telnet.send(command); results.set(name, output); console.log(`${name}: Command executed successfully`); } catch (error) { console.error(`${name}: Command failed -`, error.message); results.set(name, { error: error.message }); } } return results; } async backupConfigurations() { const backups = new Map(); for (const [name, telnet] of this.devices) { try { const config = await telnet.send('show running-config'); backups.set(name, config); // Save to file const fs = require('fs').promises; const filename = `backup-${name}-${Date.now()}.txt`; await fs.writeFile(filename, config); console.log(`Configuration backed up: ${filename}`); } catch (error) { console.error(`Failed to backup ${name}:`, error.message); } } return backups; } async disconnectAll() { const disconnections = Array.from(this.devices.values()).map( telnet => telnet.disconnect() ); await Promise.all(disconnections); this.devices.clear(); } } // Usage example const manager = new NetworkDeviceManager(); const devices = [ { name: 'core-router', ip: '192.168.1.1', type: 'cisco', username: 'admin', password: 'cisco123', enablePassword: 'secret' }, { name: 'edge-router', ip: '192.168.1.2', type: 'cisco', username: 'admin', password: 'cisco123', enablePassword: 'secret' }, { name: 'switch-1', ip: '192.168.1.10', type: 'cisco', username: 'admin', password: 'cisco123', enablePassword: 'secret' } ]; await manager.connectToDevices(devices); // Execute commands on all devices await manager.executeOnAllDevices('show version'); await manager.executeOnAllDevices('show ip interface brief'); // Backup all configurations await manager.backupConfigurations(); await manager.disconnectAll(); ``` ### Legacy System Access ```javascript // Connect to legacy Unix/Linux system const legacySystem = new TelnetProtocol({ host: '10.0.1.100', port: 23, username: 'operator', password: 'legacy_pass', deviceType: 'generic', shellPrompt: /[$#>]\s*$/, loginPrompt: /login:/i, timeout: 45000 }); await legacySystem.connect(); // System administration commands const uptime = await legacySystem.send('uptime'); console.log('System uptime:', uptime); const diskUsage = await legacySystem.send('df -h'); console.log('Disk usage:', diskUsage); const processes = await legacySystem.send('ps aux | grep -v grep'); console.log('Running processes:', processes); // Log file analysis const logTail = await legacySystem.send('tail -50 /var/log/messages'); console.log('Recent log entries:', logTail); await legacySystem.disconnect(); ``` ## Advanced Features ### Custom Device Patterns ```javascript // Define custom device pattern const customDevicePattern = { type: 'custom-router', loginPrompt: [/User Name:/i], passwordPrompt: [/Password:/i], shellPrompt: [/MyRouter>/], enablePrompt: [/MyRouter#/], configPrompt: [/MyRouter\(config\)#/], morePrompt: [/--More--/, /Continue\?/], errorPatterns: [ /Error:/i, /Invalid command/i, /Syntax error/i ], commands: { enable: 'enable', config: 'configure', exit: 'exit', save: 'write memory', show: ['show version', 'show status'] } }; // Register custom pattern const customTelnet = new TelnetProtocol({ host: '192.168.1.50', username: 'admin', password: 'password', deviceType: 'custom-router' }); // Override device patterns at runtime customTelnet.devicePattern = customDevicePattern; ``` ### Option Negotiation Handling ```javascript // Handle specific Telnet option negotiations const telnetWithOptions = new TelnetProtocol({ host: '192.168.1.1', username: 'admin', password: 'password', negotiateOptions: true, terminalType: 'XTERM-256COLOR', windowSize: { width: 132, height: 43 }, binaryMode: false }); // Listen for option negotiation events telnetWithOptions.on('optionNegotiated', (option) => { console.log(`Negotiated option: ${option.name} (${option.code}) = ${option.enabled}`); }); // Monitor negotiated options telnetWithOptions.on('connected', () => { const options = telnetWithOptions.negotiatedOptions; for (const [code, option] of options) { console.log(`Option ${option.name}: Local=${option.localState}, Remote=${option.remoteState}`); } }); ``` ### Connection Resilience ```javascript // Robust connection with automatic recovery const resilientTelnet = new TelnetProtocol({ host: '192.168.1.1', username: 'admin', password: 'password', maxReconnectAttempts: 10, keepAlive: true, keepAliveInterval: 30000, timeout: 60000 }); // Handle reconnection events resilientTelnet.on('reconnecting', (attempt) => { console.log(`Reconnection attempt ${attempt}`); }); resilientTelnet.on('maxReconnectAttemptsReached', () => { console.error('Max reconnection attempts reached, connection lost'); }); // Implement custom reconnection logic resilientTelnet.on('disconnected', () => { console.log('Connection lost, implementing custom recovery...'); setTimeout(async () => { try { await resilientTelnet.connect(); console.log('Custom reconnection successful'); } catch (error) { console.error('Custom reconnection failed:', error.message); } }, 10000); }); ``` ### Binary Data Handling ```javascript // Handle binary data transfer const binaryTelnet = new TelnetProtocol({ host: '192.168.1.1', username: 'admin', password: 'password', binaryMode: true, stripAnsiColors: false, encoding: 'binary' }); // Handle raw binary data binaryTelnet.on('output', (output) => { if (output.raw) { const binaryData = Buffer.from(output.raw, 'hex'); console.log('Binary data received:', binaryData); // Process binary data as needed processBinaryData(binaryData); } }); function processBinaryData(data) { // Custom binary data processing logic console.log(`Received ${data.length} bytes of binary data`); } ``` ## Device-Specific Examples ### Cisco IOS Configuration ```javascript const ciscoSwitch = new TelnetProtocol({ host: '192.168.1.10', deviceType: 'cisco', username: 'admin', password: 'cisco123', enablePassword: 'enable_secret' }); await ciscoSwitch.connect(); await ciscoSwitch.enablePrivilegedMode(); await ciscoSwitch.enterConfigMode(); // VLAN configuration await ciscoSwitch.send('vlan 100'); await ciscoSwitch.send('name SERVERS'); await ciscoSwitch.send('exit'); await ciscoSwitch.send('vlan 200'); await ciscoSwitch.send('name WORKSTATIONS'); await ciscoSwitch.send('exit'); // Interface configuration await ciscoSwitch.send('interface range FastEthernet0/1-10'); await ciscoSwitch.send('switchport mode access'); await ciscoSwitch.send('switchport access vlan 100'); await ciscoSwitch.send('spanning-tree portfast'); await ciscoSwitch.send('exit'); await ciscoSwitch.saveConfiguration(); await ciscoSwitch.disconnect(); ``` ### Juniper JunOS Configuration ```javascript const juniperRouter = new TelnetProtocol({ host: '192.168.1.20', deviceType: 'juniper', username: 'root', password: 'juniper123' }); await juniperRouter.connect(); await juniperRouter.enterConfigMode(); // Interface configuration await juniperRouter.send('set interfaces ge-0/0/0 unit 0 family inet address 192.168.100.1/24'); await juniperRouter.send('set interfaces ge-0/0/1 unit 0 family inet address 10.0.0.1/30'); // BGP configuration await juniperRouter.send('set protocols bgp group external type external'); await juniperRouter.send('set protocols bgp group external peer-as 65001'); await juniperRouter.send('set protocols bgp group external neighbor 10.0.0.2'); // Commit configuration await juniperRouter.send('commit check'); await juniperRouter.send('commit'); await juniperRouter.disconnect(); ``` ### Huawei VRP Configuration ```javascript const huaweiRouter = new TelnetProtocol({ host: '192.168.1.30', deviceType: 'huawei', username: 'admin', password: 'huawei123' }); await huaweiRouter.connect(); await huaweiRouter.enterConfigMode(); // Interface configuration await huaweiRouter.send('interface GigabitEthernet0/0/1'); await huaweiRouter.send('ip address 192.168.10.1 255.255.255.0'); await huaweiRouter.send('undo shutdown'); await huaweiRouter.send('quit'); // OSPF configuration await huaweiRouter.send('ospf 1'); await huaweiRouter.send('area 0'); await huaweiRouter.send('network 192.168.10.0 0.0.0.255'); await huaweiRouter.send('quit'); await huaweiRouter.send('quit'); await huaweiRouter.saveConfiguration(); await huaweiRouter.disconnect(); ``` ## Error Handling ### Connection Error Management ```javascript const telnet = new TelnetProtocol({ host: '192.168.1.1', username: 'admin', password: 'password' }); // Comprehensive error handling telnet.on('error', (error) => { console.error('Telnet error:', error.message); switch (error.code) { case 'ECONNREFUSED': console.error('Connection refused - check if telnet service is running'); break; case 'ETIMEDOUT': console.error('Connection timeout - check network connectivity'); break; case 'EHOSTUNREACH': console.error('Host unreachable - check routing'); break; default: console.error('Unknown error occurred'); } }); telnet.on('loginFailed', () => { console.error('Authentication failed - check credentials'); }); telnet.on('timeout', () => { console.warn('Connection timeout - may indicate slow response'); }); // Graceful error recovery telnet.on('disconnected', async () => { console.log('Connection lost, attempting recovery...'); try { await new Promise(resolve => setTimeout(resolve, 5000)); await telnet.connect(); console.log('Recovery successful'); } catch (error) { console.error('Recovery failed:', error.message); } }); ``` ### Command Execution Errors ```javascript // Handle command-specific errors async function executeCommandSafely(telnet, command, maxRetries = 3) { for (let attempt = 1; attempt <= maxRetries; attempt++) { try { const result = await telnet.send(command, { timeout: 15000, retryCount: 0 }); // Check for device error patterns if (result.includes('% Invalid input') || result.includes('Syntax error') || result.includes('Unknown command')) { throw new Error(`Command syntax error: ${command}`); } return result; } catch (error) { console.warn(`Attempt ${attempt} failed for command "${command}":`, error.message); if (attempt === maxRetries) { throw new Error(`Command failed after ${maxRetries} attempts: ${command}`); } // Wait before retry await new Promise(resolve => setTimeout(resolve, 2000)); } } } // Usage try { const result = await executeCommandSafely(telnet, 'show running-config'); console.log('Command successful:', result); } catch (error) { console.error('Command ultimately failed:', error.message); } ``` ## Performance Optimization ### Connection Pooling ```javascript class TelnetConnectionPool { constructor(maxConnections = 10) { this.pool = []; this.maxConnections = maxConnections; this.activeConnections = new Set(); } async getConnection(options) { // Look for available connection const available = this.pool.find(conn => conn.host === options.host && !this.activeConnections.has(conn.id) && conn.telnet.isConnected() ); if (available) { this.activeConnections.add(available.id); return available.telnet; } // Create new connection if under limit if (this.pool.length < this.maxConnections) { const telnet = new TelnetProtocol(options); await telnet.connect(); const connection = { id: Date.now() + Math.random(), host: options.host, telnet, created: Date.now() }; this.pool.push(connection); this.activeConnections.add(connection.id); return telnet; } throw new Error('Connection pool exhausted'); } releaseConnection(telnet) { const connection = this.pool.find(conn => conn.telnet === telnet); if (connection) { this.activeConnections.delete(connection.id); } } async cleanup() { const disconnections = this.pool.map(conn => conn.telnet.disconnect() ); await Promise.all(disconnections); this.pool = []; this.activeConnections.clear(); } } ``` ### Batch Command Execution ```javascript // Efficient batch command execution async function executeBatchCommands(telnet, commands, options = {}) { const results = []; const batchSize = options.batchSize || 5; const delayBetweenBatches = options.delay || 1000; for (let i = 0; i < commands.length; i += batchSize) { const batch = commands.slice(i, i + batchSize); const batchResults = await Promise.all( batch.map(async (command) => { try { const result = await telnet.send(command); return { command, result, success: true }; } catch (error) { return { command, error: error.message, success: false }; } }) ); results.push(...batchResults); // Delay between batches to prevent overwhelming the device if (i + batchSize < commands.length) { await new Promise(resolve => setTimeout(resolve, delayBetweenBatches)); } } return results; } // Usage const commands = [ 'show version', 'show interfaces', 'show ip route', 'show arp', 'show mac address-table' ]; const results = await executeBatchCommands(telnet, commands, { batchSize: 3, delay: 500 }); results.forEach(result => { if (result.success) { console.log(`✓ ${result.command}: Success`); } else { console.error(`✗ ${result.command}: ${result.error}`); } }); ``` ## Security Best Practices ### Secure Connection Management ```javascript const secureTelnet = new TelnetProtocol({ host: '192.168.1.1', username: process.env.TELNET_USERNAME, password: process.env.TELNET_PASSWORD, enablePassword: process.env.TELNET_ENABLE_PASSWORD, // Security settings timeout: 30000, // Shorter timeout maxReconnectAttempts: 3, // Limit reconnection attempts keepAliveInterval: 60000, // Longer keep-alive interval // Don't log sensitive data debug: false }); // Clear sensitive data after use process.on('exit', () => { delete process.env.TELNET_PASSWORD; delete process.env.TELNET_ENABLE_PASSWORD; }); ``` ### Command Validation ```javascript // Validate commands before execution function validateCommand(command, allowedCommands) { const commandStart = command.trim().toLowerCase().split(' ')[0]; if (!allowedCommands.includes(commandStart)) { throw new Error(`Command not allowed: ${commandStart}`); } // Check for dangerous patterns const dangerousPatterns = [ /rm\s+-rf/i, /format/i, /delete\s+.*all/i, /erase\s+.*all/i ]; for (const pattern of dangerousPatterns) { if (pattern.test(command)) { throw new Error(`Potentially dangerous command blocked: ${command}`); } } return true; } // Safe command execution async function executeSecureCommand(telnet, command) { const allowedCommands = ['show', 'display', 'get', 'status']; try { validateCommand(command, allowedCommands); const result = await telnet.send(command); return result; } catch (error) { console.error('Command validation failed:', error.message); throw error; } } ``` ## Troubleshooting ### Debug Mode ```javascript // Enable comprehensive debugging const debugTelnet = new TelnetProtocol({ host: '192.168.1.1', username: 'admin', password: 'password', debug: true }); // Monitor all events debugTelnet.on('connected', () => console.log('DEBUG: Connected')); debugTelnet.on('disconnected', () => console.log('DEBUG: Disconnected')); debugTelnet.on('timeout', () => console.log('DEBUG: Timeout')); debugTelnet.on('prompt', (prompt) => console.log('DEBUG: Prompt detected:', prompt)); debugTelnet.on('output', (output) => console.log('DEBUG: Raw output:', output.raw)); // Get connection information const connInfo = debugTelnet.getConnectionInfo(); console.log('Connection info:', connInfo); ``` ### Common Issues and Solutions ```javascript // Issue 1: Connection timeout // Solution: Increase timeout and check network connectivity const timeoutTelnet = new TelnetProtocol({ host: '192.168.1.1', timeout: 60000, // Increase timeout keepAlive: true, keepAliveInterval: 30000 }); // Issue 2: Prompt not detected // Solution: Customize prompt patterns const customPromptTelnet = new TelnetProtocol({ host: '192.168.1.1', shellPrompt: /[\w\-_.]+[>#$]\s*$/, loginPrompt: /[Ll]ogin:|[Uu]sername:/, passwordPrompt: /[Pp]assword:/ }); // Issue 3: Command execution hangs // Solution: Implement command timeout and retry async function executeWithTimeout(telnet, command, timeout = 10000) { return Promise.race([ telnet.send(command), new Promise((_, reject) => setTimeout(() => reject(new Error('Command timeout')), timeout) ) ]); } ``` ## API Reference ### Class: TelnetProtocol #### Constructor Options - `host` - Target hostname or IP address - `port` - Port number (default: 23) - `username` - Authentication username - `password` - Authentication password - `deviceType` - Device type ('cisco', 'juniper', 'huawei', 'generic') - `enablePassword` - Enable mode password - `timeout` - Connection timeout in milliseconds - `terminalType` - Terminal type (default: 'VT100') - `windowSize` - Terminal dimensions { width, height } #### Methods - `connect()` - Establish connection - `disconnect()` - Close connection - `send(command, options?)` - Execute command - `enablePrivilegedMode()` - Enter enable mode - `enterConfigMode()` - Enter configuration mode - `saveConfiguration()` - Save device configuration - `isConnected()` - Check connection status - `isAuthenticated()` - Check authentication status - `getConnectionInfo()` - Get connection details #### Events - `connected` - Connection established - `disconnected` - Connection lost - `error` - Error occurred - `output` - Output received - `prompt` - Prompt detected - `timeout` - Operation timeout - `loginFailed` - Authentication failed This comprehensive documentation covers all aspects of the Telnet Protocol implementation for production use with network devices and legacy systems.

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/ooples/mcp-console-automation'

If you have feedback or need assistance with the MCP directory API, please join our Discord server