UPS Power Failure Alert

For my server I am using an APC uninterruptible power supply for protection against blackouts and other power related issues. I built on my previous projects with Microsoft Flow to get a notification on my phone when my server loses mains power and when it regains it.

The UPS

The software provided by APC with the UPS allows for basic functionality when power was lost, such as shutting down the computer before all battery power was exhausted. However, it did not provide any more advanced features, such as being able to run a script when mains power was lost or restored.

Fortunately, the software was creating application event logs when these conditions occurred. After some research and trial and error, I was able to deduce an application event with an event ID of 174 was produced when the mains power failed and an application event with an event ID of 61455 was produced when the mains became available again. (Both of these event logs came from the source of “APC UPS Service”)

Scheduling the Alert

To generate a notification in response to one of these events, I created a simple task in Windows inbuilt task scheduler. This task looked for the specified event ID and as an action run my notification PowerShell script that I created previously (see the previous blog post for details about the script).

The procedure goes as follows:

  • Open task scheduler in Windows and click the link to create a basic task
  • Give the new task a name and description and click the next button
  • For the trigger, select the option “When a specific event is logged”
  • Configure the event log for task manager to look for
    • Select “Application” as the log type from the drop down menu
    • In the source box enter “APC UPS Service”
    • In the event ID enter either “174” for a notification on mains power failure or “61455” for a notification on mains power restoration
  • Configure the action to be performed when this task runs
    • Select the radio button for “Start a program”
    • In the “Program/script” section, enter “powershell.exe”
    • In the “Add arguments” enter the full path to the PowerShell notification script created earlier.
    • Note: It is very important that you provide “powershell.exe” as the program to start. If you simply put the path to your script in this box, your PowerShell script will be opened in notepad when your task runs and not actually executed. This is just a feature of Windows and you will notice the same action if you double click on your PowerShell script.
  • Optionally repeat the process for the other event ID so notification will be generated for both power failure and power restoration.

JSON Web POST with PowerShell

An alternative to my previous method of using Python to make web requests for the notifications is to use PowerShell. The main advantage of using PowerShell is that it is included with Windows systems and therefore does not require the installation of any other packages. Additionally, it is far easier to trigger the script to run using the likes of Window’s task scheduler, allowing notifications to be triggered in response to events on the Windows system.

My Script

  • The first task is to once again define the URL from which the requests will be made
    • This can be found in the Flow interface under the “When HTTP request is received section” and will be unique for each flow
    • In PowerShell, variables are assigned and referenced with the “$” sign in front of them
    • $URL = "https://prod-02.australiasoutheast.logic.azure.com:443/workflows/a7.....
  • Next I define a “Parameters” object to contain the parameters I want to include in the notification
    • Note: The syntax used here is to create a PowerShell object, and not JSON. It will need to be converted to JSON in the next step
    • $Parameters = @{
       "Source"= "Computer"; 
       "Message"= "42";
      }
    • Again I am using “Computer” as the source and “42” as the message, however this will be where you can add your own custom information.
  • Next we get PowerShell to take the parameters object we just created and turn it into a JSON object
    • $JSON = $Parameters | ConvertTo-Json
    • The result is stored in the “JSON” variable
  • Finally, we perform the actual web request
    • Invoke-WebRequest -Uri $URL -Method POST -Body $JSON -ContentType 'application/json'

JSON Web POST with Python

In an earlier post, it was outlined how to setup a Microsoft Flow workflow to generate a notification on a phone when a web request was made. This post will outline how to create such a web request using the popular scripting language Python.

Install Python

  • Ensure that Python (version 3) is installed on the system
  • During this process it is important to ensure that Python is added to the system PATH variable
    • This allows Python to be called from the command line
    • Having this ability will make it significantly easier to schedule this script to run when events occur, which is likely to be the role of the script.
  • After python is installed, we must install the “requests” library
    • This is the library that we will use to perform the actual request
    • Note: It is possible to perform the POST request without the “requests” library, however I believe it to be the cleanest method.
    • To install “requests” open a command line and enter “pip install requests”
      • If you get an error running this command, it is likely that Python was not added correctly to the system’s PATH variable

The Code Itself

  • First we need to import the “requests” library we just installed into the Python script
    • This is done with the following code:
    • import requests
  • Next we need to define the URL to which the request will be made
    • This can be found in your workflow you created previously and will be unique to each Flow
    • URL = "https://prod-02.australiasoutheast.logic.azure.com:443/workflows/.......
  • Next we need to define the JSON that will be sent in the request to provide the parameters to our notification service
    • For my notification I only had two parameters, a source and a message
    • For the purpose of this example I have set the source parameter to be “Computer” and the message parameter to be “42”
    • Parameters = {"Source" : "Computer", "Message" : "42"}
  • Finally we perform the actual request from the server
    • For the request to execute, we need to provide it with the URL and parameters we defined earlier
    • Request = requests.post(URL, json = Parameters)
  • After running the code you should now get a notification on your phone
  • By changing the values contained in the parameters section you can change the contents of the messages to whatever you wish.

Device Notification with Microsoft Flow

For a couple of IoT projects I’ve been working on, I wanted to allow scripts to trigger a notification on my phone. I evaluated a number of solutions, but many of them were paid services that only served that particular purpose. Additionally, many of them did not include the ability to customise the notifications.

A solution presented itself when I began to look at creating workflows with Microsoft Flow, which is included in an Office 365 for business subscription. Microsoft Flow basically allows for a trigger event to cause a number of actions. In this case there was a trigger that could be activated when a web request was made to a specific URL and one of the actions was to trigger a notification on a phone. Additionally, by including a JSON POST in the request, it was possible to modify the content of the notification. As a point of interest you could also send an email with almost the same setup if it would better suit the application.

Procedure

  1. Login to your Office 365 portal (portal.office.com)
  2. Click on the Flow link
  3. Click the button for “Create from blank”
  4. Search for the “When a HTTP request is received” trigger and add it to the flow
  5. Create the JSON Schema
    1. This is probably the most complicated part of the whole procedure as you need to define the JSON structure that will be used to provide parameters for your notification
    2. For my notification system, I only wanted to provide two parameters:
      1. A source field for the device or application sending me a message
      2. A message field for the contents of the actual message
    3. The JSON structure for these two fields looked likes the following:
      {
      
      "type": "object",
      
      "properties": {
      
      "Source": {
      
      "type": "string"
      
      },
      
      "Message": {
      
      "type": "string"
      
      }
      
      }
      
      }
    4. Note: You could create a far more advanced structure if you wanted more information in your notifications
  6. Now the trigger is fully configured you will need to add an action
    1. In this case, we will add the “send me a mobile notification” action
    2. It’s important to note that this requires you have the Microsoft Flow app installed on your mobile phone.
  7. Next we need to configure the notification action
    1. The only field we need to populate is the Text field which will be displayed as the body of the notification
    2. We could add an arbitrary text string into the field if we only ever want one message to be displayed, however we can reference the variables we created earlier in the JSON Schema to make the message more meaningful.
    3. For example with regard to my JSON schema, I created the message “Source has said Message”
      1. You will notice that the variables outlined in the JSON schema will appear as different symbols in the text, confirming that flow has recognised them as the variables above.
      2. It should look something like the following:Capture
      3. When the notification is generated the source and message placeholders will be replaced by the information you provide in the web request.
  8. Finally save the workflow
    1. This will generate a unique URL that you will make a web request to and will then trigger the notification.
    2. The whole flow should look something like this one:Capture

You will now have a working notification system. Simply install the flow app on your phone, sign into it using the same Microsoft account and make a request to the specified URL. A future blog post will go into detail about how to make a web request and provide the necessary JSON parameters using a number of scripting languages.

New Hosting Provider

For over three years this blog was hosted on a shared server offered by BlueHost. However, six months ago I lost control of the admin account. From what I could gather an adversary had been able to socially engineer BlueHost support into changing the administrator email address to one under their control. Once this had been achieved, they were able to perform password recovery and gain access to the admin account.

Once they had access, they shutdown the server running my blog and launched a high power instance which worked up a considerable bill. After much pain I managed to re-gain access to the admin account and removed the powerful instance. Luckily, BlueHost refunded the cost of the powerful instance.

After this occurred I started looking for other methods of hosting my blog. Initially, I looked at hosting on Amazon Web Services. This method would have given me the best control over the blog as I could create a small Linux EC2 instance and then install WordPress to run my blog. However, this method would have also require me to maintain the site and server, a task I don’t believe I currently have time for.

The solution to this problem was brought to my attention by one of the security podcasts I often listen to “Security Now”. One of the sponsors of the show is Worpress.com which provide you with a WordPress site of your own, that is fully maintained by them. Additionally, their pricing was very reasonable and included the costs of registering the domain.

I created this blog on WordPress.com and will now have the fun of moving my domain registration and blog content over. Hopefully it won’t be too hard.

Additionally, the security of my blog appears to be sufficient. The WordPress.com site supports two factor authentication using either my phone or an authenticator app. I elected to use the authenticator app to eliminate the risk of the SMS message begin intercepted or the telecommunications provider being socially engineered and allowing a SIM swap. Another security benefit provided is that my blog is now running over HTTPS, resulting in my login information being encrypted when it is sent to the site. Hopefully, these measures will be enough to keep the site safe this time.