This chapter could also be titled "how to upgrade/update safely your Debian GNU/Linux system" and it deserves its own chapter basically because it will not fit with any other chapter.
As of today (december 2001) Debian does not provide signed packages for the distribution and the woody release (3.0) will not integrate that feature. There is a solution for signed packages which will be, hopefully, provided in the next release.
The current (unimplemented) scheme for package signature checking using apt is:
By following the chain of MD5 sums apt is capable of verifying
that a package originates from a a specific release. This is less flexible
than signing each package one by one, but can be combined with that scheme too
(see below).
Package signing has been discussed in Debian for quite some time, for more
information you can read: http://www.debian.org/News/weekly/2001/8/
and http://www.debian.org/News/weekly/2000/11/.
The additional scheme of signing each and every packages allows packages to be checked when they are no longer referenced by an existing Packages file, and also third-party packages where no Packages ever existed for them can be also used in Debian but will not be default scheme.
This package signing scheme can be implemented using
debsig-verifyand debsigs. These two packages can
sign and verify embeded signatures in the .deb itself. Debian already has the
capability to do this now, but implementing the policy and tools won't be
started until after woody releases (so as not to slow down its release cycle).
NOTE: Currently /etc/dpkg/dpkg.conf ships with
"no-debsig" as per default.
In case you want to add now the additional security checks you can use the script below, provided by Anthony Thown. This script can automatically do some new security checks to allow the user to be sure that the software s/he's downloading matches the software Debian's distributing. This stops Debian developers from hacking into someone's system without the accountability provided by uploading to the main archive, or mirrors mirroring something almost, but not quite like Debian, or mirrors providing out of date copies of unstable with known security problems.
This sample code, renamed as apt-release-check, should be used in
the following way:
# apt-get update
# apt-release-check
(...results...)
# apt-get dist-upgrade
First you need to:
http://ftp-master.debian.org/ziyi_key.asc,
and http://ftp-master.debian.org/ziyi_key2.asc,
and add them to ~/.gnupg/trustedkeys.gpg (which is what
gpgv uses by default)
/etc/apt/sources.list lines that don't use the normal
"dists" structure, or change the script so that it works with them.
#!/bin/bash
# This script is copyright (c) 2001, Anthony Towns
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
rm -rf /tmp/apt-release-check
mkdir /tmp/apt-release-check || exit 1
cd /tmp/apt-release-check
>OK
>MISSING
>NOCHECK
>BAD
arch=`dpkg --print-installation-architecture`
am_root () {
[ `id -u` -eq 0 ]
}
get_md5sumsize () {
cat "$1" | awk '/^MD5Sum:/,/^SHA1:/' |
MYARG="$2" perl -ne '@f = split /\s+/; if ($f[3] eq $ENV{"MYARG"}) { print "$f[1] $f[2]\n"; exit(0); }'
}
checkit () {
local FILE="$1"
local LOOKUP="$2"
Y="`get_md5sumsize Release "$LOOKUP"`"
Y="`echo "$Y" | sed 's/^ *//;s/ */ /g'`"
if [ ! -e "/var/lib/apt/lists/$FILE" ]; then
if [ "$Y" = "" ]; then
# No file, but not needed anyway
echo "OK"
return
fi
echo "$FILE" >>MISSING
echo "MISSING $Y"
return
fi
if [ "$Y" = "" ]; then
echo "$FILE" >>NOCHECK
echo "NOCHECK"
return
fi
X="`md5sum < /var/lib/apt/lists/$FILE` `wc -c < /var/lib/apt/lists/$FILE`"
X="`echo "$X" | sed 's/^ *//;s/ */ /g'`"
if [ "$X" != "$Y" ]; then
echo "$FILE" >>BAD
echo "BAD"
return
fi
echo "$FILE" >>OK
echo "OK"
}
echo
echo "Checking sources in /etc/apt/sources.list:"
echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
echo
(echo "You should take care to ensure that the distributions you're downloading"
echo "are the ones you think you are downloading, and that they are as up to"
echo "date as you would expect (testing and unstable should be no more than"
echo "two or three days out of date, stable-updates no more than a few weeks"
echo "or a month)."
) | fmt
echo
cat /etc/apt/sources.list |
sed 's/^ *//' | grep '^[^#]' |
while read ty url dist comps; do
if [ "${url%%:*}" = "http" -o "${url%%:*}" = "ftp" ]; then
baseurl="${url#*://}"
else
continue
fi
echo "Source: ${ty} ${url} ${dist} ${comps}"
rm -f Release Release.gpg
wget -q -O Release "${url}/dists/${dist}/Release"
if ! grep -q '^' Release; then
echo " * NO TOP-LEVEL Release FILE"
else
origline=`sed -n 's/^Origin: *//p' Release | head -1`
lablline=`sed -n 's/^Label: *//p' Release | head -1`
suitline=`sed -n 's/^Suite: *//p' Release | head -1`
codeline=`sed -n 's/^Codename: *//p' Release | head -1`
dateline=`grep "^Date:" Release | head -1`
dscrline=`grep "^Description:" Release | head -1`
echo " o Origin: $origline/$lablline"
echo " o Suite: $suitline/$codeline"
echo " o $dateline"
echo " o $dscrline"
if [ "${dist%%/*}" != "$suitline" -a "${dist%%/*}" != "$codeline" ]; then
echo " * WARNING: asked for $dist, got $suitline/$codeline"
fi
wget -q -O Release.gpg "${url}/dists/${dist}/Release.gpg"
sigline="`gpgv --status-fd 3 Release.gpg Release 3>&1 >/dev/null 2>&1 | sed -n "s/^\[GNUPG:\] GOODSIG [0-9A-Fa-f]* //p"`"
if [ "$sigline" ]; then
echo " o Signed by: $sigline"
else
echo " * NO VALID SIGNATURE"
>Release
fi
fi
okaycomps=""
for comp in $comps; do
if [ "$ty" = "deb" ]; then
X=$(checkit "`echo "${baseurl}/dists/${dist}/${comp}/binary-${arch}/Release" | sed 's,//*,_,g'`" "${comp}/binary-${arch}/Release")
Y=$(checkit "`echo "${baseurl}/dists/${dist}/${comp}/binary-${arch}/Packages" | sed 's,//*,_,g'`" "${comp}/binary-${arch}/Packages")
if [ "$X $Y" = "OK OK" ]; then
okaycomps="$okaycomps $comp"
else
echo " * PROBLEMS WITH $comp ($X, $Y)"
fi
elif [ "$ty" = "deb-src" ]; then
X=$(checkit "`echo "${baseurl}/dists/${dist}/${comp}/source/Release" | sed 's,//*,_,g'`" "${comp}/source/Release")
Y=$(checkit "`echo "${baseurl}/dists/${dist}/${comp}/source/Sources" | sed 's,//*,_,g'`" "${comp}/source/Sources")
if [ "$X $Y" = "OK OK" ]; then
okaycomps="$okaycomps $comp"
else
echo " * PROBLEMS WITH component $comp ($X, $Y)"
fi
fi
done
[ "$okaycomps" = "" ] || echo " o Okay:$okaycomps"
echo
done
echo "Results"
echo "~~~~~~~"
echo
allokay=true
cd /tmp/apt-release-check
diff <(cat BAD MISSING NOCHECK OK | sort) <(cd /var/lib/apt/lists && find . -type f -maxdepth 1 | sed 's,^\./,,g' | grep '_' | sort) | sed -n 's/^> //p' >UNVALIDATED
cd /tmp/apt-release-check
if grep -q ^ UNVALIDATED; then
allokay=false
(echo "The following files in /var/lib/apt/lists have not been validated."
echo "This could turn out to be a harmless indication that this script"
echo "is buggy or out of date, or it could let trojaned packages get onto"
echo "your system."
) | fmt
echo
sed 's/^/ /' < UNVALIDATED
echo
fi
if grep -q ^ BAD; then
allokay=false
(echo "The contents of the following files in /var/lib/apt/lists does not"
echo "match what was expected. This may mean these sources are out of date,"
echo "that the archive is having problems, or that someone is actively"
echo "using your mirror to distribute trojans."
if am_root; then
echo "The files have been renamed to have the extension .FAILED and"
echo "will be ignored by apt."
cat BAD | while read a; do
mv /var/lib/apt/lists/$a /var/lib/apt/lists/${a}.FAILED
done
fi) | fmt
echo
sed 's/^/ /' < BAD
echo
fi
if grep -q ^ MISSING; then
allokay=false
(echo "The following files from /var/lib/apt/lists were missing. This"
echo "may cause you to miss out on updates to some vulnerable packages."
) | fmt
echo
sed 's/^/ /' < MISSING
echo
fi
if grep -q ^ NOCHECK; then
allokay=false
(echo "The contents of the following files in /var/lib/apt/lists could not"
echo "be validated due to the lack of a signed Release file, or the lack"
echo "of an appropriate entry in a signed Release file. This probably"
echo "means that the maintainers of these sources are slack, but may mean"
echo "these sources are being actively used to distribute trojans."
if am_root; then
echo "The files have been renamed to have the extension .FAILED and"
echo "will be ignored by apt."
cat NOCHECK | while read a; do
mv /var/lib/apt/lists/$a /var/lib/apt/lists/${a}.FAILED
done
fi) | fmt
echo
sed 's/^/ /' < NOCHECK
echo
fi
if $allokay; then
echo 'Everything seems okay!'
echo
fi
rm -rf /tmp/apt-release-check
Securing Debian Manual
v2.2 27 april 2002Tue, 23 Apr 2002 20:56:15 +0200jfs@computer.org