Crowdsource: Help me buy a bag

After my recent iPad acquisition, I realized that now I need a new bag to carry it in. Normally I use a large Healthy Back Bag, produced and sold by AmeriBag. Unfortunately, the iPad’s shape doesn’t lend itself to being carried in the teardrop-shaped bag.  I have narrowed down my choices, and there are oh so many of them, but now I need some help from you, gentle reader.  Each of the images below are linked to the product information page on the bag.

Ristretto for iPad by Tom Bihn

Ristretto for iPad
by Tom Bihn

The Imago - A Laptop Messenger by Tom Bihn

The Imago – A Laptop Messenger
by Tom Bihn

Bellino The Australian Vertical Messenger

The Australian Vertical Messenger
by Bellino

STM Bags Scout Extra Small

Scout Extra Small
by STM Bags

David King and Co. Distressed Leather Unisex Bag

Distressed Leather Unisex Bag
by David King and Co.

[polldaddy poll="3961786"]

XDMCP and a tale of a firewall

Recently we acquired a new firewall to place in between our datacenter and the rest of our network.  This is a fairly standard security procedure used to isolate the servers from the rest of a network that can be loaded with all kinds of nasty spyware, malware and viruses, not to mention really nifty people that want to violate the security of the data.

Security is a two-edged sword for many systems folk. Firewalls are really great security tools, yet they can also get in the way of nice tools that provide access into the servers for remote administration.

Prior to the placement of the new firewall, I often used XDMCP sessions to access my unix servers from the comfort of my office, rather than traipsing to the data center to use the console.  While these servers do have iLOM ports, there are some interface issues that make their use less elegant that I would wish.

After the new firewall entered the equation, I found that my normal XDMCP setup using Xephyr on my iMac no longer worked for some reason.  It appeared that some of the rulesets were blocking either the particular TCP or UDP traffic necessary for the communication to work.  Rather than worry our firewall administrator with troubleshooting the issue, I decided to find another way in via ssh.

It turns out that I could easily tunnel an X11 login session through an ssh session.  Given that I have sshd configured to allow for TCP forwarding I was able to use an Xnest session that was initiated after logging in via ssh.  Here’s the process I used:

First you need to initiate the ssh session while enabling X11 TCP forwarding.  Depending on your particulars this can be done by one of the following commands:

bash-3.2$ ssh -X server.example.com
bash-3.2$ ssh -Y server.example.com

The next command is executed on the server, but the X11 session is actually running under the X11 installation on the local workstation:

Xnest :1 -geometry 1280x1024 -query localhost -terminate

Here’s a breakdown of the command parameters:

:1

determines the X11 screen to be used on the local workstation, screen 0 is the default screen used for X11

-geometry

set the screen resolution to use for the X11 window on the local workstation

-query localhost

determines which host to actually make the connection with

-terminate

closes the XDMCP session once the user logs out

All of this can actually be accomplished with a single step, by chaining the ssh login command with the Xnest command:

ssh -X REMOTESERVERNAME Xnest :1 -geometry 1280x1024 -query localhost -terminate

istatd, rhel5, init.d and me

Recently, while configuring two new RHEL5 webserver nodes at VSU, I decided to install the Linux server for the iStat program.  The iStat program is an iPhone app that will allow you to receive vital stats on your remote servers.  It also gives you a nice interface for both the ping and traceroute network tools.

The installation of the istatd daemon, an open source server for Linux, Solaris and FreeBSD, was quite easy.  The configuration file is easily understood and edited for your particular installation needs, allowing you to change the defaults when necessary, for example I did not want to add an additional user, so I configured istatd to use the monitor account I created for use with Nagios.

One thing that was missing from istatd was an init script to allow for easily controlling the startup and shutdown of the daemon as well as determining what runlevels the daemon should be active in.

To solve this I wrote an init.d script.  These scripts are fairly self-explanatory.  I used the script that starts the xinetd service as my base, since I knew that this one checks to ensure that the networking service is active before it starts the service.

The location of both the binary and the configuration file may vary depending on the installation itself. When I built istatd I used the following configure command:

./configure --sysconfdir=/etc

Here’s how to install the script

  1. Copy the file into /etc/init.d/
    cp istatd /etc/init.d/
  2. make a symbolic link to this file in the rc.d directories for each runlevel specified in the script (note: this may differ based on the runlevels you use in the script.)
    ln -s /etc/init.d/istatd /etc/rc3.d/S99istatd
    ln -s /etc/init.d/istatd /etc/rc4.d/S99istatd
    ln -s /etc/init.d/istatd /etc/rc3.d/S99istatd

Here is the script in it’s entirety, and you can download it as well.

#!/bin/bash
#
# istatd        This starts and stops istatd.
#
# chkconfig: 345 99 01
# description: istatd is a daemon serving statistics to your \
#              iStat iPhone application from Linux, Solaris & FreeBSD. \
#              istatd collects data such as CPU, memory, network and \
#              disk usage and keeps the history. Once connecting from \
#              the iPhone and entering the lock code this data will be \
#              sent to the iPhone and shown in fancy graphs.
#
# processname: /usr/local/bin/istatd
# config: /etc/istat.conf
# pidfile: /var/run/istat/istatd.pid
 
# Source function library.
. /etc/init.d/functions
 
# Get config.
test -f /etc/sysconfig/network && . /etc/sysconfig/network
test -f /etc/istat.conf
 
# Check that we are root ... so non-root users stop here
[ `id -u` = 0 ] || exit 1
 
# Check that networking is up.
[ "${NETWORKING}" = "yes" ] || exit 0
 
[ -f /usr/local/bin/istatd ] || exit 1
[ -f /etc/istat.conf ] || exit 1
 
RETVAL=0
 
prog="/usr/local/bin/istatd"
 
start(){
    echo -n $"Starting istatd: "
 
    $prog -d --pid=/var/run/istat/istatd.pid
    RETVAL=$?
    echo
    touch /var/lock/subsys/istatd
    return $RETVAL
 
}
 
stop(){
    echo -n $"Stopping istatd: "
    killproc $prog
    RETVAL=$?
    echo
    rm -f /var/lock/subsys/istatd
    return $RETVAL
 
}
 
reload(){
    stop
    start
}
 
restart(){
    stop
    start
}
 
# See how we were called.
case "$1" in
    start)
     start
     ;;
    stop)
     stop
     ;;
    status)
     status $prog
     ;;
    restart)
     restart
     ;;
    reload)
     reload
     ;;
    *)
     echo $"Usage: $0 {start|stop|status|restart|reload}"
     RETVAL=1
esac
 
exit $RETVAL

If you need any assistance creating your own scripts, you might find this link from Novell’s Cool Solutions site: Creating Custom init Scripts.

WD Caviar and Sabrent SRD4 SATA card

A couple of  weekends ago I was rebuilding my home NAS to replace the Openfiler installation with CentOS 5.5.

After adding my two new Western Digital Green Caviar 1TB drives I booted the computer up to find that only the Hitachi drive was being found. After a little troubleshooting I determined that the problem was with the add-in SATA controller, a Sabrent SRD4 4-port controller.

It turns out that the firmware for the Silicon Images 3114CTU chipset support the drives. I found a post online that concerned a different model of drive, and that his problems were resolved with a firmware update.

After researching the chipset and controller I found that while Sabrent didn’t have a firmware update available, there was one available on the Silicon Images website.

After figuring out how to go about running the updater from a boot cd, since this is a Linux machine with no floppy drive, I was able to successfully use my new drives as additional storage!

RHEL5 Password Policy Enforcement

Image Credit: Ohio State University

Yesterday in my post on Solaris 10 Password Policy Enforcement, I outlined the steps necessary to implement the password requirements that have been decided upon in my system environment.  This post will outline the same process on the RHEL5 systems that I admin.  While the policy requirements are the same, the implementation is vastly different.

Desired Policy

To re-cap, here is the policy that is to be applied to normal users:

  • at least 8 characters in length
  • no more than 20 characters in length
  • contain at least on letter
  • contain at least one number
  • forced to change at least every 180 days
  • 15 minute lockout after 5 unsuccessful attempts

Implementation Differences with Solaris 10

While there were a couple of pieces of the desired password policy that I was unable to implement on Solaris 10, the ease of which the others were configured wins the game hands down.  The PAM module setup on Solaris makes it dead simple to update the policy.  All you have to do is to change the various tunable settings.  And they are all listed in fairly understandable verbiage, no complex or arcane settings.

On the RHEL5 systems I had to delve into the vagaries of PAM module attributes and ordering.  As always, it is important to make backups of any files to protect yourself and allow for disaster recovery. To implement the requirements, I had to edit two files on the system:

  1. /etc/login.defs
  2. /etc/pam.d/system-auth

Implementation Process

It is important during this process to recognize that if you set the PAM requirements incorrectly you can get burned to the point that the root user will be unable to login, forcing you to boot into single-user mode to recover or to boot the system from a live cd and revert the authentication files.

Setting the password expiration requirement and length setting

Before we get into this please note the warning notice from the login.defs file manpage on a RHEL5 system

Much of the functionality that used to be provided by the shadow password suite is now handled by PAM. Thus, /etc/login.defs is no longer used by programs such as: login(1), passwd(1), su(1). Pleaserefer to the corresponding PAM configuration files instead.

It is still important to configure the password length in the login.defs file so that we can account for legacy codebases.

  1. Open /etc/login.defs in your favorite editor
  2. Set the attribute of PASS_MAX_DAYS to be 180
  3. Set the attribute of PAS_MIN_LEN to be 9

Setting the password complexity requirements

Now here is where the going gets real interesting.  Before we look at /etc/pam.d/system-auth a strong caution

Backup up the file before you alter it and open a backup terminal session as the root user before continuing.  If you put the wrong attributes in place or put the PAM directives in the wrong order you will lock yourself, root user and all, out of the system.  At that point you have two options: single user mode recovery from the console or use a live cd to boot the machine and revert to the backup after mounting the filesystem.  Oh, and it is wise to give yourself a delay with either GRUB or LILO because without the delay you won’t be able to change the boot option to allow the single user mode recovery option.

So, the file involved in this process is /etc/pam.d/system-auth and before I go into some of the nitty gritty, here’s the configuration I ended up using:

#%PAM-1.0
# This file is auto-generated.
# User changes will be destroyed the next time authconfig is run.
auth        required      pam_env.so
auth        required      pam_tally2.so deny=6 unlock_time=900
auth        sufficient    pam_unix.so nullok try_first_pass nodelay
auth        requisite     pam_succeed_if.so uid >= 500 quiet
auth        required      pam_deny.so
 
account     required      pam_unix.so
account     sufficient    pam_succeed_if.so uid < 500 quiet
account     required      pam_permit.so
account     required      pam_tally2.so per_user
 
password    required      pam_passwdqc.so min=disabled,disabled,12,9,9 max=20 similar=deny enforce=users retry=3
password    sufficient    pam_unix.so md5 shadow nullok try_first_pass use_authtok
password    required      pam_deny.so
 
session     optional      pam_keyinit.so revoke
session     required      pam_limits.so
session     [success=1 default=ignore] pam_succeed_if.so service in crond quiet use_uid
session     required      pam_unix.so

The retries requirement is implemented using the following line

auth        required      pam_tally2.so deny=6 unlock_time=900

The complexity and length requirements are implements using the following line

password    required      pam_passwdqc.so min=disabled,disabled,12,9,9 max=20 similar=deny enforce=users retry=3

The following line is set to ensure that the retries count is maintained even if the counter for the pam_tally2 module is corrupted

account     required      pam_tally2.so per_user

References

Rather than go into the details of each individual attribute and how they interact, here are the resources used to develop this ruleset.  They contain an large amount of valuable information.

  1. http://wiki.centos.org/HowTos/OS_Protection#head-c6bf533e4f6de1ff3e13d556053fc40bc121e5cc
  2. http://www.openwall.com/passwdqc/README.shtml
  3. http://www.puschitz.com/SecuringLinux.shtml#LockingUserAccountsAfterTooManyLoginFailures
  4. http://www.linux.com/archive/feature/113807