Ergonomics Recommendations updated!

I have updated Ville’s Ergonomics Recommendations as of today. Since the list was previously reviewed and updated a few years ago, many links had to be updated along with the content that now reflects the technology today. Hopefully the resource provides useful pointers for anyone looking for information on computer workstation ergonomics!

Note that you can always access the ergonomics resource easily from the blog’s main menu.

Chrome v18, self signed certs, “signed using a weak signature algorithm”, and an internal CA

Today when I was accessing some internal resources that are protected with an SSL cert that has been signed by the internal CA, I got an SSL error I hadn’t seen before: “This site’s security certificate is signed using a weak signature algorithm!” (see image below). With a quick test it was clear this was only an issue with Chrome. And a few Googlings later I found it was thanks to a recent auto-upgrade to Chrome 18. Most of the Google hits were discussing this error in the context of Facebook – apparently some facebook servers are configured with an old, expired intermediate certificate. But this was not the case with my server cert, signed with the internal CA cert.

Digging some more, I came across a post by Dave Christiansen where he points out an obscurely documented switch for openssl req command. That works great for single self signed certs, but what if you’re using an internal CA? The CA cert can be created with “-sha512″ command using “openssl req” (as outlined in Dave’s post), but then when you sign server certs with “openssl ca” – even when you’ve created the CA cert with the “-sha512″ switch – Chrome still throws the same error.

The trick is to specify an equally obscurely documented argument “sha512″ for the “-md” switch with “openssl ca”, like so:

openssl ca -md sha512 -config /etc/ssl/openssl.cnf.internalCA -policy policy_anything -in my.server.name.csr -out my.server.name.pem -keyfile ../private/internalCA.key -days 3650

Now the signed server certificate reflects “sha512RSA” as the Signature algorithm, and the Chrome error is gone.

Trackball ergonomics

As availability of the remaining Microsoft Trackball Explorers is waning on eBay (or perhaps you’d like to buy a new device rather than a vintage piece whose bearings have worn down, buttons stick, etc.), I have been considering the alternatives. There are few options, although their ergonomics is not quite as spot on as the venerable TBE‘s which fit like a glove.

But they are workable, and human beings adapt. :) There is an interesting point I just realized, and I thought of sharing it. Kensington’s misleadingly named Expert Mouse works very well in situations where the work surface is low (as it should be for decent ergonomics) so that it is possible to use a third party arm-rest (my preference is “330 000″ series ErgoRest forearm support) with it. When your hand ‘floats’ above the trackball, it is quite pleasant to use for extended periods of time.

However, in many situations the desk height is too high and Expert Mouse suddenly becomes much less pleasant to use. Its own wrist support is not that comfortable, especially when more of your arm’s weight is on it. In such situations Logitech’s wireless M570 (for some reason “M570″ sounds like a model of Mercedes-Benz to me ;) ) works reasonably well. M570 is like a TBE in reverse. For some reason Logitech opted to place the ball at the thumb and button/scroll wheel controls at the forefinger/middle finger. I wish Logitech introduced a model with the controls (trackball/buttons+scroll wheel) reversed and we’d essentially have a new TBE… but even as it is, it works reasonably well. If you haven’t used a thumb-controlled trackball before it will take you a week or two to become fluent with it, and even then the accuracy is not quite as good as it would be with a forefinger-controlled trackball. But it’s close enough for M570 to work well. And M570 is small enough to lug along with your laptop – a lucky co-incidence since I think M570 works better in less-than-optimal ergonomic settings which you are more likely to encounter while on the road.

N.B.
While both manufacturers provide drivers/utilities for their respective devices, be sure to check out X-Mouse Button Control software as it is able to teach your trackball cool new workflow-improving tricks!

NFS automount evolves

I’ve updated the NFS automount script that provides “self-healing” NFS mounts. The script now allows a mount to be defined as read-write or read-only, and then subsequently monitors that the share is mounted as R/W or R/O (of course, it can’t mount a share that has been shared as R/O as R/W). Both Linux (tested on CentOS 6.1) and FreeBSD versions are provided.

Since various systems can provide cross-mounts via NFS, and they may be started/rebooted at the same time, various shares may or may not be available at each system’s boot time. By utilizing this script the mounts become available soon after the respective share becomes available (simply adjust the run frequency in crontab to the needs of your specific application). Also, by not adding the NFS mount points in fstab the boot process is not delayed by a share that is not [yet] available.

First for CentOS/Linux:

#!/bin/sh

SHELL=/bin/sh
PATH=/sbin:/bin:/usr/sbin:/usr/bin

# set mount/remount request flags
mount=false
remount=false

# remote system name
remotesystem="$1"

# rw/ro
if [ "$2" = "rw" ]; then
    mountmode="-w"
else
    mountmode="-r"
fi

# remote share name
remoteshare="$3"

# local mount point
mountpoint="$4"

# file to indicate local mount status
testfile=${mountpoint}/"$5" 

# rw test file
rw_testfile=${mountpoint}/nfs_enforcer_rw_testfile

# command locations
pingcmd=/bin/ping
showmountcmd=/usr/sbin/showmount
grepcmd=/bin/grep
mountcmd=/bin/mount
umountcmd=/bin/umount
statcmd=/usr/bin/stat
touchcmd=/bin/touch
rmcmd=/bin/rm

# --- end variables ---

# make sure the mountpoint is not stale
statresult=`${statcmd} ${mountpoint} 2>&1 | ${grepcmd} "Stale"`

if [ "${statresult}" != "" ]; then
   #result not empty: mountpoint is stale; remove it
   ${umountcmd} -f ${mountpoint}
fi

# ping the remote system (2 sec timeout)
${pingcmd} -w2 -c1 -q ${remotesystem} > /dev/null 2>&1

# make sure the remote system is reachable
if [ "$?" -eq "0" ]; then

   # query the availability of the remote share; not empty result indicates OK
   offsiteshare=`${showmountcmd} -e ${remotesystem} | ${grepcmd} "${remoteshare}"`
   if [ "${offsiteshare}" != "" ] ; then

      # make sure the local mount point (directory) exists (so that [re-]mount, if necessary, is valid)
      if [ -d ${mountpoint} ] ; then

         localmount=`${mountcmd} | ${grepcmd} "${mountpoint}"`

         # make sure the share test file is _not_ present (to make sure the mountpoint is inactive)
         if [ ! -f ${testfile} ] ; then

            # make sure the local mountpoint is inactive (double checking)
            if [ "${localmount}" = "" ] ; then

               # all set to go; request mount
               mount=true
            fi

         else 

            # make sure the local mountpoint is active (double checking)
            if [ "${localmount}" != "" ] ; then

               # attempt to create a test file..
               ${touchcmd} ${rw_testfile} > /dev/null  2>&1

               # ..and test its existence; first handle RW mounted shares:
               if [ -f ${rw_testfile} ] ; then

                  # share was RO requested
                  if [ "$2" = "ro" ]; then
                     remount=true
                  fi

                  # Delete the testfile
                  ${rmcmd} ${rw_testfile}

               # hanle RO mounted shares:
               else

                  # share was RW requested
                  if [ "$2" = "rw" ]; then
                     remount=true
                  fi
               fi
            fi
         fi
      fi
   fi
fi

# perform remount (unmount, request mount)
if $remount ; then
   ${umountcmd} -f ${mountpoint}
   mount=true
fi

# perform mount when so requested
if $mount ; then
   ${mountcmd} ${mountmode} -t nfs ${remotesystem}:${remoteshare} ${mountpoint}
fi

exit 0

Then for FreeBSD/UNIX:

#!/bin/sh

SHELL=/bin/sh
PATH=/etc:/bin:/sbin:/bin:/usr/bin:/usr/sbin:/usr/local/bin

# set mount/remount request flags
mount=false
remount=false

# remote system name
remotesystem="$1"

# rw/ro
if [ "$2" = "rw" ]; then
    mountmode="-w"
else
    mountmode="-r"
fi

# remote share name
remoteshare="$3"

# local mount point
mountpoint="$4"

# file to indicate local mount status
testfile=${mountpoint}/"$5" 

# rw test file
rw_testfile=${mountpoint}/nfs_enforcer_rw_testfile

# command locations
pingcmd=/sbin/ping
showmountcmd=/usr/bin/showmount
grepcmd=/usr/bin/grep
mountcmd=/sbin/mount
umountcmd=/sbin/umount
statcmd=stat
touchcmd=/usr/bin/touch
rmcmd=/bin/rm

# --- end variables ---

# make sure the mountpoint is not stale
statresult=`${statcmd} ${mountpoint} 2>&1 | ${grepcmd} "Stale"`

if [ "${statresult}" != "" ]; then
   #result not empty: mountpoint is stale; remove it
   ${umountcmd} -f ${mountpoint}
fi

# ping the remote system (2 sec timeout)
remoteping=`${pingcmd} -c1 -o -q -t2 ${remotesystem} | grep " 0.0%"`

# make sure the remote system is reachable
if [ "${remoteping}" != "" ] ; then

   # query the availability of the remote share; not empty result indicates OK
   offsiteshare=`${showmountcmd} -e ${remotesystem} | ${grepcmd} "${remoteshare}"`
   if [ "${offsiteshare}" != "" ] ; then

      # make sure the local mount point (directory) exists (so that [re-]mount, if necessary, is valid)
      if [ -d ${mountpoint} ] ; then

         localmount=`${mountcmd} | ${grepcmd} "${mountpoint}"`

         # make sure the share test file is _not_ present (to make sure the mountpoint is inactive)
         if [ ! -f ${testfile} ] ; then

            # make sure the local mountpoint is inactive (double checking)
            if [ "${localmount}" = "" ] ; then

               # all set to go; request mount
               mount=true
            fi

         else

            # make sure the local mountpoint is active (double checking)
            if [ "${localmount}" != "" ] ; then

               # attempt to create a test file..
               ${touchcmd} ${rw_testfile} > /dev/null  2>&1

               # ..and test its existence; first handle RW mounted shares:
               if [ -f ${rw_testfile} ] ; then

                  # share was RO requested
                  if [ "$2" = "ro" ]; then
                     remount=true
                  fi

                  # Delete the testfile
                  ${rmcmd} ${rw_testfile}

               # hanle RO mounted shares:
               else

                  # share was RW requested
                  if [ "$2" = "rw" ]; then
                     remount=true
                  fi
               fi
            fi
         fi
      fi
   fi
fi

# perform remount (unmount, request mount)
if $remount ; then
   ${umountcmd} -f ${mountpoint}
   mount=true
fi

# perform mount when so requested
if $mount ; then
   ${mountcmd} ${mountmode} -t nfs ${remotesystem}:${remoteshare} ${mountpoint}
fi

exit 0

You should run the automount script from a runfile, like so:

#!/bin/sh

NFS_ENFORCE=/usr/local/sbin/nfs_enforcer

# Separate the following parameters with spaces:
#
# - nfs enforcer command (set above)
# - remote system name (must be resolvable)
# - read/write (rw) or read-only (ro); NOTE: share may be read-only regardless of how this is set
# - remote share name (from remote's /etc/exports)
# - local mount point (existing local directory)
# - share test file (an immutable file on the share)

# e.g.
# $NFS_ENFORCE dbsysvm rw /nfs4shares/conduit /mnt/dbsys_conduit .conduit@dbsysvm
# or (for local remount read-only)
# $NFS_ENFORCE localhost ro /var/web/projects/repository /mnt/rorepo .repository@localhost

$NFS_ENFORCE localhost ro /var/web/projects/repository /mnt/rorepo .repository@localhost

exit 0

..and call the the above runfile from crontab:

*/10  *  *  *  *  root  /usr/local/sbin/nfs_enforcer.batch > /dev/null