GPG support in the repos

Locked
User avatar
gapan
Salix Wizard
Posts: 6238
Joined: 6. Jun 2009, 17:40

GPG support in the repos

Post by gapan »

I just added GPG support in our repo. Just do slapt-get --add-keys and slapt-get -u and you should see the repo verified by slapt-get. It creates a bit of trouble for the person that updates the repo (the gnupg passphrase is required each time) but it's a huge gain in security. :)
Image
Image
User avatar
JRD
Salix Warrior
Posts: 950
Joined: 7. Jun 2009, 22:52
Location: Lyon, France

Re: GPG support in the repos

Post by JRD »

How this is working ?
The GPG key is get from the repo ?
If yes, someone could use another repo and build news GPG keys. One must do "slapt-get --add-keys" I supposed, but the faker could say that this is required for using a mirror or something like that...
I'm not a fond of security, but when it comes to securise something, I ask myself a bunch of questions...Could you help me answer them ?
Image
User avatar
gapan
Salix Wizard
Posts: 6238
Joined: 6. Jun 2009, 17:40

Re: GPG support in the repos

Post by gapan »

The GPG key is stored in the repo: http://salix.enialis.net/i486/current/GPG-KEY

This key is used to sign the CHECKSUMS.md5 file, so by using it you are verifying that all packages are what they intended to be.

Case 1: Someone hacks into a mirror (or even the main repo) and replaces a package (for example openssh) with a hacked one. He can recreate the CHECKSUMS.md5 file but he cannot sign it with the gpg key, as he doesn't know the passphrase. Hacking into a poorly secured server is far easier than breaking gpg encryption. If he cannot sign the CHECKSUMS.md5 file properly, the key will not be verified by the package manager and the user will know that something nasty is going on. If the repo is not signed, you can only find out by calculating md5sums for each package and checking them one by one against the good ones (something that noone will ever do).

Case 2: Someone pretends to be a contributor and offers to mirror the repo, so he can replace some packages with hacked versions. If he changes something without signing the CHECKSUMS.md5 file, it's the same as Case 1. He can create a fake gpg key, but as soon as someone checks the gpg key against the one in the main server, or tries to use a legitimate mirror, the key will fail to verify. So, the hacker will be uncovered, probably sooner than later.

This was a concern I often had with some of the zenwalk mirrors and is still valid as the "management" doesn't care about such "silly" issues (gpg was proposed by someone else in the past, but - as usual - received no reply). There is no easy way to tell if a zenwalk mirror repo includes hacked packages. I'm not saying they do, but it would be trivial for someone to offer a (faked) mirror and profit from it.
Image
Image
User avatar
JRD
Salix Warrior
Posts: 950
Joined: 7. Jun 2009, 22:52
Location: Lyon, France

Re: GPG support in the repos

Post by JRD »

Thank you very much for your clear and interresting answer !
Image
Quax
Posts: 36
Joined: 16. Sep 2009, 15:09
Location: Muelheim an der Ruhr, Germany
Contact:

Re: GPG support in the repos

Post by Quax »

Hi Gapan,
gapan wrote:...It creates a bit of trouble for the person that updates the repo (the gnupg passphrase is required each time)...
Using the repo script of Jason Woodwards from jaos.org, I have extended it as follows:

Code: Select all

           
		    ...
		    gen_packages_txt
		    gen_filelist
		    gen_md5_checksums
		    echo -ne "GPG password [ 'Enter' to leave ]: "
		    read PASSPHRASE
		    if [ "$PASSPHRASE" = "" ]; then exit 1; fi
		    
		    for pkg in `find . -type f -name '*.asc' -print`
		    do
				    rm $pkg
		    done
		    
		    for pkg in `find . -type f -name '*.iso' -print`
		    do
				    echo "$PASSPHRASE" | gpg -sba --batch --passphrase-fd 0 $pkg
				    echo "$pkg signed"
		    done
		    
		    for pkg in `find . -type f -regex '.*\.[tgblzikx]+$' -print`
		    do
				    echo "$PASSPHRASE" | gpg -sba --batch --passphrase-fd 0 $pkg
				    echo "$pkg signed"
		    done
		    
		    for pkg in `find . -type f -name '*.lzm' -print`
		    do
				    echo "$PASSPHRASE" | gpg -sba --batch --passphrase-fd 0 $pkg
				    echo "$pkg signed"
		    done
		    ...
regards, Quax
Hole Deine Benutzer da ab, wo sie stehen,
nicht da, wo Du sie gerne stehen hättest...
-------------------------------------------------------------
Pick up the users where they really are
and not where you expect them to be...
User avatar
gapan
Salix Wizard
Posts: 6238
Joined: 6. Jun 2009, 17:40

Re: GPG support in the repos

Post by gapan »

You still need to input the passphrase. No way around that, unless you store it somewhere in a file, which would beat the whole purpose of using gpg. :D

Here's the one we're using (we don't sign each file, only the CHECKSUMS.md5 file, which is enough):

Code: Select all

#!/bin/sh

export LANG=C

if [ -f ~/.metagen.lock ];then
	echo "Another metagen.sh instance seems to be running!"
	echo "Check with ps and remove the ~/.metagen.lock file if it is leftover somehow."
	exit 1
else
	touch ~/.metagen.lock
fi

function gen_packages_txt {
	echo '' > PACKAGES.TXT
	find ./salix -type f -name '*.meta' -exec cat {} \; >> PACKAGES.TXT
	cat PACKAGES.TXT | gzip -9 -c - > PACKAGES.TXT.gz
}

function gen_meta {
	unset REQUIRED CONFLICTS SUGGESTS
	if [ ! -f $1 ]; then
		echo "File not found: $1"
		exit 1;
	fi
		if [ "`echo $1|grep -E '(.*{1,})\-(.*[\.\-].*[\.\-].*).t[glx]z[ ]{0,}$'`" == "" ]; then
			return;
		fi
	NAME=$(echo $1|sed -re "s/(.*\/)(.*.t[glx]z)$/\2/")
	LOCATION=$(echo $1|sed -re "s/(.*)\/(.*.t[glx]z)$/\1/")
	if [[ `echo $1 | grep "tgz$"` ]]; then
		SIZE=$( expr `gunzip -l $1 |tail -1|awk '{print $1}'` / 1024 )
		USIZE=$( expr `gunzip -l $1 |tail -1|awk '{print $2}'` / 1024 )
	elif [[ `echo $1 | grep "t[lx]z$"` ]]; then
		SIZE=$( expr `ls -l $1 | awk '{print $5}'` / 1024 )
		#USIZE is only an appoximation, nothing similar to gunzip -l for lzma yet
		USIZE=$[$SIZE * 4 ]
	fi
	
	METAFILE=${NAME%t[glx]z}meta
	
	if test -f $LOCATION/${NAME%t[glx]z}dep
	then
		REQUIRED="`cat $LOCATION/${NAME%t[glx]z}dep`"
	fi
	if test -f $LOCATION/${NAME%t[glx]z}con
	then
		CONFLICTS="`cat $LOCATION/${NAME%t[glx]z}con`"
	fi
	if test -f $LOCATION/${NAME%t[glx]z}sug
	then
		SUGGESTS="`cat $LOCATION/${NAME%t[glx]z}sug`"
	fi
	echo "PACKAGE NAME:  $NAME" > $LOCATION/$METAFILE
	if [ -n "$DL_URL" ]; then
		echo "PACKAGE MIRROR:  $DL_URL" >> $LOCATION/$METAFILE
	fi
	echo "PACKAGE LOCATION:  $LOCATION" >> $LOCATION/$METAFILE
	echo "PACKAGE SIZE (compressed):  $SIZE K" >> $LOCATION/$METAFILE
	echo "PACKAGE SIZE (uncompressed):  $USIZE K" >> $LOCATION/$METAFILE
	echo "PACKAGE REQUIRED:  $REQUIRED" >> $LOCATION/$METAFILE
	echo "PACKAGE CONFLICTS:  $CONFLICTS" >> $LOCATION/$METAFILE
	echo "PACKAGE SUGGESTS:  $SUGGESTS" >> $LOCATION/$METAFILE
	echo "PACKAGE DESCRIPTION:" >> $LOCATION/$METAFILE
	if test -f $LOCATION/${NAME%t[glx]z}txt
	then
		cat $LOCATION/${NAME%t[glx]z}txt |grep -E '[^[:space:]]*\:'|grep -v '^#' >> $LOCATION/$METAFILE
	else
		if [[ `echo $1 | grep "tgz$"` ]]; then
			tar xfO $1 install/slack-desc |grep -E '[^[:space:]]*\:'|grep -v '^#' >> $LOCATION/$METAFILE
			tar xfO $1 install/slack-desc |grep -E '[^[:space:]]*\:'|grep -v '^#' > $LOCATION/${NAME%t[glx]z}txt
		elif [[ `echo $1 | grep "t[lx]z$"` ]]; then
			lzma -c -d $1 | tar xO install/slack-desc |grep -E '[^[:space:]]*\:'|grep -v '^#' >> $LOCATION/$METAFILE
			lzma -c -d $1 | tar xO install/slack-desc |grep -E '[^[:space:]]*\:'|grep -v '^#' > $LOCATION/${NAME%t[glx]z}txt
		fi
	fi
	echo "" >> $LOCATION/$METAFILE
}


case "$1" in
	pkg)
		if [ -n "$2" ]; then
			gen_meta $2
		else
			echo "$0 [pkg [file]|all|new|PACKAGESTXT|md5]"
		fi
	;;
	all)
		for pkg in `find ./salix -type f -name '*.t[glx]z' -print`
		do
			gen_meta $pkg
		done
		gen_packages_txt
	;;
	new)
		for pkg in `find ./salix -type f -name '*.t[glx]z' -print`
		do
			if [ ! -f ${pkg%t[glx]z}meta ]; then
				gen_meta $pkg
			fi
		done
		gen_packages_txt
	;;
	PACKAGESTXT)
		gen_packages_txt
	;;
	md5)
		echo '' > CHECKSUMS.md5
		for pkg in `find ./salix -type f -name '*.t[glx]z' -print`
		do
			if [ ! -f ${pkg%t[glx]z}md5 ]; then
				md5sum ${pkg} | sed "s|  \.\(.*\)/\(.*\)|  \2|" > ${pkg%t[glx]z}md5
			fi
			cat ${pkg%t[glx]z}md5 | sed "s|`basename ${pkg}`|${pkg}|" >> CHECKSUMS.md5
		done
		cat CHECKSUMS.md5 | gzip -9 -c - > CHECKSUMS.md5.gz
		rm -f CHECKSUMS.md5.gz.asc
		gpg -sba CHECKSUMS.md5.gz
	;;
	*)
		echo "$0 [pkg [file]|all|new|PACKAGESTXT|MD5|]"
		echo "$0 [miss|provide] pattern"
	;;
esac

rm ~/.metagen.lock

Image
Image
Locked