108 lines
4.1 KiB
Perl
108 lines
4.1 KiB
Perl
|
#!/usr/bin/env perl
|
||
|
#
|
||
|
# Copyright 2020, Mischa Peters <mischa AT netskope DOT com>, Netskope.
|
||
|
# Netskope_ZScalerImporter.pl - Version 3.0 - 20200615
|
||
|
#
|
||
|
# Permission to use, copy, modify, and distribute this software for any
|
||
|
# purpose with or without fee is hereby granted, provided that the above
|
||
|
# copyright notice and this permission notice appear in all copies.
|
||
|
#
|
||
|
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||
|
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||
|
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||
|
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||
|
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||
|
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||
|
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||
|
#
|
||
|
# ZScaler integration with Netskope
|
||
|
#
|
||
|
use 5.024;
|
||
|
use strict;
|
||
|
use warnings;
|
||
|
use autodie;
|
||
|
use Config::Tiny;
|
||
|
use Time::HiRes qw(gettimeofday);
|
||
|
use POSIX qw(strftime);
|
||
|
use HTTP::Tiny;
|
||
|
use HTTP::CookieJar;
|
||
|
use JSON::PP;
|
||
|
use Text::CSV;
|
||
|
use MIME::Lite;
|
||
|
|
||
|
my $LOGMODE = "";
|
||
|
#my @CONFIG_FILES = grep { -e } ('./netskope.cnf', './.netskope.cnf', '/etc/netskope.cnf', "$ENV{'HOME'}/.netskope.cnf", "$ENV{'HOME'}/netskope.cnf");
|
||
|
my @CONFIG_FILES = grep { -e } ('./tbi.cnf');
|
||
|
my $config = Config::Tiny->read($CONFIG_FILES[-1], 'utf8');
|
||
|
my $USER_COUNT = $config->{report}{USER_COUNT};
|
||
|
my $MAX_DOMAIN= $config->{report}{MAX_DOMAIN};
|
||
|
my $NTSKP_TENANT = $config->{netskope}{NTSKP_TENANT};
|
||
|
my $NTSKP_TOKEN = $config->{netskope}{NTSKP_TOKEN};
|
||
|
my $NTSKP_TIMEPERIOD = $config->{netskope}{NTSKP_TIMEPERIOD};
|
||
|
my $ZS_MAX_DOMAINS = $config->{zscaler}{ZS_MAX_DOMAINS};
|
||
|
my $ZS_BASE_URI = $config->{zscaler}{ZS_BASE_URI};
|
||
|
my $ZS_API_KEY = $config->{zscaler}{ZS_API_KEY};
|
||
|
my $ZS_API_USERNAME = $config->{zscaler}{ZS_API_USERNAME};
|
||
|
my $ZS_API_PASSWORD = $config->{zscaler}{ZS_API_PASSWORD};
|
||
|
my $ZS_CATEGORY_NAME = $config->{zscaler}{ZS_CATEGORY_NAME};
|
||
|
my $ZS_CATEGORY_DESC = $config->{zscaler}{ZS_CATEGORY_DESC};
|
||
|
my $PROXY = $config->{general}{PROXY};
|
||
|
my $SMTP = $config->{general}{SMTP};
|
||
|
my $FROM = $config->{general}{FROM};
|
||
|
my $TO = $config->{general}{TO};
|
||
|
my $SUBJECT = $config->{general}{SUBJECT};
|
||
|
my $TEXT = $config->{general}{TEXT} . "\n\n";
|
||
|
my %HEADERS = ("Content-Type" => "application/json", "Cache-Control" => "no-cache");
|
||
|
my $EMAIL_CSV = "";
|
||
|
|
||
|
### Netskope ###
|
||
|
sub mail_csv {
|
||
|
my $msg = MIME::Lite->new(From=> $FROM, To => $TO, Subject => $SUBJECT, Type => 'TEXT', Data => $TEXT);
|
||
|
$msg->send('smtp', $SMTP, Debug=>0);
|
||
|
say "MAIL From: $FROM -> $TO - Attach CSV" if $LOGMODE;
|
||
|
}
|
||
|
|
||
|
sub _check_return {
|
||
|
my ($status, $content, $uri) = @_;
|
||
|
if ($status =~ /^2/ && $LOGMODE) {
|
||
|
print "URI: $uri\nHTTP RESPONSE: $status\n";
|
||
|
print "CONTENT:\n$content\n" if ($LOGMODE eq "DEBUG");
|
||
|
}
|
||
|
if ($status !~ /^2/) {
|
||
|
print "URI: $uri\nHTTP RESPONSE: $status\n$content\n";
|
||
|
my $msg = MIME::Lite->new(From => $FROM, To => $TO, Subject => 'API Error along the way', Type => 'TEXT',
|
||
|
Data => "URI: $uri\nHTTP RESPONSE: $status\n$content\n\n",
|
||
|
);
|
||
|
$msg->send('smtp', $SMTP, Debug=>0);
|
||
|
say "MAIL From: $FROM -> $TO - Error Notification" if $LOGMODE;
|
||
|
say "exit 1";
|
||
|
exit 1;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
sub netskope {
|
||
|
my $uri = "$NTSKP_TENANT/api/v1/alerts?token=$NTSKP_TOKEN&timeperiod=$NTSKP_TIMEPERIOD&type=policy";
|
||
|
my $request = HTTP::Tiny->new('default_headers' => \%HEADERS);
|
||
|
my $response = $request->get($uri);
|
||
|
_check_return($response->{'status'}, $response->{'content'}, $uri);
|
||
|
|
||
|
my $json = JSON::PP->new->utf8->decode($response->{'content'});
|
||
|
my $data = $json->{'data'};
|
||
|
printf "%-7s %-45s %-35s %s\n", "Action", "Page", "Policy", "Category";
|
||
|
say "#############################################################################################################################";
|
||
|
|
||
|
my @seen;
|
||
|
for my $item (@{$data}) {
|
||
|
if (exists($item->{'page'})) {
|
||
|
next if (grep {$_ eq $item->{'site'}} @seen);
|
||
|
printf "%-7s %-45s %-35s %s\n", $item->{'action'}, $item->{'page'}, $item->{'policy'}, $item->{'category'};
|
||
|
push @seen, $item->{'site'};
|
||
|
}
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
say "Running in $LOGMODE mode..." if $LOGMODE;
|
||
|
netskope();
|
||
|
say "Completed." if $LOGMODE;
|