Raimo Niskanen wrote:
A very nice startegy from you. I have been looking for how to patch
several machines this way. The kernel is easy since it is just
one file to patch. But the userland is more delicate. Just to summarize
your script (I want to understand how to do it manually),
this seems what to do (?):


Preparation:
# MYTMP=/var/tmp/myroot # better use mktemp
# mkdir $MYTMP
# mkdir $MYTMP/obj $MYTMP/dest
# cd /usr/src/etc
# DESTDIR=$MYTMP/dest make distrib-dirs
# cd $MYTMP/dest
# mtree -c -k type > ../dest.mtree

Patching:
# cd /usr/src
Patch and build all patches as usual, but use
`make DESTDIR=$MYTMP/dest install'
instead of plain `make install'

Creating the patch:
# cd $MYTMP/dest
# sudo mtree -f ../dest.mtree > ../patch.mtree
# MYPATCH=$MYTMP/patch.tar.gz # better use mktemp
# grep '^extra:' ../patch.mtree | cut -d' ' -f2 \
    | tar czf $MYPATCH -I - && echo OK || echo FAILED

Where the important tricks are `make distrib-dirs' in
/usr/src/etc with DESTDIR set, mtree of the directory
tree that was created there, patching with make install
using argument DESTDIR, and mtree of the resulting tree
to find what has changed; tar:ing the added files.

You got it. If you run the entire command sequence as root you don't need to use sudo. I run this as a regular user, who can sudo to root. Most of the command sequence can be run without privileges except for the 'make install/distrib-dirs' and mtree.

Also, the places where you mentioned using mktemp, you should. However, if you run as root, you could just build in a non-public directory, like /root, to be safe. I just use temp files/dirs because after the build I place the binary patches into my versioned patch distribution system, which automates the distribution of these patches to all the nodes on the network.



On Thu, Nov 01, 2007 at 02:25:31PM -0700, Clint Pachl wrote:
Markus Wernig wrote:
Dear list

I have a couple of 4.1 firewalls that I would like to upgrade to 4.2.
Before taking them online again I'd like to deploy the openssl patch
>from
ftp://ftp.openbsd.org/pub/OpenBSD/patches/4.2/common/002_openssl.patch
I feel your pain. Others have dissed on you for not having compile tools on your hosts and assume you're doing it for security reasons. I don't know your reason, but I only have compile tools on my build system. I create binary patches (see script below) and distribute across the network. Who the hell wants 20 (# of servers in my network) builds cranking on all your machines in the network? What a nightmare. What if they all fail? Worse yet, what if one fails? Someone is going to say, "script/automate it." Screw that. Now you need to figure out how to make the sources available to all the hosts, initiate the build, make sure the build didn't fail, etc.

Another reason I don't have compile tools on some of my servers is because they won't fit. Many of my dedicated systems use 256MB flash drives.

The third reason to keep crap off your servers, including compiler tools, is that potentially that extra stuff could be exploitable. If it is, then you have to patch it too. Just extra work.

Being perimeter firewalls, those systems don't have compile tools installed. I would thus need to pre-compile libssl on a 4.2 buildhost and deploy it onto the firewalls. I've been looking through the documentation but did not find a "good" way to do this, because openssl is not a package, but part of the base system.
OpenBSD makes if very easy to create binary patches. I wrote a script below that automates most of the process. I have been using this script for a while and it works pretty good. The good thing about this is that it only creates a binary patch of executables and files that were affected by the source patch. This also has the benefit of touching only a small portion of the installed system, which can be helpful when you are monitoring for trojan horses.

The alternative, which someone else mentioned, is just make a release. This is straightforward and officially supported. See release(8).

Is there any way other than tar - scp - untar after compiling libssl?

thx for any pointers

/markus
I will apologize in advance for the screwed spacing/tabbing.

#!/bin/sh
#
# Builds kernel and userland from the /usr/src tree. The script sets up the
# build environment then kicks the user to a shell to manually patch the
# source. When in userland build mode, the user is also asked to build and
# install using the instructions specified in the official OpenBSD patch. After # the user exits the work shell, this script will build the kernel or create a
# binary userland patch depending on the operation mode.
#
# BUGS
# Does not build or make binary patches for the X system.
#

usage()
{
       cat <<- EOF
               usage: $APP {-k | -u} [-h] [-p patch-name]

                 -k : kernel build mode; makes GENERIC & GENERIC.MP kernels
                 -u : userland build mode; makes binary patches
                 -p : embedded in the newly built kernel/patch filenames
                 -h : help
       EOF
       exit $1
}

APP=${0##*/}
REL=`uname -r`
ARCH=`uname -m`
Mode=0
PatchName=
KernCfgs='GENERIC GENERIC.MP'

while getopts p:kuh i
do      case $i in
               k) Mode=1 ;;
               u) Mode=2 ;;
               p) PatchName=-$OPTARG ;;
               h) usage 0 ;;
               *) echo "$APP: cmdline parse error."
                  usage 1
       esac
done

[ $Mode -ne 0 ] || usage 1

TDIR=`mktemp -d /var/tmp/${APP}.XXXXXXX` || exit 1
trap 'rm -rf $TDIR 2>/dev/null || sudo rm -rf $TDIR' EXIT

if [ $Mode -eq 1 ]
then    KDIR=`mktemp -d /var/tmp/kernels-XXXXXXX` || exit 1
       cat <<- EOF

       === Kernel Build Rules ===
       - Patch the kernel source.
       - Type "exit" when complete.
       - The kernels ($KernCfgs) will automatically build.

       === Command Sequence Hint ===
       $ cd /usr/src
$ ftp -Vo - ftp://ftp.openbsd.org/pub/OpenBSD/patches/$REL/$ARCH/<patch> | patch -p0
       $ exit

       EOF

       $SHELL

       for k in $KernCfgs
       do      mkdir $TDIR/$k
               cd $TDIR/$k
               cp /sys/arch/$ARCH/conf/$k .
               config -s /sys -b . $k
               make clean && make depend && make || exit 1
               mv bsd $KDIR/bsd.$k$PatchName
               rm -rf $TDIR/$k &
       done

       cat <<- EOF

       The kernels have been built and can be found in "$KDIR".

       Install your kernel safely:
               # ln -f /bsd /bsd.old
               # cp $KDIR/<new-kernel> /bsd.tmp
               # mv /bsd.tmp /bsd

       EOF

else    export BSDOBJDIR=$TDIR/obj _DESTDIR=$TDIR/dest
       readonly BSDOBJDIR _DESTDIR
       mkdir $BSDOBJDIR $_DESTDIR

       cd /usr/src/etc
       sudo env DESTDIR=$_DESTDIR make distrib-dirs >/dev/null
       cd $_DESTDIR
       sudo mtree -c -k type > ../dest.mtree

       cat <<- EOF

       === Userland Build Rules ===
- Manually patch and rebuild the affected sources according to the patch instructions. - Set "DESTDIR=\$_DESTDIR" on the command line for ALL make install targets!
       - Type "exit" when complete.

       === Command Sequence Hint ===
       $ cd /usr/src
$ ftp -Vo - ftp://ftp.openbsd.org/pub/OpenBSD/patches/$REL/$ARCH/<patch> | patch -p0
       $ cd <thing that needs building>
$ make obj && make cleandir && make depend && make && sudo make DESTDIR=\$_DESTDIR install
       $ exit

       EOF

       $SHELL

       cd $_DESTDIR
       sudo mtree -f ../dest.mtree > ../tmp.mtree
[ -s ../tmp.mtree ] || { echo "Nothing installed in \$_DESTDIR."; exit 1; }

       PATCH=`mktemp /var/tmp/patch$PatchName.tgz-XXXXXXX` || exit 1
       echo -n "\nCreating binary patch '$PATCH'..."
       sudo mtree -f ../dest.mtree | grep '^extra:' | cut -d' ' -f2 |
           tar czf $PATCH -I - && echo OK || echo FAILED
fi

Reply via email to