Skip to main content
Glama

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

Implementation Reference

  • 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
        };
      }
    }
  • 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}`);
    });
  • 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
      }));
  • 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();
          });
        });
      });
    }
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries full burden for behavioral disclosure. 'Manage' implies both read and write operations, but the description doesn't specify which actions are destructive (e.g., 'reset' likely removes all rules), authentication requirements (sudo is a parameter but not highlighted), or potential side effects. For a multi-action tool with zero annotation coverage, this is insufficient.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, efficient sentence that directly states the tool's purpose without unnecessary words. It's appropriately sized and front-loaded, earning a perfect score for conciseness.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's complexity (6 parameters including potentially destructive actions like 'reset'), no annotations, and no output schema, the description is inadequate. It doesn't explain what the tool returns, error conditions, or behavioral nuances. For a multi-action system management tool, this leaves significant gaps in understanding.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema fully documents all 6 parameters. The description adds no additional parameter semantics beyond what's in the schema. According to scoring rules, when schema coverage is high (>80%), the baseline is 3 even with no param info in the description.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description 'Manage Ubuntu Uncomplicated Firewall (UFW)' clearly states the tool's purpose as managing a specific firewall system. It identifies the resource (UFW firewall) and implies a range of management actions. However, it doesn't distinguish this tool from potential sibling firewall tools (none exist in the provided list), so it earns a 4 rather than a 5.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides no guidance on when to use this tool versus alternatives. It doesn't mention prerequisites like requiring an SSH connection, nor does it differentiate from other system management tools in the sibling list (e.g., ubuntu_nginx_control). Without any usage context or exclusions, this scores a 2.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

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