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