\documentclass{ictlab}

\RCS $Revision: 1.14 $

\usepackage{alltt,key,xr,cols}
\externaldocument[lt-]%
{../../linux_training-plus-config-files-ossi/build/masterfile}

\ifx\pdftexversion\undefined \else
  \usepackage[pdfpagemode=None,pdfauthor={Nick Urbanik}]{hyperref}
\fi

\newcommand*{\labTitle}{Applying OS Updates}
\renewcommand*{\subject}{Operating Systems and Systems Integration}

\providecommand*{\RPM}{\acro{RPM}\xspace}
\providecommand*{\CD}{\acro{CD}\xspace}

\begin{document}

% \tableofcontents

\section{Aim}
\label{sec:aim}

After successfully working through this exercise, You will:
\begin{itemize}
\item understand the importance of applying updates to the operating
  system of servers

\item understand how to apply the updates to Red Hat Linux.

\item understand how to use \RPM and \texttt{rpmfind} to resolve
  software package dependencies

\item understand how to automate the update process
\end{itemize}

\section{Background}
\label{sec:background}

All operating systems contain bugs.  Even Microsoft's OS, despite what
Bill may say (See \url{http://www.cantrip.org/nobugs.html}), contains
bugs.  See for example,
\url{http://www.gcn.com/archives/gcn/1998/july13/cov2.htm}.  And Linux
contains bugs.  Now crackers are just waiting for a new bug to be
uncovered.  The company that provides the OS also will provide updates
to their OS, thanks to \acro{CERT}: \url{http://www.cert.org/}, who
eventually publish information about the bug even if the company does
not. As a system administrator, it is a vitally important part of your
duty to apply updates to important or sensitive computers in your
company.

Here in the \acro{ICT} Department, I have implemented a system that
automatically downloads the current updates for Red Hat Linux from the
Internet every day.  You will use these updates and apply them to your
computer.  The updates are software packages.

You will use the Network File System (\NFS) to \emph{mount} the network
drive containing these updates, and then use the Red Hat Package
Manager (\RPM) to apply these updates to your machine.

The \RPM package manager does far more than allow you to install
updates.  It can also check that the installed software packages are
correctly installed, and verify that none of the programs have been
changed by a cracker (as long as \RPM itself is unchanged!)  See
chapter 25, \emph{Package Management with RPM}, of the \emph{The
  Official Red Hat Linux Customization Guide}, available from the Red
Hat web site at \url{http://www.redhat.com/docs/manuals/linux/}, and
also on the documentation \CDROM (burn a copy on our \CD burner).

\subsection{The RPM Package Manager}
\label{sec:rpm}

The \RPM package manager has a number of basic capabilities: It can
\emph{install} software, \emph{update} software packages,
\emph{remove} packages, \emph{build} software packages, \emph{query}
and \emph{verify} software packages.

Please see section~\vref{lt-sec:rpm} in the \emph{Linux Training
  Materials Project} (the workshop notes we have used in the lab) for
more information about using \RPM to query and verify software
packages.  


\paragraph{Building RPM Packages}

If anyone is interested in building your own \RPM packages, you are
very welcome to see Nick, he may even give you a book about it!  The
online book is called \emph{Maximum RPM}, and is good reading for those
who are interested.

If you find an \RPM package for another version of Linux, it is a good
idea to rebuild it, since that will solve library dependencies.  For
this, you use the \emph{source} \RPM package.  To do this is simple.
For example, suppose you download the latest Emacs package from
\url{ftp://rawhide.redhat.com/pub/redhat/linux/rawhide/SRPMS/SRPMS/emacs-21.1-3.src.rpm}
and want to use it in Red Hat 7.2 instead of the older version there.
All you need do is:
\begin{alltt}
$ sudo rpm --rebuild emacs-21.1-3.src.rpm
\end{alltt}%$
You will see that it requires the \texttt{gettext} package, so you can
download and rebuild that also.
The code compiles, and eventually creates the binary \RPM{}s, which
you can then install:
\begin{verbatim}
$ sudo rpm -Uhv /usr/src/redhat/RPMS/i386/gettext-0.10.40-3.i386.rpm
$ sudo rpm -Uhv /usr/src/redhat/RPMS/i386/emacs-*21.1-3.i386.rpm
\end{verbatim}
Hmm, nice, Emacs version 21 is better!

Table~\vref{tab:rpm} shows the basic \RPM operations that we will use
today.  Table~\vref{tab:rpm-queries} shows more information about how
to make queries using \RPM.

\begin{table}[htb]
  \begin{tabularx}{\linewidth}[t]{@{}>{\ttfamily}llY@{}}
    \toprule%
    \textnormal{\emph{Command}} & \emph{Action} & \emph{Description}\\
    \midrule%
    rpm -i & install & install the software package; do not uninstall
    any previous version of the software.  Use this when installing
    kernels; normally, use the \texttt{upgrade} action. \\
    rpm -U & upgrade & if an older copy of the package has been
    installed, uninstall it and replace it with this newer package.
    Do not delete the configuration files from the old package.
    Otherwise, it is the same as the \texttt{install} action, and is
    what I use most often. \\
    rpm -F & freshen & install this package only if an older version
    of this software package has already been installed.  Otherwise,
    do nothing.  Useful when upgrading software packages.\\
    rpm -e & remove & will completely erase the software package.\\
    \midrule%
    \multicolumn{3}{c}{Useful ``helper'' options}\\
    \midrule%
    -h & hashes & Print fifty hashes (`\textsl{\#}') to show progress
    of
    installation \\
    -v & verbose & print the name of each package as it is installed.
    Useful when installing more than one package at a time.  In
    practice, I always use this option, as well as the \texttt{-h}
    option. \\
    --force & force \texttt{:-)} & For updates, go ahead and force the
    update, even if the same package or a newer one is already
    installed.  Be very careful in using this; understand what you are
    doing.  It can also override dependencies, and you can end up with
    a system that does not work if you use this option carelessly. \\
    \bottomrule
  \end{tabularx}
  \caption{The \RPM options that we use to install and upgrade software.}
  \label{tab:rpm}
\end{table}

\begin{table}[htb]
  \begin{tabularx}{\linewidth}{@{}>{\ttfamily}lY@{}}
    \toprule%
    \textnormal{command} & effect\\
    \midrule%
    rpm -qa \textbar{} less & list all installed software packages\\
    rpm -q apache & show the version of the apache package, if it is
    installed.  Also use this to determine if a package is installed
    or not. \\
    rpm -qa \textbar{} grep apache & show all installed packages that
    have \emph{apache} in their name\\
    rpm -ql apache & list all files in the apache package \\
    rpm -qld apache & list all documentation files in the apache package \\
    rpm -qlc apache & list all configuration files in the apache
    package \\
    rpm -qi apache & display information about the package \\
    rpm -V apache & verify that the apache package is correctly
    installed\\
    rpm -qf /etc/passwd & determine which package the
    \texttt{/etc/passwd} file belongs to\\
    \bottomrule
  \end{tabularx}%
  \caption{This is a brief list of \RPM query commands.  I have used the
  \texttt{apache} package as an example.}
  \label{tab:rpm-queries}
\end{table}

\section{Procedure}
\label{sec:procedure}

Note that updating the kernel requires that you configure
\texttt{lilo} with the new kernel, or the machine will not boot.  We
will use two methods; a manual method in which you manually resolve
software package dependencies, and an automatic method using
\texttt{rpmfind}

There are three steps in the manual method:
\begin{itemize}
\item Mount the network drive

\item If there are kernel updates that need to be applied, apply them
  first, installing any dependent packages first.
  
\item Apply the remaining updates, first those specialised to the
  Pentium III, and secondly, the remaining updates.

\item Finally configure \texttt{lilo}.
\end{itemize}

Here is how we do it.


\subsection{Mounting the network drive}
\label{sec:mountictlab}

\begin{enumerate}
\item Type:
  \begin{alltt}
$ sudo mount nicku.org:/var/ftp/pub /mnt/ftp
  \end{alltt}%$
  \begin{explanation}
    Now you have mounted the directory \texttt{/var/ftp/pub} from the machine
    \texttt{ictlab} over the network to the local directory
    \texttt{/mnt/ftp}, using the \acro{NFS} protocol.  If you change to
    your local directory \texttt{/mnt/ftp}, you will be accessing the
    directory \texttt{/var/ftp/pub} on \texttt{ictlab} over the
    network.

    We say that \texttt{ictlab} \emph{exports} the directory
    \texttt{/var/ftp/pub} by \acro{NFS}, and that your machine has
    \emph{mounted} this on the local directory \texttt{/mnt/ftp}.
  \end{explanation}
\end{enumerate}


\subsection{Installing Updates Manually}
\label{sec:using-rpm}

\paragraph{The Organisation of the Updates:}

The updates, as organised on Red Hat's ftp sites and mirrors, is in a
group of directories:
\begin{verbatim}
$ ls
athlon  i386  i486  i586  i686  ia64  images  noarch  SRPMS
\end{verbatim}%$
Most binary packages we need are in the \texttt{i386} directory.  Some
platforms benefit from packages that are compiled specifically for
their architecture, so if you have a P-II or P-III, install the
packages from the \texttt{i686} directory rather than the same
packages from the \texttt{i386} directory.  Table~\vref{tab:arch}
summarises what is in each of the directories.
\begin{table}[htb]
  \begin{tabularx}{\linewidth}[t]{@{}>{\ttfamily}lY@{}}
    \toprule%
    \textnormal{\emph{directory}} & \emph{What it's for} \\
    \midrule%
    athlon & Contains packages for \acro{ADM}'s Athlon processors \\
    i386 & Most of the packages you install come from here \\
    i486 & If a 486 will benefit from an updated package compiled for
    the 486, then it will be placed here\\
    i586 & Packages optimised for the Pentium \\
    i686 & Packages optimised for the Pentium-II \\
    ia64 & Packages compiled for the new 64-bit processors from Intel \\
    images & These are updated installation disk images to put
    on a floppy disk using the \texttt{dd} command \\
    noarch & These software packages contain no architecture specific
    code, and are used on all platforms \\
    SRPMS & The source \RPM packages \\
    \bottomrule
  \end{tabularx}
  \caption{The directories in the updates directory.}
  \label{tab:arch}
\end{table}

\begin{enumerate}
\item Now change to a directory on that network drive:
  \begin{alltt}
$ cd /mnt/ftp/redhat-7.1/updates/i686
  \end{alltt}%$

\item Let's try to install the kernel:
  \begin{alltt}
$ sudo rpm -ihv kernel-2*.rpm
Password:
error: failed dependencies:
        modutils >= 2.4.6 is needed by kernel-2.4.9-6
        mkinitrd >= 3.2.2 is needed by kernel-2.4.9-6
        tux < 2.1.0 conflicts with kernel-2.4.9-6
  \end{alltt}%$
It didn't work, since the \texttt{kernel} package \emph{depends} on
the software packages \texttt{modutils}, \texttt{mkinitrd} and
\texttt{tux}, so these must be installed first.
  \begin{explanation}
    The command \texttt{rpm} is important to you.  There is a whole
    book about this command, called \emph{Maximum RPM}, freely
    available on the documentation \CDROM as the package
    \texttt{maximum-rpm-1.0-0.20010810.noarch.rpm}.

    It is important to use the \texttt{-i} option when installing
    kernel packages.  Otherwise, your system would lose the modules
    that it is currently using, and you would \emph{have} to run
    \texttt{lilo} or your system would not boot.

    The three options:
    \begin{itemize}
    \item [\texttt{-i}] \textbf{i}nstall the package.  Install the
      package in any case, and \emph{do not} uninstall any older
      version of the package if any exist.

%     \item [\texttt{-F}] \textbf{F}reshen the package.  Install the
%       package \emph{only} if an older version of the same package is
%       already installed.
      
      
%     \item [\texttt{-U}] \textbf{U}pdate the package.  If the package
%       is already installed, install the package if it is newer, and
%       uninstall the older version.  Otherwise just install it.
      
%     \item [\texttt{-i}] \textbf{i}nstall the package.  Install the
%       package in any case, and \emph{do not} uninstall any older
%       version if any exist.
      
    \item [\texttt{-h}] Print \textbf{h}ashes (\textsf{\#}) to
      indicate progress.

    \item [\texttt{-v}] \textbf{v}erbosely print the name of each
      package as install it.
    \end{itemize}
  \end{explanation}

Then change to the directory with these packages and install them:
\begin{verbatim}
$ cd ../i386
$ sudo rpm -Fhv modutils* mkinitrd* tux*
error: failed dependencies:
        filesystem >= 2.1.0 is needed by mkinitrd-3.2.6-1
\end{verbatim}
\begin{explanation}
  \begin{itemize}
  \item [\texttt{-F}] \textbf{F}reshen the package.  Install the
    package \emph{only} if an older version of the same package is
    already installed.
  \end{itemize}
\end{explanation}

\item Okay, so we have one more dependency.  The package \texttt{filesystem}
is in the \texttt{noarch} directory, so we install it together with
the others:
\begin{verbatim}
$ rpm -Fhv modutils* mkinitrd* tux* ../noarch/filesystem*
\end{verbatim}%$
\begin{explanation}
  At last, it worked!  After all a packages dependencies are
  satisfied, it can be installed.  You may have read that there is an
  option to \texttt{rpm} called \texttt{--force}, but do not use this
  unless necessary; a package installed without the packages it
  depends on will not work properly.
  
  The package \texttt{filesystem} may not install correctly, since it
  cannot create directories in \texttt{/usr/local}.  Note that
  currently, the directory\texttt{/usr/local} is managed by the
  automounter, so it cannot create directories there while the
  automouter is running.  If you are doing this as a local user (but
  perhaps not if you are logged in with your \LDAP account), you can
  turn the automounter off temporarily to install the
  \texttt{filesystem} package, then turn it back on when you have
  finished:
\begin{verbatim}
$ sudo service autofs stop
$ sudo rpm -Uhv ../noarch/filesystem*
$ sudo service autofs start
\end{verbatim}%$
\end{explanation}

\item Now go back and install the kernel:
  \begin{alltt}
$ cd ../i686
$ sudo rpm -ihv kernel-2*.rpm
  \end{alltt}
  \begin{explanation}
    It is important to use the \texttt{-i} option when installing
    kernel packages.  Otherwise, your system would lose the modules
    that it is currently using, and you would \emph{have} to run
    \texttt{lilo} or your system would not boot.
    \begin{itemize}
    \item [\texttt{-i}] \textbf{i}nstall the package.  Install the
      package in any case, and \emph{do not} uninstall any older
      version if any exist.
    \end{itemize}
    So at last, we have installed the kernel!
  \end{explanation}

%   \begin{explanation}
%     \begin{itemize}
%     \item [\texttt{-U}] \textbf{U}pdate the package.  If the package
%       is already installed, install the package if it is newer, and
%       uninstall the older version.  Otherwise just install it.
%     \end{itemize}
%   \end{explanation}
  
\item If you are using the excellent \texttt{grub} boot loader
  (default in RH 7.2), then you don't need to do anything else with
  \texttt{grub}, since the 7.2 kernel \RPM{}s update
  \texttt{/boot/grub/grub.conf} automatically.
  
\item If and only if you are using \texttt{lilo}, to use the new
  kernel, you need to add it to your \texttt{/etc/lilo.conf}, then run
  \texttt{lilo}.
  \begin{enumerate}
  \item I added a section to my \texttt{lilo.conf}, and changed the
    label for my old kernel, so that my own \texttt{lilo.conf} looks
    like this:
    \begin{alltt}
boot=/dev/hda
map=/boot/map
install=/boot/boot.b
prompt
timeout=50
message=/boot/message
default=linux

image=/boot/vmlinuz-2.4.9-12
        label=linux
        read-only
        root=/dev/hda9

image=/boot/vmlinuz-2.4.3-2
        label=linux243-2
        read-only
        root=/dev/hda9

other=/dev/hda1
         label=windows
    \end{alltt}

  \item Now run lilo:
    \begin{alltt}
$ sudo lilo
Added linux *
Added linux243-2
Added windows
\end{alltt}%$
\end{enumerate}
\end{enumerate}
It's a good idea to leave the old kernel there as a boot option so
that you can use it if the new kernel does not work for you for any
reason.

Well now you have applied the update to the kernel, and to some other
related packages.

\emph{Note: do not apply the other updates as described here.}  Use
\texttt{rpmfind} instead, as explained in section~\vref{sec:rpmfind}.
I have provided this as a guide on how you \emph{could} (but won't!)
install the remaining updates manually.


There are some other updates to apply, and again, if you were
continuing to use the manual method, you would need to sort out the
dependencies.  You would begin by installing any other (non-kernel)
packages from the \texttt{i686} directory.  Finally (after installing
all the packages from the \texttt{i686} directory), you would change
to the \texttt{i386} directory and apply all the remaining updates
with
\begin{verbatim}
$ sudo rpm -Fhv *.rpm ../noarch/*.rpm
\end{verbatim}%$


\subsection{Applying Updates Automatically: Setting up \texttt{rpmfind}}
\label{sec:rpmfind}

You might say, there has to be a better way.  And there is:
\texttt{rpmfind}.  It is possible to automate the update process
totally using \texttt{rpmfind}.

\paragraph{An Overview of Configuring \texttt{rpmfind}:}

There are a few steps to configuring \texttt{rpmfind}.  You only need
to configure it once; you can then run it regularly.  This is an
outline of what we will do here:
\begin{itemize}
\item install \texttt{rpmfind} if it's not already installed;
\item create a local account for yourself (or use one you created
  previously);
\item add this user to the \texttt{sudoers} file;
\item update the login script of this account to include the
  directories \texttt{/sbin} and \texttt{/usr/sbin};
\item log into this new account;
\item import Red Hat's public key that matches the key used
  to digitally \texttt{sign} the packages.
\item finally, create a configuration file for \texttt{rpmfind}, and
  edit it;
\end{itemize}
The documentation for \texttt{rpmfind} is available online at
\url{http://rpmfind.net/linux/rpmfind/} and
\url{http://rpmfind.net/linux/rpmfind/autoupgrade.html}.  You will
need to refer to it.
\paragraph{Setting up \texttt{rpmfind}}

\begin{enumerate}
\item Make sure that rpmfind is installed on your computer.
\begin{verbatim}
$ rpm -q rpmfind
rpmfind-1.6-5                                                                   \end{verbatim}%$
\begin{explanation}
  In this case, it is installed.  If you get a message like,
  ``\texttt{package rpmfind is not installed}'', then, well, the
  package needs to be installed.
\end{explanation}
In Red Hat 7.x, it is part of the main Red Hat distribution. and is on
one of the two installation disks.

You can install it like this:
\begin{verbatim}
$ cd /mnt/ftp/redhat-7.1/RedHat/RPMS
$ sudo rpm -Uhv rpmfind-1.6-5.i386.rpm
\end{verbatim}

\item Now create a local account for yourself, as described
  in section~\vref{lt-sec:local-accounts} of the \emph{Linux
    Training Materials Project}.  You may use one of the accounts you
  created previously.
  \begin{explanation}
    \texttt{rpmfind} will create a configuration file in your home
    directory.  It is better to create this on a local account than on
    your network account, since the \texttt{rpmfind} configuration
    applies to your local machine.
  \end{explanation}

\item Add your new account to the sudoers file as described in the
  handout on \texttt{sudo}.

\item Change the \texttt{PATH} on your new account to include the
  directories \texttt{/sbin} and \texttt{/usr/sbin} (see
  section~\vref{lt-sec:PATH} of the \emph{Linux
    Training Materials Project}.
{\small%
\begin{alltt}
$ sudo sh -c "echo 'export PATH=$PATH:/usr/sbin:/sbin' >> \(\sim\)nickl/.bash_profile"
\end{alltt}}

  \begin{explanation}
    This appends the line
\begin{verbatim}
export PATH=$PATH:/usr/sbin:/sbin
\end{verbatim}%$
to the end of the login script for the user \texttt{nickl}.
Obviously, use the name of your own local account instead of \texttt{nickl}.
  \end{explanation}

\item Log out and log into your new account.

\item Now you will import Red Hat's public key into \acro{GNU} Privacy
  Guard\@.  I assume you have \texttt{ictlab:/var/ftp/pub} mounted on
  \texttt{/mnt/ftp}.
\begin{verbatim}
$ gpg --import /mnt/ftp/redhat-7.2/i386/RPM-GPG-KEY
gpg: Warning: using insecure memory!
gpg: /home2/nickl/.gnupg: directory created
gpg: /home2/nickl/.gnupg/options: new options file created
gpg: you have to start GnuPG again, so it can read the new options file
$ gpg --import /mnt/ftp/redhat-7.2/i386/RPM-GPG-KEY
gpg: Warning: using insecure memory!
gpg: /home2/nickl/.gnupg/secring.gpg: keyring created
gpg: /home2/nickl/.gnupg/pubring.gpg: keyring created
gpg: key DB42A60E: public key imported
gpg: /home2/nickl/.gnupg/trustdb.gpg: trustdb created
gpg: Total number processed: 1
gpg:               imported: 1
\end{verbatim}
  \begin{explanation}
    \textsc{Gnu} Privacy Guard is a very important tool for encrypting
    and signing data.  It is often used for encrypting email, but even
    more often for verifying the \texttt{integrity} of data.  When
    data is \emph{signed} using \texttt{gpg}, the receiver can verify
    that there has been absolutely no change to the original data
    since it was signed by the person from whom the data came from.

    We will use \texttt{gpg} to verify that the packages we install
    are genuine packages from Red Hat, and that they are not false
    packages containing Trojan programs created by bad people who want
    to crack your computer systems.

    \texttt{gpg} is a free version of Pretty Good Privacy
    (\texttt{pgp}).  \texttt{pgp} is described well in a book of that
    name.  You can read more about \texttt{gpg} from
    \url{http://www.gnupg.org/}.  \texttt{gpg} uses powerful public key
    encryption (together with other encryption technologies) to
    encrypt any data you want.  Other people can decrypt it without
    you sending them any secret information.  It is really quite
    remarkable, and very useful.
  \end{explanation}

\item You need to run \texttt{rpmfind} for the first time to create
  the configuration file in your home directory.

Here, we ask \texttt{rpmfind} to list its options:
\begin{verbatim}
$ rpmfind -h
\end{verbatim}%$
  \begin{explanation}
    This will take some time, since we are behind a firewall and
    \texttt{rpmfind} will be unable to reach the Internet servers
    until we set a proxy.  That will be the next step.
  \end{explanation}

\item Now \texttt{rpmfind} has created a configuration file in your
  home directory: $\sim$\texttt{/.rpmfind} \ Edit this file:
\begin{verbatim}
$ emacs .rpmfind &
\end{verbatim}%$

\item Here is the output of \texttt{diff -u} showing the changes I
  made to my $\sim$\texttt{/.rpmfind} file:
\begin{verbatim}
--- /home2/nickl/.rpmfind~      Fri Jan  4 08:36:47 2002
+++ /home2/nickl/.rpmfind       Fri Jan  4 08:41:00 2002
@@ -31,10 +31,10 @@
 ; Where to lookup for autoupgrades
 ; multiple local or FTP directories can be specified
 ;
-autoupgradeURL=
+autoupgradeURL=/mnt/ftp/rh-7.1-updated/RedHat/RPMS
 
 ; your HTTP proxy/cache if any: http://myhttpproxy/
-httpProxy=
+httpProxy=http://sheep.vtc.edu.hk:8080/
 
 ; your FTP proxy/cache if any: ftp://myftpproxy/
 ; If authentication is needed use ftpProxyUser and ftpProxyPasswd
@@ -43,7 +43,7 @@
 ftpProxyPasswd=
 
 ; Default mode upgrade, latest or lookup (default)
-mode=lookup
+mode=upgrade
 
 ; Run in automatic mode: yes or no (default)
 auto=no
@@ -52,7 +52,7 @@
 nodelete=no
 
 ; Be paranoid when checking signatures: yes or no (default)
-paranoid=no
+paranoid=yes
 
 ; Run in overwrite mode: yes or no (default)
 overwrite=no
\end{verbatim}
\end{enumerate}


\subsection{Running \texttt{rpmfind}}
\label{sec:running-rpmfind}

\begin{enumerate}
\item Now you are ready to run \texttt{rpmfind}:
\begin{verbatim}
$ sudo rpmfind --autoupgrade
\end{verbatim}%$
  \begin{explanation}
    I found that it become stuck with some unresolved dependencies.
    You may need to resolve these manually!  If so, install the set of
    packages that depend on each other, then run \texttt{rpmfind
      --autoupgrade} again until all the updates are applied.  I found
    that the version of \texttt{rpmfind-1.7-2} with Red Hat Linux 7.2
    works much better.
  \end{explanation}
\end{enumerate}

You are finished.  Your system is much more secure against attack by
crackers and malicious programs such as the Ramen Worm
(\url{http://www.redhat.com/support/alerts/ramen_worm.html}).

At home, you can either:
\begin{itemize}
\item In our lab, burn a \CDROM containing the updates and take them
  home, or

\item download them from a Red Hat Mirror such as
  \url{ftp://rufus.w3.org/linux/redhat/updates/7.2/}
  \begin{explanation}
    Note that a list of Red Hat mirror sites is available from
    \url{http://www.redhat.com/mirrors.html}.
  \end{explanation}
\end{itemize}

\subsection{How to Automatically Download the Updates?}
\label{sec:downloading-updates}


\paragraph{For sites with a number of Linux machines:}

 a site where you have many Linux computers, a scheme like this is
a good way to maintain updates.

Here is a single line script to download updates for Red Hat 7.2 and
Red Hat 7.1 to the local directories
\(\sim\)\texttt{ftp\allowbreak/pub\allowbreak/redhat-7.2%
  \allowbreak/updates} and 
\(\sim\)\texttt{ftp\allowbreak/pub\allowbreak/redhat-7.1%
  \allowbreak/updates}.

Note that if you are using Red
Hat 7.1, you should apply updates for Red Hat 7.1.
\begin{verbatim}
#! /bin/sh

rsync -avz \
    --delete \
    rufus.w3.org::linux/redhat/updates/7.2/en/os/ \
    ~ftp/pub/redhat-7.2/updates

rsync -avz \
    --delete \
    rufus.w3.org::linux/redhat/updates/7.1/en/os/ \
    ~ftp/pub/redhat-7.1/updates
\end{verbatim}

If you saved this script as
\texttt{/root/bin/rsync-redhat-7.x-updates}, then this
\texttt{crontab} entry for root will run it at 7.31\,am and 5.31\,pm:
\begin{verbatim}
31 7,17 * * * /root/bin/rsync-redhat-7.x-updates
\end{verbatim}
You would create this crontab entry for the user \texttt{root} with
the command:
\begin{verbatim}
$ sudo crontab -e
\end{verbatim}%$

This solution uses the important \texttt{rsync} protocol, described in
my handout on burning \CDROM{}s.  The advantages of \texttt{rsync}
include that it only transfers only the differences between files.  It
provides a very efficient way of synchronising files between two
networked computers.

Refer to section~\vref{lt-sec:crontab} in the \emph{Linux Training
  Materials Project} for more about \texttt{cron} and the
  \texttt{crontab}.  Also do
\begin{verbatim}
$ man 5 crontab
\end{verbatim}%$
to see what each of the fields in the \texttt{crontab} entry represent.

\paragraph{For only one Linux computer:}

You can simply use \texttt{rpmfind} to directly download and install
the updates itself.  There are other choices too; the \texttt{up2date}
program is incredibly convenient for interactive updates.  First run
the program \texttt{rhn\_register} one time, then after that run
\texttt{up2date}.  Another good choice is the Red Carpet program that
comes with the Ximian Gnome desktop.  See \url{http//www.ximian.com}
for more details.

\subsection{Running rpmfind automatically}
\label{sec:rpmfind-and-cron}

You can have \texttt{rpmfind} automatically update your computer by
adding this to root's \texttt{crontab}:
\begin{verbatim}
# at 8.03 am every day, install new updates if they are available.
3 8 * * *       /usr/bin/rpmfind --autoupgrade
\end{verbatim}
For this to work, the path \texttt{autoupgradeURL} in your
$\sim$\texttt{/.rpmfind} file should point to the directories where
the updates are downloaded, probably mounted by \NFS, and either
mounted permanently, or perhaps mounted on demand by the automounter.

It is important to ensure that root has a secure
$\sim$\texttt{/.rpmfind} configuration.  In particular, you should
have \GNU Privacy Guard set up for root with the Red Hat public key,
and \texttt{rpmfind} should have the \texttt{paranoid=yes} setting to
make sure that you are installing trusted packages and not those
created by crackers.

\subsection{Remote upgrade with rpmfind}
\label{sec:remote-upgrade}

One problem system administrators face is upgrading a production
system.  Normally, upgrading the \OS (say from Red Hat 7.0 to 7.2)
would involve taking the machine out of production for a couple of
hours, rebooting it from a kickstart boot disk or \CDROM.

I have use \texttt{rpmfind} to upgrade our laboratory server from Red
hat 7.1 to Red hat 7.2 while it was online, and with no physical
access to the computer.  I upgraded it from my home on the weekend.
This is not recommended by Red Hat, and you need to know what to do if
you have any problems, but it was smooth for our machine, and is
viable.  The Debian Linux distribution has a much better system for
doing updates and upgrades called \texttt{apt-get}.  \texttt{rpmfind}
is not as good, but it does the job.
\end{document}
