djwong: (Default)
[personal profile] djwong
It's tinfoil hat time! Let's say you run Debian or Ubuntu, maintain your own package archive, and want to make it harder for someone to tamper with that archive and trick you into installing malicious packages. If you want to sign your Debian packages and apt archive, here's a quick guide to how you set this up. It's important to have a signed archive, because the archive contains package metadata (md5sums of the .deb files, etc) that are used by the receiving apt program to sanity-check the incoming packages. Signing the metadata (if the private keys are secure) prevents other people from modifying the archive contents; signing the packages themselves ensures that the .deb files haven't been tampered with. In theory it's only necessary to provide a signed archive.

First, use gpg to generate two key pairs -- one keypair on the package builder machine, and another pair on machine where the package archive will live. Let's call the pairs pkg_priv, pkg_pub, ppa_priv, and ppa_pub.
Let pkg_keyid=last 4 hunks of gpg --fingerprint -k ${pkg_priv}

On the package builder, do this:
apt-get install debsigs debsig-verify
gpg --armor --export ${pkg_priv} > ${pkg_pub_file}

For each package built, do:
debsigs --sign=origin -v ${debfile} -k ${pkg_priv}


On the package archive box, do this:
apt-get install reprepro
mkdir ${repodir}
add "SignWith: ${ppa_priv}" to ${repodir}/conf/distributions
gpg --armor --export ${ppa_priv} > ${ppa_pub_file}

To inject a package into the archive, do this:
reprepro -S main includedeb ${distro} ${debfile}


On the client, do this to add the package archive's gpg public key to apt:
apt-key add ${ppa_pub_file}

On the client, do this to make dpkg verify the signatures of individual package files:
mkdir -p /usr/share/debsig/keyrings/${pkg_keyid}/ /etc/debsig/policies/${pkg_keyid}
gpg --no-default-keyring --keyring /usr/share/debsig/keyrings/${keyid}/debsig.gpg --import ${pkg_pub_file}
cat > /etc/debsig/policies/${pkg_keyid}/djwong.pol << ENDL
<?xml version="1.0"?>
<!DOCTYPE Policy SYSTEM "http://www.debian.org/debsig/1.0/policy.dtd">
<Policy xmlns="http://www.debian.org/debsig/1.0/">

<Origin Name="djwong" id="${pkg_keyid}" Description="Packages by djwong"/>

<Selection>
<Required Type="origin" File="debsig.gpg" id="${pkg_keyid}"/>
</Selection>

<Verification MinOptional="0">
<Required Type="origin" File="debsig.gpg" id="${pkg_keyid}"/>
</Verification>

</Policy>
ENDL
mv /usr/bin/debsig-verify /usr/bin/debsig-verify.real # really this should be dpkg-divert
cat > /usr/bin/debsig-verify << ENDL
#!/bin/sh

/usr/bin/debsig-verify.real $*
RESULT=$?
if [ $RESULT -eq 10 ]; then
echo 'Passing unsigned package.'
exit 0
fi
exit $RESULT
ENDL
remove no-debsig from /etc/dpkg/dpkg.cfg

This sets up a policy such that packages signed with the package builder's private key must be verified before dpkg will install them. The strange activity in /usr/bin "patches" the debsig-verify program so that unsigned packages (none of the Ubuntu/Debian package files themselves are signed) don't fail.

If you're particularly paranoid, the "package archive" steps should be done on a private machine and the contents later rsync'd up to the real archive host, so that neither private key ever has to be on a well-known system. If you don't perform this step, attackers can modify the archive, though they won't be able to tamper with the individual .deb files.

N.B. debsign signatures are NOT compatible with dpkg-sig signatures!

Profile

djwong: (Default)
Bogus J. Simpson

May 2016

S M T W T F S
1234567
891011121314
15161718192021
2223242526 2728
293031    

Style Credit

Expand Cut Tags

No cut tags
Page generated 18 Aug 2025 03:50
Powered by Dreamwidth Studios