rhel5 | arfore dot com

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.

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.

During the migration of a production system from Solaris 10 to RedHat Enterprise Linux 5, I discovered that I had a problem with a couple of my LDAP scripts.  The commands being run were standard ldapsearch and ldapmodify commands in a format similar to the following:

ldapsearch -h hostname.domain.com -p 389 -b o=organisation -D cn=admin -w password cn=foobar
ldapmodify -h hostname.domain.com -p 389 -b o=organisation -D cn=admin -w password -f updates.ldif

Each time I ran the commands I got the following error:

SASL/EXTERNAL authentication started
ldap_sasl_interactive_bind_s: Unknown authentication method (-6)
        additional info: SASL(-4): no mechanism available:

It turns out that the versions of the ldapsearch and ldapmodify commands that comes with RHEL5 are based on the standard OpenLDAP code.  The OpenLDAP code defaults to expecting an SASL authentication mechansim on the server-side.  Given that the LDAP server I am connecting to is a iPlanet 5.1 LDAP server, it is not configured to understand the SASL authentication types.

The solution is to add the -x option to the commands:

ldapsearch -x -h hostname.domain.com -p 389 -b o=organisation -D cn=admin -w password cn=foobar
ldapmodiy -x -h hostname.domain.com -p 389 -b o=organisation -D cn=admin -w password -f updates.ldif

This command option specifies that the command should be executed using simple authentication instead of SASL.

When doing system administration it is often more convenient to connect to a server through some sort of remote connection setup rather than having to sit at a console in a datacenter.  The comfort of one’s office (or living-room) is often far superior in terms of noise and temperature than the environs of the datacenter itself.

When setting up the RHEL5 server this week here at VSU, I was forced to use the Sun iLOM connection to do the initial install of the server.  While I generally use command-line only tools, the ease of use one gains from the GUI tools can often make some tasks much simpler.  Towards this end I decided to setup the server and my client to allow XDMCP sessions so that I could have full access to the GUI when necessary.

On the server there are a couple of things that you need to configure in order to make this workFirew:

  1. Firewall ports
  2. GDM configuration options

On the client you will need to configure the OS X firewall, as well as use the correct Xephyr connection syntax.
Continue reading