Blog

Patching Solaris with Patch Check Advanced

Patching Solaris with Patch Check Advanced

Neil H. Watson

Abstract:

This document describes how use Patch Check Advanced to report on and patch Solaris hosts.


Contents

About PCA

Patch Check Advanced is an open source third party tool that claims to be superior to Sun's smpatch tool. PCA was first published in 2003. PCA can generate patch reports, download and install patches based upon both Sun's and the user's criteria. PCA can even be used to report on or patch systems that do not have Internet access.

PCA works by comparing certain host information derived from uname -a, showrev -p and pkginfo -x against the patch information file, patchdiag.xref, published by Sun (http://sunsolve.sun.com/patchdiag.xref). PCA is designed to be portable so that reports can be generated and required patches can be downloaded on a host that is not the target host. This is done by copying the host and Sun files to the third party host.

In order to download patches PCA must be given credentials for a Sunsolve account. A free account can be used but the patches available will be limited to security and driver patches only. If you use a free account PCA may report missing or skipped patches when attempting to download. These are the patches that the free account cannot access.

PCA is written in perl. It is self documented using perldoc. The PCA program's first line calls the shell (#!/bin/sh). PCA may not work this way with certain shells (e.g. cygwin or Solaris' sh). Change this to a perl call (e.g. #!/bin/perl) and PCA will work as expected.

The following examples show how PCA might be used.

pca -l missingrs
PCA will automatically gather uname, showrev and pkginfo information from the current host, download the xref file from Sun and generate a patch report of all missing recommended or security patches. See PCA¿s documentation about operands for more information.

pca -X . -l missingrs
PCA will generate the same report as above but it will not download Sun's xref file. Instead PCA will consult the current directory (.) for the required file.

pca -f . -l missingrs
PCA will generate the same report, will download Sun's xref file but, will consult local uname.out, showrev.out and pkginfo.out files. These files can be generated from another target host (e.g. uname -a > uname.out) and moved to another host for processing.

pca -askauth -d missingrs
PCA will automatically gather uname, showrev and pkginfo information from the current host, download the xref file from Sun and download all missing recommended or security patches. PCA will prompt for Sunsolve account credentials before attempting to download patches. See PCA¿s documentation about operands for more information.

pca -askauth -X . -d missingrs
PCA will download patches as above but it will not download Sun's xref file. Instead PCA will consult the current directory (.) for the required file.

pca -askauth -f . -d missingrs
PCA will download patches as above, will download Sun's xref file but, will consult local uname.out, showrev.out and pkginfo.out files. These files can be generated from another the target host (e.g. uname a > uname.out) and moved to another host for processing.

For the most up to date information on PCA one should consult the official web site (http://www.par.univie.ac.at/solaris/pca/intro.html).

Getting remote reports

Suppose you have a group of hosts that do not have Internet access. How will you generate patch reports?

The script sshdo allows for the files to be copied or remote commands to be run sequentially across a list of hosts read from a separate file. It assumes that you have the same remote account across all hosts. Key pair authentication will prevent you from being prompted for a password for every host. To see the actual script please consult the appendix (A).

Copy PCA to all hosts:
sshdo -p -c /path/to/pca /remote/path

Copy Sun's xref file to all hosts:
sshdo -p -c path/to/patchdiag.xref /remote/path

Create a remote patch report labeled with the remote hostname and the date:
sshdo './pca -X . -l missingrs > pca-$(hostname)-$(date '+%Y-%m-%d').txt'

Copy the patch report from the remote hosts back to the central host:
sshdo -g -c 'pca-*' /local/path

Patching from remote reports

PCA cannot download patches by consulting a patch report. The pca-patch-get script (see Appendix B) uses existing patch reports to download the latest versions of the required patches from Sunsolve. For example:
pca-patch-get -u username -p secret pca-hostname-2008-09-25.txt

Installing patches

PCA can install a group of patches in the correct order provided it has host information and the xref file. Following our current example, we must next copy all of the downloaded patches to the target host. Also be sure that a copy of PCA and the xref file are still available on the target host. When you are ready install the patches with:
pca -X /path/to/xref -i *.zip

This assumes that the patch files are located in the current directory. You might also use the -I option in place of -i. This option is a pretend or dry run. No patches are actually installed but you will be able to see what would have been done. PCA actually uses patchadd to install the patches so the usual system logs will be available.

Caveats

The Sunsolve site has been known to move files and to be slow at times. PCA should be kept up to date so that it will always look in the right place for files to download. The pca-patch-get script may also have to be changed. PCA also has an option (dltries) to allow it to attempt a download multiple times.

Proxy

When combined with a web server PCA can act as Sunsolve proxy. Using this method PCA is used as a cgi script. PCA on a remote host is instructed via arguments to query the proxy server instead of Sunsolve. The proxy server then queries Sunsolve on behalf of the client. This can save a considerable amount of bandwidth since every patch need only be downloaded once. See PCA's documentation about operands for more information.

Configuration management

Among other things configuration management allows centralized distribution and collection of files. Such a service (e.g. Cfengine) would allow PCA and support files to be automatically distributed to all relevant hosts. Further, current patch reports could be automatically generated and stored in a central location. This offers an always current report of host patch levels.


sshdo

#!/bin/bash

# Limit path for good security practice
OLDPATH=$PATH
export PATH=/bin:/usr/bin

# Name me!
PROGRAM=sshdo
VERSION=1.1

local="."

# This list of hosts assumes a working DNS.  Another
# option is to use an ~/.ssh/config file.  IP addresses
# can also be used.  As user name may also be required.
HOSTS="$(awk '{print $1}' ~/etc/my-hosts)"

usage(){
    cat <<EOF
    $PROGRAM issues remote commands or copies files to all servers
    sequencially.
    USAGE:  $PROGRAM 
        [ -?|-h HELP ]
        [ -v ] VERSION
        [ -r|--recurse ] recursive copy BEFORE -c
        [ -g|--get ] get files BEFORE -c
        [ -p|--put ] put files BEFORE -c
        [ -c|--copy ] COPY from to
        [ "remote command" ] 
EOF
}

version(){
    echo "$PROGRAM version $VERSON"
}

killagent(){
    eval "$(ssh-agent -k)" 2>1 1>/dev/null
}

error(){
# Errors are sent to stderr

    # This syslog action need only be used on hosts that have a running syslog
    #logger -s -t $PROGRAM "$@, $STATUS $ERROR"
    echo "Error: $@"
    usage
    exit 1
}

# get opts
while test $# -gt 0
do
    case $1 in

        # For each option
        #-o)
        #shift
        #option="$1"
        #;;
        # Add custom options ABOVE the defaults below.

        # For remote copying get from and to
        --copy | --cop | --co | --c | -copy | -cop | -co | -c)
        shift
        cfrom="$1"
        shift
        cto="$1"

        if [ -z "$cfrom" ] || [ -z "$cto" ]
        then
            error "Missing scp arguements"
        fi
        copy=1
        ;;

        --recurse | --recurs | --recur | --recu | --rec | --rc | --r|        -recurse | -recurs | -recur | -recu | -rec | -rc | -r)
        recurse="-r"
        ;;

        --get | --ge | --g | -get | -ge | -g)
        get=1
        ;;

        --put | --pu | --p | -put | -pu | -p)
        put=1
        ;;

        --version | --versio | --versi | --vers | --ver | --ve | --v |        -version | -versio | -versi | -vers | -ver | -ve | -v)
        version
        exit 0
        ;;

        --help | --hel | --he | --h | --? |        -help | -hel | -he | -h | -?)
        usage
        exit 0
        ;;

        -*)
        error "Unrecognized option: $1"
        ;;

        *)
        break
        ;;
    esac
    shift
done

# Get remote command
rcmd=$1

# Check for required ops
if [ -z "$rcmd" ] && [ "$copy" -ne 1 ]
then
    error "Missing remote command option"
fi
if [ "$copy" -eq 1 ] && [ -z $get ] && [ -z $put ]
    then
        error "Missing get or put"
fi

# Kill ssh-agent on any exit
#trap "killagent; exit" EXIT
# Load private key into ssh-agent but, only for 5 minutes
#eval "$(ssh-agent -t 300)" 2>1 1>/dev/null
# Add private keys to ssh-agent
#ssh-add

# Main matter.  Perform tasks for each host in list
for h in $HOSTS
do

    # Remote command if from and to are empty
    if [ -z "$cfrom" ] && [ -z "$cto"  ]
    then
        ssh $h "$rcmd"

    # Else we want to copy
    else
        if [ $get -eq 1 ]
        then
            scp $recurse ${h}:$cfrom $cto
        elif [ $put -eq 1 ]
        then
            scp $recurse $cfrom ${h}:${cto}
        fi
    fi
done

exit 0


pca-patch-get

#!/bin/sh

# Limit path for good security practice
OLDPATH=$PATH
export PATH=/bin:/usr/bin

# Name me!
PROGRAM=pca-patch-get
VERSION=0.1
USAGE="Downloads patches defined by pca report from Sunsolve.
    pca-patch-get -u <username -p <password> <pca-patch-report.txt>"

usage(){
    cat <<EOF
    USAGE:  $PROGRAM 
    $USAGE
        [ -?|-h HELP ]
        [ -v ] VERSION
EOF
}

version(){
    echo "$PROGRAM version $VERSON"
}

error(){
# Errors are sent to stderr and to syslog
    logger -s -t $PROGRAM "$@, $STATUS $ERROR"
    usage
    exit 1
}
local="."

# get opts
while test $# -gt 0
do
    case $1 in

        # For each option
        #-o)
        #shift
        #option="$1"
        #;;
        # Add custom options ABOVE the defaults below.

        -p)
        shift
        pass=$1
        ;;

        -u)
        shift
        user=$1
        ;;

        --version | --versio | --versi | --vers | --ver | --ve | --v |        -version | -versio | -versi | -vers | -ver | -ve | -v)
        version
        exit 0
        ;;

        --help | --hel | --he | --h | --? |        -help | -hel | -he | -h | -?)
        usage
        exit 0
        ;;

        -*)
        error "Unrecognized option: $1"
        ;;

        *)
        break
        ;;
    esac
    shift
done

file=$1

# Check for required ops
if [[ -z $user ]] || [[ -z $pass ]] || [[ -z $file ]]
then
    error "Missing option(s)"
fi

patches=$(grep -oE '^[[:digit:]]{6}' $file)

for p in $patches
do
     wget --http-user=$user --http-password=$pass --no-check-certificate         --auth-no-challenge         https://sunsolve.sun.com/pdownload.do?target=$p         -O $p.zip
done



Neil Watson 2008-10-23