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
TableJSON 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(); }); }); }); }