It's been well over a year since I wrote the original "Let's Encrypt with FortiGate", and while my mediocre python code proved popular, many others have gone on to implement it in their environment. I'll say it again, I am not a coder, I am just a guy who thought it would be neat to automate this, and I would be very interested to see your implementations.
This article is a result of Hendrik reaching out to me. Hendrik essentially outlined the problem for me:
"Let's Encrypt with FortiGate works well on my non-VDOM FGTs, however on multi-VDOM setups, then I get a 403 error when setting the admin-server-cert parameter.".
Well Hendrik, thanks to you I decided to lab this up.
Assumptions:
You have access to FNDN - If not get in touch with your account team to get access. This is not required to do what we're doing in this article, but it provides access to the FortiOS API, which can be very handy
FortiGate is running 6.2.x or above - this will probably work on 6.0.x (as the endpoint is the same) but has not been tested
You've already created an admin profile for your REST user
For this Scenario I used Postman to test the JSON/API calls, it's just cleaner when I need to understand what the JSON/URL need to look like
Ok, with the boring stuff out of the way, let's get to it!
To replicate Hendrik's issue we will be using this API endpoint:
api/v2/cmdb/system/global?access_token=xxxxx
So your request URL should look something like this:
https://<fortigate_IP_or_FQDN>:port/api/v2/cmdb/system/global?access_token=xxxxxx
The JSON we're using is very simple:
{
"admin-server-cert": "cert_name"
}
Don't forget to set your method to 'PUT' which essentially means "Update this resource with the following - JSON - Values". I am sure there's a better explanation, but you're getting front row seats to my mind.
The request receives the following response:
{
"http_method": "PUT",
"status": "error",
"http_status": 403,
"vdom": "uv-office",
"path": "system",
"name": "global",
"serial": "FGXXXXXXXXXXX",
"version": "v6.4.3",
"build": 1778
}
Well shoot. I should be getting something with a "success" status and a code 200.
Time to take a deeper look, after doing some digging and discussing with a peer, I decided to get a debug going on the httpsd process with the following commands:
diag debug application httpsd -1
diag debug enable
And we got the following output:
BOOM! There it is, the user we created for REST doesn't have access to the system.global endpoint, causing the 403 error.
I could go into a long article on how permissions change a bit when you go to multi-vdom setups, but that's a whole other series of articles. Let's just settle for the fact that, this user doesn't have access to Global settings (settings that will be the same no matter what, like what SSL cert to use for the web UI). And it's not readily available in the GUI when you create the new admin profile, because it really is bad practice to apply "super_admin" access to every user.
So, what do we do?
We make the rest API's admin profile global!
How do we do that you say?
The CLI!
Ok, ok, I am way too excited over this. But simply put we just need to go to the admin profile in the CLI and set the scope of the admin profile to global:
config global
config system accprofile
edit "rest_super"
set scope global
set sysgrp custom
config sysgrp-permission
set admin read-write
set upd read-write
set cfg read-write
set mnt read-write
end
next
end
end
And that's it!!!
After trying that, I was able to get the following result:
{
"http_method": "PUT",
"revision": "ommitted",
"revision_changed": false,
"status": "success",
"http_status": 200,
"vdom": "uv-office",
"path": "system",
"name": "global",
"serial": "FGxxxxxxxxxxx",
"version": "v6.4.3",
"build": 1778
}
Big thanks to Hendrik, James, and Tri. Thank you all for reading, I hope this helps.
Σχόλια