Skip to main content
Glama

ubuntu_ufw_firewall

Simplify Ubuntu UFW management via SSH MCP. Enable, disable, configure, or view firewall status, allowing or denying specific ports, protocols, and IPs with ease.

Instructions

Manage Ubuntu Uncomplicated Firewall (UFW)

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
actionYesAction to perform (enable, disable, status, allow, deny, delete, reset)
connectionIdYesID of an active SSH connection
fromNoSource IP address or network
portNoPort number or service name (e.g., 80, 443, ssh, http)
protocolNoProtocol (tcp, udp)
sudoNoWhether to run the command with sudo (default: true)

Implementation Reference

  • The main handler function that executes UFW firewall management actions (enable, disable, status, allow, deny, delete, reset) via SSH commands on Ubuntu servers.
    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 }; } }
  • The input schema defining parameters for the ubuntu_ufw_firewall tool, used in tool 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:293-296 (registration)
    Registration in the CallToolRequestSchema handler: dispatches to ubuntuToolHandlers[toolName] for ubuntu_ prefixed tools.
    // Handle Ubuntu tools directly if (toolName.startsWith('ubuntu_') && ubuntuToolHandlers[toolName]) { return ubuntuToolHandlers[toolName](request.params.arguments); }
  • The addUbuntuTools function registers the tool schema by overriding ListToolsRequestSchema to include all Ubuntu tools including ubuntu_ufw_firewall.
    export function addUbuntuTools(server: Server, connections: Map<string, { conn: Client; config: any }>) { // Store connection map for tool handlers to use connectionMap = connections; // We can't retrieve existing handlers, so we need to work with the server object directly // Override the ListToolsRequestSchema handler to include Ubuntu tools // Note: This completely replaces the existing handler, so we need to include all tools server.setRequestHandler(ListToolsRequestSchema, async () => { // Create array of Ubuntu tools const ubuntuTools = Object.entries(ubuntuToolSchemas).map(([name, schema]) => ({ name, description: schema.description, inputSchema: schema.inputSchema })); // Return both core SSH tools and Ubuntu tools // Note: In a real implementation, we should coordinate with the main server to avoid duplicating tool definitions return { tools: [ // Core SSH tools - keep in sync with the list in index.ts { name: 'ssh_connect', description: 'Connect to a remote server via SSH', inputSchema: { type: 'object', properties: { host: { type: 'string', description: 'Hostname or IP address of the remote server' }, port: { type: 'number', description: 'SSH port (default: 22)' }, username: { type: 'string', description: 'SSH username' }, password: { type: 'string', description: 'SSH password (if not using key-based authentication)' }, privateKeyPath: { type: 'string', description: 'Path to private key file (if using key-based authentication)' }, passphrase: { type: 'string', description: 'Passphrase for private key (if needed)' }, connectionId: { type: 'string', description: 'Unique identifier for this connection' } }, required: ['host', 'username'] } }, { name: 'ssh_exec', description: 'Execute a command on the remote server', inputSchema: { type: 'object', properties: { connectionId: { type: 'string', description: 'ID of an active SSH connection' }, command: { type: 'string', description: 'Command to execute' }, cwd: { type: 'string', description: 'Working directory for the command' }, timeout: { type: 'number', description: 'Command timeout in milliseconds' } }, required: ['connectionId', 'command'] } }, { name: 'ssh_upload_file', description: 'Upload a file to the remote server', inputSchema: { type: 'object', properties: { connectionId: { type: 'string', description: 'ID of an active SSH connection' }, localPath: { type: 'string', description: 'Path to the local file' }, remotePath: { type: 'string', description: 'Path where the file should be saved on the remote server' } }, required: ['connectionId', 'localPath', 'remotePath'] } }, { name: 'ssh_download_file', description: 'Download a file from the remote server', inputSchema: { type: 'object', properties: { connectionId: { type: 'string', description: 'ID of an active SSH connection' }, remotePath: { type: 'string', description: 'Path to the file on the remote server' }, localPath: { type: 'string', description: 'Path where the file should be saved locally' } }, required: ['connectionId', 'remotePath', 'localPath'] } }, { name: 'ssh_list_files', description: 'List files in a directory on the remote server', inputSchema: { type: 'object', properties: { connectionId: { type: 'string', description: 'ID of an active SSH connection' }, remotePath: { type: 'string', description: 'Path to the directory on the remote server' } }, required: ['connectionId', 'remotePath'] } }, { name: 'ssh_disconnect', description: 'Close an SSH connection', inputSchema: { type: 'object', properties: { connectionId: { type: 'string', description: 'ID of an active SSH connection' } }, required: ['connectionId'] } }, // Add Ubuntu tools ...ubuntuTools ] }; }); console.log("Ubuntu website management tools loaded"); }
  • Utility function executeSSHCommand used by the 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(); }); }); }); }

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/mixelpixx/SSH-MCP'

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