urllib.error.HTTPError: HTTP Error 403: Forbidden

Hello, I am trying to obtain the disconnection and connection data in json format from icingaweb 2 (installed in debian 10) through a python code, for later it works with that data but when executing the code it gives me this error: urllib.error .HTTPError: HTTP Error 403: Forbidden, I leave you my code so that you can guide me.

from urllib.request import Request, urlopen

import json

req = Request(‘http://localhost/icingaweb2/monitoring/list/eventhistory?timestamp>=-7%20days’, headers={‘User-Agent’: ‘Mozilla/5.0’})

response = urlopen(req).read()

data = json.loads(response.read())

1 Like

What does your API user config look like? Don’t forget to redact the password

Specifically, I want to see the API perms.

Usually located in /etc/icinga2/conf.d/api-users.conf

I would also verify that it’s not something silly like putting the creds in twice and mis-typing the creds to one of your calls.

PS, you can format your code with triple back-ticks. See this post for some formatting tips

As this is a request against the webinterface the API users for the core don’t come into play here.

There should be some form of authentication to query the eventhistory (or anything) via the webinterface, which I don’t see in your code.

1 Like

this is what I have configured so far in the document you mentioned:

object ApiUser “director” {
password = “some-password”
permissions = [ “" ]
}
object ApiUser “icingaweb2” {
password = “hello:)”
permissions = [ “status/query”, "actions/
”, “objects/modify/", "objects/query/” ]
}

Oh no, redact that password!

Assuming you are using the “icingaweb2” API user, you need the events/ permission to hit this endpoint I do believe:
http://localhost/icingaweb2/monitoring/list/eventhistory?timestamp>=-7%20days

And how can I generate a new password or reset the created object so that everything is well established, I just realized that I did it wrong hehe

You simply just change the password string in the config file to whatever you want. Just make sure you keep it enclosed with quotes.

I retested my python script and I still don’t get the json data: /

Even with the events/ permission?

It might need a wild card like events/* – if that doesn’t work, we could do a quick test and assign “all permissions” (just a simple wildcard as shown below):

object ApiUser “icingaweb2” {
password = “thisismypassword”
permissions = [ “*” ]
}

If that works, great, then you can start with individual endpoint permissions, otherwise something else might be wrong (ie, typo in the creds for the api call).

Oh, after adding/changing the permissions, you will want to reload the Icinga2 configs.

None of that works :(, and according to me the call to the api is fine, isn’t there a way to create a new root object with a new password and use it for the api?

Yes!

In the api-users.conf file, just create a new object:

object ApiUser “root” {
password = “secret”
permissions = [ “*” ]
}

Be sure and change that password.
As always, reload Icinga2
systemctl reload icinga2 or systemctl restart icinga2

But if you tried adding all permissions to the icingaweb2 api user, and reloaded, and still get the error, then your creds are probably wrong in the script.

Not really related, but I have a plug for the icinga2apic library for Python. This could help clean up the script a little and is a pretty straight forward Python3 client for Icinga2

I’ll quote myself again :wink:
You are currently querying the Icinga Web 2 webinterface and not the Icinga2 Core API. So the API user doesn’t come into play here (or brutally speaking: it is useless for your scenario).

Try the query with your user you log into the webinterface with (maybe the default admin icingaadmin?).

If you instead want to run queries against the core API (https://localhost:5665/v1/…), for which that user and the permissions are needed (as @steaksauce already explained):
See the API docs for more information and a step-by-step explanation.

Ooofff… It was so obvious (I thought you meant he was querying with a web user to the API), but I now notice that the URL in the request doesn’t have the API port :man_facepalming:

Friend, I am not very clear about the first thing, then how would the query (url) be with the user with whom I log in?thanks

I have never used a script to query anything from the webinterface, but the URL in the webinterface for the json ouput of the last events is
image
image

So add a &format=json to your url and try again. And use your user you log into the webinterface with, not the API users.

I also tried that url but it didn’t work :(, I’m thinking it’s a problem with the icinga configuration when installing it

I have tried one of the url that appears in the api section of the icinga documentation and add it to my script, since I tried in different ways but I kept getting using the aforementioned error, when adding the new url below I got the error:

urllib.error.URLError: <urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: self signed certificate in certificate chain (_ssl.c:1131)>

Does anyone know what this error is due to? I read that it was related to obtaining an SSL certificate.

My script:

#import urllib.request, json

from urllib.request import Request, urlopen

url = “https://localhost:5665/v1/objects/hosts?hosts=first-host&hosts=second-host

#response = urllib.request.urlopen(url)

#data = json.loads(response.read())

#print (data)

req = Request(url)

data = urlopen(req).read()

print (data)

This is a urllib python package error, not directly related to Icinga. You would likely encounter this making an API call to any URL that has a self-signed cert. Places like this stack overflow post would be the best bet for a work around.

I think the requests package just gives you a warning when you make a call like this – the warning shows in the output, but doesn’t prevent you from making the call. Of course, that package has it’s own ways around the warning.