User Tools

Site Tools


zh:docs:guide-user:security:release_signatures

发行版签名

概述

OpenWrt使用了 GnuPG,以及 usign,一个由 OpenBSD signify 工具派生出来的签名软件,对发行版进行签名。

OPKG 软件包管理器使用 usign Ed25519 签名来在安装软件时校验软件库的数据,而OpenWrt固件开发者通常会附带上GPG签名以便用户校验下载的文件是否被更改。

usign 签名文件的后缀名是 .sig,而 GPG 签名文件的后缀是 .gpg

需要注意的是,并不是所有的文件都有单独的签名文件,但我们会使用sha256sums来计算他们的校验和。对于软件库来说,软件包的信任链是这样的:SHA256 校验文件保证了软件包不被更改,而校验文件的签名文件保证了校验文件是可信的。

校验下载完整性

你可以通过以下步骤来校验下载的固件的完整性:

  1. 下载 sha256sumsha256sum.gpg 文件
  2. 使用命令 gpg --with-fingerprint --verify sha256sum.gpg sha256sum, 确保 GnuPG 告诉你这个签名是正确的,并且签名的指纹符合指纹页面上面所记载的指纹.
  3. 将固件文件下载并存放至与 sha256sums 文件相同的文件夹下,使用命令 sha256sum -c --ignore-missing sha256sums 来校验固件文件

使用验证脚本

你也可以使用我们提供的验证脚本来方便的下载并校验你的固件。

下面是一个使用download.sh脚本的例子:

user@host:~$ wget -O download.sh https://lede-project.org/_export/code/docs/user-guide/release_signatures?codeblock=1
--2016-12-24 01:48:14--  https://lede-project.org/_export/code/docs/user-guide/release_signatures?codeblock=1
Resolving lede-project.org (lede-project.org)... 139.59.209.225, 2a03:b0c0:3:d0::1af1:1
Connecting to lede-project.org (lede-project.org)|139.59.209.225|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: unspecified [text/plain]
Saving to: ‘download.sh’

    [ <=>                                                                                ] 4,091       --.-K/s   in 0s      

2016-12-24 01:48:14 (722 MB/s) - ‘download.sh’ saved [4091]

user@host:~$ chmod +x download.sh 
user@host:~$ ./download.sh https://downloads.lede-project.org/snapshots/targets/ar71xx/generic/lede-ar71xx-generic-tl-wr1043nd-v1-squashfs-factory.bin 
1) Downloading image file
=========================
############################################################ 100,0%

2) Downloading checksum file
============================
############################################################ 100,0%

3) Downloading the GPG signature
================================
############################################################ 100,0%

4) Verifying GPG signature
==========================
The signature was signed by a public key with the id F93525A88B699029 which is not present on this system.

Provide a public keyserver url below or press enter to accept the default suggestion. Hit Ctrl-C to abort the operation.

Keyserver to use? [hkp:%%//%%pool.sks-keyservers.net] > 
gpg: requesting key 8B699029 from hkp server pool.sks-keyservers.net 
gpg: key 626471F1: public key "LEDE Build System (LEDE GnuPG key for unattended build jobs) <<lede-adm@lists.infradead.org>>" imported 
gpg: Total number processed: 1 
gpg:               imported: 1 (RSA: 1) 
gpg: Signature made Di 02 Aug 2016 10:10:40 CEST using RSA key ID 8B699029 
gpg: Good signature from "LEDE Build System (LEDE GnuPG key for unattended build jobs) <<lede-adm@lists.infradead.org>>" 
gpg: WARNING: This key is not certified with a trusted signature! 
gpg:          There is no indication that the signature belongs to the owner. 
Primary key fingerprint: 54CC 7430 7A2C 6DC9 CE61 8269 CD84 BCED 6264 71F1 
     Subkey fingerprint: 6D92 78A3 3A9A B314 6262 DCEC F935 25A8 8B69 9029

5) Verifying SHA256 checksum
============================
lede-ar71xx-generic-tl-wr1043nd-v1-squashfs-factory.bin: OK

Verification done!
==================
Firmware image placed in ///home/user/lede-ar71xx-generic-tl-wr1043nd-v1-squashfs-factory.bin//.

Cleaning up. <user@host>:~$

对于开发者

参与OpenWrt的所有开发者都需要将自己的 GnuPGusign 公钥存放在主密钥环库中。

你可以参考 key generation howto 页面来为自己生成一个公钥。

Download.sh

这个脚本可以帮你快速的生成或校验公钥

Download.sh
#!/usr/bin/env bash
# Script to perform verified file downloads.
# Exit codes:
#  0 - File downloaded successfully and verified
#  1 - Failed to download requested file
#  2 - Failed to download sha256sums file
#  3 - Failed to download sha256sums.gpg file
#  4 - GnuPG is available but fails to verify the signature (missing pubkey, file integrity error, ...)
#  5 - The checksums do not match
#  6 - Unable to copy the requested file to its final destination
#  254 - The script got interrupted by a signal
#  255 - A suitable download or checksum utility is missing
 
[ -n "$1" ] || {
	echo "Usage: $0 <url>" >&2
	exit 1
}
 
finish() {
	[ -e "/tmp/verify.$$" ] && {
		echo "Cleaning up."
		rm -r "/tmp/verify.$$"
	}
	exit $1
}
 
trap "finish 254" INT TERM
 
destdir="$(pwd)"
image_url="$1"
image_file="${image_url##*/}"
sha256_url="${image_url%/*}/sha256sums"
gpgsig_url="${image_url%/*}/sha256sums.gpg"
keyserver_url="hkp://pool.sks-keyservers.net"
 
# Find a suitable download utility
if which curl >/dev/null; then
	download() { curl --progress-bar -o "$1" "$2"; }
elif which wget >/dev/null; then
	download() { wget -O "$1" "$2"; }
elif which fetch >/dev/null; then
	download() { fetch -o "$1" "$2"; }
else
	echo "No suitable download utility found, cannot download files!" >&2
	finish 255
fi
 
# Find a suitable checksum utility
if which sha256sum >/dev/null; then
	checksum() { sha256sum -c --ignore-missing "sha256sums"; }
elif which shasum >/dev/null; then
	checksum() {
		local sum="$(shasum -a 256 "$image_file")";
		grep -xF "${sum%% *} *$image_file" "sha256sums";
	}
else
	echo "No SHA256 checksum executable installed, cannot verify checksums!" >&2
	finish 255
fi
 
# Check for gpg availability
if which gpg >/dev/null; then
	runpgp() { gpg "$@"; }
else
	runpgp() {
		echo "WARNING: No GnuPG installed, cannot verify digital signature!" >&2
		return 0
	}
fi
 
mkdir -p "/tmp/verify.$$"
cd "/tmp/verify.$$"
 
echo ""
echo "1) Downloading image file"
echo "========================="
download "$image_file" "$image_url" || {
	echo "Failed to download image file!" >&2
	finish 1
}
 
echo ""
echo "2) Downloading checksum file"
echo "============================"
download "sha256sums" "$sha256_url" || {
	echo "Failed to download checksum file!" >&2
	finish 2
}
 
echo ""
echo "3) Downloading the GPG signature"
echo "================================"
download "sha256sums.gpg" "$gpgsig_url" || {
	echo "Failed to download GPG signature!" >&2
	finish 3
}
 
echo ""
echo "4) Verifying GPG signature"
echo "=========================="
missing_key=$(runpgp --status-fd 1 --with-fingerprint --verify \
	"sha256sums.gpg" "sha256sums" 2>/dev/null | sed -ne 's!^.* NO_PUBKEY !!p')
 
if [ -n "$missing_key" ]; then
	echo "The signature was signed by a public key with the id $missing_key" >&2
	echo "which is not present on this system."                              >&2
	echo ""                                                                  >&2
 
	echo "Provide a public keyserver url below or press enter to accept the" >&2
	echo "default suggestion. Hit Ctrl-C to abort the operation."            >&2
	echo ""                                                                  >&2
 
	while true; do
		printf "Keyserver to use? [$keyserver_url] > "
		read url; case "${url:-$keyserver_url}" in
			hkp://*)
				gpg --keyserver "${url:-$keyserver_url}" --recv-keys "$missing_key" || {
					echo "Failed to download public key." >&2
					finish 7
				}
				break
			;;
			*)
				echo "Expecting a key server url in the form 'hkp://hostname'." >&2
			;;
		esac
	done
fi
 
runpgp --with-fingerprint --verify "sha256sums.gpg" "sha256sums" || {
	echo "Failed to verify checksum file with GPG signature!" >&2
	finish 4
}
 
echo ""
echo "5) Verifying SHA256 checksum"
echo "============================"
checksum || {
	echo "Checksums do not match!" >&2
	finish 5
}
 
cp "$image_file" "$destdir/$image_file" || {
	echo "Failed to write '$destdir/$image_file'" >&2
	finish 6
}
 
echo ""
echo "Verification done!"
echo "=================="
echo "Firmware image placed in '$destdir/$image_file'."
echo ""
 
finish 0
zh/docs/guide-user/security/release_signatures.txt · Last modified: 2018/06/25 17:11 by jiangming1399