Configuring Network UPS Tools to use Nextcloud’s Push Notifications

One of the problem with running servers in a home environment is the lack of 100% reliable electricity. I’ve noticed that since moving house nearly 2 years ago, going from underground to above ground power, has resulted in a significant reduction in grid reliability. There have been frequent outages due to replacing power poles, road accidents that have destroyed poles and other maintenance that just wasn’t an issue in our old place. To cut a long story short, this means I have a renewed interest in monitoring my uninterruptible power supplies (UPS) for outages so I can respond. Ordinarily I would use email for this, however my alerts go to a separate folder and I which I only check periodically and when I’m in the office or out on the weekend, I need to know instantly if there is an issue.

This is where push notifications come in handy. Nextcloud has a function to allow administrators to send notifications so I needed to write a script that hooks into the API and sends the message. The steps are simple enough:

  • Create a service account for sending API notifications in Nextcloud
  • Create an API key for the above
  • Create the script to be executed by the network UPS tool monitoring service that will send an email and call another script (below)
  • Create a script that will send the push notification.

Starting with the service account, however you would normally do it, depends on your circumstances. In mine, I created an service account in AD, then in Nextcloud granted the minimum required permissions to be able to send notifications to that account. If you’re doing it this way, you’ll need the ObjectGUID from AD later. If necessary create an app password in nextcloud for the service account.

Edit the file /etc/nut/upsmon.conf and add the following to the NOTIFTYCMD section:

NOTIFYCMD /usr/local/bin/nut-email.sh

Create the script below in the correct location (/usr/local/bin/nut-email.sh) and make it executable and owned by root. This script will send an email and then run another script to send the push notification.

#!/bin/bash 
# /usr/local/bin/nut-email.sh 

TO="youremail@yourdomain.tld" 
SUBJECT="UPS Alert: $UPSNAME $NOTIFYTYPE" 
BODY="Event: $NOTIFYTYPE occurred on $UPSNAME at $(date)." 

echo "$BODY" | mail -s "$SUBJECT" "$TO" 

# execute push notifcation 
export SUBJECT 
/usr/local/bin/nut-push.py

Create the script for interacting with nextcloud’s notification app in the location /usr/local/bin/nut-push.py. Ensure it is owned by root and executable.

#!/usr/bin/env python3 

import requests, os 
from requests.auth import HTTPBasicAuth 

# Your Nextcloud configuration 
NEXTCLOUD_URL = 'https://your.nextcloud.url' 
USERNAME = 'service_account@yourdomain.tld' 
PASSWORD = 'account_password' 

# Notification content 
MESSAGE = ' '+os.getenv('SUBJECT') 
# MESSAGE = ' UPS warning: Power failure detected. System may shut down soon.' 

# API endpoint 
url = f'{NEXTCLOUD_URL}/ocs/v2.php/apps/notifications/api/v2/admin_notifications/<ObjectGUID>' 

# Headers required by Nextcloud OCS API 
headers = { 
   'OCS-APIREQUEST': 'true', 
   #'Content-Type': 'application/x-www-form-urlencoded' 
} 

# Payload 
payload = { 
   'shortMessage': MESSAGE 
} 

# Make the request 
response = requests.post(url, headers=headers, data=payload, auth=HTTPBasicAuth(USERNAME, PASSWORD)) 

# Check result 
if response.status_code == 200: 
   print('Notification sent successfully!') 
else: 
   print(f'Failed to send notification: {response.status_code}, {response.text}')

And thats it! You should be able to test this by executing the script above.

 

 

 

 

 

Deploying Authentik Part 1

A recent episode of the Risky Biz Podcast featured an interview with Fletcher Heisler from Authentik, who make an open-source SSO/IdP. I’ve been using Keycloak for a couple of years now and while I have found it reliable, I have also found its feature-set to be rather limited as I would like to move to using passkeys for logging into my systems and bring RADIUS (easily) to my networking. So, after listening to the interview and hearing about what Authentik can do, I’ve spun up an instance to see if I can swap from Keycloak. The purpose of this blog post is to record some of the headaches I had getting my AD (Samba) back-end configured.

The basic installation is straight forward, and their documentation is mostly good. Spinning up a docker instance was an easy task and should make managing the software in the future (as when during a distro upgrade) much easier. I learned the hard way recently that when you do a Ubuntu in-place distribution upgrade, and MariaDB is upgraded, that you need to also upgrade MariaDB’s internal schema too. But with docker, and containers maintaining their own instances of, well, everything, the system becomes more resilient to my changes to the OS. Tick.

After following the bouncing ball getting through the initial setup, things started to fall apart when I added my AD backend via LDAP. I found the users would sync with no issue, once I correctly applied the filters to remove computer objects, however groups and group memberships did not. The documentation did not make it clear where exactly the filters needed to go and additional (superfluous) mappings were included by default, which caused the sync from Samba to fail.

I found that for my simple AD setup, that I only needed to sync ‘authentic default OpenLDAP Mapping:cn’ for the group properties. And under additional settings, I changed the User object filter to ‘(&(objectClass=user)(!(objectClass=computer)))’, group membership filed to ‘memberOf:1.2.840.113556.1.4.1941:’ and enabled the ‘loookup using user attribute’ option. All of which was in the documentation, but was left ambiguous – leaving me to try a couple of different combinations of settings until the groups appeared and then were correctly populated. I then tested changing the group membership in Samba AD, running a sync and checking the changes propagated.  

With the basics up and running I can now look forward to setting up the built-in RADIUS functionality which I hope to integrate into my Ubiquiti Unifi WiFi so I can enable identity aware WPA3-enterprise networking. I also began playing around with the default flows and logging in with my user account using a passkey with some success. I suspect that Authentik will end up replacing Keycloak as my single-sign-on provider once I’ve finished learning its nuances.