GPG 入門
GnuPG は、Pretty Good Privacy (PGP) のOSS版です。
GNU Privacy Guard (GnuPG, GPGはOpenPGP標準の実装。以下のことを行います。
- 暗号化
- 電子署名
- 公開鍵認証
例えば、パッケージマネージャーなどのインストーラーがダウンロードするソフトウェアが意図した作成者が作成したものであるか確認してからインストールします。これを実現する仕組みの一つです。 鍵管理には、公開鍵方式を使用しますが、認証局を設置せず、ユーザーそれぞれが鍵管理をして、取得した公開鍵を確認します。
GPGでは、以下の2つの秘密鍵を作ります。
- 署名のためのmaster key
- 署名に加えて暗号化を行うためのsub key
master keyは絶対に流出させないように厳重に管理し、普段の運用にsub keyを使用する。
master keyを使用するのは以下の場合です(参照: *** GPGで自分用の秘密鍵を1つに統一する)。
- 他人の鍵に署名
- 鍵を取り消し
- UIDを強く信頼
- 新しいsub keyを作成
- 他の鍵の暗号化アルゴリズム、ハッシュ関数などを変更
- 鍵の有効期限を指定
master keyは、オフライン環境で、一度もネットワークに繋いだことのないOSのような環境で実行し、厳重に管理します。信頼できない、OS上では実行してはいけない。 署名と暗号化に同一の鍵を使うと、暗号化アルゴリズム依存の脆弱性が生じる場合があるので、暗号化、署名、認証のそれぞれに専用のsub keyを作ると良い。
Web of Trust
公開鍵の正当性を確認するために、フィンガープリントが一致していることを確認します。正当性の確認が済んだ後,受け取った公開鍵に,自分の秘密鍵で署名することで準備完了です。
信頼できる人が信頼している公開鍵は信用することを、広げていきます。このように、互いに、鍵の署名を行いあうことで、信頼の関係を構築していくことで、信頼関係を構築します。 公開鍵の正当性の確認を行わないと、Web of Trust全体の信頼性が下がります。
自身の鍵ペアについては、公開鍵はWeb上で公開したり、鍵サーバーに登録し、メールを送る都度添付することで対応します。他の人は自身あてに暗号化メールを送ったり、他の人が自身の公開鍵で自身が署名した内容を検証できるようになります。
これらの公開鍵をまとめておくものが鍵束(Keyring)です。これは以下のようにバイナリーファイルとして格納されています。
# hexdump -C ~/.gnupg/pubring.kbx
00000000 00 00 00 20 01 01 00 02 4b 42 58 66 00 00 00 00 |... ....KBXf....|
00000010 61 b9 5c bc 61 ba a7 13 00 00 00 00 00 00 00 00 |a.\.a...........|
00000020 00 00 07 c2 02 01 00 00 00 00 00 66 00 00 07 48 |...........f...H|
:
000027f0 f2 ec 82 b0 06 00 03 67 70 67 00 d1 fd 7d fe cb |.......gpg...}..|
00002800 a7 a0 a2 96 5e 5b 72 f9 d3 24 a8 3d b6 91 7c |....^[r..$.=..||
0000280f
ただし、公開鍵は普段使いには、サイズが大きいため、電子指紋(鍵指紋)をメールのヘッダーやフッターに添付することで、Web上に公開しておいた公開鍵の電子指紋と比較することができる。
gpgコマンドの使い方
環境
以下のバージョンで検証。
GPGのバージョンは以下。
$ gpg --version
gpg (GnuPG) 2.2.33
libgcrypt 1.8.8
Copyright (C) 2021 Free Software Foundation, Inc.
License GNU GPL-3.0-or-later <https://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Home: /home/ec2-user/.gnupg
Supported algorithms:
Pubkey: RSA, ELG, DSA, ECDH, ECDSA, EDDSA
Cipher: IDEA, 3DES, CAST5, BLOWFISH, AES, AES192, AES256, TWOFISH,
CAMELLIA128, CAMELLIA192, CAMELLIA256
Hash: SHA1, RIPEMD160, SHA256, SHA384, SHA512, SHA224
Compression: Uncompressed, ZIP, ZLIB
RPMのバージョンは以下。
$ rpm --version
RPM version 4.11.3
Get Started
GPG鍵の生成
GPG鍵を生成。鍵の種類や有効期限などを聞かれるがここではすべてデフォルトのまま使用する。
$ gpg --gen-key
gpg (GnuPG) 2.2.33; Copyright (C) 2021 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Note: Use "gpg --full-generate-key" for a full featured key generation dialog.
GnuPG needs to construct a user ID to identify your key.
Real name: Sample1
Email address: hayashier@example.com
You selected this USER-ID:
"Sample1 <hayashier@example.com>"
Change (N)ame, (E)mail, or (O)kay/(Q)uit? O
以下のような画面でパスフレーズを入力します。
┌──────────────────────────────────────────────────────┐
│ Please enter the passphrase to │
│ protect your new key │
│ │
│ Passphrase: ________________________________________ │
│ │
│ <OK> <Cancel> │
└──────────────────────────────────────────────────────┘
インポートされている公開鍵の情報は以下。
$ gpg --list-keys
/home/ec2-user/.gnupg/pubring.gpg
---------------------------------
pub rsa3072 2021-12-15 [SC] [expires: 2023-12-15]
ACADDFEEB9D5D60EFAC9463544B04C2E699AC5F0
uid [ultimate] Sample1 <hayashier@example.com>
sub rsa3072 2021-12-15 [E] [expires: 2023-12-15]
なお、上記コマンドの初回実行時は以下のようなデバッグメッセージが出力されるので、自動化の際は注意。
$ gpg --list-keys
gpg: directory `/home/ec2-user/.gnupg' created
gpg: new configuration file `/home/ec2-user/.gnupg/gpg.conf' created
gpg: WARNING: options in `/home/ec2-user/.gnupg/gpg.conf' are not yet active during this run
gpg: keyring `/home/ec2-user/.gnupg/pubring.gpg' created
gpg: /home/ec2-user/.gnupg/trustdb.gpg: trustdb created
$ gpg --list-keys
$
GPGで暗号化、署名
まず、GPGはどのように扱うか基本を抑えておく必要がある。
$ echo "Hello, World" > test.txt
ファイルの署名には以下のコマンドを実行します。
$ gpg -s test.txt
以下のような入力画面が出てくるので、鍵作成時に指定したパスワードを入力します。
┌────────────────────────────────────────────────────────────────┐
│ Please enter the passphrase to unlock the OpenPGP secret key: │
│ "Sample1 <hayashier@example.com>" │
│ 3072-bit RSA key, ID AAC5DE59A84FCD28, │
│ created 2021-12-15. │
│ │
│ │
│ Passphrase: ********__________________________________________ │
│ │
│ <OK> <Cancel> │
└────────────────────────────────────────────────────────────────┘
すると、以下のようなバイナリーファイルが作成されます。
$ hexdump -C test.txt.gpg
00000000 a3 01 01 e2 01 1d fe 90 0d 03 00 08 01 c1 d2 ca |................|
00000010 ea 38 27 7e e6 01 ac 1b 62 08 74 65 73 74 2e 74 |.8'~....b.test.t|
00000020 78 74 61 bd d0 49 48 65 6c 6c 6f 2c 20 57 6f 72 |xta..IHello, Wor|
00000030 6c 64 0a 89 01 b3 04 00 01 08 00 1d 16 21 04 43 |ld...........!.C|
00000040 1e ab 98 4a 91 25 b4 58 c3 24 bc c1 d2 ca ea 38 |...J.%.X.$.....8|
00000050 27 7e e6 05 02 61 bd d0 49 00 0a 09 10 c1 d2 ca |'~...a..I.......|
00000060 ea 38 27 7e e6 16 68 0b ff 48 ab 8e a5 87 d8 fd |.8'~..h..H......|
00000070 7a 04 7c 7a 17 43 81 a6 c7 4e 20 37 09 04 fe be |z.|z.C...N 7....|
00000080 92 68 89 e9 b9 67 54 d8 4e 64 9e 92 4e 5f a2 ee |.h...gT.Nd..N_..|
00000090 0a ce 5b 09 2d 72 a3 3c 5d 56 bc 8a bc 44 9c 30 |..[.-r.<]V...D.0|
000000a0 a3 30 39 5b a6 9a b3 a0 09 f0 dc a8 6a c9 04 44 |.09[........j..D|
000000b0 c7 bf a6 ff 9e 97 ed 1e 78 38 58 88 56 56 83 f3 |........x8X.VV..|
000000c0 6b 94 6f 0c 05 79 83 05 96 19 89 7d 8f 59 72 75 |k.o..y.....}.Yru|
000000d0 2b 8a 4c 76 4f a0 cd e0 0e 71 d7 1b f1 78 aa 9d |+.LvO....q...x..|
000000e0 3e ec 9d f8 c4 af 4f 32 67 69 11 22 44 33 e9 3e |>.....O2gi."D3.>|
000000f0 22 77 aa 05 24 cd 8a f2 57 5e d5 db 0c cd 51 00 |"w..$...W^....Q.|
00000100 30 25 29 bd 01 1b f8 24 9a 86 67 cc 17 73 c3 90 |0%)....$..g..s..|
00000110 0c dd 5e dd 9e a3 4d 84 c6 6f 57 86 4e f2 8f 0c |..^...M..oW.N...|
00000120 92 a7 2c 2b 11 aa e9 7a b9 e1 1f 4a a3 3e e0 f2 |..,+...z...J.>..|
00000130 53 fc 16 a9 9e d1 e2 b5 5b ee e3 94 e7 0b 17 1d |S.......[.......|
00000140 28 8a 35 f5 79 61 3b d8 d0 3b e3 d4 3a b9 7a 7e |(.5.ya;..;..:.z~|
00000150 47 89 7b 10 56 bb c2 fc ad 7d ad cb 5f ef b6 b7 |G.{.V....}.._...|
00000160 31 f1 7c d7 5b b7 cb fe aa 8d 82 b0 32 5f c5 3a |1.|.[.......2_.:|
00000170 8d 62 91 42 10 d8 96 2b 5e 9f 26 ef 9b e6 f2 26 |.b.B...+^.&....&|
00000180 43 95 ee 65 77 3b 5e 2c c6 d1 f7 63 3a 4b 64 31 |C..ew;^,...c:Kd1|
00000190 d5 29 da 60 a9 d3 78 bd 4f 22 f7 27 f3 0c 0c b2 |.).`..x.O".'....|
000001a0 f4 18 ca 2a c5 6c 7c 84 77 68 0e 2d 58 a5 55 f6 |...*.l|.wh.-X.U.|
000001b0 05 7f bf 4a 23 d1 b4 ac 16 84 ae 0e b1 63 be 79 |...J#........c.y|
000001c0 99 45 b2 e5 95 59 94 ec 79 e9 e0 8f cd 9a 15 5d |.E...Y..y......]|
000001d0 63 1c 35 ce 7f 84 02 de d7 a5 21 f2 72 69 bf 06 |c.5.......!.ri..|
000001e0 98 93 1d ab 20 9a 45 33 7a |.... .E3z|
000001e9
-a
オプションを使用することで、テキスト形式でファイルが出力されます。
$ gpg -s -a test.txt
$ cat test.txt.asc
-----BEGIN PGP MESSAGE-----
owEB4gEd/pANAwAIAcHSyuo4J37mAawbYgh0ZXN0LnR4dGG90N5IZWxsbywgV29y
bGQKiQGzBAABCAAdFiEEQx6rmEqRJbRYwyS8wdLK6jgnfuYFAmG90N4ACgkQwdLK
6jgnfuYYZQv/XbZbbcWx2ZpOKs85ld6IPqiXlSTw3+8qh+pzWEiIvhopLGkzVjov
P0nSxSzKwmsmRaKAaLBLFulp0ZoL0/JW/Fu4UznyCB7m29UGJ4oBuGJj/5CKdkgJ
GQqED6H9OjAdts+uQq8iTZUwUVaMjQ8oUFgp5gLkZVEouxeKcDqeXz6BXhKuaXsi
iI7iQ/eHOSQZ3aQAcdBg+WPZgm3xoSEA7/x5aRdxtzt6E9+fLQe3nZ2XEYUOoGR3
BpOTqzvqvt5BiITfkReWtJIEmcTbGJpODQg4xXdfioUrIHA3pKX4rkOloYQj5baa
bssXlWSgErRGKvks/vOPrKbRFIT7WDrmCZ5+CfTS2Lug/v+yXpepSynuaK1q2Xm3
mXdTyQFmQKIFmbTczCMlpRXiCOzLh+cRhzyd+jM4I1sj0igkSu3KLCOOXQ6Wlrho
nEnfGnvHtqonb3cB5+wq6wJGplTYGyddni90SEX84oB4ifOxvXHuh6x5URzTlah/
sPg9PTU7L9Cf
=obJ6
-----END PGP MESSAGE-----
元のデータを残した状態で署名するには以下のように実行します。
$ gpg --clearsign test.txt
$ cat test.txt.asc
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256
Hello, World
-----BEGIN PGP SIGNATURE-----
iQGzBAEBCAAdFiEEQx6rmEqRJbRYwyS8wdLK6jgnfuYFAmG90ZcACgkQwdLK6jgn
fubo9gv9FqWLZ4BNK4juyxddiXOW08EuVaEOEPrzIFexqBbE8Qto+BNn9XnQNW00
GQ85+r9QRREE/ayXT3DC7u5MClL0AozPo7Fklnb25RRhapkPbIylWdiZtBhJJRmz
Qtqt9zABnz1IX06fA359cABfCpuce6gUIpI4XOPpnEpeAS1yP8MuGKRUQsBxE4G2
UVgJXmQ4h6jiIhtuudtHP4t70A3KUd1zCxd3BN0wv2K9DCcLQV4o0l/f2LXdqIG3
S9/uiEPAgEHrCMIys2Qo14KvL/9tOvX1F59VGUTTkaqBtU5wT7xf95DHkkcI0/Ub
t3gfQlvfRwuBw73JwWFxl8VTnQO6sDrOxnEt3DD4Xl1C1TPCDPTcWIYE4XpinKLR
QHT2tvv6c/ml7L6uD1RPyqGuDAoGwoYnb3SAekMcYOzapx1IlPJal6nsbwZ3qSlC
O6P0nvLwabMRGBAg3NNPzLEgdXjDl84rFuY3Rvtff12RMPYIVl7HkLzir0TRzqWh
wJQcbLb4
=4QtG
-----END PGP SIGNATURE-----
元のデータとは別に署名用のファイルを作成する場合は以下のように実行します。すると、バイナリ形式の署名ファイルが生成されます。
$ gpg --detach-sign test.txt
$ hexdump -C test.txt.sig
00000000 89 01 b3 04 00 01 08 00 1d 16 21 04 43 1e ab 98 |..........!.C...|
00000010 4a 91 25 b4 58 c3 24 bc c1 d2 ca ea 38 27 7e e6 |J.%.X.$.....8'~.|
00000020 05 02 61 bd d1 e7 00 0a 09 10 c1 d2 ca ea 38 27 |..a...........8'|
00000030 7e e6 5d 9b 0b fe 3f b6 dc d7 62 4d ce bc ea bf |~.]...?...bM....|
00000040 75 91 3c 1d 3a d4 6c a6 7e f0 4c 40 2f cf 0e 1e |u.<.:.l.~.L@/...|
00000050 71 27 a0 27 19 ca 2a b6 9a b5 c4 92 38 8b 54 17 |q'.'..*.....8.T.|
00000060 0a 06 a9 92 f2 23 12 6d b8 17 25 96 3c 9f 1c b1 |.....#.m..%.<...|
00000070 e4 1e 78 aa 3d bc 7c f3 80 98 01 61 58 9a 5f b5 |..x.=.|....aX._.|
00000080 ce 37 f7 8d 01 71 d2 b5 dd e2 ae 83 a7 6a 6d 06 |.7...q.......jm.|
00000090 de a0 f2 6a 11 af 40 e1 13 1f 66 b1 62 3e 0a 22 |...j..@...f.b>."|
000000a0 4f af ff 90 b6 b0 0d 93 a2 3e 92 44 73 4e ae d7 |O........>.DsN..|
000000b0 1e 8e 2f 6d 0c b8 d5 9e be 61 29 29 5d a1 59 7a |../m.....a))].Yz|
000000c0 25 97 ba 89 c4 63 a8 a2 67 da 49 34 87 82 c8 ba |%....c..g.I4....|
000000d0 ee 40 ab 72 42 73 34 9c 2c ce 0c fd 20 0b f8 6a |.@.rBs4.,... ..j|
000000e0 50 66 1f a4 47 e4 7d 37 0e ca 23 00 a6 68 85 31 |Pf..G.}7..#..h.1|
000000f0 7e 97 ce ee b8 b1 e9 b1 9f 92 04 4a 0b 96 15 22 |~..........J..."|
00000100 9e 9f 6b a7 74 31 a2 b0 a9 7a 0b 8d 5b 29 0f 6c |..k.t1...z..[).l|
00000110 c7 85 29 f1 8e 93 02 69 52 8d d8 79 42 95 0e ac |..)....iR..yB...|
00000120 9f ba d1 81 65 46 e6 7a 59 d8 08 5e 63 7a 71 3e |....eF.zY..^czq>|
00000130 d1 28 43 53 74 8c 60 c8 77 cc fc 57 b5 2a 36 54 |.(CSt.`.w..W.*6T|
00000140 86 ab bd 9d ea 9f 1b 11 43 8d b8 c2 88 87 2c 2f |........C.....,/|
00000150 0c 16 ba 3b eb 80 2f 8c f9 5a 5d 5d ea 6e f0 cb |...;../..Z]].n..|
00000160 66 c9 df 41 cc 76 d7 3a 77 43 56 fb 06 bf f0 bc |f..A.v.:wCV.....|
00000170 17 66 d3 22 bc a6 78 4d 7e 59 25 a6 0d fa f6 42 |.f."..xM~Y%....B|
00000180 8d 55 73 a8 c7 05 6c 98 fe 76 cb 74 9c 73 eb 67 |.Us...l..v.t.s.g|
00000190 67 04 5e 50 22 81 c5 ef f7 f0 e3 70 ed 0a 72 0d |g.^P"......p..r.|
000001a0 6b 2b d4 4c 93 c3 d7 32 e8 58 72 26 71 f4 22 d6 |k+.L...2.Xr&q.".|
000001b0 d3 a9 3a 20 64 2a |..: d*|
000001b6
先程同様に-a
オプションを付与することで、テキスト形式で署名ファイルを生成します。
$ gpg --detach-sign -a test.txt
$ cat test.txt.asc
-----BEGIN PGP SIGNATURE-----
iQGzBAABCAAdFiEEQx6rmEqRJbRYwyS8wdLK6jgnfuYFAmG90ikACgkQwdLK6jgn
fubgHQv8CkZgPQ318Trh4GCDMyQ9CnI/MyWpyRe2WDhNTVWgfhjYGQjGK+pEuGkj
RTIL3eXwF7JDx2ZU5B/Xo8BIjarl+3Ole7gEVw79dO6gUFPXmRxK8ar5GbgrnvIB
pvuTs1QxAZrAguSuw0tamw8oWMk1BSn3L1JL4UCSFj9brGATAKjfCdxDDocFWcZL
Ed4DGXzkRH2oZT1QoaMmg9Xe8SK1dhw16SnSCpswIHaGCLp4RI/5hgWdsbaFKL/p
sdkbMIJcRhY6CvaLhaRVUxZXpNnWFvFuNfQVtw6JnKBWPSTJpBAGl97T2H5wVohQ
XHGTfElu18F4pHFD/6Fae6+fcyTDKol/EEeJBCEwjxFZuwHTcSznMlsCxPtXectC
s+/77cCXeI8QCqLc7GYNtnwOoXN4axLmD4+B2KAkXz7ykX5mbpm2Xr1z2MkUXutA
1QWbMFxGT3Tk60WQi+4uRR5HEucHhPtMlc816Z/1ZJx0ooKhfnW4IEptGhl4cema
kJGjn5VC
=bKZi
-----END PGP SIGNATURE-----
署名を検証。署名ファイルと同じディレクトリに元のファイルがあることを前提としている。
$ gpg --verify test.txt.sig
gpg: assuming signed data in 'test.txt'
gpg: Signature made Sat Dec 18 12:19:51 2021 UTC
gpg: using RSA key 431EAB984A9125B458C324BCC1D2CAEA38277EE6
gpg: Good signature from "Sample1 <hayashier@example.com>" [unknown]
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: 431E AB98 4A91 25B4 58C3 24BC C1D2 CAEA 3827 7EE6
ここで、ファイル名を変更してみます。
$ mv test.txt test.changed.txt
すると、データがないものと認識されてしまいます。
$ gpg --verify test.txt.sig
gpg: no signed data
gpg: can't hash datafile: No data
引数に変更後のファイル名を指定すると、正常に署名を検証できます。
$ gpg --verify test.txt.sig test.changed.txt
gpg: Signature made Sat Dec 18 12:19:51 2021 UTC
gpg: using RSA key 431EAB984A9125B458C324BCC1D2CAEA38277EE6
gpg: Good signature from "Sample1 <hayashier@example.com>" [unknown]
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: 431E AB98 4A91 25B4 58C3 24BC C1D2 CAEA 3827 7EE6
- References
RPMでGPG署名
RPMパッケージの作成
RPMパッケージにGPGで署名する前に、簡単なRPMファイルを作成しておく。
以下、Amazon Linux 2での検証です。CentOS 7でもおおよそ同様に検証できるでしょう。 RPM環境のセットアップと、目的のアプリケーションの用意。
$ sudo yum install rpm-build rpmdevtools git -y
$ rpmdev-setuptree
$ cd $HOME/rpmbuild
$ mkdir motd-1.0
$ echo "THIS IS MY CUSTOM MOTD" > motd-1.0/motd
$ tar -czvf SOURCES/motd-1.0.tar.gz motd-1.0
$ rpmdev-newspec SPECS/motd.spec
以下の内容でSpecファイルを作成
$ cat SPECS/motd.spec
Name: motd
Version: 1.0
Release: 1%{?dist}
Summary: Test Summary
License: Test License
Source0: motd-%{version}.tar.gz
BuildArch: noarch
%define _topdir %(echo $PWD)/
%description
This is my custom MOTD config
%prep
%setup -q
%install
rm -rf $RPM_BUILD_ROOT
install -d $RPM_BUILD_ROOT/etc
install motd $RPM_BUILD_ROOT/etc/motd
%clean
rm -rf $RPM_BUILD_ROOT
%files
%defattr(-,root,root,-)
/etc/motd
%doc
%changelog
rpmの作成 + インストール。
$ rpmbuild -ba -v SPECS/motd.spec
$ sudo rpm -ivh RPMS/noarch/motd-1.0-1.amzn2.noarch.rpm --force
結果確認。
$ cat /etc/motd
THIS IS MY CUSTOM MOTD
SSHでログイン時にも反映されていることを確認。
$ ssh -i ~/.ssh/myprivate.pem ec2-user@xxx.xxx.xxx.xxx
Last login: Thu Dec 2 09:29:00 2021 from 205.251.233.182
THIS IS MY CUSTOM MOTD
作成されたパッケージは以下のように、Signatureがnoneより無署名状態。
$ rpm -qpi ~/rpmbuild/RPMS/noarch/motd-1.0-1.amzn2.noarch.rpm
Name : motd
Version : 1.0
Release : 1.amzn2
Architecture: noarch
Install Date: (not installed)
Group : Unspecified
Size : 23
License : Test License
Signature : (none)
Source RPM : motd-1.0-1.amzn2.src.rpm
Build Date : Thu Dec 2 09:30:17 2021
Build Host : ip-172-31-10-148.us-west-2.compute.internal
Relocations : (not relocatable)
Summary : Test Summary
Description :
This is my custom MOTD config
- References
- カスタムRPMや独自yumリポジトリではじめるソフトウェア管理術 !!
- Notes
- specファイルの作成からgpgの署名方法など
- Notes
- カスタムRPMや独自yumリポジトリではじめるソフトウェア管理術 !!
実際にRPMに対してgpgで署名(ファイルに対する署名)
署名を付加するのに必要なライブラリをインストール。
$ sudo yum install rpm-sign -y
署名の状態を確認する。
$ rpm --checksig motd-1.0-1.amzn2.noarch.rpm
motd-1.0-1.amzn2.noarch.rpm: sha1 md5 OK
署名を付加する。
$ echo "%_gpg_name Sample1" >> ~/.rpmmacros
$ rpm --addsign motd-1.0-1.amzn2.noarch.rpm
raw RPM マクロ定義、すなわち、上記署名は以下のデフォルト値が適用されている。後ほどカスタムマクロを用いてGPGの設定を編集する。
$ rpm --showrc | egrep "gpg|signature|tmppath"
-14: __gpg %{_bindir}/gpg2
-14: __gpg_check_password_cmd %{__gpg}
gpg --batch --no-verbose --passphrase-fd 3 -u "%{_gpg_name}" -so -
-14: __gpg_sign_cmd %{__gpg}
gpg --batch --no-verbose --no-armor --passphrase-fd 3
%{?_gpg_digest_algo:--digest-algo %{_gpg_digest_algo}}
-u "%{_gpg_name}" -sbo %{__signature_filename} %{__plaintext_filename}
-14: _tmppath %{_var}/tmp
GPGの署名も有効であることが確認できる。
$ rpm --checksig motd-1.0-1.amzn2.noarch.rpm
motd-1.0-1.amzn2.noarch.rpm: RSA sha1 ((MD5) PGP) md5 NOT OK (MISSING KEYS: (MD5) PGP#699ac5f0)
以下でも署名が有効であることが確認できる。
$ rpm -q --qf '%{SIGPGP:pgpsig} %{SIGGPG:pgpsig}\n' -p motd-1.0-1.amzn2.noarch.rpm
RSA/SHA1, Thu Dec 2 13:23:22 2021, Key ID c76aabff28c0b322 (none)
Signatureも付加されている。
$ rpm -qpi motd-1.0-1.amzn2.noarch.rpm
Name : motd
Version : 1.0
Release : 1.amzn2
Architecture: noarch
Install Date: (not installed)
Group : Unspecified
Size : 23
License : Test License
Signature : (none)
Source RPM : motd-1.0-1.amzn2.src.rpm
Build Date : Thu Dec 2 09:30:17 2021
Build Host : ip-172-31-10-148.us-west-2.compute.internal
Relocations : (not relocatable)
Summary : Test Summary
Description :
This is my custom MOTD config
.gnupg/
以下には以下のようなファイルが生成されている。
$ ls ~/.gnupg/
gpg-agent.conf gpg.conf openpgp-revocs.d private-keys-v1.d pubring.gpg pubring.gpg~ secring.gpg sshcontrol trustdb.gpg
カスタムマクロファイル
GPGの設定を先程は、デフォルト設定で署名したが、設定した値で署名する。
そのためにカスタムマクロファイルを作成。custom_rpm.macros
という名前で以下のファイルを作成
%__gpg /usr/bin/gpg
%_signature gpg
%_gpg_name Sample1
%__gpg_check_password_cmd /bin/true
%__gpg_sign_cmd %{__gpg} --batch --no-verbose --use-agent --no-secmem-warning --sign --detach-sign --no-armor -u '%{_gpg_name}' --output %{__signature_filename} %{__plaintext_filename}
%_tmppath /tmp/
以下のように実行
$ rpm --macros=custom_rpm.macros -vvv --addsign motd-1.0-1.amzn2.noarch.rpm
Enter pass phrase:
Pass phrase is good.
motd-1.0-1.amzn2.noarch.rpm:
D: Expected size: 2092 = lead(96)+sigs(180)+pad(4)+data(1812)
D: Actual size: 2092
D: GPG sig size: 461
D: Got 461 bytes of GPG sig
D: GPG sig size: 461
D: Got 461 bytes of GPG sig
D: Signature: size(1136)+pad(0)
署名されていることが確認できる。
$ rpm -qpi motd-1.0-1.amzn2.noarch.rpm
warning: motd-1.0-1.amzn2.noarch.rpm: Header V4 RSA/SHA256 Signature, key ID 699ac5f0: NOKEY
Name : motd
Version : 1.0
Release : 1.amzn2
Architecture: noarch
Install Date: (not installed)
Group : Unspecified
Size : 23
License : Test License
Signature : RSA/SHA256, Sat Dec 18 12:35:36 2021, Key ID 44b04c2e699ac5f0
Source RPM : motd-1.0-1.amzn2.src.rpm
Build Date : Thu Dec 2 09:30:17 2021
Build Host : ip-172-31-10-148.us-west-2.compute.internal
Relocations : (not relocatable)
Summary : Test Summary
Description :
This is my custom MOTD config
- References
- How to sign rpms with GPG !
- Notes
- rpmにGPGで署名する方法が端的にまとまっている。
- Notes
- 4.1. パッケージの署名 !
- Notes
- コマンドの用法やカスタムマクロの説明が端的にまとまっている。
- Notes
- GnuPG (The GNU Privacy Guard) !!!
- Notes:
- GnuPGの基礎知識がまとまっている。
- Notes:
- RPMパッケージング: はじめてのRPMを作成するための簡単なガイド
- RPMパッケージと、ローカル・リポジトリへの署名方法
- How to sign rpms with GPG !
鍵に対する署名
前述の通り、GPGではWeb of Trustの仕組みを利用します。公開鍵への署名は、公開鍵のフィンガープリントを--sign-key
オプションで指定します。その後、その情報を共有するため、公開鍵の鍵IDまたはフィンガープリントを--send-keys
オプションで指定して、鍵サーバーに送ります。
公開鍵(自身のを含む)の署名情報を更新するために、--refresh-keys
を実行する必要がある。
GPGキーの削除
作成したGPGキーを削除する方法は以下。秘密鍵を削除してから公開鍵を削除する。
秘密鍵:
$ gpg --list-secret-keys
$ gpg --delete-secret-keys Sample1
公開鍵:
$ gpg --list-key
$ gpg --delete-keys Sample1
生成したGPGキーをエクスポートして、RPMにインポートすることもできる。
$ gpg --export -a 'RPM Build Test User' > RPM-GPG-KEY-pbuild-test-user
$ cat RPM-GPG-KEY-pbuild-test-user
-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: GnuPG v2.0.22 (GNU/Linux)
mQENBGGos5QBCACzm3O593jFSpggkvCProHcyYaiRwQOV/wuGjalaCSIkWZ3KXpK
oHmOJNoQEiYjtHYRKqUzVCthk9m78ASfTki8t+TL0uUf0lot5TI43AT6XAOcZBgr
Mz7Fa4ef6JZWaYqv6iUMHafS/Uk98ReEHPhrb4wJn2/QOrKvn7re7KMmHlZ1WFdM
rx/SNbw/3CRtZhL+cPCCRA1EMu74dCY+4FrfFvh/AQ8R/JBSLOYaPnbfjZYNondf
lcfZ+nBe6KzxbQWXwohW/SxDxSHaDPPwho63HLhT6pwLj7bsqR9F+dl1GqXV7GQX
6gxVbJNLF+1h3PzqBtZaB5a/USfTG/qipxRtABEBAAG0TlJQTSBCdWlsZCBUZXN0
IFVzZXIgKFJQTSBCdWlsZGVyIFRlc3QgR1BHIFNpZ25pbmcgS2V5KSA8aGF5c2hv
Z29AYW1hem9uLmNvLmpwPokBOQQTAQIAIwUCYaizlAIbAwcLCQgHAwIBBhUIAgkK
CwQWAgMBAh4BAheAAAoJEMdqq/8owLMilEkIAJ9CwXvTgnLFQmhelPRAu2QOj5hj
EqphwGlnedCM5wd8iSGmP7cJ8FlcFsShYCQRemG5+9HKjGXLrpbWssgSeFxHYHy5
eRgHMAllO8G+S3TTFFOGlsMX54mSK+P3Ydyn9XnZLxQFmRppWeRfnaRDQrSV4bFI
+cAMwJ/YK5s+TM3IB5Fmt05G89TfQrXPDnDotPJy4TN0Ma2RVtXOCRiOZ25KJeXH
vlhT5FEDSuT34G89LbBdYHA71mwStqI5YnX3/weNEy7f6R+sjVeCTLIKfV7c9HiH
1Cmromjxq/cuhgaRVbjt2UWD/xjmLtzQxgMXqR24SWcj853oxMOzY6MsUEK5AQ0E
YaizlAEIANUEqn9uGKE2qb3IfC6wEOLaPbn/T3KxQIemjzH3t2bZRp9NGK5Fv4y8
FBHQ5OnLUtY+PegW7AMbfWYC5llR8YsdxbkDNexYYXUkYitzRVNGZIh47DZ5Hg3F
DSZILkpwG14tcaCuawFTgHyMTPonHeqlTs0Yyf3s+WHJyr3UrBMtNDz7GGbnmeah
qbWgVQ2f0DdIDCyKEgfKyB4CwjEdQFQz0vGBcBixAucp8UKQm5f8pRFMqvNtPHne
N9lMqR0Hnj7I1GyYoaGLtBIdizxQuiHPOTDG3Dvg0V3sCtdp99AxdIVxB2+j6L48
UlOAY3J1VT6f/qqH6R+xROsnfSX5X30AEQEAAYkBHwQYAQIACQUCYaizlAIbDAAK
CRDHaqv/KMCzIjoBB/9HTKBIprdog3UwARrRJTGpumjE/4JSY8lPss4Q73jAO+n8
7kqeg7LyFxneuPpYnPVu6LHrQ+JoPQb9myM3zLXJbzjAyF+1/HpeQaM5L/WzJJ6K
VTVVaYTBdtmFr/z/DjVJJUcCUJDQBqMsO+SdpTN8oJ3/1wa/DQpodZD3WlhPkce4
Xtw49GRnw3iFFohrZlD+xSO6GzFQy54FB9iUdJBb98UXxX8OBeaSgLgo6B89Hler
7/1etMCwBbRiwVY++q5RyN467pz/ZxE/qBmKgKNaEiUuM0jS5iYtlxJXd9BEdnY6
nrOISjiGFn1zYKxEmVDKvnZCk3QuB2OvTteAzLys
=CaiQ
-----END PGP PUBLIC KEY BLOCK-----
$ sudo rpm --import RPM-GPG-KEY-pbuild-test-user
RPMレポジトリのGPGキーを除去する方法は以下。
$ rpm -q gpg-pubkey --qf '%{NAME}-%{VERSION}-%{RELEASE}\t%{SUMMARY}\n'
gpg-pubkey-c87f5b1a-593863f8 gpg(Amazon Linux <amazon-linux@amazon.com>)
gpg-pubkey-28c0b322-61a8b394 gpg(RPM Build Test User (RPM Builder Test GPG Signing Key) <hayashier@example.com>)
gpg-pubkey-77392555-61a8ccf4 gpg(RPM Build Test User 2 (RPM Signing Key Test 2) <hayashier@example.com>)
gpg-pubkey-61dcf3cd-61a8d830 gpg(Test1 (Test1 Comment) <hayashier@example.com>)
gpg-pubkey-54c79201-61adc686 gpg(Test2 (Test2 comment) <hayashier@example.com>)
$ sudo rpm -e gpg-pubkey-54c79201-61adc686
- References
rpm --import or gpg --import
利用しているパッケージ管理次第では、両方必要であったり、どちらも使用しなくてもインストールの過程で必要に応じて鍵をインポートするといったこともある。 相互に作用したり、片方しかなければ独立したような動作になることもある。
- References
秘密鍵のエクスポート
2.2.33では以下。
$ keyid=$(gpg --list-secret-keys | gpg --list-secret-keys | grep -B 1 "SampleGpg1" | grep -v uid | sed -e 's/[[:blank:]]//g' | tail -n 1) && echo $keyid
$ gpg --export-secret-keys --armor --output gpg-samplegpg1-secret $keyid
$ cat gpg-samplegpg1-secret
-----BEGIN PGP PRIVATE KEY BLOCK-----
:
2.0.22では以下。
$ keyid=$(gpg --list-secret-keys | gpg --list-secret-keys | grep -B 1 "Sample1" | grep sec | awk '{print $2}' | sed -e 's/.*\///' | tail -n 1)
$ gpg --export-secret-keys --armor --output gpg-private-sample1 $keyid
$ cat gpg-private-sample1
-----BEGIN PGP PRIVATE KEY BLOCK-----
Version: GnuPG v2.0.22 (GNU/Linux)
:
gpg --list-secret-keys
を2回繰り返しているのは初回実行時に以下のようにgpgからのメッセージが出てしまうため。
$ keyid=$(gpg --list-secret-keys | grep -B 1 "SampleGpg1" | grep -v uid | sed -e 's/[[:blank:]]//g' | tail -n 1) && echo $keyid
gpg: checking the trustdb
gpg: marginals needed: 3 completes needed: 1 trust model: pgp
gpg: depth: 0 valid: 1 signed: 0 trust: 0-, 0q, 0n, 0m, 0f, 1u
gpg: next trustdb check due at 2023-12-16
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
$ keyid=$(gpg --list-secret-keys | grep -B 1 "SampleGpg1" | grep -v uid | sed -e 's/[[:blank:]]//g' | tail -n 1) && echo $keyid
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
オプション
man gpg
の結果でいくつかオプションを記載。使用したオプションをいくつか抜粋。
--batch
--no-batch
Use batch mode. Never ask, do not allow interactive commands. --no-batch disables this option. Note that even with a filename given on the command
line, gpg might still need to read from STDIN (in particular if gpg figures that the input is a detached signature and no data file has been specified).
Thus if you do not want to feed data via STDIN, you should connect STDIN to `/dev/null'.
:
--no-verbose
Reset verbose level to 0.
:
--no-secmem-warning
Suppress the warning about "using insecure memory".
:
--sign
-s Make a signature. This command may be combined with --encrypt (for a signed and encrypted message), --symmetric (for a signed and symmetri-
cally encrypted message), or --encrypt and --symmetric together (for a signed message that may be decrypted via a secret key or a passphrase).
The key to be used for signing is chosen by default or can be set with the --local-user and --default-key options.
:
--detach-sign
-b Make a detached signature.
:
--armor
-a Create ASCII armored output. The default is to create the binary OpenPGP format.
--no-armor
Assume the input data is not in ASCII armored format.
:
--output file
-o file
Write output to file.
--sign / --clear-sign / --detach-sign の違い
-
-s(--sign)
- ファイルへの署名
- バイナリファイルが生成
-
--clear-sign
- データを残したまま署名
- ファイル上部に署名した元データが入っている
-
--detach-sign
- 元のデータと署名ファイルを分離して生成
- 署名の検証をユーザーに強制したくない場合等
適宜、以下のオプションも併用する形で活用すると良い。
-
-a(--armor)
- 出力をバイナリではなくASCII(テキスト)形式で出力
- Webサイトやメールの本文でデータをやり取りする場合
-
References
公開鍵の共有方法
- 手作業で交換する方法
- 鍵サーバーを使って交換する方法
1つめについて、例えば、公開鍵を手作業で交換したものを以下のようにインポートできる。(公開鍵の例は https://gnupg.org/signature_key.html のものを使用)
$ cat << EOS > gnupg-signature-key.txt
-----BEGIN PGP PUBLIC KEY BLOCK-----
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
eiInsGZ/+h5XYrpXTgA=
=4+Sn
-----END PGP PUBLIC KEY BLOCK-----
EOS
$ cat gnupg-signature-key.txt | gpg --import
2つめについては、以下のようにインポート。
$ gpg --keyserver keyserver.ubuntu.com --recv-key 5B80C5754298F0CB55D8ED6ABCEF7E294B092E28 6DAA6E64A76D2840571B4902528897B826403ADA AC8E115BF73E2D8D47FA9908E98E9B2D19C6C8BD 02F38DFF731FF97CB039A1DA549E695E905BA208
鍵サーバーには種類があるので、好きなものを選べば良い。SKS Keyserver Network(hkp://keys.gnupg.net)がDeprecated。そのため、他のGPG鍵サーバーを利用すると良い。
- keyserver.ubuntu.com
- keys.openpgp.org
- pgp.mit.edu
鍵サーバーがSPOFになる可能性があるが、鍵サーバープールを使用することで、鍵サーバーを集めることによって信頼性が保証される。
GPGの設定ファイル~/.gnupg/gpg.conf
のkeyserverに指定する。
$ ls -al ~/.gnupg/gpg.conf
-rw------- 1 ec2-user ec2-user 7680 Dec 14 10:18 /home/ec2-user/.gnupg/gpg.conf
<!--
- References
- How to raise a key to ultimate trust on another machine?
- How to raise a key to ultimate trust on another machine?
- How to make auto trust gpg public key?
- Notes
$ gpg --list-keys --fingerprint --with-colons | sed -E -n -e 's/^fpr:::::::::([0-9A-F]+):$/\1:6:/p' | gpg --import-ownertrust
- Notes
- [GnuPG] 公開鍵と秘密鍵を写す方法 -->
利用例
たとえば、MySQLではGPGを利用したインストール方法について、以下のように案内されています。
Operator SDKでは、以下のように案内されています。
Topics
GPGに関連するいくつかの話題について触れていきます。
Yumレポジトリの作成
自前でYumレポジトリを作成します。このとき、レポジトリで管理するRPMにGPG鍵で署名しておきます。
最初に、Yumレポジトリを作成する上でオプションの作業ですが、GPG鍵に秘密鍵で署名しておきます。gpg --export -a 'Test1'
コマンドで公開鍵をエクスポートしたものは後ほど使用するので、控えておきます。
$ sudo su
# gpg --gen-key
# gpg --export -a 'Test1'
# rpm --define "_gpg_name Test1" --addsign test-1.0-1.amzn2.noarch.rpm
Webサーバーを用意し、そこにRPMパッケージを配置します。ここでは、Apacheを使用します。作成したディレクトリ直下(/var/www/rpmrepo/x86_64/rpmtest
)に目的のrpmファイル(ここでは、motd-1.0-1.amzn2.noarch.rpm
)を配置します。
# yum install httpd -y
# mkdir -p /var/www/rpmrepo/x86_64/rpmtest
# cp test-1.0-1.amzn2.noarch.rpm /var/www/rpmrepo/x86_64/rpmtest/
Apacheの設定ファイルを変更します。
# vim /etc/httpd/conf/httpd.conf
# Before
DocumentRoot "/var/www/html/"
# After
DocumentRoot "/var/www/"
設定を読み込みます。
# systemctl start httpd
Yumレポジトリを作成していきます。createrepo_c
パッケージをインストールします(createrepo
はobsoleted)。
# yum install createrepo_c -y
実際にレポジトリを作成します。レポジトリ内のファイルを更新した場合は、--update
オプションを付与してコマンドを実行します。アーキテクチャ毎にディレクトリを作成する場合は、それごとにcreaterepo
コマンドを実行する。
# createrepo -s sha256 /var/www/rpmrepo/x86_64/
するとrepodata
というディレクトリとその配下にメタデータが作成され、ここにrepomd.xml
も作成されます。
tree
コマンドでディレクトリを確認すると以下のようになっています(インストールしていない場合は、yum install tree -y
でインストール可能)。
# tree /var/www/rpmrepo/x86_64/
/var/www/rpmrepo/x86_64/
|-- test-1.0-1.amzn2.noarch.rpm
`-- repodata
|-- 5218112b0b159a0b1615532dcf7ceb47cb7900c06dcd0a310656ba1dcc7f2d13-other.sqlite.bz2
|-- 5f4df02d743c67fff2afb7b461e74b15385ede8bd07fecdc3b7db3c8043daddd-filelists.xml.gz
|-- c3feb12f3bc05bde1ca443b3a18f647e14de7c16bc7c783e4e8a60730f00d501-filelists.sqlite.bz2
|-- c6a899f41d7332e7f99051b077db4a44846b06701fc8ff9746b68b371fcc3a4f-other.xml.gz
|-- cb4369dfa7ba3084f8d4f30c87a5efbfc707f35dd11aa33ace0d6cff9650e807-primary.sqlite.bz2
|-- e3f815c84b54ede3784f167d6e766069da11ec894bc32a06b45e5c6ba7d206ba-primary.xml.gz
`-- repomd.xml
1 directory, 8 files
repomd.xml
には以下のようなファイルが作成されています。
<?xml version="1.0" encoding="UTF-8"?>
<repomd xmlns="http://linux.duke.edu/metadata/repo" xmlns:rpm="http://linux.duke.edu/metadata/rpm">
<revision>1639883424</revision>
<data type="primary">
<checksum type="sha256">5458165e4c403030f018772e8b94a21424e93ebf288407f52724fffb14a5b287</checksum>
<open-checksum type="sha256">bacebcaba37b934ae4a352b61215b772d8f37a666af9222f6e7070676d40432d</open-checksum>
<location href="repodata/5458165e4c403030f018772e8b94a21424e93ebf288407f52724fffb14a5b287-primary.xml.gz"/>
<timestamp>1639883424</timestamp>
<size>613</size>
<open-size>1147</open-size>
</data>
<data type="filelists">
<checksum type="sha256">51fe632fa208c2802f7ef36252de47e0ee0a4ce026579b9c72a6c3260ad5aafd</checksum>
<open-checksum type="sha256">4498a658d030875ed6a3159796f8d3836fb7dce669bcae079cb259dafc19da0a</open-checksum>
<location href="repodata/51fe632fa208c2802f7ef36252de47e0ee0a4ce026579b9c72a6c3260ad5aafd-filelists.xml.gz"/>
<timestamp>1639883424</timestamp>
<size>240</size>
<open-size>317</open-size>
</data>
<data type="other">
<checksum type="sha256">3823765b2701bd593d2cbef41e58f0973943b5e6d1d79d4355735b7a51238a8b</checksum>
<open-checksum type="sha256">30e16f56d09457bd1265643d565d6a137a20da202a5ee5a93214d1b9e27fca19</open-checksum>
<location href="repodata/3823765b2701bd593d2cbef41e58f0973943b5e6d1d79d4355735b7a51238a8b-other.xml.gz"/>
<timestamp>1639883424</timestamp>
<size>227</size>
<open-size>288</open-size>
</data>
<data type="primary_db">
<checksum type="sha256">5f86a71d7d89901a4c4507d0cd55182bfc480d90e88952954be81414edd2b7e0</checksum>
<open-checksum type="sha256">840eeabedc1816e13e369bc0324b3fe8eeb85558347718a338d619b409feb2d1</open-checksum>
<location href="repodata/5f86a71d7d89901a4c4507d0cd55182bfc480d90e88952954be81414edd2b7e0-primary.sqlite.bz2"/>
<timestamp>1639883424</timestamp>
<size>1825</size>
<open-size>30720</open-size>
<database_version>10</database_version>
</data>
<data type="filelists_db">
<checksum type="sha256">3361c1db37aef3cdc8414abfa46e8d1c70aefd2e16510a7cb65f9ea14b18564e</checksum>
<open-checksum type="sha256">86ac4a9fa98bcba332e686aa08ed82ae0e49db04b137ee1fe9c244e1a70e654c</open-checksum>
<location href="repodata/3361c1db37aef3cdc8414abfa46e8d1c70aefd2e16510a7cb65f9ea14b18564e-filelists.sqlite.bz2"/>
<timestamp>1639883424</timestamp>
<size>712</size>
<open-size>7168</open-size>
<database_version>10</database_version>
</data>
<data type="other_db">
<checksum type="sha256">5c39d881720de15448f0fdbeb96acb51156d9d609bea7c78d0c1bc720b20f4cf</checksum>
<open-checksum type="sha256">8727f6561e1621f2d95685e3ddf60e8b1b607aabe6d82d86e0a68913a4fbea6d</open-checksum>
<location href="repodata/5c39d881720de15448f0fdbeb96acb51156d9d609bea7c78d0c1bc720b20f4cf-other.sqlite.bz2"/>
<timestamp>1639883424</timestamp>
<size>659</size>
<open-size>6144</open-size>
<database_version>10</database_version>
</data>
</repomd>
クライアント側でレポジトリの設定をします。
$ sudo vim /etc/yum.repos.d/rpmtest.repo
[rpmtest]
name=Sample RPM package
baseurl=http://34.209.96.87/rpmrepo/x86_64
gpg --export -a 'Test1'
で出力したファイルを例えば、RPM-GPG-KEY-pbuild-sample1
といったファイル名で作成し、これに貼り付けます。その後、RPMに読み込みます。
$ sudo rpm --import RPM-GPG-KEY-pbuild-sample1
キャッシュをクリアします。
$ sudo yum clean all
レポジトリが追加されていることが確認できます。
$ yum repolist
Failed to set locale, defaulting to C
Loaded plugins: extras_suggestions, kernel-livepatch, langpacks, priorities, update-motd
repo id repo name status
!amzn2-core/2/x86_64 Amazon Linux 2 core repository 26926
amzn2extra-docker/2/x86_64 Amazon Extras repo for docker 55
amzn2extra-kernel-5.10/2/x86_64 Amazon Extras repo for kernel-5.10 95
amzn2extra-livepatch/2/x86_64 Amazon Extras repo for livepatch 72
rpmtest Sample RPM package 1
repolist: 27149
レポジトリ情報が確認できるようになります。
$ sudo yum info --disablerepo=* --enablerepo=rpmtest test
Failed to set locale, defaulting to C
Loaded plugins: copr, extras_suggestions, kernel-livepatch, langpacks, priorities, update-motd
Available Packages
Name : test
Arch : noarch
Version : 1.0
Release : 1.amzn2
Size : 2.0 k
Repo : rpmtest
Summary : Test Summary
License : Test License
Description : This is my custom TEST config
以下のようにインストールできるようになります。
$ sudo yum install --disablerepo=* --enablerepo=rpmtest test
GPG鍵でRPMに署名していない場合は、以下のようにインストールが中断して、実行できません。その場合、署名するか、gpgcheck=0
オプションを先程のrepoファイルに追加する必要があります。
$ sudo yum install --disablerepo=* --enablerepo=rpmtest test
Failed to set locale, defaulting to C
Loaded plugins: copr, extras_suggestions, kernel-livepatch, langpacks, priorities, update-motd
Resolving Dependencies
--> Running transaction check
---> Package test.noarch 0:1.0-1.amzn2 will be installed
--> Finished Dependency Resolution
Dependencies Resolved
===========================================================================================================================================================================
Package Arch Version Repository Size
===========================================================================================================================================================================
Installing:
test noarch 1.0-1.amzn2 rpmtest 2.0 k
Transaction Summary
===========================================================================================================================================================================
Install 1 Package
Total download size: 2.0 k
Installed size: 23
Is this ok [y/d/N]: y
Downloading packages:
Package test-1.0-1.amzn2.noarch.rpm is not signed
test-1.0-1.amzn2.noarch.rpm | 2.0 kB 00:00:00
Package test-1.0-1.amzn2.noarch.rpm is not signed
<!--
既に別パッケージによって管理されているファイルについては、衝突してYumではインストールできない。
$ sudo yum install --disablerepo=* --enablerepo=rpmtest motd : Running transaction test
Transaction check error: file /etc/motd from install of motd-1.0-1.amzn2.noarch conflicts with file from package setup-2.8.71-10.amzn2.0.1.noarch
Error Summary
$ rpm -qf /etc/motd
setup-2.8.71-10.amzn2.0.1.noarch
-->
- References
- *** カスタムRPMや独自yumリポジトリではじめるソフトウェア管理術
- Notes
- /etc/yum.repos.dディレクトリ内の設定ファイルと、公開鍵の設定をいちいち手動で実行するのは手間がかかるため、これらを自動で行えるRPMパッケージを配ると便利。
- Notes
- ** 今さらですがyum(^^;)
- Notes
- 各種Yumの操作が参考になる。
- Notes
- createrepo を使って CentOS7 用の自前リポジトリを作成する
- yumリポジトリサーバの構築方法
- ローカルにyumリポジトリを作成してみた
- *** カスタムRPMや独自yumリポジトリではじめるソフトウェア管理術
署名処理の自動化
- GPG Agent + Preset phraseの利用(後述)
- expectコマンドと
--passphrase-fd
オプションを利用してパスワード入力する方法
2つめについて、例えば、以下のコマンドを実行する。
#!/bin/bash
file=~/list.txt
pass_phrase=Test1234
key_file=/home/ec2-user/gpg-private-sample1
fingerprint=ffad0f14
RPM_SIGN_MAX_ATTEMPTS=3
sudo yum install expect -y
for rpm_file in `cat $file`
do
echo "Checking: $rpm_file"
package_fig=$(rpm -qp $rpm_file --qf "%|RSAHEADER?{%{RSAHEADER:pgpsig}}:{none}| %{NVRA}\n" | grep "Key ID" | awk '{print substr($9,0,8)}')
if [[ $package_fig =~ $fingerprint ]]; then
echo "RPM is already signed, no need to resign."
else
for ((i=0; i<$RPM_SIGN_MAX_ATTEMPTS; i++)); do
gpg --import $key_file
expect -c '
set timeout -1
spawn rpm --define "__gpg /usr/bin/gpg" --define "_gpg_name Sample1" --define "%__gpg_check_password_cmd /bin/true" --define "%__gpg_sign_cmd %{__gpg} gpg --batch --passphrase-fd 3 --no-verbose --no-secmem-warning --sign --detach-sign --no-armor -u '%{_gpg_name}' --output %{__signature_filename} %{__plaintext_filename}" --addsign '"$rpm_file"'
expect "Enter pass phrase:"
send "'"$pass_phrase\n"'"
expect "Pass phrase is good."
expect eof
catch wait result
exit [lindex $result 3]
' 3<&0
package_fig=$(rpm -qp $rpm_file --qf "%|RSAHEADER?{%{RSAHEADER:pgpsig}}:{none}| %{NVRA}\n" | grep "Key ID" | awk '{print substr($9,0,8)}')
if [[ $package_fig =~ $fingerprint ]]; then
continue 2
fi
done
exit 1
fi
done
gpg-agent
-
gpg-agentは GnuPGの中核コンポーネントで,秘密鍵の管理を行い一定期間キャッシュ
-
gpg、gpgconf、gpg-connect-agentなどのコンポーネントから起動し、互いに通信起
-
Pinentry
- PinentryはパスフレーズやスマートカードのPINコードを入力する際にgpg-agentから呼び出し
- gpgに
--batch
、--pinentry-mode loopback
オプションとパスフレーズ指定オプション(--passphrase, --passphrase-fd, --passphrase-file)をセットで指定している場合はPinentryを迂回する方法もある。
-
GnuPG 2.1.0からgpg-agentとpinentryの利用が必須
- これによって
--passphrase-fd 0
コマンドラインオプションによって STDIN からパイプで渡されたパスフレーズの後方互換性が損ねられています。 - 古いリリースと同じような機能を使うには2つのことをする必要があります:
- loopback pinentry モードの許可
- ``~/.gnupg/gpg-agent.conf
に
allow-loopback-pinentry`を追加し、設定ファイルの読み込み。
- ``~/.gnupg/gpg-agent.conf
- gpgコマンドをloopbackモードで使用。以下2通りの方法。
- gpgコマンドの
--pinentry-mode loopback
オプション$ gpg --pinentry-mode loopback ...
~/.gnupg/gpg.conf
にpinentry-mode loopback
を追加
- gpgコマンドの
- loopback pinentry モードの許可
- これによって
実際に動作を検証。
~/.gnupg/gpg-agent.conf
に以下のようなファイルを作成し、適宜設定を事前に読み込んでおく。
pinentry-program /usr/bin/pinentry-curses
allow-preset-passphrase
$ /usr/local/bin/gpgconf --reload gpg-agent
以下のように実行。KeygripはOpenPGP鍵以外の鍵にも対応するためのもの。
$ /usr/local/bin/gpg-agent --daemon --allow-preset-passphrase --no-detach --log-file gpg_agent_log_file --debug-level guru
$ GPG_KEYGRIP=$(/usr/local/bin/gpg --with-keygrip --list-key | grep Sample1 -B 2 | grep Keygrip | awk -F = '{print $2}' | sed -e 's/[[:blank:]]//g' | tail -n 1) && echo $GPG_KEYGRIP
$ GPG_PASSPHRASE_HEX=$(echo Test1234 | tr -d '\n' | hexdump -v -e '/1 "%02X"') && echo $GPG_PASSPHRASE_HEX
$ GPG_AGENT_SOCKET=$(gpgconf --list-dirs | grep agent-socket | sed -e 's/.*://g') && echo $GPG_AGENT_SOCKET
$ echo "PRESET_PASSPHRASE $GPG_KEYGRIP -1 $GPG_PASSPHRASE_HEX" | /usr/local/bin/gpg-connect-agent -S $GPG_AGENT_SOCKET
$ gpg-connect-agent reloadagent /bye
以下のように実行すると、特にパスワードを要求されることなく、署名ができる。
$ rpm_file=./motd-1.0-1.amzn2.noarch.rpm
$ rpm --define "__gpg /usr/local/bin/gpg" --define "_gpg_name Sample1" --define "%__gpg_check_password_cmd /bin/true" --define "%__gpg_sign_cmd %{__gpg} gpg --batch -vv --no-secmem-warning --sign --detach-sign --no-armor -u %{_gpg_name} --output %{__signature_filename} %{__plaintext_filename}" --addsign $rpm_file
gpg-agentをssh-agentとして使用
- gpg-agentがSSH-agentとしても機能するようにする。
~/.gnupg/gpg-agent.conf
にenable-ssh-support
を追加。
GPG最新バージョンをインストール
CentOSやUbuntuでレポジトリからGPGをインストールしてきても、最新は2.3.3。LTSで2.2.33(?)だが、2.0.22と古い。
#!/bin/bash
# Script to build and install GnuPG 2.2.33 for Amazon Linux 2 and MacOS
# Link: https://gnupg.org/download/
# Run:
# $ export PATH=/usr/local/bin/:$PATH
# $ chmod +x install-gpg22.sh
# $ sudo ./install-gpg22.sh
set -euvx -o pipefail
trap 'echo "ERROR: line no = $LINENO, exit status = $?" >&2; exit 1' ERR
GNUPG_VERSION=2.2.33
LIBGPG_ERROR_VERSION=1.43
LIBGCRYPT_VERSION=1.9.4
LIBKSBA_VERSION=1.6.0
LIBASSUAN_VERSION=2.5.5
NPTH_VERSION=1.6
NTBTLS_VERSION=0.2.0
WORKSPACE_DIR=/tmp/gnupg
ROOT_DIR=/usr/local
LIBRARY_DIR=$ROOT_DIR/lib
INSTALL_DIR=/usr/local/bin/
if [[ "$(uname -r)" == *amzn2* ]]; then
yum install gcc rpm-sign sqlite-devel gnutls-devel -y
fi
mkdir -p $WORKSPACE_DIR && cd $WORKSPACE_DIR || exit 1
# Verifying downloads.
# Actually, We should import GPG key by running the following command.
#
# $ gpg --keyserver keyserver.ubuntu.com --recv-key 5B80C5754298F0CB55D8ED6ABCEF7E294B092E28 6DAA6E64A76D2840571B4902528897B826403ADA AC8E115BF73E2D8D47FA9908E98E9B2D19C6C8BD 02F38DFF731FF97CB039A1DA549E695E905BA208
#
# For example, we want to verify by using imported keys as follows.
#
# $ gpg -d libgpg-error-${LIBGPG_ERROR_VERSION}.tar.bz2.sig
#
# However, the version of GPG key is old (like, 2.0.x). So gpg process causes `gpg: Can't check signature: Invalid public key algorithm` error because this version does not support EDDSA as follows.
#
# $ gpg --version
# gpg (GnuPG) 2.0.22
# libgcrypt 1.5.3
# Copyright (C) 2013 Free Software Foundation, Inc.
# License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
# This is free software: you are free to change and redistribute it.
# There is NO WARRANTY, to the extent permitted by law.
#
# Home: ~/.gnupg
# Supported algorithms:
# Pubkey: RSA, ?, ?, ELG, DSA
# Cipher: IDEA, 3DES, CAST5, BLOWFISH, AES, AES192, AES256, TWOFISH,
# CAMELLIA128, CAMELLIA192, CAMELLIA256
# Hash: MD5, SHA1, RIPEMD160, SHA256, SHA384, SHA512, SHA224
# Compression: Uncompressed, ZIP, ZLIB, BZIP2
#
# That is why we check integrity by using SHA-1 check sums retrieved from this link https://gnupg.org/download/integrity_check.html as a workaround.
echo "First, Installing dependencies."
echo "Installing Libgpg-error..."
curl -L https://gnupg.org/ftp/gcrypt/libgpg-error/libgpg-error-${LIBGPG_ERROR_VERSION}.tar.bz2 -O
if [[ $(sha1sum libgpg-error-${LIBGPG_ERROR_VERSION}.tar.bz2) != "e71b77e8e32023dfd9cb06504942aa8e028c8795 libgpg-error-1.43.tar.bz2" ]] ; then
exit 1
fi
tar xvf libgpg-error-${LIBGPG_ERROR_VERSION}.tar.bz2
pushd libgpg-error-${LIBGPG_ERROR_VERSION} || exit 1
./configure --prefix=$ROOT_DIR
make
make install
popd
echo "Installing Libgcrypt..."
curl -L https://gnupg.org/ftp/gcrypt/libgcrypt/libgcrypt-${LIBGCRYPT_VERSION}.tar.bz2 -O
if [[ $(sha1sum libgcrypt-${LIBGCRYPT_VERSION}.tar.bz2) != "1bccc8393482fa1953323ff429c6b5ba5676eb1a libgcrypt-1.9.4.tar.bz2" ]] ; then
exit 1
fi
tar xvf libgcrypt-${LIBGCRYPT_VERSION}.tar.bz2
pushd libgcrypt-${LIBGCRYPT_VERSION} || exit 1
./configure --prefix=$ROOT_DIR --with-libgpg-error-prefix=$ROOT_DIR
make
make install
popd
echo "Installing Libassuan..."
curl -L https://gnupg.org/ftp/gcrypt/libassuan/libassuan-${LIBASSUAN_VERSION}.tar.bz2 -O
if [[ $(sha1sum libassuan-${LIBASSUAN_VERSION}.tar.bz2) != "ec4f67c0117ccd17007c748a392ded96dc1b1ae9 libassuan-2.5.5.tar.bz2" ]] ; then
exit 1
fi
tar xvf libassuan-${LIBASSUAN_VERSION}.tar.bz2
pushd libassuan-${LIBASSUAN_VERSION} || exit 1
./configure --prefix=$ROOT_DIR --with-libgpg-error-prefix=$ROOT_DIR
make
make install
popd
echo "Installing Libksba..."
curl -L https://gnupg.org/ftp/gcrypt/libksba/libksba-${LIBKSBA_VERSION}.tar.bz2 -O
if [[ $(sha1sum libksba-${LIBKSBA_VERSION}.tar.bz2) != "d71e18a71b44d7f0e93180e05971857b4900c788 libksba-1.6.0.tar.bz2" ]] ; then
exit 1
fi
tar xvf libksba-${LIBKSBA_VERSION}.tar.bz2
pushd libksba-${LIBKSBA_VERSION} || exit 1
./configure --prefix=$ROOT_DIR --with-libgpg-error-prefix=$ROOT_DIR
make
make install
popd
echo "Installing ntbTLS..."
curl -L https://gnupg.org/ftp/gcrypt/ntbtls/ntbtls-${NTBTLS_VERSION}.tar.bz2 -O
if [[ $(sha1sum ntbtls-${NTBTLS_VERSION}.tar.bz2) != "3bbd98e5cfff7ca7514ae600599f0e1c1f351566 ntbtls-0.2.0.tar.bz2" ]] ; then
exit 1
fi
tar xvf ntbtls-${NTBTLS_VERSION}.tar.bz2
pushd ntbtls-${NTBTLS_VERSION} || exit 1
./configure --prefix=$ROOT_DIR --with-libgpg-error-prefix=$ROOT_DIR --with-libgcrypt-prefix=$ROOT_DIR --with-ksba-prefix=$ROOT_DIR
make
make install
popd
echo "Installing nPth..."
curl -L https://gnupg.org/ftp/gcrypt/npth/npth-${NPTH_VERSION}.tar.bz2 -O
if [[ $(sha1sum npth-${NPTH_VERSION}.tar.bz2) != "f9d63e9747b027e4e404fe3c20c73c73719e1731 npth-1.6.tar.bz2" ]] ; then
exit 1
fi
tar xvf npth-${NPTH_VERSION}.tar.bz2
pushd npth-${NPTH_VERSION} || exit 1
./configure --prefix=$ROOT_DIR
make
make install
popd
echo "Installing GnuPG..."
curl -L https://gnupg.org/ftp/gcrypt/gnupg/gnupg-${GNUPG_VERSION}.tar.bz2 -O
if [[ $(sha1sum gnupg-${GNUPG_VERSION}.tar.bz2) != "70053b799a79139e0e7889282805fc889dd22540 gnupg-2.2.33.tar.bz2" ]] ; then
exit 1
fi
tar xvf gnupg-${GNUPG_VERSION}.tar.bz2
pushd gnupg-${GNUPG_VERSION} || exit 1
./configure --prefix=$ROOT_DIR --with-libgpg-error-prefix=$ROOT_DIR --with-libgcrypt-prefix=$ROOT_DIR --with-libassuan-prefix=$ROOT_DIR --with-ksba-prefix=$ROOT_DIR --with-npth-prefix=$ROOT_DIR --with-ntbtls-prefix=$ROOT_DIR
make
make install
popd
if [[ "$(uname -r)" == *amzn2* ]]; then
echo $LIBRARY_DIR | tee /etc/ld.so.conf.d/gpg2.conf && ldconfig -v
fi
cp ./gnupg-2.2.33/g10/gpg $INSTALL_DIR
cp ./gnupg-2.2.33/agent/gpg-agent $INSTALL_DIR
cp ./gnupg-2.2.33/tools/gpgconf $INSTALL_DIR
cp ./gnupg-2.2.33/tools/gpg-connect-agent $INSTALL_DIR
echo "Successfully built and installed GnuPG ${GNUPG_VERSION} to $INSTALL_DIR"
echo "Dependencies under /usr/local are as follows"
ls $LIBRARY_DIR | egrep 'libgpg-error|libgcrypt|libksba|libassuan|ntbtls|npth|gnupg'
rm -Rf $WORKSPACE_DIR
GPG_AGENT_ROOT=$HOME/.gnupg
GPG_AGENT_CONF=$GPG_AGENT_ROOT/gpg-agent.conf
if [ ! -e $GPG_AGENT_CONF ]; then
mkdir $GPG_AGENT_ROOT
touch $GPG_AGENT_CONF
fi
set +euvx
trap - ERR
echo "Configuring GPG Agent..."
grep pinentry-program $GPG_AGENT_CONF
if [[ $? -eq 1 ]]; then
echo "pinentry-program /usr/bin/pinentry-curses" >> $GPG_AGENT_CONF
fi
grep allow-preset-passphrase $GPG_AGENT_CONF
if [[ $? -eq 1 ]]; then
echo "allow-preset-passphrase" >> $GPG_AGENT_CONF
fi
/usr/local/bin/gpgconf --reload gpg-agent
echo "Showing Version..."
/usr/local/bin/gpg --version
/usr/local/bin/gpg-agent --version
/usr/local/bin/gpg-connect-agent --version
/usr/local/bin/gpgconf --version
echo "Done!"
exit 0
- References
Errors
以下、検証時に遭遇したエラーと対処法のまとめを記録。
rpm: /usr/bin/rpmsign: No such file or directory
以下のコマンドを実行したところエラー
$ rpm --addsign motd-1.0-1.amzn2.noarch.rpm
rpm: /usr/bin/rpmsign: No such file or directory
--addsignオプションを使用するためには別途rpm-signライブラリをインストールする必要がある。
$ sudo yum install rpm-sign -y
You must set "%_gpg_name" in your macro file
以下のコマンドを実行したところエラー
$ rpm --addsign motd-1.0-1.amzn2.noarch.rpm
You must set "%_gpg_name" in your macro file
以下のように実行すればOK。
$ rpm --define "_gpg_name Sample1" --addsign motd-1.0-1.amzn2.noarch.rpm
もしくは、.rpmmacrosに%_gpg_nameを定義する形でも良い。
$ echo "%_gpg_name RPM Build Test User" >> ~/.rpmmacros
$ /bin/rpm -vvv --addsign motd-1.0-1.amzn2.noarch.rpm
Enter pass phrase:
Pass phrase is good.
motd-1.0-1.amzn2.noarch.rpm:
D: Expected size: 2092 = lead(96)+sigs(180)+pad(4)+data(1812)
D: Actual size: 2092
D: GPG sig size: 287
D: Got 287 bytes of GPG sig
D: GPG sig size: 287
D: Got 287 bytes of GPG sig
D: Signature: size(784)+pad(0)
[ec2-user@ip-172-31-10-148 ~]$ /bin/rpm -vvv --addsign motd-1.0-1.amzn2.noarch.rpm
Enter pass phrase:
Pass phrase is good.
motd-1.0-1.amzn2.noarch.rpm:
D: Expected size: 2692 = lead(96)+sigs(784)+pad(0)+data(1812)
D: Actual size: 2692
D: GPG sig size: 287
D: Got 287 bytes of GPG sig
D: GPG sig size: 287
D: Got 287 bytes of GPG sig
warning: motd-1.0-1.amzn2.noarch.rpm already contains identical signature, skipping
error: rpmMkTemp failed
sudoをつければエラー解消
$ /bin/rpm --macros=custom_rpm.macros -vvv --addsign motd-1.0-1.amzn2.noarch.rpm
:
error: error creating temporary file /tmp/rpmtest/rpm-tmp.Uz4bQN: Permission denied
error: rpmMkTemp failed
gpg: packet(3) with unknown version 0
もともとのカスタムマクロは以下だった。
%__gpg /usr/bin/gpg
%_signature gpg
%_gpg_name Test1
%__gpg_check_password_cmd /bin/true
%__gpg_sign_cmd %{__gpg} --no-armor -u '%{_gpg_name}' --output %{__signature_filename} %{__plaintext_filename}
%_tmppath /tmp/
gpgコマンド実行時におけるオプション指定がそもそもだめだった。--signと--detach-signを添えてあげる必要があった。以下で問題を解消した。
%__gpg /usr/bin/gpg
%_signature gpg
%_gpg_name Test1
%__gpg_check_password_cmd /bin/true
%__gpg_sign_cmd %{__gpg} --batch --no-verbose --use-agent --no-secmem-warning --sign --detach-sign --no-armor -u '%{_gpg_name}' --output %{__signature_filename} %{__plaintext_filename}
%_tmppath /tmp/
上記原因を見つけるために、gpgコマンドで実際の動作確認をしてデバッグしていった。
その後、.rpmmacrosをゼロベースで作成しながら、raw RPM マクロ定義に値が反映されているかを確認しながら検証していった。
$ cat .rpmmacros
%__gpg /usr/local/bin/gpg
%_signature gpg
%_gpg_name Test1
%__gpg_check_password_cmd true
%__gpg_sign_cmd %{__gpg} --no-armor -u '%{_gpg_name}' -sbo %{__signature_filename} %{__plaintext_filename}
%_tmppath /tmp/
上記確認の都度、raw RPM マクロ定義に反映されていっているか確認をしていった。
$ rpm --showrc | egrep "gpg|signature|tmppath"
-13: __gpg /usr/local/bin/gpg
-13: __gpg_check_password_cmd true
-13: __gpg_reserved_space 4096
-13: __gpg_sign_cmd %{__gpg} --no-armor -u '%{_gpg_name}' -sbo %{__signature_filename} %{__plaintext_filename}
-13: _gpg_name Test1
-13: _signature gpg
-13: _tmppath /tmp/
その後、以下のようにファイル名を変更して、--macros=custom_rpm.macros
オプションを指定して実行できるようにした。
$ mv ~/.macros custom_rpm.macros
以下を用意し、デバッグをしやすいようにしておいた。
$ gpg --gen-key
$ gpg --export -a 'Sample1' > RPM-GPG-KEY-pbuild-sample1
$ cat RPM-GPG-KEY-pbuild-sample1
$ sudo rpm --import RPM-GPG-KEY-pbuild-test1
$ rpm -q gpg-pubkey --qf '%{name}-%{version}-%{release} --> %{summary}\n'
$ rpm -qpi motd-1.0-1.amzn2.noarch.rpm
$ rpm --macros=custom_rpm.macros -vvv --addsign motd-1.0-1.amzn2.noarch.rpm
Pass phrase check failed or gpg key expired
rpm --addsignを実行したところ、以下のエラー。
$ rpm --define "_gpg_name Test1" --addsign motd-1.0-1.amzn2.noarch.rpm
Enter pass phrase:
gpg: signing failed: Operation cancelled
gpg: signing failed: Operation cancelled
Pass phrase check failed or gpg key expired
ここでは、GnuPGの設定は不要であったため、一旦すべて削除することで解消
$ rm -Rf .gnupg/
__gpg_signで入力待ち
いずれの場合も必要な情報がrpmコマンドに適切に入力できていないために状況が発生していた。
Pattern 1
以下の状態だと、その外のfor文で読み込んでいたfor rpm_file in cat $file
のcat $file
がファイルディスクリプターのNo.0としてこれを読み込んでいた。
rpm --define \"__gpg /usr/bin/gpg\" --define \"_gpg_name Sample1\" --define \"%__gpg_check_password_cmd /bin/true\" --define \"%__gpg_sign_cmd %{__gpg} gpg --batch --no-verbose --no-secmem-warning --sign --detach-sign --no-armor -u '%{_gpg_name}' --output %{__signature_filename} %{__plaintext_filename}\" --addsign $rpm_file
--passphrase-fd
を指定しないと、cat $file
をstdinの情報として読み込み、入力待ち状態になってしまっていたことが原因。
そのため、これを実行していたexpect文の末尾に3<&0
を追加し、標準入力を新しいファイル記述子に複製して、--passphrase-fd 3
のようにファイルディスクリプターの番号を引数として指定した
rpm --define \"__gpg /usr/bin/gpg\" --define \"_gpg_name Sample1\" --define \"%__gpg_check_password_cmd /bin/true\" --define \"%__gpg_sign_cmd %{__gpg} gpg --batch --passphrase-fd 3 --no-verbose --no-secmem-warning --sign --detach-sign --no-armor -u '%{_gpg_name}' --output %{__signature_filename} %{__plaintext_filename}\" --addsign $rpm_file 3<&0
Pattern 2
expectコマンド中で使用していたが、expect命令で指定していた一致するメッセージが来ないため、待機状態になっていた。
gpg: skipped "Sample1": No secret key
rpmコマンドで--addsign
を実行したところ、以下のエラー。spawnはexpectコマンド中で使用しているため。
spawn rpm --define __gpg %{_bindir}/gpg2 --define _gpg_name Sample1 --define %__gpg_check_password_cmd /bin/true --define %__gpg_sign_cmd %{__gpg} gpg --batch --passphrase-fd 3 --no-verbose --no-secmem-warning --sign --detach-sign --no-armor -u %{_gpg_name} --output %{__signature_filename} %{__plaintext_filename} --addsign /tmp/sample/motd-1.0-2.amzn2.noarch.rpm
Enter pass phrase:
Pass phrase is good.
/tmp/sample/motd-1.0-2.amzn2.noarch.rpm:
gpg: skipped "Sample1": No secret key
gpg: signing failed: No secret key
error: gpg exec failed (2)
秘密鍵をインポートしていなかったことが原因。秘密鍵をインポートすれば解消。
error: Macro % has illegal name (%define)
いらない二重引用符をつけていた
18c20
< spawn rpm --define \"__gpg %{_bindir}/gpg2\" --define \"_gpg_name Sample1\" --define \"%__gpg_check_password_cmd /bin/true\" --define \"%__gpg_sign_cmd %{__gpg} gpg --batch --passphrase-fd 3 --no-verbose --no-secmem-warning --sign --detach-sign --no-armor -u '%{_gpg_name}' --output %{__signature_filename} %{__plaintext_filename}\" --addsign '"$rpm_file"'
---
> spawn rpm --define "__gpg %{_bindir}/gpg2" --define "_gpg_name Sample1" --define "%__gpg_check_password_cmd /bin/true" --define "%__gpg_sign_cmd %{__gpg} gpg --batch --passphrase-fd 3 --no-verbose --no-secmem-warning --sign --detach-sign --no-armor -u '%{_gpg_name}' --output %{__signature_filename} %{__plaintext_filename}" --addsign '"$rpm_file"'
- References
warning: motd-1.0-1.amzn2.noarch.rpm: Header V4 RSA/SHA1 Signature, key ID ac73620c: NOKEY
パッケージをダウンロードしてrpmコマンドでインストールする場合、自動でGPG署名のチェックが行われるが、パッケージリリース元のGPG公開鍵がサーバに取り込まれていない場合以下のような警告が出る
$ rpm -qpi motd-1.0-1.amzn2.noarch.rpm
warning: motd-1.0-1.amzn2.noarch.rpm: Header V4 RSA/SHA1 Signature, key ID ac73620c: NOKEY
正しく署名の確認を行うにはGPG公開鍵のインポートを行わなくてはならない
rpm --import /Path/To/PublicKey
のようにインポートする。
- References
gpg-agent: no gpg-agent running in this session
$ /usr/bin/gpg-agent --allow-preset-passphrase --no-detach --pinentry-program /bin/exit --write-env-file gpg_agent_info_env --log-file gpg_agent_log_file --debug-level guru
gpg-agent[14150]: enabled debug flags: command mpi crypto memory cache memstat hashing assuan
gpg-agent: no gpg-agent running in this session
gpg-agent: random usage: poolsize=600 mixed=0 polls=0/0 added=0/0
outmix=0 getlvl1=0/0 getlvl2=0/0
gpg-agent: secmem usage: 0/32768 bytes in 0 blocks
--daemon
をつけて起動する必要があった。
$ /usr/bin/gpg-agent --daemon --allow-preset-passphrase --no-detach --pinentry-program /bin/exit --write-env-file gpg_agent_info_env --log-file gpg_agent_log_file --debug-level guru
gpg-agent[14287]: enabled debug flags: command mpi crypto memory cache memstat hashing assuan
- References
ERR 67108924 Not supported <GPG Agent> - no --allow-preset-passphrase
gpg-connect-agent
コマンドでPRESET_PASSPHRASE
でパスワードを事前登録しようとしたところ下記のエラー
$ gpg-connect-agent -S $GPG_AGENT_SOCKET
> PRESET_PASSPHRASE 3C877B122B7C71913E57CF63A07F4150AC73620C -1 5465737431323334
ERR 67108924 Not supported <GPG Agent> - no --allow-preset-passphrase
$ echo "PRESET_PASSPHRASE $GPG_FINGERPRINT -1 $GPG_PASSPHRASE_HEX" | gpg-connect-agent -S $GPG_AGENT_SOCKET
ERR 67108924 Not supported <GPG Agent> - no --allow-preset-passphrase
~/.gnupg/
以下にgpg-agent.conf
という名前のファイルを作成し、allow-preset-passphrase
の文字列を追記した上でGPG Agentの設定を読み込み直す必要があった。
$ echo "allow-preset-passphrase" >> ~/.gnupg/gpg-agent.conf
$ gpgconf --reload gpg-agent
gpg: Can't check signature: Invalid public key algorithm
Amazon Linux 2上だと、以下のエラー
$ gpg -d libgpg-error-1.43.tar.bz2.sig
gpg: Signature made Wed Nov 3 14:03:23 2021 UTC using ? key ID 26403ADA
gpg: Can't check signature: Invalid public key algorithm
gpg: Signature made Wed Nov 24 01:07:32 2021 UTC using ? key ID 19C6C8BD
gpg: Can't check signature: Invalid public key algorithm
検証環境のバージョンは以下。
$ gpg --version
gpg (GnuPG) 2.0.22
libgcrypt 1.5.3
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Home: ~/.gnupg
Supported algorithms:
Pubkey: RSA, ?, ?, ELG, DSA
Cipher: IDEA, 3DES, CAST5, BLOWFISH, AES, AES192, AES256, TWOFISH,
CAMELLIA128, CAMELLIA192, CAMELLIA256
Hash: MD5, SHA1, RIPEMD160, SHA256, SHA384, SHA512, SHA224
Compression: Uncompressed, ZIP, ZLIB, BZIP2
バージョンが古いことが原因だった。以下のようにバージョンを上げたところ、解消
$ gpg --version
gpg (GnuPG) 2.2.33
libgcrypt 1.8.8
Copyright (C) 2021 Free Software Foundation, Inc.
License GNU GPL-3.0-or-later <https://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Home: /home/ec2-user/.gnupg
Supported algorithms:
Pubkey: RSA, ELG, DSA, ECDH, ECDSA, EDDSA
Cipher: IDEA, 3DES, CAST5, BLOWFISH, AES, AES192, AES256, TWOFISH,
CAMELLIA128, CAMELLIA192, CAMELLIA256
Hash: SHA1, RIPEMD160, SHA256, SHA384, SHA512, SHA224
Compression: Uncompressed
$ gpg -d libgpg-error-1.43.tar.bz2.sig
gpg: assuming signed data in 'libgpg-error-1.43.tar.bz2'
gpg: Signature made Wed Nov 3 14:03:23 2021 UTC
gpg: using EDDSA key 6DAA6E64A76D2840571B4902528897B826403ADA
gpg: checking the trustdb
gpg: marginals needed: 3 completes needed: 1 trust model: pgp
gpg: depth: 0 valid: 1 signed: 0 trust: 0-, 0q, 0n, 0m, 0f, 1u
gpg: next trustdb check due at 2023-12-14
gpg: Good signature from "Werner Koch (dist signing 2020)" [unknown]
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: 6DAA 6E64 A76D 2840 571B 4902 5288 97B8 2640 3ADA
gpg: Signature made Wed Nov 24 01:07:32 2021 UTC
gpg: using EDDSA key AC8E115BF73E2D8D47FA9908E98E9B2D19C6C8BD
gpg: Good signature from "Niibe Yutaka (GnuPG Release Key)" [unknown]
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: AC8E 115B F73E 2D8D 47FA 9908 E98E 9B2D 19C6 C8BD
MacOS上だと、バージョンが2.2.33であるため、最初から正常に検証できる。
$ gpg -d libgpg-error-1.43.tar.bz2.sig
gpg: assuming signed data in 'libgpg-error-1.43.tar.bz2'
gpg: Signature made 水 11/ 3 23:03:23 2021 JST
gpg: using EDDSA key 6DAA6E64A76D2840571B4902528897B826403ADA
gpg: Good signature from "Werner Koch (dist signing 2020)" [unknown]
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: 6DAA 6E64 A76D 2840 571B 4902 5288 97B8 2640 3ADA
gpg: Signature made 水 11/24 10:07:32 2021 JST
gpg: using EDDSA key AC8E115BF73E2D8D47FA9908E98E9B2D19C6C8BD
gpg: Good signature from "Niibe Yutaka (GnuPG Release Key)" [unknown]
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: AC8E 115B F73E 2D8D 47FA 9908 E98E 9B2D 19C6 C8BD
$ gpg --version
gpg (GnuPG) 2.2.33
libgcrypt 1.8.8
Copyright (C) 2021 Free Software Foundation, Inc.
License GNU GPL-3.0-or-later <https://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Home: /Users/hayashier/.gnupg
Supported algorithms:
Pubkey: RSA, ELG, DSA, ECDH, ECDSA, EDDSA
Cipher: IDEA, 3DES, CAST5, BLOWFISH, AES, AES192, AES256, TWOFISH,
CAMELLIA128, CAMELLIA192, CAMELLIA256
Hash: SHA1, RIPEMD160, SHA256, SHA384, SHA512, SHA224
Compression: Uncompressed, ZIP, ZLIB, BZIP2
- References
gpg: error while loading shared libraries: libgcrypt.so.20: cannot open shared object file: No such file or directory
Amazon Linux 2の環境で、GnuPGの最新版をインストールし、コマンドを実行しようとしたところ、以下のエラー。
$ gpg --version
gpg: error while loading shared libraries: libgcrypt.so.20: cannot open shared object file: No such file or directory
以下を実行する必要があった。ライブラリのインストール先をgpg2.confに指定して、ldconfigコマンドで読み込む。
echo "/usr/local/lib" | sudo tee /etc/ld.so.conf.d/gpg2.conf && sudo ldconfig -v
gpg: agent_genkey failed: No pinentry
gpgをインストール後コマンドを実行すると以下のエラー
$ gpg --gen-key
gpg (GnuPG) 2.2.33; Copyright (C) 2021 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Note: Use "gpg --full-generate-key" for a full featured key generation dialog.
GnuPG needs to construct a user ID to identify your key.
Real name: Sample1
Email address: hayashier@example.com
You selected this USER-ID:
"Sample1 <hayashier@example.com>"
Change (N)ame, (E)mail, or (O)kay/(Q)uit? O
We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.
gpg: agent_genkey failed: No pinentry
Key generation failed: No pinentry
gpg-agent.conf
に設定を追加して、gpg-agentの設定を読み込み直す必要があった。
echo "pinentry-program /usr/bin/pinentry-curses" >> ~/.gnupg/gpg-agent.conf
gpgconf --reload gpg-agent
- References
gpg: key AAC5DE59A84FCD28/AAC5DE59A84FCD28: error sending to agent: Operation cancelled
gpg --importしたところ、操作が途中でキャンセルされている。秘密鍵のインポートがOperation cancelled
と表示されている。
$ /usr/local/bin/gpg --import /tmp/gpg-secret-sample1
gpg: starting migration from earlier GnuPG versions
gpg: porting secret keys from '/root/.gnupg/secring.gpg' to gpg-agent
gpg: migration succeeded
gpg: key AAC5DE59A84FCD28: public key "Sample1 <hayashier@example.com>" imported
gpg: key AAC5DE59A84FCD28/AAC5DE59A84FCD28: error sending to agent: Operation cancelled
gpg: error reading '/tmp/gpg-secret-sample1': Operation cancelled
gpg: import from '/tmp/gpg-secret-sample1' failed: Operation cancelled
gpg: Total number processed: 0
gpg: imported: 1
gpg: secret keys read: 1
rpm --importでパスワード入力していないことが原因。パイプライン中ではインタラクティブなパスワード入力画面がないことに起因。ためしに、GPGの鍵生成時にパスワードを設定せずに実行したところ、以下のように正常に実行された。
$ /usr/local/bin/gpg --import /tmp/gpg-secret-sample-1
gpg: starting migration from earlier GnuPG versions
gpg: porting secret keys from '/root/.gnupg/secring.gpg' to gpg-agent
gpg: migration succeeded
gpg: key A711DC45371329D4: public key "Sample1 <hayashier@example.com>" imported
gpg: key A711DC45371329D4: secret key imported
gpg: Total number processed: 1
gpg: imported: 1
gpg: secret keys read: 1
gpg: secret keys imported: 1
パスワードが設定された状態でも、--batch
オプションで解消した。
$ gpg --batch --import /tmp/gpg-secret-sample1
gpg: starting migration from earlier GnuPG versions
gpg: porting secret keys from '/root/.gnupg/secring.gpg' to gpg-agent
gpg: migration succeeded
gpg: key AAC5DE59A84FCD28: public key "Sample1 <hayashier@example.com>" imported
gpg: key AAC5DE59A84FCD28: secret key imported
gpg: Total number processed: 1
gpg: imported: 1
gpg: secret keys read: 1
gpg: secret keys imported: 1
- References
rpm: /usr/bin/rpmsign: No such file or directory
rpmコマンドで--addsign
オプションを付与して実行したところ、以下のエラー。
$ rpm --define "__gpg /usr/local/bin/gpg" --define "_gpg_name Sample1" --define "%__gpg_check_password_cmd /bin/true" --define "%__gpg_sign_cmd %{__gpg} gpg --batch --no-verbose --no-secmem-warning --sign --detach-sign --no-armor -u '%{_gpg_name}' --output %{__signature_filename} %{__plaintext_filename}" --addsign $rpm_file
rpm: /usr/bin/rpmsign: No such file or directory
rpm-signをインストールして解消。
$ sudo yum install rpm-sign -y
configure: error: libgpg-error is needed.
Amazon Linux 2で、rootユーザー環境で、libgpg-errorに依存する他のライブラリを./configureするときに、既にインストールされているにも関わらず、上記エラー。ec2-userだと問題なく、インストールできる。
ライブラリの場所を明示的に指定する必要があった。libgpg-error以外の他のライブラリも同様。./configure --help
でそれらしきオプションを探してくる。
./configure --prefix=/tmp/gpnug --with-libgpg-error-prefix=/tmp/gpnug
You need libksba to build this program.
ntbtlsをビルド時に以下のエラー
configure:
***
*** You need libksba to build this program.
*** This library is for example available at
*** ftp://ftp.gnupg.org/gcrypt/libksba/
*** (at least version 1.2.0 using API 1 is required).
***
configure: error:
***
*** Required libraries not found. Please consult the above messages
*** and install them before running configure again.
***
make: *** No targets specified and no makefile found. Stop.
make: *** No rule to make target `install'. Stop.
--help
オプション上は--with-libksba-prefix
となっているが、--with-ksba-prefix
が正しい。libksbaのバグ。
# ./configure --help | grep prefix
--prefix=PREFIX install architecture-independent files in PREFIX
--exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
an installation prefix other than `/usr/local' using `--prefix',
for instance `--prefix=$HOME'.
--program-prefix=PREFIX prepend PREFIX to installed program names
--with-libgpg-error-prefix=PFX
prefix where GPG Error is installed (optional)
--with-libgcrypt-prefix=PFX
prefix where LIBGCRYPT is installed (optional)
--with-libksba-prefix=PFX
prefix where KSBA is installed (optional)
- References
No package 'gnutls' found
./configureを実行していたところ、上記エラー。gnutls-devel
をインストールする。
$ sudo yum install gnutls-devel -y
- References
No package 'sqlite3' found
./configureを実行していたところ、上記エラー。sqlite-devel
をインストールする。
$ sudo yum install sqlite-devel -y
WARNING: server 'gpg-agent' is older than us (2.0.22 < 2.2.33)
# rpm --define "__gpg /usr/local/bin/gpg" --define "_gpg_name Sample1" --define "%__gpg_check_password_cmd /bin/true" --define "%__gpg_sign_cmd %{__gpg} gpg --batch --no-verbose --no-secmem-warning --sign --detach-sign --no-armor -u '%{_gpg_name}' --output %{__signature_filename} %{__plaintext_filename}" --addsign $rpm_file
Enter pass phrase:
Pass phrase is good.
./motd-1.0-1.amzn2.noarch.rpm:
gpg: WARNING: server 'gpg-agent' is older than us (2.0.22 < 2.2.33)
gpg: Note: Outdated servers may lack important security fixes.
gpg: Note: Use the command "gpgconf --kill all" to restart them.
gpg: signing failed: Invalid length specifier in S-expression
gpg: signing failed: Invalid length specifier in S-expression
error: gpg exec failed (2)
gpg-agentのバージョンがgpgよりも古いことが原因。 合わせて他の関連バイナリのバージョン(gpg-agent, gpg-connect-agent, gpgconf)もgpgに合わせた。
$ INSTALL_DIR=/usr/local/bin/
$ cp ./gnupg-2.2.33/g10/gpg $INSTALL_DIR
$ cp ./gnupg-2.2.33/agent/gpg-agent $INSTALL_DIR
$ cp ./gnupg-2.2.33/tools/gpgconf $INSTALL_DIR
$ cp ./gnupg-2.2.33/tools/gpg-connect-agent $INSTALL_DIR
gpg --importがexit 2で終了する。
バージョンによって挙動が異なることもある様子。自己署名のようなログが流れていたのでそれに起因している可能性がある。
スクリプトを終了するような環境で処理を止めたくない場合は || true
のように実行することもできるが、GPG鍵をインポートしたくてもバージョンが古く対応していないアルゴリズムで署名されていたので、回避策として、ファイルのハッシュ値を比較して、GPG鍵を利用しない方向で対応した。
gpg: pinentry launched (23774 unknown 0.8.1 ? ? ?)
rpm --addsign実行時に、以下のメッセージが出て処理に失敗。
# rpm --define "__gpg /usr/local/bin/gpg" --define "_gpg_name Sample3" --define "%__gpg_check_password_cmd /bin/true" --define "%__gpg_sign_cmd %{__gpg} gpg --batch -vv --no-secmem-warning --sign --detach-sign --no-armor -u %{_gpg_name} --output %{__signature_filename} %{__plaintext_filename}" --addsign motd-1.0-1.amzn2.noarch.rpm
Enter pass phrase:
Pass phrase is good.
motd-1.0-1.amzn2.noarch.rpm:
gpg: writing to '/var/tmp/rpm-tmp.bm0upg.sig'
gpg: pinentry launched (18127 unknown 0.8.1 ? ? ?)
gpg: signing failed: No passphrase given
gpg: signing failed: No passphrase given
error: gpg exec failed (2)
expectコマンド中での場合は、以下のようなエラー。
spawn rpm --define __gpg /usr/local/bin/gpg --define _gpg_name Sample1 --define %__gpg_check_password_cmd /bin/true --define %__gpg_sign_cmd %{__gpg} gpg --batch -vv --no-secmem-warning --sign --detach-sign --no-armor -u %{_gpg_name} --output %{__signature_filename} %{__plaintext_filename} --addsign /tmp/sample/motd-1.0-1.amzn2.noarch.rpm
Enter pass phrase:
Pass phrase is good.
/tmp/sample/motd-1.0-1.amzn2.noarch.rpm:
gpg: writing to '/var/tmp/rpm-tmp.ISKqRF.sig'
gpg: pinentry launched (23742 unknown 0.8.1 ? ? ?)
gpg: signing failed: Operation cancelled
gpg: signing failed: Operation cancelled
error: gpg exec failed (2)
以下のようなパスワード入力画面が出てしまっていることが理由。
┌────────────────────────────────────────────────────────────────┐
│ Please enter the passphrase to unlock the OpenPGP secret key: │
│ "SampleGpg1 <hayashier@example.com>" │
│ 3072-bit RSA key, ID 187D25C1E2CFA3BD, │
│ created 2021-12-16. │
│ │
│ │
│ Passphrase: __________________________________________________ │
│ │
│ <OK> <Cancel> │
└────────────────────────────────────────────────────────────────┘
インポートしている秘密鍵と実際に指定しているGPG名が不一致で、GPGエージェントによるパスワード入力が効かなかったことが原因。以下のようにechoによるパスフレーズ(echo "PRESET_PASSPHRASE $GPG_KEYGRIP -1 $GPG_PASSPHRASE_HEX" | /usr/local/bin/gpg-connect-agent -S $GPG_AGENT_SOCKET
)を実行していた。
rpm_file=./motd-1.0-1.amzn2.noarch.rpm
kill $(ps aux | grep "gpg-agent --" | awk '{print $2}')
ps aux | grep gpg-agent
/usr/local/bin/gpgconf --reload gpg-agent
/usr/local/bin/gpg-agent --daemon --allow-preset-passphrase --no-detach --log-file gpg_agent_log_file --debug-level guru
GPG_KEYGRIP=$(/usr/local/bin/gpg --with-keygrip --list-key | grep Sample1 -B 2 | grep Keygrip | awk -F = '{print $2}' | sed -e 's/[[:blank:]]//g' | tail -n 1) && echo $GPG_KEYGRIP
GPG_PASSPHRASE_HEX=$(echo Test1234 | tr -d '\n' | hexdump -v -e '/1 "%02X"') && echo $GPG_PASSPHRASE_HEX
GPG_AGENT_SOCKET=$(gpgconf --list-dirs | grep agent-socket | sed -e 's/.*://g') && echo $GPG_AGENT_SOCKET
echo "PRESET_PASSPHRASE $GPG_KEYGRIP -1 $GPG_PASSPHRASE_HEX" | /usr/local/bin/gpg-connect-agent -S $GPG_AGENT_SOCKET
以下がechoコマンドによるもののときのログ
2021-12-16 05:10:10 gpg-agent[18402] DBG: agent_get_cache '5A3AA79AAEC2864B4C7E0AE40571E00499328023'.0 (mode 2) ...
2021-12-16 05:10:10 gpg-agent[18402] DBG: ... miss
2021-12-16 05:10:10 gpg-agent[18402] starting a new PIN Entry
2021-12-16 05:10:10 gpg-agent[18402] DBG: connection to PIN entry established
2021-12-16 05:10:10 gpg-agent[18402] DBG: chan_10 -> INQUIRE PINENTRY_LAUNCHED 18432 unknown 0.8.1 ? ? ?
2021-12-16 05:10:10 gpg-agent[18402] DBG: chan_10 <- END
/usr/libexec/gpg-preset-passphrase --passphrase $GPG_PASS_PHRASE --preset $GPG_KEYGRIP
を実行の方がシンプルで、こちらを利用することにした。
- References
gpg: keyserver receive failed: No name
Ubuntu上で実行したところ以下のエラー
$ gpg --keyserver hkp://keys.gnupg.net --recv-key 6DAA6E64A76D2840571B4902528897B826403ADA AC8E115BF73E2D8D47FA9908E98E9B2D19C6C8BD D8692123C4065DEA5E0F3AB5249B39D24F25E3B6
gpg: keyserver receive failed: No name
SKS Keyserver NetworkがDeprecatedになって、利用できない状態。そのため、他のGPG鍵サーバーを利用すると良い。
-
keyserver.ubuntu.com
-
keys.openpgp.org
-
pgp.mit.edu
-
References
gpg: Can't check signature: No public key
Amazon Linux 2上で以下のようにキーをインポート後、
$ gpg --keyserver hkp://keys.gnupg.net --recv-key 6DAA6E64A76D2840571B4902528897B826403ADA AC8E115BF73E2D8D47FA9908E98E9B2D19C6C8BD D8692123C4065DEA5E0F3AB5249B39D24F25E3B6
以下のように署名を検証
$ LIBGPG_ERROR_VERSION=1.43
$ curl -L https://gnupg.org/ftp/gcrypt/libgpg-error/libgpg-error-${LIBGPG_ERROR_VERSION}.tar.bz2 -O
$ curl -L https://gnupg.org/ftp/gcrypt/libgpg-error/libgpg-error-${LIBGPG_ERROR_VERSION}.tar.bz2.sig -O
$ gpg -d libgpg-error-${LIBGPG_ERROR_VERSION}.tar.bz2.sig
すると以下のエラー
gpg: assuming signed data in 'libgpg-error-1.43.tar.bz2'
gpg: Signature made Wed Nov 3 14:03:23 2021 UTC
gpg: using EDDSA key 6DAA6E64A76D2840571B4902528897B826403ADA
gpg: Good signature from "Werner Koch (dist signing 2020)" [unknown]
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: 6DAA 6E64 A76D 2840 571B 4902 5288 97B8 2640 3ADA
gpg: Signature made Wed Nov 24 01:07:32 2021 UTC
gpg: using EDDSA key AC8E115BF73E2D8D47FA9908E98E9B2D19C6C8BD
gpg: Can't check signature: No public key
SKS Keyserver NetworkがDeprecatedになって、利用できない状態。そのため、他のGPG鍵サーバーを利用すると良い。
- References
Links
GnuPG
- Get Started
- Practice
-
- Notes
- 入門記事
- Notes
-
- Notes
- リファレンスとして良い
- Notes
-
GPG でファイルを暗号化, 復号化, 署名, 検証する方法 !!
- Notes
- gpgコマンドによる暗号化、復号、署名、検証方法の代表的なパターンが一通り書かれている。
- Notes
-
GPG でファイルをパスワードで暗号化(共通鍵暗号)するときの簡易コマンド一覧
- Notes
- gpgの利用例
- Notes
-
- Notes
- 以下のパターンでの使い方を解説
- 「電子署名が付加」されただけのPGP MESSAGE
- 「ファイルを暗号化」しただけのPGP MESSAGE
- 「電子署名 + 暗号化」がファイルに施されたPGP MESSAGE
- 以下のパターンでの使い方を解説
- Notes
-
- Notes
- パッケージの署名には、以下の 3 つの方法があります。
- 「既存パッケージへの署名の追加」.
- 「既存のパッケージの署名の置き換え」.
- 「ビルド時のパッケージの署名」.
- パッケージの署名には、以下の 3 つの方法があります。
- Notes
-
RPM
- Overview
- Get Started