\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 ictlab.tyict.vtc.edu.hk:/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}