Add OU discovery to samba monitoring

GLPI #47623
tags/zabbix-agent-addons-0.2.139-1
Daniel Berteaud 4 years ago
parent 4dedf3dc30
commit 1c2c4e8377
  1. 6
      zabbix_conf/samba_dc.conf
  2. 231
      zabbix_scripts/check_samba_dc_sudo
  3. 34
      zabbix_scripts/disco_samba_dc_sudo
  4. 47
      zabbix_templates/Template_App_Samba_DC.xml

@ -1,3 +1,7 @@
UserParameter=samba_dc.discovery[*],sudo /var/lib/zabbix/bin/disco_samba_dc_sudo --what='$1'
# Create a text item with key samba_dc.info[300] and a check interval of 300 # Create a text item with key samba_dc.info[300] and a check interval of 300
# Then use dependent item to get individual counters # Then use dependent item to get individual counters
UserParameter=samba_dc.info[*],sudo /var/lib/zabbix/bin/check_samba_dc_sudo --since=$1 UserParameter=samba_dc.info[*],sudo /var/lib/zabbix/bin/check_samba_dc_sudo --since='$1'
# Create a text item with key samba_dc.ou[{#SAMBA_OU}], then use dependant items with JSONPath to get individual info
UserParameter=samba_dc.ou[*],sudo /var/lib/zabbix/bin/check_samba_dc_sudo --ou='$1'

@ -13,6 +13,9 @@ my $pdbedit = which('pdbedit');
# Number of seconds in the past to count authentications # Number of seconds in the past to count authentications
my $since = 300; my $since = 300;
my $pretty = 0; my $pretty = 0;
my $general = 1;
my $ou = undef;
# This log is expected to be in JSON format. For example, in smb.conf : # This log is expected to be in JSON format. For example, in smb.conf :
# log level = 1 auth_audit:3 auth_json_audit:4@/var/log/samba/audit_auth.log # log level = 1 auth_audit:3 auth_json_audit:4@/var/log/samba/audit_auth.log
my $audit_auth_log = '/var/log/samba/audit_auth.log'; my $audit_auth_log = '/var/log/samba/audit_auth.log';
@ -25,132 +28,150 @@ if (not defined $samba_tool or not defined $pdbedit){
GetOptions( GetOptions(
'pretty' => \$pretty, 'pretty' => \$pretty,
'since=i' => \$since, 'since=i' => \$since,
'audit-auth-log=s' => \$audit_auth_log 'audit-auth-log=s' => \$audit_auth_log,
'general' => \$general,
'ou=s' => \$ou
); );
if ($since !~ m/^\d+$/){ if ($since !~ m/^\d+$/){
die "Invalid value for since\n"; die "Invalid value for since\n";
} }
my $json = { my $json = {};
accounts => {
users => 0, if (defined $ou){
inactive_users => 0, $json = {
active_users => 0, objects => 0
groups => 0, };
computers => 0 if ($ou !~ m/^(?<RDN>(?<Key>(?:\\[0-9A-Fa-f]{2}|\\\[^=\,\\]|[^=\,\\]+)+)\=(?<Value>(?:\\[0-9A-Fa-f]{2}|\\\[^=\,\\]|[^=\,\\]+)+))(?:\s*\,\s*(?<RDN>(?<Key>(?:\\[0-9A-Fa-f]{2}|\\\[^=\,\\]|[^=\,\\]+)+)\=(?<Value>(?:\\[0-9A-Fa-f]{2}|\\\[^=\,\\]|[^=\,\\]+)+)))*$/){
}, die "Invalid OU\n";
replication => 'UNKNWON', }
processes => { foreach (qx($samba_tool ou listobjects '$ou')){
cldap_server => 0, die "Error while counting objects of OU $ou\n" if ($? != 0);
kccsrv => 0, chomp;
dreplsrv => 0, $json->{objects}++;
ldap_server => 0, }
kdc_server => 0, } elsif ($general){
dnsupdate => 0, $json = {
'notify-daemon' => 0, accounts => {
rpc_server => 0, users => 0,
winbind_server => 0, inactive_users => 0,
nbt_server => 0, active_users => 0,
dnssrv => 0, groups => 0,
samba => 0, computers => 0
},
gpo => 0,
ou => 0,
activity => {
authentications => {
users => {
success => 0,
failure => 0
},
computers => {
success => 0,
failure => 0
}
}, },
authorizations => { replication => 'UNKNWON',
users => 0, processes => {
computers => 0 cldap_server => 0,
kccsrv => 0,
dreplsrv => 0,
ldap_server => 0,
kdc_server => 0,
dnsupdate => 0,
'notify-daemon' => 0,
rpc_server => 0,
winbind_server => 0,
nbt_server => 0,
dnssrv => 0,
samba => 0,
}, },
since => $since gpo => 0,
} ou => 0,
}; activity => {
authentications => {
# Get the numbers of users. pdbedit is prefered here because we can users => {
# differentiate active and inactive users, which samba-tool can't do success => 0,
# While at it, also get the computers failure => 0
foreach (qx($pdbedit -L -v)){ },
next unless (m/^Account Flags:\s+\[(.*)\]/); computers => {
my $flags = $1; success => 0,
if ($flags =~ m/U/){ failure => 0
$json->{accounts}->{users}++; }
if ($flags =~ m/D/){ },
$json->{accounts}->{inactive_users}++; authorizations => {
} else { users => 0,
$json->{accounts}->{active_users}++; computers => 0
},
since => $since
}
};
# Get the numbers of users. pdbedit is prefered here because we can
# differentiate active and inactive users, which samba-tool can't do
# While at it, also get the computers
foreach (qx($pdbedit -L -v)){
next unless (m/^Account Flags:\s+\[(.*)\]/);
my $flags = $1;
if ($flags =~ m/U/){
$json->{accounts}->{users}++;
if ($flags =~ m/D/){
$json->{accounts}->{inactive_users}++;
} else {
$json->{accounts}->{active_users}++;
}
} elsif ($flags =~ m/W/){
$json->{accounts}->{computers}++;
} }
} elsif ($flags =~ m/W/){
$json->{accounts}->{computers}++;
} }
}
# Now count groups # Now count groups
foreach (qx($samba_tool group list)){ foreach (qx($samba_tool group list)){
$json->{accounts}->{groups}++; $json->{accounts}->{groups}++;
} }
# Get replication status # Get replication status
# We want just a quick summary, so only output the first line # We want just a quick summary, so only output the first line
# manual checks will be needed to get the details, but if this field doesn't contains [ALL GOOD], # manual checks will be needed to get the details, but if this field doesn't contains [ALL GOOD],
# then something is probably wrong # then something is probably wrong
$json->{replication} = (split(/\n/, qx($samba_tool drs showrepl --summary)))[0]; $json->{replication} = (split(/\n/, qx($samba_tool drs showrepl --summary)))[0];
# Get the list of workers # Get the list of workers
foreach (qx($samba_tool processes)){ foreach (qx($samba_tool processes)){
if (/^([^\(\s]+).+\d+$/){ if (/^([^\(\s]+).+\d+$/){
$json->{processes}->{$1}++; $json->{processes}->{$1}++;
}
} }
}
# Get the number of GPO # Get the number of GPO
foreach (qx($samba_tool gpo listall)){ foreach (qx($samba_tool gpo listall)){
next unless (/^GPO/); next unless (/^GPO/);
$json->{gpo}++; $json->{gpo}++;
} }
# Get the number of OU # Get the number of OU
foreach (qx($samba_tool ou list)){ foreach (qx($samba_tool ou list)){
$json->{ou}++; $json->{ou}++;
} }
if (-e $audit_auth_log){ if (-e $audit_auth_log){
open (my $auth_log, '<', $audit_auth_log) or die "Couldn't open $audit_auth_log : $!\n"; open (my $auth_log, '<', $audit_auth_log) or die "Couldn't open $audit_auth_log : $!\n";
foreach my $line (<$auth_log>){ foreach my $line (<$auth_log>){
my $event = from_json($line); my $event = from_json($line);
my $type = $event->{type}; my $type = $event->{type};
# We're only interested in Authentication and Authorization messages # We're only interested in Authentication and Authorization messages
next if ($type ne 'Authentication' and $type ne 'Authorization'); next if ($type ne 'Authentication' and $type ne 'Authorization');
# Parse the date in the timstamp field # Parse the date in the timstamp field
my $timestamp = str2time($event->{timestamp}); my $timestamp = str2time($event->{timestamp});
# Only look at lines from the last $since seconds. Skip if date couldn't be parsed # Only look at lines from the last $since seconds. Skip if date couldn't be parsed
next if (not defined $timestamp or time() - $timestamp > $since); next if (not defined $timestamp or time() - $timestamp > $since);
my $subject; my $subject;
if ($type eq 'Authentication'){ if ($type eq 'Authentication'){
# Accounts ending with $ are for computers # Accounts ending with $ are for computers
$subject = ($event->{$type}->{mappedAccount} =~ m/\$$/) ? 'computers' : 'users'; $subject = ($event->{$type}->{mappedAccount} =~ m/\$$/) ? 'computers' : 'users';
if ($event->{Authentication}->{status} eq 'NT_STATUS_OK'){ if ($event->{Authentication}->{status} eq 'NT_STATUS_OK'){
$json->{activity}->{authentications}->{$subject}->{success}++; $json->{activity}->{authentications}->{$subject}->{success}++;
} else {
$json->{activity}->{authentications}->{$subject}->{failure}++;
}
} else { } else {
$json->{activity}->{authentications}->{$subject}->{failure}++; $subject = ($event->{$type}->{account} =~ m/\$$/) ? 'computers' : 'users';
$json->{activity}->{authorizations}->{$subject}++;
} }
} else {
$subject = ($event->{$type}->{account} =~ m/\$$/) ? 'computers' : 'users';
$json->{activity}->{authorizations}->{$subject}++;
} }
close $auth_log;
} }
close $auth_log;
} }
print to_json($json, { pretty => $pretty }); print to_json($json, { pretty => $pretty });

@ -0,0 +1,34 @@
#!/usr/bin/perl -w
use strict;
use warnings;
use JSON;
use Getopt::Long;
use File::Which;
my $what = 'ou';
my $pretty = 0;
my $json = [];
my $samba_tool = which('samba-tool');
if (not defined $samba_tool){
print $json;
exit 0;
}
GetOptions(
'what=s' => \$what,
'pretty' => \$pretty
);
if ($what eq 'ou'){
foreach (qx($samba_tool ou list)){
chomp;
push @{$json}, {
'{#SAMBA_OU}' => $_
}
}
}
print to_json($json, { pretty => $pretty });

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<zabbix_export> <zabbix_export>
<version>5.0</version> <version>5.0</version>
<date>2021-01-11T08:38:19Z</date> <date>2021-01-11T15:08:31Z</date>
<groups> <groups>
<group> <group>
<name>Templates</name> <name>Templates</name>
@ -644,6 +644,51 @@
</triggers> </triggers>
</item> </item>
</items> </items>
<discovery_rules>
<discovery_rule>
<name>Samba:OU discovery</name>
<key>samba_dc.discovery[ou]</key>
<delay>1h</delay>
<item_prototypes>
<item_prototype>
<name>Samba: Number of objects in {#SAMBA_OU}</name>
<type>DEPENDENT</type>
<key>samba_dc.ou[{#SAMBA_OU},objects]</key>
<delay>0</delay>
<history>60d</history>
<trends>1825d</trends>
<units>!objects</units>
<applications>
<application>
<name>Samba</name>
</application>
</applications>
<preprocessing>
<step>
<type>JSONPATH</type>
<params>$.objects</params>
</step>
</preprocessing>
<master_item>
<key>samba_dc.ou[{#SAMBA_OU}]</key>
</master_item>
</item_prototype>
<item_prototype>
<name>Samba: Info for {#SAMBA_OU}</name>
<key>samba_dc.ou[{#SAMBA_OU}]</key>
<delay>5m</delay>
<history>0</history>
<trends>0</trends>
<value_type>TEXT</value_type>
<applications>
<application>
<name>Samba</name>
</application>
</applications>
</item_prototype>
</item_prototypes>
</discovery_rule>
</discovery_rules>
</template> </template>
<template> <template>
<template>Template_App_Samba_DC_Aggregate</template> <template>Template_App_Samba_DC_Aggregate</template>

Loading…
Cancel
Save