Skip to main content
Glama
JohnGilligan2

ufw-mcp

ufw-mcp: UFW-Allow mit minimalen Rechten für die VoIP-Server

Vorschlag. Nichts davon wurde auf einem Server angewendet.

Geplanter Host: ufw-mcp.example.com (entspricht itglue-mcp, proxmox-mcp, network-mcp). Separater Server von network-mcp, weil die Read-only-Garantie von network-mcp per AST erzwungen wird und das Hinzufügen eines Schreibpfads die Eigenschaft zerstört, die es sicher macht, ihn fünf Ingenieuren zu übergeben. Gleiche Trennung wie bei tactical-rmm-mcp / tactical-rmm-audit-mcp.

Der Hausbefehl, den es automatisiert

Laut Dan, und in der Shell-Historie bestätigt, zwei Regeln pro Adresse:

sudo ufw allow from <ip> to any port 5060 proto tcp
sudo ufw allow from <ip> to any port 5060 proto udp

In großen Mengen über die Bereiche eines Carriers durchgeführt, dann verifiziert mit ufw status | grep 5060 | grep -c tcp / -c udp. Das Tool entspricht dieser Form: Der Wrapper behandelt EINE Adresse (damit der privilegierte Code klein bleibt), das MCP-Tool loopt für Massenoperationen und gibt die Vorher/Nachher-Zähler auf dieselbe Weise zurück.

Related MCP server: toolfence

Was das Tool gegenüber dem Tippen des Befehls hinzufügt

Es verweigert, wenn das Allow stillschweigend nichts bewirken würde.

UFW funktioniert nach dem Prinzip „erster Treffer gewinnt“ und ufw allow HÄNGT an. Auf diesen Servern gibt es ~3.600 Regeln, von denen ~2.150 DENY-Einträge die obersten Positionen belegen. Wenn die Adresse also bereits abgelehnt wird, landet das Allow darunter, der Befehl wird erfolgreich ausgeführt, die Regel erscheint in ufw status, und kein Paket kommt jemals durch.

Das ist nicht hypothetisch. Live gefunden am 2026-08-17, schreibgeschützt:

core1   [2145] DENY IN 198.51.100.36   # FraudWatch 2026-07-15 example-isp-NY /32
            [3371] 5060/tcp ALLOW IN 198.51.100.36     <- dead
            [3372] 5060/udp ALLOW IN 198.51.100.36     <- dead

core2   [2145] DENY IN 198.51.100.36   # FraudWatch 2026-07-15 example-isp-NY /32
            [2150] DENY IN 198.51.100.42
            [2914] 5060/tcp ALLOW IN 198.51.100.42     <- dead
            [2915] 5060/udp ALLOW IN 198.51.100.42     <- dead
            [3440] 5060/tcp ALLOW IN 198.51.100.36     <- dead

198.51.100.42 ist außerdem inkonsistent über die beiden Kerne: funktioniert auf core1, tot auf core2. Dieser Kunde würde sich als intermittierend darstellen.

Der Wrapper erkennt dies und beendet sich mit Exit-Code 4 und der betreffenden Zeile, anstatt Erfolg zu melden. Ein Argument override-deny existiert, um OBERHALB des Deny einzufügen, aber es ist bewusst nicht die Standardeinstellung: Eine Betrugssperre zu überstimmen sollte eine Entscheidung sein, kein Nebeneffekt.

Audit: Wer hat was hinzugefügt oder widerrufen

Drei Ebenen, alle an die Entra-Identität aus dem validierten JWT gebunden, niemals an ein Argument, das der Aufrufer liefert. Das ist die Eigenschaft, die die Spur vertrauenswürdig macht: Sie ist signaturgeprüft, nicht selbst deklariert. network-mcp macht das bereits in server.py::_actor() und derselbe Code wird übernommen.

  1. In der Regel selbst. comment "mcp by:approver@example.com <ts>". Die Audit-Information lebt im Artefakt, sodass ufw status dauerhaft benennt, wer jede Regel hinzugefügt hat, ohne dass ein Log korreliert werden muss, sichtbar für jeden auf dem Rechner, der noch nie vom MCP-Server gehört hat.

  2. Auf dem VoIP-Server. logger -t ufw-mcp schreibt in das Syslog dieser Maschine, sodass der Datensatz dort existiert, wo die Änderung passiert ist.

  3. Auf dem MCP-Server. Eine nur-anhängbare Audit-Datei mit Aufrufer, Aktion, Ziel, Host und Ergebnis. Sie muss auf einem benannten Volume liegen, sonst löscht ein Portainer-Redeploy sie, was hier eine echte Falle ist, da Push-to-Deploy den Container neu aufbaut.

Entra-Anmeldeprotokolle sind eine vierte, unabhängige Aufzeichnung darüber, wer sich authentifiziert hat.

Revoke wird identisch protokolliert, und ufw-mcp-revoke entfernt nur Regeln mit dem Tag mcp by:, sodass es physisch keinen APIBAN- oder FraudWatch-Eintrag löschen kann.

Minimale Rechte auf dem Rechner

Das Konto ist KEIN Superuser. Es ist ein normaler Benutzer, der eine privilegierte Aktion ausführen darf:

sudo useradd --create-home --shell /bin/bash --comment 'ufw allow automation' nocufw

Kein -G sudo, keine zusätzlichen Gruppen. Dann visudo -f /etc/sudoers.d/ufw-mcp:

Cmnd_Alias UFW_MCP = /usr/local/sbin/ufw-mcp-allow, \
                     /usr/local/sbin/ufw-mcp-revoke, \
                     /usr/local/sbin/ufw-mcp-list
nocufw ALL=(root) NOPASSWD: UFW_MCP
Defaults!UFW_MCP !requiretty

Niemals NOPASSWD: /usr/sbin/ufw *. ufw hat auch reset, disable und delete, und sudoers-Argument-Wildcards sind routinemäßig umgehbar. Die Sicherheitsgrenze ist das SKRIPT; sudoers entscheidet nur, welches Binary.

Die Falle, die daraus ein Root-Konto macht: Der Wrapper muss root gehören und nicht von nocufw beschreibbar sein, und auch nicht in einem Verzeichnis liegen, das dieser beschreiben kann. Installation mit install -o root -g root -m 0755. Überprüfen Sie die gesamte Berechtigung mit sudo -l -U nocufw auf beiden Servern.

Es braucht eine echte Shell, anders als das Relay-Konto, weil das MCP-Tool sudo ufw-mcp-allow ... über SSH ausführt und OpenSSH Remote-Befehle über die Shell des Benutzers ausführt. Die Shell ist nicht das Privileg; die sudoers-Zeile ist es.

apiban2ufw.sh: gelesen am 2026-08-17, und es ändert eine Sache

Läuft alle 4 Minuten aus /etc/cron.d/ns_apiban, als root.

Die gute Nachricht: Es leert oder überschreibt nichts. Es vergleicht den Feed mit ufw status | grep APIBAN | grep DENY, berücksichtigt also nur Regeln mit seinem eigenen Kommentar. Es fügt die Differenz hinzu und entfernt Feed-Einträge, die weggefallen sind. Unsere ALLOW-Regeln sind für ihn unsichtbar und können nicht überschrieben werden. Die Sorge um die Ausschlussliste war unbegründet, und das Konto-/sudoers-Design bleibt unverändert.

Das Entscheidende: Es fügt hinzu mit

/usr/sbin/ufw insert 1 deny from $line to any comment "From APIBAN $dateVar"

insert 1, nicht append. Also setzt APIBAN alle vier Minuten neue Deny-Regeln an die SPITZE. Das bedeutet, dass „unser Allow an Position 1 einfügen“ keine dauerhafte Position ist: Es steht über allem, was zum Zeitpunkt des Schreibens existiert, und unter allem, was APIBAN danach hinzufügt.

Konsequenz, und der Wrapper sagt das jetzt laut aus:

  • Deny kam von APIBAN -> das Einfügen eines Allow darüber funktioniert, bis apiban.org die Adresse erneut listet, dann bricht es still. Die dauerhafte Lösung liegt upstream im Feed, nicht in UFW.

  • Deny ist manuell / FraudWatch -> das Einfügen darüber ist dauerhaft, weil nichts es erneut hinzufügt.

Beide example-isp-NY-Denys sind FraudWatch, nicht APIBAN, also sind das die dauerhaften Fälle.

Ein latenter Bug, den man kennen sollte, aber heute nicht von uns zu beheben: remove_ips_ufw löscht nach Regelspezifikation (ufw delete deny from $line/32), nicht nach Kommentar. Wenn eine Adresse jemals sowohl im APIBAN-Feed als auch in einem manuellen Deny auftaucht, könnte eine Feed-Entfernung stattdessen die manuelle Regel löschen.

Noch offen vor dem Bau

  1. Entscheiden, ob das Entfernen einer Betrugssperre im Umfang liegt. Das Hinzufügen eines eingeschränkten Allow und das Löschen eines FraudWatch-DENY sind unterschiedliche Privilegien. Empfehlung: Das Tool wird nur mit Allow + Revoke-eigener-Regeln ausgeliefert, und das Entsperren einer betrugsblockierten Adresse bleibt manuell oder bekommt eine eigene strengere Gruppe.

  2. Die fünf toten Regeln oben von Hand korrigieren, unabhängig von diesem Projekt.

Revoke entfernt, 2026-08-18

Johns Entscheidung, passend zu Alices Bedenken im Design-Meeting, dass ein Benutzer der ersten Ebene eine SIP-Trunk- oder Inteliquent-Adresse entfernen könnte. Auf BEIDEN Ebenen entfernt, denn nur das Tool zu entfernen würde das Privileg bestehen lassen:

  • kein ufw_revoke_ip-Tool, und ufw.py hat keine REVOKE-Konstante, sodass der Ausführende diesen Pfad physisch nicht ausführen kann

  • die sudoers-Berechtigung auf beiden Switches ist auf ufw-mcp-allow und ufw-mcp-list eingeschränkt

  • /usr/local/sbin/ufw-mcp-revoke von beiden Switches gelöscht

Nach der Änderung verifiziert: sudo -l -U nocufw listet zwei Pfade, das Aufrufen des Revoke-Wrappers als nocufw wird verweigert, und Allow/List funktionieren weiterhin.

tests/test_no_revoke.py schlägt fehl, wenn das Tool oder die Konstante zurückkommt, sodass das Wiederaktivieren eine bewusste Handlung ist. Es richtig zu machen bedeutet, alle vier wiederherzustellen: Konstante, Tool, sudoers-Eintrag, Wrapper-Datei.

F
license - not found
Not graded
quality - not tested
C
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

  • A
    license
    Not graded
    quality
    C
    maintenance
    Governance engine for MCP tool calls, providing deterministic rule enforcement to block destructive actions like SQL drops, shell commands, and file system modifications before execution.
    2
    Apache 2.0
  • A
    license
    Not graded
    quality
    A
    maintenance
    A local, fail-closed firewall for MCP tool calls that enforces least-privilege policies and human approval between AI agents and stdio MCP servers.
    7
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    Enforces deterministic security policies as an inline firewall for MCP server tool calls, with AST-based validation, cryptographic audit logging, and CLI-based evaluation and verification.
    MIT

View all related MCP servers

Related MCP Connectors

View all MCP Connectors

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/JohnGilligan2/ufw-mcp'

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