To prevent your users from possibly facing man-in-the-middle attacks and secure your repository, you should follow these steps. To get started, we'll need you to have a GPG key to sign with and export the public key (it's easier than you might think). I provide instructions for Linux and macOS because these are the two operating systems I use--this should be doable in WSL or Cygwin.
-
Get the GnuPG utilities. This is most likely included on your distro of Linux and can be installed with
sudo apt install gnupg
orbrew install gnupg
on macOS. -
Generate a new key. Open a terminal and run
gpg --full-generate-key
. Pick(9) ECC (sign and encrypt)
as the type, pick(1) Curve 25519 *default*
for your curve, and0
to keep the key from expiring (if you don't have the option to use ECC, choose(1) RSA and RSA
, then select4096
as your key length). Then enter your real name, email address, and an optional comment to fill out the signature details. Once you've done this, hitO
and enter to save your settings, enter a password (you can leave it blank if you desire) and there you go! You now have a new key to sign with. -
Find the key's signature.
gpg --list-secret-keys --keyid-format=long
will list the keys you've created on your system. What you're after is thesec
of the key, which is expanded in full on the second line (what the blue arrow is pointing to). -
Create Release.gpg. With this signature copied, you can now run the next command:
gpg -abs -u <what you copied> -o Release.gpg Release
. This signs your Release and creates Release.gpg, which marks the first part of signing properly complete. (example:gpg -abs -u 0EA1CD919AF64DDE44F2AF3EAEE9BA5226A6631B -o Release.gpg Release
) -
Export your public key. Now, the final step is to export the public key. This allows your users to download and trust your repo is really yours. Remember that picture up above with the two arrows? This time, you need to copy what the yellow arrow is pointing to (all of the numbers and letters to the right of
rsa4096/
. Once copied, you can typegpg --export <what you copied> > <yourname/username>-repo.gpg
. (example:gpg --export AEE9BA5226A6631B > doregon-repo.gpg
) -
Verify your key works. Upload Release.gpg to your repo's server, and move the exported key to
/etc/apt/trusted.gpg.d/
on iOS or/opt/procursus/etc/apt/trusted.gpg.d
on macOS. If you're successful, you should only see errors about an incorrect Date and missing Hashes (we solve this in the next section). GettingBADSIG
,NO_PUBKEY
, or any other GPG related errors means that you should check again and possbily regenerate your keys.
- Generate and sign your files. When you or your package manager downloads repo files, in this case Packages*, Contents* and Release, we need to certify that these files you download are exactly the ones you're supposed to get. It's possible to do so by checking the hash of a file, thanks to protocols like MD5, SHA1, SHA256...
Each time you're doing a modification to yourdeb
s, you'll need to run this script from your repo's root folder:
apt-ftparchive packages ./debs > Packages
bzip2 -c9 Packages > Packages.bz2
xz -c9 Packages > Packages.xz
xz -5fkev --format=lzma Packages > Packages.lzma
lz4 -c9 Packages > Packages.lz4
gzip -c9 Packages > Packages.gz
zstd -c19 Packages > Packages.zst
# While we are at it, also generate Contents files
apt-ftparchive contents ./debs > Contents-iphoneos-arm
bzip2 -c9 Contents-iphoneos-arm > Contents-iphoneos-arm.bz2
xz -c9 Contents-iphoneos-arm > Contents-iphoneos-arm.xz
xz -5fkev --format=lzma Contents-iphoneos-arm > Contents-iphoneos-arm.lzma
lz4 -c9 Contents-iphoneos-arm > Contents-iphoneos-arm.lz4
gzip -c9 Contents-iphoneos-arm > Contents-iphoneos-arm.gz
zstd -c19 Contents-iphoneos-arm > Contents-iphoneos-arm.zst
grep -E "Origin:|Label:|Suite:|Version:|Codename:|Architectures:|Components:|Description:" Release > Base
apt-ftparchive release . > Release
cat Base Release > out && mv out Release
# This line below will ask for your password defined on step 2. Replace what's on <> with the right value, it should look like step 4.
gpg -abs -u <blue-arrow-value> -o Release.gpg Release
(If you are hosting your repo on GitHub Pages, you can use GitHub Actions like that)
Some info:
- This script requires
zstd
, that can be installed usingbrew install zstd
orsudo apt install zstd
- Same thing for
xz
,lz4
andlzma
(bundled inxz
andlz4
brew package)
- Same thing for
- macOS users:
- May need to use the GNU versions of
md5sum
andsha256sum
. - Do need Procursus fork of apt-ftparchive as macOS doesn't features
apt
. You may need to add './
' before eachapt-ftparchive
in the script.
- May need to use the GNU versions of
- What is does:
- Generates Packages with hashes from the debs/ folder, change this if your debs are not in debs/
- Compresses it with xz, gzip, zstd, bzip2, lz4, and lzma, this is for the widest compatibility. Change if you don't see the need for it.
- Generates Conetnts file which allows previewing package filenames before downloading
- Also compresses it with xz, gzip, zstd, bzip2, lz4 and lzma, this is for the widest compatibility.
- Saves temporarily key values of Release file in Base file
- Generates hashes and date of Packages files in the Release file
- Adds the content of Base then Release in Release
- Note that you shouldn't push Base file, it's temporary. Remove it by adding
rm Base
in the script or don't push it by doinggit add Packages* Conetnts* Release*
instead ofgit add .
. - Even better, you could add it to .gitignore
- Note that you shouldn't push Base file, it's temporary. Remove it by adding
- Signs Release in Release.gpg
- Upload your new changes!. The files changed by the above shell script can be uploaded to your repo server. To your users, nothing will have changed and the repo will still work as usual. For your GPG key, you can put it somewhere public, like the README of a GitHub Pages repository, the main page for a private one, or another location where your users can easily get at. If you want to include your key in your README in a GitHub repo, you can drag it into the README while editing it from the web editor. I've been working closely with the Procursus Team to add keys to their keyring, so in a future update of Sileo adding your repo automatically installs your keyring (or users can manually install it), and you can email me at
tunnic.adam@gmail.com
to see about getting your keys onto Procursus.