Παρασκευή 6 Αυγούστου 2021

Get Telegram notifications for APC UPS using SNMP traps in Linux

In this post I am going to explain how I used SNMP traps on a Linux Debian system in order to get some telegram notifications. I used them in order to be informed in case our company UPS systems runs on battery.

First of all, you have to setup and test a Telegram Notification script.
I used the one here: https://github.com/samsulmaarif/telegram-notify , it is very easy to install and use.

The binary is installed in: /usr/local/bin/telegram-notify

We assume that you already have a telegram bot running.
The two things you 've got to find are your bot api-key and chat id or Channel id.
In case you are not yet using a telegram bot, there are plenty of guides showing how to setup one and how to get your user-id.

In order to get SNMP traps from your UPS Network management card, you should first enable them in the "Notifications". Just enter your Linux hostname as a trap receiver.


First install snmpd and snmptrapd

sudo apt install snmpd snmptrapd 


Edit your config files:

The only change I did to this file is the agentAddress.
/etc/snmp/snmpd.conf

agentAddress udp:161,udp6:161


Then, edit the configuration for the traps. The matching SNMPv1 OIDs for the online/offline battery status of an APC UPS are SNMPv2-SMI::enterprises.318.0.5 and SNMPv2-SMI::enterprises.318.0.9.

So, when each trap is received, my local script /usr/local/ups-telegram.sh  is ran, follwed by a string onbattery/offbattery used to identify the status.


/etc/snmp/snmptrapd.conf 

authcommunity log,execute,net public
snmpTrapdAddr udp:162
traphandle SNMPv2-SMI::enterprises.318.0.5 /usr/local/ups-telegram.sh "onbattery"  
traphandle SNMPv2-SMI::enterprises.318.0.9 /usr/local/ups-telegram.sh "offbattery"

Traps are enabled only for the matching OIDs. In order to de tests, you may use "traphandle default" instead of using specific OIDs.

Restart the services:

sudo service snmpd restart
sudo service snmptrapd restart


test the traps locally:

snmptrap -v 2c -c public localhost "" SNMPv2-SMI::enterprises.318.0.5
snmptrap -v 2c -c public localhost "" SNMPv2-SMI::enterprises.318.0.9

if everyting is fine, you should see some SNMP trap logs at your syslog.

In the second part, we will configure our "action" script. The variable $1 is passed from the snmptrapd.conf file.
In order to get the Telegram Notifications, I used a modified offical Example handler script:

ups-telegram.sh

#!/bin/bash

userid="myuserid"
apikey="myapikey"

read host
read ip
vars=
count=1

while read oid val
do
count=$[count+1]
if [ "$vars" = "" ]
then
vars="$oid = $val"
else
vars="$vars, $oid = $val"
fi
done

UPS_TIME="/tmp/UPS_TIME.tmp"

#echo a $1 trap from host=$host at IP $ip vars=$vars>>/var/log/messages
if [ "$1" = "onbattery" ]; then
starttime="$(TZ=UTC0 printf '%(%s)T\n' '-1')"
echo "$starttime" > "$UPS_TIME"

/usr/local/bin/telegram-notify --user "$userid" --key
"$apikey" --text "$host - On
battery power in response to an input power problem" --error

fi
if [ "$1" = "offbattery" ]; then
starttime=$(head -n 1 $UPS_TIME)
rm -f "$UPS_TIME"
elapsedseconds=$(( $(TZ=UTC0 printf '%(%s)T\n' '-1') - starttime ))

/usr/local/bin/telegram-notify --user "$userid" --key
"$apikey" --text "$host - No longer
on battery power - was on battery for $elapsedseconds secs" --success
fi

exit

 

Τρίτη 13 Ιουλίου 2021

Configure Cisco Jabber DNS and Single Domain using Response Policy Zone (RPZ) and a single BIND9 DNS server

Cisco recommends dual DNS: public (external) and local (internal) DNS in order that Mobile and Remote Access can work more efficiently.

Pinpoint entries (a zone created for a single host only) as suggested by Cisco could be a solution, but our DNS server is authoritative for the parent domain, so this wouldn't work.

With the follwing setup and by using RPZ, jabber requests coming from the internet, are forwarded to Expressway-Edge and requests coming from the internal network are forwarded to Expressway-Core.


Public (External) Records needed:

_collab-edge._tls.example.com      SRV 10 10 8443 expe1.example.com.

Local (Internal) Records needed:

_cisco-uds._tcp.example.com        SRV    10 10 8443 cucm1.example.com
_cuplogin._tcp.example.com         SRV    10 10 8443 cup1.example.com


Cisco states that a client first searches for internal DNS records:
For example, Adam McKenzie's services domain is example.com when he starts the client. The client then issues the following query:

    _cisco-uds._tcp.example.com
    _cuplogin._tcp.example.com
    _collab-edge._tls.example.com


We will be using RPZ, so that the client gets different DNS results depending on which DNS is using for recursion (Public or Private).
Our DNS server is authoritative for all our domains and recursive allowing queries only from internal network (allow-recursion { ournets; };).

First, create the RPZ zone file to your bind9 recursor. This is where all the overrides will be placed.
I copied the file from https://deteque.com/m3aawg-bind-training/ and modified it according to our needs.

db.rpz.local

$TTL 3600

@               IN SOA  localhost. need.to.know.only. (
                       201702135 ; Serial number
                       60        ; Refresh every minute
                       60        ; Retry every minute
                       432000    ; Expire in 5 days
                       60 )      ; negative caching ttl 1 minute
                IN NS   LOCALHOST.
;_collab-edge._tls.example.com IN CNAME *. ; return NODATA for internal queries - Probably not needed
_cisco-uds._tcp.example.com          SRV     10 10 8443 cucm1.example.com. ;internal only
_cuplogin._tcp.example.com           SRV     10 10 8443 cup1.example.com. ;internal only


In my Debian Buster BIND configuration, I use seperate config files in named.conf:

include "/etc/bind/named.conf.options";
include "/etc/bind/named.conf.local";
include "/etc/bind/named.conf.log";


If you use a single config file, then put the following parts in the same file, usually named.conf.
Enable logging of RPZ requests, it is a goood thing to know what's going on:

named.conf.log

        channel rpzlog {
                file "/var/log/rpz.log" versions 14 size 1m;
                print-time yes;
                print-category yes;
                print-severity yes;
                severity info;
        };
        category rpz { rpzlog; };


In your domain main zone file, among your other records, you have to add the following record.
This should be available publicly so that remote clients can access your Cisco Expressway Edge.
In my case, this zone is also transferred to our domain slaves.

example.com zone:

_collab-edge._tls       SRV     10 10 8443 expe1.example.com. ; VCS Expressway or Cisco Expressway-E server


Then, add the zone in your config file:

named.conf.local

zone "rpz.local" {
        type master;
        file "db.rpz.local";
        allow-update { none; };
        allow-transfer { none; };
};


-----------
Finally, enable the Response Policy Zone:

named.conf.options:

        response-policy {
                zone "rpz.local";
        };


Restart Bind and reload the zone

sudo /etc/init.d/bind9 restart
sudo rndc reload rpz.local


Do some tests from some clients and check the rpz.log file!
When querying locally for _cisco-uds._tcp.example.com, you should get a result and see some Local-Data rewrite for your queries.
When querying remotely for _cisco-uds._tcp.example.com, you should get no answer.

Πέμπτη 14 Ιανουαρίου 2021

Allow Adobe Flash for certain sites after 2021 EOL announcement

You can still use Adobe Flash as of January 2021 by "whitelisting" certain sites. I mostly use it to manage some old Enterprise Appliances. All you have to do is edit your mms.cfg file, located in:  

C:\Windows\System32\Macromed\Flash 

or

C:\Windows\SysWOW64\Macromed\Flash

So, the file should look be edited as following:

EOLUninstallDisable=1
AutoUpdateDisable=1
EnableAllowList=1
AllowListRootMovieOnly=1
AllowListURLPattern=*://mydomain.example.com

According to the Adobe Flash Admin guide, AllowListUrlPattern syntax is the follwing:

AllowListUrlPattern = <scheme> ://<host>:<port>/<path>
<scheme> = ‘*’ | ‘http’ | ‘https’
<host> = <any char except ‘.’ and ‘*’>
<port> (optional) = <any valid port number>
<path> = ‘/’ <any chars>
 
With EnableAllowList=1 set, administrators can then specify a discrete URL or pattern to allow