Archive for June, 2011

Preparing APC Smart-UPS 1500 for Critical Servers

June 16, 2011

Part one of a three part series

on Setting up a UPS solution, to enable clean shutdown of vital network components.

This post is essentially about setting up a Smart-UPS and it’s NMC (Network Management Card),
as the project I embarked upon was a little large for a single post.

Christchurch NZ used to have quite stable power,
but recent earthquakes we’ve been having have changed that.
Now we endure very unstable power.
This fact,
along with the fact that if my RAID arrays were being written to when a power outage occurred,
prompted me to get my A into G on this project.

For a while now I’ve been looking into setting up a UPS solution to support my critical servers.
I already had a couple of UPS’s
Liebert PowerSure 250 VA
Eaton Powerware 5110 500 VA
Both of which were a bit small to support a fairly hungry hypervisor, dedicated file server, 24 port Cisco catalyst switch and a home made router.
Also the FreeNAS (BSD ) driver for USB that was supposed to work with the 5110, didn’t seem to.
In considering the above; I had a couple of options.
With ESXi we can use an APC UPS and a network management card or the Powerware 5110 connected to a network USB hub
and a virtual guest listening to its events, ready to issue shutdown procedures as per James Pearce’s solution
but to any number of machines.

What I wanted was a single UPS plugged into a single box that would receive on battery events and do the work of shutting down the various machines listed (any type of machine, including virtual hosts and guests).
There didn’t appear to be a single piece of software that would do this, so I wrote it.
I’ll go over this in a latter post.

So I would need either a network connected USB hub. As explained here.

Simple Two Port Network Connected USB Hub

Hardware solutions and all work well from VM guests from what I’ve read.
AnywhereUSB from Digi …
USB server from Keyspan
USB Anywhere from Belkin

Software solutions, Need physical PC that has USB device/s plugged in.
USB@nywhere
USB over Network
USB Redirector

Or a network management card (something like the AP9606) for the UPS as explained here by James
Powerware 5110 doesn’t support a network management card, so only option I see for this UPS is a network connected USB hub.
APC SMART-UPS supports network management cards and I think these would be the best option for this UPS.

The AP9606

It was starting to look like an APC UPS would be the better option.
I had already been looking for one of these for quite a while, and I missed a couple of them.

The one I eventually picked up

APC Smart-UPS

Second hand APC Smart-UPS 1500
$200 + shipping = just under $300.
AP9606 NMC $50 + shipping = aprx $80.
So for $380 even if I needed a new battery ($250),
I still had a $1300 UPS, NMC not included, for $600.
Turned out the battery was fine,
so all up $380 to support a bunch of hardware.

You’ll need to give the card an IPv4 address that suites your subnet.
As my card was second hand, it already had one,
but I didn’t know what it was.
In order to give the card an IP, you have 2 obvious options

1.  serial cable and terminal emulator

2.  Ethernet and ARP

As I didn’t have the “special” serial cable,
I decided to go the Ethernet route.
I would need the MAC address.
The subnet mask and default gateway also need to be set up.
Pg 11 of APC_ap9606_installation_guide.pdf goes through the procedure.
All APC devices have a MAC address that begin with 00 C0 B7
Although my network management card had a sticker with the MAC address on it.
“You may want to check your DHCP client list for any MAC addresses beginning with 00 C0 B7,
which indicates an APC address.
In addition, check the card you are trying to configure.
Any card with valid IP settings will have a solid green status LED”.

When I received my AP9606 Web SNMP Management Card, I didn’t have a clue what the IP address had been set to.
If it was a new card it wouldn’t have yet been set and I would be able to easily set it without having to workout
what its subnet was.
On Pg 11 of the “Web/SNMP Management Card Installation Manual”
It goes through setting up an IP from scratch using ARP.
So I plugged my notebook into the AP9606’s Ethernet port and spun up Wireshark.

What you’ll generally be looking for is a record with the Source looking like

"American_[last 3 bytes of MAC]"

Time                    Source                Destination    Protocol    Info
231    715.948894    American_42:6f:b1    Broadcast    ARP        Who has 10.1.80.3?  Tell 10.1.80.222

And an ARP request that looks something like the following…
The first 3 bytes of the MAC will always be 00-C0-B7 for a AP9606.

Address Resolution Protocol (request)
 Sender MAC address: American_42:6f:b1 (00:c0:b7:[3 more octets here])
 Sender IP address: 10.1.80.222 (10.1.80.222)
 Target MAC address: American_42:6f:b1 (00:c0:b7:[3 more octets here])
 Target IP address: 10.1.80.3 (10.1.80.3)

I set the notebook to use a static IP of
10.1.80.2/24
and default gateway to the Target IP of
10.1.30.3
You may have to play around a bit with the subnet mask until you get it right.
I was just lucky.
Then tried using ARP to assign the new IP address,
but it wasn’t sticking.
So I tried to telnet in and was prompted for a username and password.
The default of apc for both was incorrect so obviously it had already been altered.
There is also another account of u- User p- apc
but this didn’t exist or had been changed.
So I contacted APC for the backdoor account as discussed here
and was directed to here.
This is no good unless you have a special serial cable which I didn’t.
I asked for the pin layout of the cable and was told,
that they make them,
but don’t know what the pin layout is.
The nice fellow at APC support directed me to a cable to buy.
A little pricey at $100NZ,
for a single use cable.
There is no proper way to reset the password by the Ethernet interface.
This left me with two obvious options.

1.  Make up a serial cable with I believe…

Pin#2 Female to Pin#2 Male,
Pin#3 Female to Pin#1 Male,
Pin#5 Female to Pin#9 Male,
and find a computer with a com port.
Layout info found here
It was correct.
That would cost next to nothing.

2.  just crack the credentials with one of these.

The second seemed like it would be the path of least resistance immediately (this turned out to be incorrect),
as I had the software, but not enough parts for a serial cable.
THC-Hydra seemed like a good option.
Once I downloaded and ran Hydra, I received the following error

 5 [main] ? (1988) C:\cygwin\bin\bash.exe: *** fatal error - system shared
 memory version mismatch detected - 0x75BE0074/0x75BE0096.
 This problem is probably due to using incompatible versions of the cygwin DLL.
 Search for cygwin1.dll using the Windows Start->Find/Search facility
 and delete all but the most recent version.  The most recent version *should*
 reside in x:\cygwin\bin, where 'x' is the drive on which you have
 installed the cygwin distribution.  Rebooting is also suggested if you
 are unable to find another cygwin DLL

This error is due to having incompatible versions of cygwin1.dll on your system.
So did a search for them and found that my SSH install had an older version of cygwin1.dll.
So renamed it,
and still had problems,
rebooted, and all was good.
the only cygwin1.dll should be in the same directory that hydra.exe is run from.

How to use THC-Hydra

Some good references here…
http://www.youtube.com/watch?v=kzJFPduiIsI
http://www.pauldotcom.com/2007/03/01/password_cracking_with_thchydr.html

Command I used.

C:\hydra-5.4-win>hydra -L logins.txt -P passwords.txt -e n -e s -o hydraoutput.txt -v 10.1.80.222 telnet "Welcome hacker"

I got a false positive of User name n/a Password steven
So rather than spend more time on populating the logins.txt and passwords.txt.

I decided to try the serial cable route

As it turned out, I wouldn’t have guessed the username,
found this out once I logged on using the serial interface.
This is the pinout I used.

This is the single use cable I made.
Total cost of $0.00


Make sure you’re all plugged in.
I used minicom as my terminal emulator to connect to the UPS’s com port.
Installation and usage details here.

You need to make sure you’re serial port/s are on in the BIOS.
I didn’t check mine, but they were on.

Need to make sure Linux knows about your serial port/s
Run the following command:

Use setserial to provide the configuration information associated with your serial ports.

Configuring your serial ports.

To setup your terminal emulator (minicom in my case):

$ minicom -s -c on

Choose “Serial port setup”
and you will be presented with a menu like the following.

This is where you get to set the following:
2400 BPS, 8 databits, No parity,
one stop bit and flow control is set to none.
Then select Save setup as dfl

Exit.

You should now be prompted for authentication from the Smart-Ups.

Or you can choose “Exit from Minicom” and run

$ minicom -c on

later.
If you get output like…

Device /dev/ttyS[number of your port here] is locked.

You’ll have to

# rm /var/tmp/LOCK..ttyS[number of your port here]

Now is where you get to log on as the default user/pass apc/apc
Press the reset button on the AP9606
and press Enter key,
then repeatedly if necessary.
This is poking the AP9606 in order to get a login prompt
Once you get the User Name,
you can enter the “apc” user (without the quotes) and then for the Password,
“apc” (without the quotes).
You have a 30 second window here to login.
Else you have to repeat the reset process and try again.

From the Control Console menu,
select System, then User Manager.
Select Administrator,
and change the User Name and Password settings,
both of which are currently apc.

I also changed the IP settings.
From the Control Console,
select
2- Network
1- TCP/IP
and change your IP settings.

There are quite a few settings you can change on the card,
you should just be able to follow your nose from here.
You’ll also want to make sure the Web Access is Enabled.
Take note of the port also, usually 8000.
Changing the password via the serial interface is also detailed here.
This post was also quite helpful.

Changed the IP settings back to how they were on my notebook.
Could now connect via telnet and HTTP.
Turned md5 on to try and boost the security of passing credentials to the web UI.
Turned out the jre is also needed for this.
Went through that process and it was looking promising,
but the web UI no longer accepted my password.
Not sure why this is,
but it means if you want to be secure when you log into the web UI,
you are going to have to plug your Ethernet cable directly into the AP9606.
Otherwise your passing credentials in plan text.

Upgrade of firmware

The latest firmware is found here.
Directions on upgrading are found here.
In saying that, APC recommended I use the earlier aos325.bin and sumx326.bin from here if using Windows XP.
Some details around the firmware required for the different management card types for use in a Smart Slot equipped APC UPS
The firmware version is found under Help->About System on the NMC’s Web interface.

Excluding ads from your browsing experience

June 6, 2011

If you like the idea of

  • Saving bandwidth
  • Removing annoying adds while browsing the web
  • Minimising the likelihood of having your privacy compromised, by way of spy-ware, unwanted analytics, Cross-Site Scripting (XSS), and others
  • Gaining control over who can download what
  • Monitoring what exactly is being downloaded or even attempted

Keep reading, if you’d like to know the process I took to acquire the above.

hosts file

Most/all Operating Systems have a hosts file.

You can add all the dodgy domains you want blocked, to your hosts file and direct them to localhost.

Example of hosts file with blocked domains

Providing your hosts file is kept up to date.
This is one alternative to blocking these domains.

Example host files

http://hostsfile.mine.nu/downloads/
http://winhelp2002.mvps.org/hosts.htm
http://someonewhocares.org/hosts/

On some systems if you add the dodgy sites to your hosts file, you may experience the “waiting for the ad server” problem.
As far as your browser is concerned, these URL’s don’t exist (because it’s looking at localhost).
Your browser may wait for a timeout for the blocked server.
In this case you could use eDexter to serve up a local image instead of waiting for a server timeout.
At this time, only OS X and Windows versions are available.

There is an alternative.
JavaDog will apparently run on all platforms that have the Java VM.
This doesn’t appear to be in the Debian repositories. At least not the ones I’m using.
I read here “As for Edexter, Firefox in Linux doesn’t seem to have the “waiting for the ad server” problem Mozilla in windows had.”

From my experience it does.

I had a quick look at JavaDog for Linux.
Found this site

It can be an administrative pain to keep the hosts file up to date with the additions and removals of domains.
Although Linux users could use the script here to do the updating.
This could be added to a Cron job in Linux.

If your on a windows box you may run into another type of slow down every 25 minutes for 5 minutes with apparently 100% CPU usage resulting in the described DNS cache timeout error.
There is a workaround, but I wouldn’t be very happy with it. Disabling the DNS client service.
If you rely on Network Discovery (enables you to see other computers on your network and for them to see you), this is not going to be a solution.

As stated here
A better Win7/Vista workaround would be to add two Registry entries to control the amount of time the DNS cache is saved.

  • Flush the existing DNS cache (see above)
  • Start > Run (type) regedit
  • Navigate to the following location:
    HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Dnscache\Parameters
  • Click Edit > New > DWORD Value (type) MaxCacheTtl
  • Click Edit > New > DWORD Value (type) MaxNegativeCacheTtl
  • Next right-click on the MaxCacheTtl entry (right pane) and select: Modify and change the value to 1
  • The MaxNegativeCacheTtl entry should already have a value of 0 (leave it that way – see screenshot)
  • Close Regedit and reboot …
  • As usual you should always backup your Registry before editing … see Regedit Help under “Exporting Registry files”

If you decide to give the hosts file a go
On Linux it’s found in /etc
On Windows it’s location is defined by the following registry key
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\DataBasePath

 Usually here

Windows 7/Vista/XP    =    C:\WINDOWS\SYSTEM32\DRIVERS\ETC
Windows 2K               =    C:\WINNT\SYSTEM32\DRIVERS\ETC

Make sure you backup the hosts file in case anything goes wrong.
Make sure you don’t remove what’s already in your default hosts file. especially the first line that has the loop back address

127.0.0.1              localhost
127.0.1.1              [MyComputerName].local          [MyComputerName]

Just add the new entries at the bottom of the hosts file.
Remove any duplicate entries.
You will then have to flush your DNS cache if you have one.

If your on windows

Clear your browsers cache.
Close all browsers.
From a cmd prompt run the following

ipconfig /flushdns

or reboot the machine.

If your on Linux (Debian)

Clear your browsers cache.
That may be all you need to do.
Otherwise
At the command prompt (as root) try

/etc/init.d/nscd restart

or for other Linux distros
“killall -hup inetd” (without the quotes) which will restart the inetd process and should not require a reboot.
I found that just updating the file was enough to see the changes,
as my default Debian Lenny install doesn’t have a DNS cache.

Adblock Plus

 I decided to just give the Firefox add-on Adblock Plus a try
as I thought it would be allot easier and less (zero) administrative overhead.
Just make sure you’ve got a good filter subscription selected. I used EasyList (English).
As I was on Lenny. Adblock Plus wasn’t available for Iceweasel (firefox on debian) 3.0.6 unless I installed the later version of Iceweasel from the backports.debian.org repository.
I looked in the Tools->Add-ons->Get Add-ons and searched for Adblock Plus.
I was planning on performing a re-install of Debian testing soon anyway, but was keen on giving Adblock Plus a try now.

Installing Iceweasel (firefox) from backports

Most won’t have to do this, but I’m still on old stable.
This site is quite helpful
For most people they will just have to make a change to their /etc/apt/sources.list
If you are running Debian Lenny you would have to add the following line:

deb http://backports.debian.org/debian-backports lenny-backports main contrib non-free

For later versions of Debian substitute the version specific part with your versions code name.
As I’m using apt-proxy to cache my packages network wide, I had to make sure I had the following section in the /etc/apt-proxy/apt-proxy-v2.conf file

[backports]
 ;; backports
 backends = http://backports.debian.org/debian-backports
 min_refresh_delay = 1d

and the following in the client pc’s /etc/apt/sources.list

deb http://[MyAptProxyServer]:[MyAptProxyServersListeningPort]/backports lenny-backports main contrib non-free

You can see how the directory structure works for the repositories.
In this case have a look at http://backports.debian.org/debian-backports/
in dists you will see lenny-backports as a subdirectory.
Within lenny-backports you’ll see main, contrib and non-free
Now just add the below section to the client pc’s /etc/apt/preferences file
In my case I didn’t have this file, so created it.
What’s this for?
If a package was installed from Backports and there is a newer version there,
it will be upgraded from there.
Other packages that are also available from Backports will not be upgraded to the Backports version unless explicitly stated with
-t lenny-backports
Check the apt_preferences man page as usual for in depth details.

# APT PINNING PREFERENCES
 Package: *
 Pin: release a=lenny-backports
 Pin-Priority: 200

Now as root

apt-get update
apt-get -t lenny-backports install iceweasel

Now because we’ve added the /etc/apt/preferences file,
when ever there are updates to the backported version of iceweasel,
we’ll get them for Iceweasel when we do a

apt-get upgrade

Now through iceweasel’s Tools->Add-ons->Get Add-ons
and a search for Adblock Plus now revealed the plugin.
Installed it and selected the EasyList (English) filter subscription.
Browsed some sites I knew there were popups and ads I didn’t want and it worked great!
Adblock Plus gives good visibility for each request made,
as to what it’s blocking, could possibly block etc, through it’s Close blockable items menu Ctrl+Shift+V

So personally I think I’d stick with the add-on (for firefox users that is) going forward, as it seemed like it just worked.
Not sure about other browser platforms.

Now I use this with the NoScript pluggin also,
which I find great at stopping javascript, flash and other executable code from being run from domains I’m not expecting it to be run from.

I’m also using OpenDNS as name servers.
They provide allot of control over what can be accessed by way of domain.

You can also provide custom images and messages to be displayed for requested sites that you don’t want to allow.
Statistics of who on your network is accessing which sites and which sites they are attempting to access.
Plus allot more.

I’m looking into using
Squid with
Snort or
Privoxy
and  to take care of allot more.
Provide anonymous web browsing.
Content caching.

Resources

http://hostsfile.mine.nu/
http://winhelp2002.mvps.org/hosts.htm
http://www.accs-net.com/hosts/hostsforlinux.html

There is also a good pod-cast on the hosts file by Xoke here.

Password-less Repository Authentication for Mercurial

June 3, 2011

I setup a free account a short while ago at bitbucket with the intention of creating a version control repository for Hg.
So far this has worked out well.

Although every time I communicated with the back end repo I’d have to enter my credentials.
I realized if I added my user name to the URL, I’d only receive a password prompt.

https://MyUserName@bitbucket.org/MyUserName/MyRepoName

If I also added my password in the URL I wouldn’t be prompted for anything.

https://MyUserName:MyPassword@bitbucket.org/MyUserName/MyRepoName

Obviously I didn’t want to be entering this each time I communicated with my back end repo,
also especially with my password in plain text on the screen.
So I did a little research.

TortoiseHg comes bundled with the keyring extension.
So if your using TortoiseHg you don’t even have to install it.
Just add the following to your mercurial.ini file in your user directory.

[extensions]
mercurial_keyring=

You’ll also have to edit your repository specific hgrc file.
If this file doesn’t already exist, create it.

[paths]
bitbucket = https://LethalDuck@bitbucket.org/LethalDuck/code-scripts
default = https://LethalDuck@bitbucket.org/LethalDuck/code-scripts

You could put your password in the above URL too, but that kind of defeats the purpose of using the keyring.
So you associate your username with the URL you are wanting to communicate with.
Now you can add as many URL’s as you like.
As you can see I’ve just added the same one twice, as an experiment to see how it’s handled.
In Repository Explorer, it’ll look like this…

Now when you select either of the URL’s to push to or pull from,
the keyring will prompt for your password once and store it encrypted.

After that, the stored encrypted password is used
and no more prompt.

Resources:
http://stackoverflow.com/questions/1997601/store-password-in-tortoisehg

Using PSCredentials

June 2, 2011

I’ve been working on a small project that shuts down machines attached by network and of course power feed to an APC Smart-UPS.
The code that was shutting down the guests required authentication to be passed to the receiving services.

I decided to give the following PowerShell cmdlets a try.

  • Get-Credential
  • ConvertTo-SecureString

———————————————————————————-

Script that creates the password file

(Set-Credential.ps1) looks like this:

Param($file)
$credential = Get-Credential
$credential.Password | ConvertFrom-SecureString | Set-Content $file

Get-Credential prompts for a username and password and creates the PSCredential associating the password with the username.
ConvertFrom-SecureString from the PS documentation…
The ConvertFrom-SecureString cmdlet converts a secure string
(System.Security.SecureString) into an encrypted standard string (System.String).
Then writes the string to the file specified.

Set-Credential can be invoked like this:

C:\Scripts\UPS\Set-myCredential.ps1 C:\Scripts\UPS\mp.txt

———————————————————————————-

Script that reads the password file

(Get-Credential.ps1) into a SecureString.
Then creates the PSCredential based on the username provided and the password as a SecureString.
Then returns the PSCredential:

Param($user,$passwordFile)
$password = Get-Content $passwordFile | ConvertTo-SecureString
$credential = New-Object System.Management.Automation.PsCredential($user,$password)
$credential

———————————————————————————-

By the look of it, when creating the encrypted password Get-Credential adds some machine specific information.
As the password file is not machine agnostic (can’t be shared or tranfered).

From my PowerShell script that loaded the assembly into memory and started the shutdown procedure, it looked something like this.

param (
   [parameter(Mandatory=$true, position=0)][string] $scriptPath,
   [parameter(Mandatory=$true, position=1)][string] $fileServerName,
   [parameter(Mandatory=$true, position=2)][string] $fileServerUser,
   [parameter(Mandatory=$true, position=3)][string] $vSphereServerName,
   [parameter(Mandatory=$true, position=4)][string] $vSphereServerUser
)

Set-StrictMode -Version 2.0
# Creates a .net assembly in memory containing the PowerOffUPSGuests class.
# Then we call the InitShutdown passing the details of the machines that need to be shutdown.

$credentialRetrievalScript = Join-Path -Path $scriptPath -ChildPath 'Get-Credential.ps1'
$fileServerUserPwLocation = Join-Path -Path $scriptPath -ChildPath 'FileServerPw.txt'
$vSphereServerUserPwLocation = Join-Path -Path $scriptPath -ChildPath 'VMHostPw.txt'

# names of the ServerController's I.E. the collection of servers that will be shutdown
# these class's need to exist in the $scriptPath and derive from ServerController
$freeNASController = 'FreeNASController'
$vMServerController = 'VMServerController'

# instantiate the credential objects
$fileServerCredential = & $credentialRetrievalScript $fileServerUser $fileServerUserPwLocation
$vSphereServerCredential = & $credentialRetrievalScript $vSphereServerUser $vSphereServerUserPwLocation

# add the assembly that does the work.
Add-Type -Path .\PowerOffUPSGuests.dll

# instantiate a ServerAdminDetails for each server we want to shutdown
$fileServerAdminDetailsInstance = New-Object -TypeName BinaryMist.Networking.Infrastructure.ServerAdminDetails -ArgumentList $freeNASController, $fileServerName, $fileServerCredential
$vSphereServerAdminDetailsInstance = New-Object -TypeName BinaryMist.Networking.Infrastructure.ServerAdminDetails -ArgumentList $vMServerController, $vSphereServerName, $vSphereServerCredential

# instantiate a PowerOffUPSGuests
$powerOffUPSGuestsInstance = New-Object -TypeName BinaryMist.Networking.Infrastructure.PowerOffUPSGuests

# create generic queue and populate with each of the ServerAdminDetail items
# ServerAdminDetails is the base class of FileServerAdminDetails and vSphereServerAdminDetails
$serverAdminDetailsQueueInstance = .\New-GenericObject System.Collections.Generic.Queue BinaryMist.Networking.Infrastructure.ServerAdminDetails
$serverAdminDetailsQueueInstance.Enqueue($fileServerAdminDetailsInstance)
$serverAdminDetailsQueueInstance.Enqueue($vSphereServerAdminDetailsInstance)

$powerOffUPSGuestsInstance.InitShutdownOfServers($serverAdminDetailsQueueInstance)

To debug my library code, I needed to run it somehow.
So I just wrote a small test which passed the PSCredential instance to the code that was going to shutdown the UPS guest.

private PSCredential GetMyCredential(string userName, string pWFileName) {

   string encryptedPw;
   using (StreamReader sR = new StreamReader(pWFileName)) {
   //read the encrypted bytes into a string
   encryptedPw = sR.ReadLine();
   }

   PSCredential pSCredential;
   using(SecureString pW = new SecureString()) {
      char[] pWChars = encryptedPw.ToCharArray();
      foreach(char pWChar in pWChars) {
         pW.AppendChar(pWChar);
      }
      pSCredential = new PSCredential(userName, pW);
   }
   return pSCredential;
}

[TestMethod]
public void TestInitFileServerShutdown() {
   _powerOffUPSGuests = new PowerOffUPSGuests(ConfigurationManager.AppSettings[LogFilePath]);

   PSCredential fileServerCredential = GetMyCredential(
      ConfigurationManager.AppSettings[FileServerUser],
      Path.GetFullPath(ConfigurationManager.AppSettings[FileServerUserPwFile])
   );

   _powerOffUPSGuests.InitFileServerShutdown(ConfigurationManager.AppSettings[FileServer], fileServerCredential);
}

Inspiration