On Nov 2, 2007, at 5:23 AM, 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 (?):

Just build a release and upgrade from that. Use yaifo if the machines in question happen to be headless. Done and done. No need to overthink things and make them a lot harder than they need to be. OpenBSD has all the tools to do this quickly and easily with just a little work upfront.


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.



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

--

/ Raimo Niskanen, Erlang/OTP, Ericsson AB

Reply via email to