Category Archives: Tools

Configuring Multiple Networked OR USB APC UPS devices

As any proper IT-nerd would agree, UPS devices are critical pieces of equipment not only in the data center, but also at home. However, most home users are not in a position to acquire a massive 10+ kilovolt-amp UPS capable of protecting all circuits by which our various “personal devices” are powered; rather, most home/small office UPS installations are often small desktop units usually under 3kVA. In this scenario, these smaller units are typically allocated to individual devices / ares, and are typically only responsible for signaling the status of the incoming utility power to one device.

What about using multiple UPS devices for different components of the same “workspace”? Or home networks with access points and switches in more than one location (therefore each having its own battery backup)? How would one monitor multiple distributed battery backup units (presuming each UPS unit has only USB connectivity)?

APCUPSD

Enter apcupsd: “A daemon for controlling APC UPSes.” Unfortunately, the plurality of this utility’s tagline indicates a wide range of supported devices rather than multiple concurrently connected devices. To date, I’ve found one article describing how to configure apcupsd to support multiple USB-attached UPS devices, and it’s not really pretty. The gist of the process is as follows:

  1. Configure udev rules to ensure a consistent mapping (by UPS serial number) to a named mount point
  2. Create multiple apcupsd configuration files for each connected UPS
  3. Create new “action” and “control” scripts for each UPS
  4. Re-configure the apcupsd init.d/systemd scripts to launch multiple instances of the daemon (one for each UPS)

I’m generally not a fan of creating large “custom” configuration files in obscure locations with great variance from the distributed package, so this process seemed a little “hackey” to me; especially since the end result of all of these configuration files was to have “isolated processes” for each UPS to monitor.

Dockerizing APCUPSD

At this point, I decided to take a different approach to isolating each apcupsd process: an approach with far greater discoverability, version-control potential, and scalability. Docker.

I decided to use the first step outlined in the apcupsd guide on the Debian Wiki (creating udev rules to ensure physical devices are given a persistent path on boot/attach). UPS devices are generally mounted at /dev/usb/hiddev*, so we should confirm that we have a few present:

# ls /dev/usb
hiddev0  hiddev1

# lsusb
Bus 002 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 004 Device 002: ID 051d:0002 American Power Conversion Uninterruptible Power Supply
Bus 004 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 003 Device 002: ID 051d:0002 American Power Conversion Uninterruptible Power Supply
Bus 003 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub

Great! we’ve got things that look like UPS devices on /dev/usb/hiddev0 and /dev/usb/hiddev1. Now to get the serialnumbers:

# udevadm info --attribute-walk --name=/dev/usb/hiddev0 | egrep 'manufacturer|product|serial'
    ATTRS{manufacturer}=="American Power Conversion"
    ATTRS{product}=="Back-UPS BX1500G FW:866.L5 .D USB FW:L5 "
    ATTRS{serial}=="8975309"
    ATTRS{manufacturer}=="Linux 4.4.0-170-generic ohci_hcd"
    ATTRS{product}=="OHCI PCI host controller"
    ATTRS{serial}=="0000:00:02.0"
# udevadm info --attribute-walk --name=/dev/usb/hiddev1 | egrep 'manufacturer|product|serial'
    ATTRS{manufacturer}=="American Power Conversion"
    ATTRS{product}=="Back-UPS NS 1100M2 FW:953.e3 .D USB FW:e3     "
    ATTRS{serial}=="8675310"
    ATTRS{manufacturer}=="Linux 4.4.0-170-generic ohci_hcd"
    ATTRS{product}=="OHCI PCI host controller"
    ATTRS{serial}=="0000:00:04.0"

With the now known serial numbers, we create udev rules to persist these devices to known map points:

## FILE AT /lib/udev/rules.d/ups.rules

# SCREEN UPS
KERNEL=="hiddev*", ATTRS{manufacturer}=="American Power Conversion", ATTRS{serial}=="8975309", OWNER="root", SYMLINK+="usb/ups-screen"

# ComputeAndNetwork UPS
KERNEL=="hiddev*", ATTRS{manufacturer}=="American Power Conversion", ATTRS{serial}=="8675310", OWNER="root", SYMLINK+="usb/ups-compute-and-network"

And now to re-run the udev rules:

udevadm trigger --verbose --sysname-match=hiddev*

Now, we should have some “nicely named” UPS USB devices:

# ls -la /dev/usb
total 0
drwxr-xr-x  2 root root    120 Dec 18 19:55 .
drwxr-xr-x 22 root root   4280 Dec 18 19:55 ..
crwxrwxrwx  1 root root 180, 0 Dec 18 19:55 hiddev0
crwxrwxrwx  1 root root 180, 1 Dec 18 19:55 hiddev1
lrwxrwxrwx  1 root root      7 Dec 18 19:55 ups-compute-and-network -> hiddev1
lrwxrwxrwx  1 root root      7 Dec 18 19:55 ups-screen -> hiddev0

Excellent! Now, anytime these devices are plugged/unplugged, we shouldn’t have to guess which is hiddev0 and which is hiddev1, since udev will automagically provide us named mount points for these USB devices, which will be critical to the next steps

Next, I created a docker-compose file with the three “services” I decided I’d like for this setup:

  • APCUPSD for the “screens” UPS
  • APCUPSD for the “Compute and Network” UPS
  • Apache/Multimon to provide an HTTP based interface

This docker-compose file also contained pointers to specific Dockerfiles to actually build an image for each service (hint: the two apcupsd services use the same container with different configurations).

The apcupsd container is nothing more than the latest Alpine linux image; apcupsd from the apk repository and a very lightweight apcupsd configuration files (configured to watch onlythe UPS at /dev/ups – more on this later)

The multimon container uses the latest Apache/alpine image, and adds apcupsd-webif from the apk repository along with a few configuration files for multimon. Additionally, I wrote an entrypoint.sh script to parse environment variables and generate a configuration file for multimon so that the UPS(s) displayed on the web interface can be set from the docker-compose file.

Having now covered the build process, let’s put together the docker-compose services:

Full Docker setup here: https://github.com/crossan007/APCUPSD-Multimon-Docker

Now, instead of attempting to create custom init scripts, multiplex processes within systemd, and override the packaged mechanisms for apcupsd‘s configuration discovery, I instead have a cleanly defined interface for isolating instances of apcupsd to provide a status page for my two APC UPS devices.

Thanks for reading, and hopefully this helps you in some way!

Display HTTPS X509 Cert from Linux CLI

Recently, while attempting a git pull, I was confronted with the following error:

Peer's certificate issuer has been marked as not trusted by the user.

The operation worked on a browser on my dev machine, and closer inspection revealed that the cert used to serve the GitLab service was valid, but for some reason the remote CentOS Linux server couldn’t pull from the remote.

I found this post on StackOverflow detailing how to retrieve the X509 cert used to secure an HTTPS connection:

echo | openssl s_client -showcerts -servername MyGitServer.org -connect MyGitServer.org:443 2>/dev/null | openssl x509 -inform pem -noout -text

This was my ticket to discover why Git on my CentOS server didn’t like the certificate: the CentOS host was resolving the wrong DNS host name, and therefore using an invalid cert for the service.

And now a Haiku:

http://i.imgur.com/eAwdKEC.png

Let’s Encrypt Setup

The “Let’s Encrypt” setup process is very painless – Just clone a Git repo, run a comand, and edit some apache config files.

  1. sudo apt-get install git
  2.  sudo git clone https://github.com/letsencrypt/letsencrypt /opt/letsencrypt
  3. cd /opt/letsencrypt
  4. ./letsencrypt-auto –apache -d ccrossan.com -d www.ccrossan.com
  5. edit the sites-enabled config files so that the appropriate virtual host uses the correct ssl certs.
  6. delete the newly generated ssl.conf file
  7. restart apache
  8. [Optional] Set up Cron for auto-renew
  9. sudo crontab -e
  10. 30 2 * * 1 /opt/letsencrypt/letsencrypt-auto renew >> /var/log/le-renew.log

 

These commands taken from the DigitalOcean Let’s Encrypt Setup Guide

Unprotect an Excel Worksheet

C/O: https://uknowit.uwgb.edu/page.php?id=28850

  1. Press ALT+F11
  2. Double Click the worksheet in question
  3. Paste the Following Code:
    
    Sub PasswordBreaker()
    
    'Breaks worksheet password protection.
    Dim i As Integer, j As Integer, k As Integer
    Dim l As Integer, m As Integer, n As Integer
    Dim i1 As Integer, i2 As Integer, i3 As Integer
    Dim i4 As Integer, i5 As Integer, i6 As Integer
    On Error Resume Next
    For i = 65 To 66: For j = 65 To 66: For k = 65 To 66
    For l = 65 To 66: For m = 65 To 66: For i1 = 65 To 66
    For i2 = 65 To 66: For i3 = 65 To 66: For i4 = 65 To 66
    For i5 = 65 To 66: For i6 = 65 To 66: For n = 32 To 126
    ActiveSheet.Unprotect Chr(i) & Chr(j) & Chr(k) & _
    Chr(l) & Chr(m) & Chr(i1) & Chr(i2) & Chr(i3) & _
    Chr(i4) & Chr(i5) & Chr(i6) & Chr(n)
    If ActiveSheet.ProtectContents = False Then
    MsgBox "One usable password is " & Chr(i) & Chr(j) & _
    Chr(k) & Chr(l) & Chr(m) & Chr(i1) & Chr(i2) & _
    Chr(i3) & Chr(i4) & Chr(i5) & Chr(i6) & Chr(n)
    Exit Sub
    End If
    Next: Next: Next: Next: Next: Next
    Next: Next: Next: Next: Next: Next
    End Sub
    
  4. Press the Run button
  5. The password to unlock the form is displayed, and the sheet is no longer password protected

Stay up to date with RSS

Staying Up-To-Date

I spend spent a lot of time watching various blogs, web pages, and other online sources for updates to the many platforms I’m responsible for supporting.  Windows has a new security patch. Mac OSX needs heart-bleed remediation.  SharePoint has a new Cumulative Update.  There’s a new Linux Kernel out, and 52 commits have occurred for the ROM on my phone.

That’s a lot of moving targets, with many different pages to remember to check on a semi-regular basis.  With probability against me, the time spent loading a page (and possibly googling it if I forgot to bookmark it) and deciphering what’s changed since I last visited generally resulted in a lot of lost time.

My Solution

Recently, a co-worker turned me on to RSS feeds.  They’ve been around forever, and yet, I’ve never really used them.  That is, until I realized how valuable they can be.   Just think: superbookmarks! One “Single Pane of Glass” to view all of the content updates. Feedly is a web based RSS reader.  You can use various authentication methods ( I prefer logging in with my Google Account) to access your list of “Subscribed” RSS feeds.

Whenever new content is posted, it shows up in your “unread” subscriptions.  Just make it your homepage, and enjoy the easy reading!

Subscribing to Content

After you’ve found a content source you’d like to stay current on, You’ll need to:

  1. Identify the RSS Feed URL
    1. Most sites will have an RSS button.  It should look like this: However, some sites do not publish the RSS feed, but still make it available.
    2. The RSS Feed for WordPress sites can be accessed via http://<sitename>/feed or http://<sitename>/?feed=rss2.
    3. Reddit publishes RSS Feeds for subreddits in the form of http://reddit.com/r/<subreddit>/.rss
  2. Point Feedly at the URL
    Click the “Add Content” button in Feedly, and provide the URL you discovered in step 1.

  3. Add the Feed to one of your collections
    Click the green “+”

  4. Choose a Collection

  5. Enjoy!
    New posts from this content source will now automagically show up when you open Feedly!

My Feeds

If you’re curious what I’m following, here’s a list of the RSS feeds I choose to follow.  You could also download, and import my feeds directly into your Feedly!

  • Ars Technica
    • http://feeds.arstechnica.com/arstechnica/index/
  • Michael Niehaus’ Windows and Office deployment ramblings
    • http://blogs.technet.com/mniehaus/rss.xml
  • Reddit /r/sysadmin
    • http://www.reddit.com/r/sysadmin/.rss
  • codeinsecurity
    • http://codeinsecurity.wordpress.com/feed/
  • Krebs on Security
    • http://krebsonsecurity.com/feed/
  • In the Cloud
    • http://blogs.technet.com/b/in_the_cloud/rss.aspx
  • Ask Premier Field Engineering (PFE) Platforms
    • http://blogs.technet.com/b/askpfeplat/rss.aspx
  • Errata Security
    • http://blog.erratasec.com/feeds/posts/default
  • NPR News
    • http://www.npr.org/rss/rss.php?id=1001
  • XKCD
    • http://xkcd.com/rss.xml
  • LifeHacker
    • http://feeds.gawker.com/lifehacker/vip
  • Todd Klindt’s Blog Posts (SharePoint Patches)
    • http://www.toddklindt.com/blog/_layouts/listfeed.aspx?List={56F96349-3BB6-4087-94F4-7F95FF4CA81F}
  • Reddit /r/sharepoint
    • http://www.reddit.com/r/sharepoint/.rss
  • Stefan Goßner (SharePoint)
    • http://blogs.technet.com/b/stefan_gossner/rss.aspx