Zum Inhalt springen
>_marc-oltersdorf.de

FortiManager-API per PowerShell: Fehler -11 „No permission for the resource“ trotz gültigem Token

Marc Oltersdorf 3 Min. Lesezeit

Der FortiManager lehnte jede JSON-RPC-Anfrage mit Fehler -11 („No permission for the resource“) ab, obwohl der API-Benutzer volle Rechte und einen passenden Trusted Host hatte. Windows PowerShell 5.1 schickte die Anfragen über den System-Proxy, vermutlich sah der FortiManager deshalb eine fremde Quelladresse. Mit abgeschaltetem Proxy lief dieselbe Anfrage sofort.

$ git log --graph Der Weg zur Lösung

  1. Problem Jede Anfrage endet mit Fehler -11

    Der FortiManager antwortet auf alle JSON-RPC-Aufrufe mit „No permission for the resource“, selbst auf /sys/status.

  2. Versuch Rechte hochgesetzt

    Profil Super_User, alle ADOMs, JSON-API-Zugriff Read-Write und Trusted Host mit dem passenden Netz. Keine Änderung.

  3. Irrweg Token mehrfach neu erzeugt

    Ein neues Token änderte nichts. Auch die Prüfung des gespeicherten Tokens brachte keinen Fehler zutage.

  4. Erkenntnis Benutzer fehlt im Event Log

    Die Anfragen tauchen im Log nicht unter dem API-Benutzer auf: Er wird gar nicht erkannt, die Anmeldung kommt nicht zustande.

  5. Erkenntnis Anfrage ohne Modul nachgestellt

    Mit einem minimalen Invoke-RestMethod gab es denselben Fehler. Das eigene Skript war damit als Ursache ausgeschlossen.

  6. Lösung System-Proxy abgeschaltet

    Mit DefaultWebProxy = $null lief dieselbe Anfrage sofort. Der FortiManager sah vermutlich die Adresse des Proxys, die nicht zum Trusted Host gehörte.

Ich wollte den FortiManager (Version 7.4) aus Windows PowerShell 5.1 über die JSON-RPC-Schnittstelle ansprechen, mit einem API-Benutzer und seinem Token. Jede Anfrage endete mit demselben Fehler, selbst eine harmlose Abfrage wie /sys/status:

{
    "id":  1,
    "result":  [
        {
            "status":  { "code": -11, "message": "No permission for the resource" },
            "url":  "/sys/status"
        }
    ]
}

Der Fehlertext legt Rechte als Ursache nahe. Das war hier die falsche Fährte.

Das Problem

Der API-Benutzer war so angelegt, wie es die Dokumentation für Token-Anmeldung beschreibt:

config system admin user
    edit "api-benutzer"
        set trusthost1 netz 255.255.255.0
        set profileid "Super_User"
        set user_type api
        set rpc-permit read-write
    next
end

Der Rechner, von dem die Anfrage kam, lag im eingetragenen Netz. Trotzdem kam bei jedem Aufruf Fehler -11. Auffällig war: Im Event Log des FortiManagers tauchte der API-Benutzer bei den Versuchen gar nicht auf. Der FortiManager hat die Anfrage also nicht als diesen Benutzer erkannt, sondern wie eine Anfrage ohne Anmeldung behandelt.

Die Lösung

Windows PowerShell 5.1 schickt Web-Anfragen automatisch über den im System eingestellten Proxy. Der FortiManager hat dann vermutlich die Adresse des Proxys als Quelle gesehen, und die gehörte nicht zum Trusted Host. Ohne Proxy lief dieselbe Anfrage durch.

Zum Prüfen lässt sich die Anfrage ohne irgendein Modul absetzen. Das Token wird beim Eintippen abgefragt, damit es nicht im Verlauf der Konsole landet:

[System.Net.WebRequest]::DefaultWebProxy = $null
$t = Read-Host "Token"
$h = @{ Authorization = "Bearer $t" }
$b = '{"id":1,"method":"get","params":[{"url":"/sys/status"}]}'
$u = "https://fortimanager/jsonrpc"
[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::Tls12
[System.Net.ServicePointManager]::ServerCertificateValidationCallback = { $true }
Invoke-RestMethod -Uri $u -Method Post -Headers $h -ContentType 'application/json' -Body $b | ConvertTo-Json -Depth 5
[System.Net.ServicePointManager]::ServerCertificateValidationCallback = $null
Remove-Variable t, h

Ohne die erste Zeile (DefaultWebProxy = $null) kam bei mir Fehler -11, mit ihr die Antwort mit den Statusdaten. Für ein eigenes Skript gehört der Proxy nur für die Dauer des Aufrufs ausgeschaltet und danach wieder auf den alten Wert gesetzt:

$proxyAlt = [System.Net.WebRequest]::DefaultWebProxy
[System.Net.WebRequest]::DefaultWebProxy = $null
try {
    $antwort = Invoke-RestMethod -Uri $u -Method Post -Headers $h -ContentType 'application/json' -Body $b
} finally {
    [System.Net.WebRequest]::DefaultWebProxy = $proxyAlt
}

So lief auch mein Modul mit dem Aufruf einer ADOM-Abfrage durch. Die Antwort enthielt danach die erwarteten Objektdaten.

Warum das funktioniert

Ein API-Benutzer vom Typ api darf sich nur von den eingetragenen Trusted Hosts anmelden. Kommt die Anfrage von einer anderen Adresse, lehnt der FortiManager sie ab. Dass der Benutzer im Event Log fehlt, passt dazu: Er wird gar nicht erst erkannt. Die Fehlermeldung „No permission for the resource“ klingt nach fehlenden Rechten, kann hier aber auch bedeuten, dass die Anmeldung nicht zustande kam.

Stolperfallen

  • Rechte sind es nicht. Ich habe zuerst das Profil auf Super_User mit allen ADOMs gestellt und die JSON-API-Zugriffsstufe auf Read-Write. Das änderte nichts.
  • Token neu erzeugen half ebenfalls nicht, ist aber ein sinnvoller Zwischenschritt, falls das gespeicherte Token falsch kopiert wurde (Leerzeichen am Ende).
  • Token im Kopf, nicht in der Adresse. Seit FortiManager 7.2.2 geht Authorization: Bearer <Token>. Das Anhängen als ?access_token=… soll laut Fortinet-Community ab 7.4.7 und 7.6.2 nicht mehr funktionieren. Das habe ich nur nachgelesen, nicht selbst getestet.
  • Leerzeichen in Objektnamen (z. B. eine Adressgruppe mit Leerzeichen im Namen) gehören unverändert in den Pfad im JSON-Text, nicht URL-kodiert. Der Pfad steht im Body der Anfrage und nicht in der Web-Adresse.
  • PowerShell 7: Dort sollte statt der globalen Einstellung der Parameter -NoProxy an Invoke-RestMethod genügen. Das habe ich nicht ausprobiert.
  • Umlaute: Windows PowerShell 5.1 liest Antworten ohne Zeichensatz-Angabe als Latin-1. Ein Kommentarfeld mit „für“ kam als „für“ an. Ich habe das Lesen auf UTF-8 umgestellt, den Erfolg aber noch nicht bestätigt.

Hat dir das geholfen?

RSS abonnieren

$ ls ../ Passt dazu