Knowledge Base

Preserving for the future: Shell scripts, AoC, and more

Building an apt repository on CentOS

Apt is a dpkg management tool used by Debian and its offpsring, particularly Ubuntu and Linux Mint. CentOS is from the RHEL/Fedora side of the Linux family tree and uses yum (and dnf nowadays). Making a simple, signed apt repository on centos (or manually, on any system really) is possible. This is how to do it.

Building an apt repository

So you have packages you want to make available for your LAN or wherever. This document will show you how to make a directory with all the right parts for an apt repository that is gpg-signed (to stave off that annoying "Do you trust the source?" question).

Preparing gpg keys

Note: generating new keys can require some time orand entropy generation.

# as root; no sudo!
gpg --gen-key

The first time you run gpg --gen-key, break it after it has generated some directories and files. Add the SHA256 requirement to the gpg conf.

cat <<'EOF' >> ~/.gnupg/gpg.conf
cert-digest-algo SHA256
digest-algo SHA256
EOF

Reference: Weblink 3 Run gpg again and this time follow the prompts to generate a key.

gpg --gen-key

If you need to generate extra entropy, consider running some mundane tasks in another terminal.

while true; do dd if=/dev/sda of=/dev/zero; find / | xargs file >/dev/null 2>&1; done

Just break it off when you get the gpg keys you need. Export the keys as needed with these commands.

gpg --list-keys
# take the key name shown and do this:
gpg --output debian-repo-public.gpg --armor --export 123456AB
gpg --output debian-repo-private.gpg --armor --export-secret-key 123456AB

So the end state of this section is to have the public key as a file, preferably in the repository directory.

Installing required packages

Install epel-release which wil lget you the dpkg-dev and tar packages you need (just in case tar isn't on your system).

yum –y install epel-release
yum –y install dpkg-dev tar

Building the repository building script

Make a script that automates building the Release and Package files.

updatescript=/mnt/mirror/ubuntu/example-debian/update-repo.sh
cat <<'EOFSH' >${updatescript}
#!/bin/sh

# working directory
repodir=/mnt/mirror/ubuntu/example-debian/
cd ${repodir}

# create the package index
dpkg-scanpackages -m . > Packages
cat Packages | gzip -9c > Packages.gz

# create the Release file
PKGS=$(wc -c Packages)
PKGS_GZ=$(wc -c Packages.gz)
cat <<EOF > Release
Architectures: all
Date: \$(date -R)
MD5Sum:
 $(md5sum Packages  | cut -d" " -f1) $PKGS
 $(md5sum Packages.gz  | cut -d" " -f1) $PKGS_GZ
SHA1:
 $(sha1sum Packages  | cut -d" " -f1) $PKGS
 $(sha1sum Packages.gz  | cut -d" " -f1) $PKGS_GZ
SHA256:
 $(sha256sum Packages | cut -d" " -f1) $PKGS
 $(sha256sum Packages.gz | cut -d" " -f1) $PKGS_GZ
EOF
gpg -abs -o Release.gpg Release
EOFSH
chmod 755 ${updatescript}

It might be useful to modify the script to chmod 444 *.deb or something similar. When running the script, make sure you use the correct key to sign the release file. Note that this script calls gpg, which will interactively ask the user to enter the passphrase for the key.

Managing the repository

The repository is ready to receive files and be updated. The example location is /mnt/mirror/ubuntu/example-debian/.

Adding packages to the repo

Move any .deb packages you want to the repo directory. Run the update-repo script form root (because the gpg keys were generated as root).

./update-repo.sh

Provide the passphrase.

Configuring a client

For each system you want to add the repository to, you need to follow these steps. Import the public key into apt and add the repo to the sources.

sudo wget --quiet http://mirror.example.com/ubuntu/example-debian/example-debian.gpg -O /root/example-debian.gpg
sudo apt-key add /root/example-debian.gpg   
sudo wget --quiet http://mirror.example.com/ubuntu/example-debian/example-debian.list -O /etc/apt/sources.list.d/example-debian.list

Update the available package list.

apt-get update

The system is now ready to install packages from your repository.

Addenda

Last modified 2020-02-28

You can store your plaintext gpg passphrase (use at your own risk!) and pass a few parameters to gpg for the whole task to be automatic.

gpg --batch --yes --passphrase-file /root/.gnupg/passphrasefile -abs -o Release.gpg Release

Weblinks

  1. Main layout of entire document https://www.sidorenko.io/blog/2015/05/19/easy-creation-of-a-simple-apt-repo/
  2. Manipulating gpg keys https://www.debuntu.org/how-to-importexport-gpg-key-pair/
  3. Using SHA256 for apt http://askubuntu.com/questions/760796/how-to-fix-apt-signature-by-key-uses-weak-digest-algorithm-sha1-after-install/776599#776599
  4. Extra information about debian repos https://wiki.debian.org/RepositoryFormat
  5. Discussion of various debian repo utilities https://wiki.debian.org/HowToSetupADebianRepository
  6. Alternate method for making a repo http://hyperlogos.org/page/Simple-recipe-custom-UbuntuDebian-repositories-apt-ftparchive
  7. How to make a super simple, unsigned repo https://help.ubuntu.com/community/Repositories/Personal

Comments