Implement gpg signature checking
This commit is contained in:
parent
b3dde04553
commit
75057de7d3
2 changed files with 62 additions and 3 deletions
15
README.md
15
README.md
|
@ -108,7 +108,9 @@ repo.example.com
|
|||
| ├── customlinux
|
||||
| | ├── database # Plain text file containing : delimited lists of all available images `image_name:compression_method:sha1sum`
|
||||
| | ├── customlinux_v1.0.tar.zst # Compressed disk images
|
||||
| | ├── customlinux_v1.0.tar.zst.sig # Detached GPG signature
|
||||
| | ├── customlinux_v2.0.tar.zst # Compressed disk images
|
||||
| | ├── customlinux_v2.0.tar.zst.sig # Detached GPG signature
|
||||
| ├── customlinux-gnome
|
||||
| | ├── database
|
||||
| | ├── customlinux-gnome_v1.0.tar.zst
|
||||
|
@ -136,3 +138,16 @@ The sha1sum is used to ensure the file was downloaded properly.
|
|||
|
||||
Arkdep will assume the top most entry in the database is the latest one, when no image version is defined or `latest` is requested it will grab the top most entry.
|
||||
|
||||
### Signed images
|
||||
A GPG signature is by default optional, if available Arkdep will use it instead of the sha1sum to verify image integrity. Arkdep can be configured to require these files to be provided by setting `gpg_signature_check` to `2` in the config file.
|
||||
|
||||
A keyring with trusted (private) keys is stored at `/arkdep/keys/trusted-keys`, keys are only accepted in binary format.
|
||||
|
||||
Arkdep assumes the signatures to be identical in name to their parent file with a .sig appended.
|
||||
|
||||
Generate a signature like so;
|
||||
```shell
|
||||
gpg --output customlinux_v1.0.tar.zst.sig --detach-sig customlinux_v1.0.tar.zst
|
||||
```
|
||||
|
||||
Then simply drop these signatures next to disk image itself.
|
||||
|
|
50
arkdep
50
arkdep
|
@ -56,6 +56,7 @@ source $(readlink -m $arkdep_dir/config)
|
|||
[[ -z ${deploy_keep+x} ]] && deploy_keep=3 && printf '\e[1;33m<!>\e[0m\e[1m deploy_config not defined in config, using default\e[0m\n'
|
||||
[[ -z ${clean_cache_on_remove+x} ]] && clean_cache_on_remove=1 && printf '\e[1;33m<!>\e[0m\e[1m clean_cache_on_remove not defined in config, using default\e[0m\n'
|
||||
[[ -z ${always_healthcheck+x} ]] && always_healthcheck=1 && printf '\e[1;33m<!>\e[0m\e[1m always_healthcheck not defined in config, using default\e[0m\n'
|
||||
[[ -z ${gpg_signature_check+x} ]] && gpg_signature_check=1 && printf '\e[1;33m<!>\e[0m\e[1m gpg_signature_check not defined in config, using default\e[0m\n'
|
||||
|
||||
## Common functions
|
||||
#
|
||||
|
@ -128,6 +129,11 @@ healthcheck () {
|
|||
done
|
||||
fi
|
||||
|
||||
# Warn if gpg check is enabled but no keys are installed
|
||||
if [[ ! $gpg_signature_check -eq 0 ]] && [[ ! -s $arkdep_dir/keys/trusted-keys ]]; then
|
||||
printf "\e[1;33m<!>\e[0m\e[1m gpg_signature_check is enabled but $arkdep_dir/keys/trusted-keys does not exist or is empty\n\e[0m"
|
||||
fi
|
||||
|
||||
# If $1 is healthcheck it was manually called by the user
|
||||
[[ $1 == 'healthcheck' ]] && exit 0
|
||||
|
||||
|
@ -144,7 +150,7 @@ healthcheck () {
|
|||
exit 1
|
||||
|
||||
# Check if all dependencies are installed, quit if not
|
||||
for prog in btrfs wget dracut bootctl curl; do
|
||||
for prog in btrfs wget dracut bootctl curl gpg gpgv; do
|
||||
if ! command -v $prog > /dev/null; then
|
||||
printf "\e[1;31m<#>\e[0m\e[1m Failed to locate $prog, ensure it is installed\e[0m\n"
|
||||
err=1
|
||||
|
@ -176,11 +182,13 @@ init () {
|
|||
$(readlink -m $arkdep_dir/cache) \
|
||||
$(readlink -m $arkdep_dir/templates) \
|
||||
$(readlink -m $arkdep_dir/overlay) \
|
||||
$(readlink -m $arkdep_dir/keys) \
|
||||
$(readlink -m $arkdep_dir/shared) ||
|
||||
cleanup_and_quit "Failed to create $arkdep_dir and related directories"
|
||||
|
||||
# Create empty database files
|
||||
touch $(readlink -m $arkdep_dir/tracker)
|
||||
touch $(readlink -m $arkdep_dir/keys/trusted-keys)
|
||||
|
||||
# Add home shared subvolume and make writable
|
||||
btrfs subvolume create $(readlink -m $arkdep_dir/shared/home) || cleanup_and_quit "Failed to create home subvolume"
|
||||
|
@ -189,7 +197,7 @@ init () {
|
|||
# Write default config file
|
||||
printf '\e[1;34m-->\e[0m\e[1m Adding default config file\e[0m\n'
|
||||
cat <<- END > $arkdep_dir/config
|
||||
# Write /arkdep/overlay overlay to root or etc
|
||||
# Write /arkdep/overlay overlay to new deployments
|
||||
enable_overlay=1
|
||||
|
||||
# URL to image repository, do not add trailing slash
|
||||
|
@ -206,6 +214,10 @@ init () {
|
|||
|
||||
# Check for untracked deployments and other issues on run
|
||||
always_healthcheck=1
|
||||
|
||||
# Perform a GPG signature check on remote sources
|
||||
# 1 = enable, 2 = error on gpg key download fail
|
||||
gpg_signature_check=1
|
||||
END
|
||||
|
||||
# Add default bootloader config file
|
||||
|
@ -435,11 +447,43 @@ deploy () {
|
|||
if [[ ! -e $arkdep_dir/cache/${data[0]}.tar.${data[1]} ]]; then
|
||||
wget -q --show-progress -P $(readlink -m $arkdep_dir/cache/) "$repo_url/$deploy_target/${data[0]}.tar.${data[1]}" ||
|
||||
cleanup_and_quit 'Failed to download tarball'
|
||||
|
||||
# If new download perform GPG check
|
||||
#
|
||||
# Only perform check if not disabled by user and keychain exists
|
||||
if [[ ! $gpg_signature_check -eq 0 ]] && [[ -s $arkdep_dir/keys/trusted-keys ]]; then
|
||||
|
||||
printf '\e[1;34m-->\e[0m\e[1m Checking GPG signature\e[0m\n'
|
||||
|
||||
# Download gpg signature
|
||||
wget -q --show-progress -P $(readlink -m $arkdep_dir/cache/) "$repo_url/$deploy_target/${data[0]}.tar.${data[1]}.sig"
|
||||
declare -r sig_exitcode=$?
|
||||
|
||||
# If download failed skip GPG check
|
||||
if [[ ! $sig_exitcode -eq 0 ]] && [[ $gpg_signature_check -eq 1 ]]; then
|
||||
# Sig download is allowed to fail
|
||||
printf "\e[1;33m<!>\e[0m\e[1m Failed to download GPG signature, signature check will be skipped\e[0m\n"
|
||||
skip_pgp_check=1
|
||||
elif [[ ! $sig_exitcode -eq 0 ]] && [[ $gpg_signature_check -eq 2 ]]; then
|
||||
# If this triggers the user explicitely defined gpg_signature_check to fail on error
|
||||
cleanup_and_quit 'GPG signature check configured to quit on download failure'
|
||||
fi
|
||||
|
||||
# If not configured to skip by previous error handeling check the signature to the downloaded image
|
||||
if [[ ! $skip_pgp_check -eq 1 ]]; then
|
||||
gpgv --keyring $arkdep_dir/keys/trusted-keys $arkdep_dir/cache/${data[0]}.tar.${data[1]}.sig $arkdep_dir/cache/${data[0]}.tar.${data[1]} ||
|
||||
cleanup_and_quit 'gpg check failed'
|
||||
|
||||
# We have already gpg checked, no need to check hash
|
||||
was_gpg_checked=1
|
||||
fi
|
||||
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
# Do not checksum if - provided
|
||||
if [[ ${data[2]} != '-' ]]; then
|
||||
if [[ ${data[2]} != '-' ]] && [[ ! was_gpg_checked -eq 1 ]]; then
|
||||
printf '\e[1;34m-->\e[0m\e[1m Validating integrity\e[0m\n'
|
||||
sha1sum "$(readlink -m $arkdep_dir/cache/${data[0]}.tar.${data[1]})" |
|
||||
grep "${data[2]}" ||
|
||||
|
|
Loading…
Add table
Reference in a new issue