ubuntu_ufw_firewall
Configure Ubuntu firewall rules via SSH to manage network security by enabling, disabling, allowing, or denying specific ports and protocols.
Instructions
Manage Ubuntu Uncomplicated Firewall (UFW)
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| connectionId | Yes | ID of an active SSH connection | |
| action | Yes | Action to perform (enable, disable, status, allow, deny, delete, reset) | |
| port | No | Port number or service name (e.g., 80, 443, ssh, http) | |
| protocol | No | Protocol (tcp, udp) | |
| from | No | Source IP address or network | |
| sudo | No | Whether to run the command with sudo (default: true) |
Implementation Reference
- src/ubuntu-website-tools.ts:421-512 (handler)The main execution handler for the 'ubuntu_ufw_firewall' tool. It handles various UFW actions like enable, disable, status, allow, deny, delete, reset by executing corresponding SSH commands.
async ubuntu_ufw_firewall(params) { const { connectionId, action, port, protocol, from, sudo = true } = params; try { const conn = getConnection(connectionMap, connectionId); const sudoPrefix = sudo ? 'sudo ' : ''; // Validate action const validActions = ['enable', 'disable', 'status', 'allow', 'deny', 'delete', 'reset']; if (!validActions.includes(action)) { throw new Error(`Invalid action: ${action}. Valid actions are: ${validActions.join(', ')}`); } // Ensure UFW is installed const checkUfw = await executeSSHCommand(conn, 'which ufw || echo "not-found"'); if (checkUfw.stdout === 'not-found') { const installUfw = await executeSSHCommand(conn, `${sudoPrefix}apt-get update && ${sudoPrefix}apt-get install -y ufw`); if (installUfw.code !== 0) { throw new Error(`Failed to install ufw: ${installUfw.stderr}`); } } let command = ''; switch (action) { case 'enable': command = `${sudoPrefix}ufw --force enable`; break; case 'disable': command = `${sudoPrefix}ufw disable`; break; case 'status': command = `${sudoPrefix}ufw status verbose`; break; case 'reset': command = `${sudoPrefix}ufw --force reset`; break; case 'allow': case 'deny': // Check if port is provided if (!port) { throw new Error('Port or service name is required for allow/deny actions'); } let ruleCommand = `${sudoPrefix}ufw ${action} `; // Add protocol if specified if (protocol) { ruleCommand += `${port}/${protocol} `; } else { ruleCommand += `${port} `; } // Add source IP/network if specified if (from) { ruleCommand += `from ${from}`; } command = ruleCommand; break; case 'delete': if (!port) { throw new Error('Port or service name is required for delete action'); } let deleteCommand = `${sudoPrefix}ufw delete allow `; if (protocol) { deleteCommand += `${port}/${protocol}`; } else { deleteCommand += port; } command = deleteCommand; break; } const result = await executeSSHCommand(conn, command); return { content: [{ type: 'text', text: `Firewall ${action} result:\n\n${result.stdout || result.stderr}` }] }; } catch (error: any) { return { content: [{ type: 'text', text: `Firewall error: ${error.message}` }], isError: true }; } } - src/ubuntu-website-tools.ts:637-669 (schema)The input schema and description definition for the 'ubuntu_ufw_firewall' tool, used for validation and listing.
ubuntu_ufw_firewall: { description: 'Manage Ubuntu Uncomplicated Firewall (UFW)', inputSchema: { type: 'object', properties: { connectionId: { type: 'string', description: 'ID of an active SSH connection' }, action: { type: 'string', description: 'Action to perform (enable, disable, status, allow, deny, delete, reset)' }, port: { type: 'string', description: 'Port number or service name (e.g., 80, 443, ssh, http)' }, protocol: { type: 'string', description: 'Protocol (tcp, udp)' }, from: { type: 'string', description: 'Source IP address or network' }, sudo: { type: 'boolean', description: 'Whether to run the command with sudo (default: true)' } }, required: ['connectionId', 'action'] } } - src/index.ts:270-299 (registration)The central CallToolRequestSchema handler registration that dispatches calls to ubuntu_ tools, including 'ubuntu_ufw_firewall', by invoking the corresponding function from ubuntuToolHandlers.
this.server.setRequestHandler(CallToolRequestSchema, async (request: any) => { const toolName = request.params.name; // Handle core SSH tools directly if (toolName.startsWith('ssh_')) { switch (toolName) { case 'ssh_connect': return this.handleSSHConnect(request.params.arguments); case 'ssh_exec': return this.handleSSHExec(request.params.arguments); case 'ssh_upload_file': return this.handleSSHUpload(request.params.arguments); case 'ssh_download_file': return this.handleSSHDownload(request.params.arguments); case 'ssh_list_files': return this.handleSSHListFiles(request.params.arguments); case 'ssh_disconnect': return this.handleSSHDisconnect(request.params.arguments); default: throw new Error(`Unknown SSH tool: ${toolName}`); } } // Handle Ubuntu tools directly if (toolName.startsWith('ubuntu_') && ubuntuToolHandlers[toolName]) { return ubuntuToolHandlers[toolName](request.params.arguments); } throw new Error(`Unknown tool: ${toolName}`); }); - src/ubuntu-website-tools.ts:683-689 (registration)The ListToolsRequestSchema handler override in addUbuntuTools that includes the 'ubuntu_ufw_firewall' schema in the tools list.
server.setRequestHandler(ListToolsRequestSchema, async () => { // Create array of Ubuntu tools const ubuntuTools = Object.entries(ubuntuToolSchemas).map(([name, schema]) => ({ name, description: schema.description, inputSchema: schema.inputSchema })); - src/ubuntu-website-tools.ts:18-58 (helper)Utility function executeSSHCommand used by the ubuntu_ufw_firewall handler to run UFW commands over SSH with timeout and error handling.
async function executeSSHCommand(conn: Client, command: string, timeout = 60000): Promise<{ code: number; signal: string; stdout: string; stderr: string; }> { return new Promise((resolve, reject) => { // Set up timeout const timeoutId = setTimeout(() => { reject(new Error(`Command execution timed out after ${timeout}ms`)); }, timeout); conn.exec(command, {}, (err: Error | undefined, stream: any) => { if (err) { clearTimeout(timeoutId); return reject(new Error(`Failed to execute command: ${err.message}`)); } let stdout = ''; let stderr = ''; stream.on('close', (code: number, signal: string) => { clearTimeout(timeoutId); resolve({ code, signal, stdout: stdout.trim(), stderr: stderr.trim() }); }); stream.on('data', (data: Buffer) => { stdout += data.toString(); }); stream.stderr.on('data', (data: Buffer) => { stderr += data.toString(); }); }); }); }