There has been some activity lately regarding how to set up a non-admin account with access to Windows event logs. Here is my understanding of the situation, based on the comments here and some testing that I have done:
In order to prevent the "WBEM_E_ACCESS_DENIED" error when using a nonprivileged account to access event logs, you must do one of two things...
...unless you specify, within the code ($ZENHOME/Products/ZenWin/zeneventlog.py), that only the specific event logs you've allowed access to are included:
wql = """SELECT * FROM __InstanceCreationEvent where """\
"""TargetInstance ISA 'Win32_NTLogEvent' """\
"""and TargetInstance.EventType <= %d"""\
"""and (TargetInstance.LogFile = 'Application' OR TargetInstance.LogFile = 'System')"""\
It would be great if there were some way to phrase the query such that only the events a user has access to are displayed. Unfortunately, I can't tell from the documented properties how exactly to do that. Ideally, the WMI provider itself should return only entries to which you have access... but that's not how it behaves. So, we're forced to either grant read access to all logs or restrict what Zenoss queries.
I plan to play around with the WQL and see if there's some way to modify the query beyond just specifying "Application" and "System". I'm sure there are plenty of people that like to monitor other logs (DNS Server, File Replication Service, etc) that it's not worthwhile to place an arbitrary restriction in the Zenoss core code itself.
Here's an idea: what if there were a zProperty added that allowed you to specify which event logs Zenoss would attempt to hook? Perhaps set the default options to 'Application', 'Security', and 'System', and then on an individual device determine the available options by doing a query against Win32_NTEventlogFile.LogfileName and populating a listbox. That way, administrators could grant the permissions required (via GPO or otherwise) and then make selections per-device as needed.
I'm still trying to build up my Zenpack creation knowledge, so I don't know how difficult it would be to do this, or even if it is possible to modify code purely via ZenPack. Feedback appreciated.
I'm pretty sure that to support differing security levels by log you'd have to test the access rights for each log then build a precise eventh query based on the results. I don't think you can craft the query itself. Microsoft assumed you'd want to know if there was an access failure in the query.
It's an interesting problem deciding how to approach all this. There's lots of different cases, and how you should handle all the different situations is open to debate. For example, if you expect to have access to the application log and don't, should you process events from the system log only, silently? Or should you create an event and fail everything? Different people make different choices, and I'm sure we've all seen them all!
It's true that everybody will have different expectations for the desired outcome.
In my case it is to modify Zenoss to only read the desired event logs which I have selected/scripted. Anything else can be ignored regardless of the granted access to the log or not.
At the moment, the way it works is each different event log has to have its security access modified for the zenoss user to access it. If you miss out on one, the ZenEventlog fails and you got none of the eventlogs. Now to me, this is not logical. Why miss out on everything, just because one log is not set.
Zenoss should be able to ignore the event logs it doesn't have access to, and if it can't do that, it should be able to specify which event logs it can read.
makes sense no?
Unfortunately, the true problem does not lie with Zenoss, it lies in Microsoft's implementation of __InstanceCreationEvent. You get the same "access denied" behavior whether you run the notification query in Zenoss or via VBScript or via wbemtest.
That's why I suggested what I did in the OP. I'll elaborate a bit more: what if another parameter was added to the method that executes the notification query in zeneventlog, so that instead of having to edit the code and add the extra criterion to the WHERE clause, you can specify it via a zProperty? I plan to test that a bit today. The behavior should be that the default "hook everything" is attempted unless the zEventlogFilter property is set (in which case the contents of that property are added to the end of the WQL).
So, for example, setting zEventlogFilter to "AND (TargetInstance.LogfileName = 'Application' OR TargetInstance.LogfileName = 'System')" would add that filter to the WQL, which would only hook those two logs. In my own use case, I would set that on /Devices/Windows and then make an adjustment to /Devices/Windows/Domain Controllers to also grab the File Replication Service and DNS Server logs.
Okay, I've modified the code as follows:
Restart zenoss and it now only pulls Application and System event logs from Windows servers.
If you want to add additional logs (in my case, NTDS, DNS, and FRS on domain controllers), just modify the filter in the desired device class through the UI:
zWinEventlogFilter = AND (TargetInstance.LogFile = 'Application' OR TargetInstance.LogFile = 'System' OR TargetInstance.LogFile = 'Directory Service'' OR TargetInstance.LogFile = 'DNS Server' OR TargetInstance.LogFile = 'File Replication Service')
I hope this helps anyone seeking the same goal as me: granting a non-administrator Zenoss service account access to Windows event logs without having to touch every single server that you want to monitor. With the above modifications, I can now create Group Policy objects that will grant the service account read access to App and System on all of my member servers, and all of the AD/DNS logs on my domain controllers. If anyone is interested, I'll post how to do that as well.
Message was edited by: felbane Worked out the solution on my own, revising post with details.
Count me out, I'm just a simple end user....
thanks for going into detail.
If I understand correctly, what you need is to reprgoam the Zenventlog deamon or perhaps not use it at all and create a subsitute one....
Well, not so much 'reprogram' as 'give it a shove in the right direction'. All I'm trying to achieve here is adding another zProperty and then use it as a variable in the zeneventlog collector. Shouldn't be terribly difficult, but I'm not familiar enough with the inner workings yet to be able to get it perfect on the first try.
Edited my post above with the solution (at least, the one that works for me).
I'm going to see about filing this as a feature request for future versions of Zenoss. I'm sure there are some tweaks that the dev team will come up with that I haven't, but I think this is a useful feature for any Core/Community installation.
Let's hope someone form the Zenoss Team reads this post and kindly gets one of their colleagues or themselves to respond.
Follow Us On Twitter »
||Latest from the Zenoss Blog »||Community||Products||Services||Customers||About Us|
Copyright © 2005-2011 Zenoss, Inc.