Gpg
在 Alpine Linux Docker 映像上生成 GPG 密鑰失敗
我在 docker alpine linux 上進行了以下測試:
ole@MKI:~$ docker run --rm -it alpine /bin/ash / # apk add --update duplicity fetch http://dl-4.alpinelinux.org/alpine/v3.3/main/x86_64/APKINDEX.tar.gz fetch http://dl-4.alpinelinux.org/alpine/v3.3/community/x86_64/APKINDEX.tar.gz (1/28) Installing libbz2 (1.0.6-r4) (2/28) Installing expat (2.1.0-r2) ... (28/28) Installing duplicity (0.7.05-r0) Executing busybox-1.24.1-r7.trigger OK: 72 MiB in 39 packages / # gpg --list-keys gpg: directory '/root/.gnupg' created gpg: new configuration file '/root/.gnupg/dirmngr.conf' created gpg: new configuration file '/root/.gnupg/gpg.conf' created gpg: WARNING: options in '/root/.gnupg' are not yet active during this run gpg: keybox '/root/.gnupg/pubring.kbx' created gpg: /root/.gnupg/trustdb.gpg: trustdb created / # gpg --list-keys / # gpg --gen-key gpg (GnuPG) 2.1.10; Copyright (C) 2015 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 "gpg2 --full-gen-key" for a full featured key generation dialog. GnuPG needs to construct a user ID to identify your key. Real name: Testing Email address: testing@test You selected this USER-ID: "Testing <testing@test>" 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 such file or directory Key generation failed: No such file or directory / # ls /root/.gnupg/ S.gpg-agent dirmngr.conf gpg.conf private-keys-v1.d pubring.kbx trustdb.gpg / #
關於為什麼密鑰生成失敗的任何想法?
$$ Edit $$ 我總是可以使用 ubuntu 映像生成密鑰並將它們安裝在一個卷中。無論如何,這最終就是我正在做的事情,但我認為將它與 alpine 圖像一起使用會很好,所以我
strace
按照建議粘貼了以下內容:/ # strace -f gpg --gen-key execve("/usr/bin/gpg", ["gpg", "--gen-key"], [/* 6 vars */]) = 0 arch_prctl(ARCH_SET_FS, 0x7f75271edda8) = 0 set_tid_address(0x7f75271edde0) = 17 open("/etc/ld-musl-x86_64.path", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) open("/lib/libz.so.1", O_RDONLY|O_CLOEXEC) = 3 fcntl(3, F_SETFD, FD_CLOEXEC) = 0 fstat(3, {st_mode=S_IFREG|0755, st_size=87976, ...}) = 0 read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\0!\0\0\0\0\0\0"..., 960) = 960 mmap(NULL, 2187264, PROT_READ|PROT_EXEC, MAP_PRIVATE, 3, 0) = 0x7f7526d4f000 mmap(0x7f7526f63000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED, 3, 0x14000) = 0x7f7526f63000 close(3) = 0 open("/lib/libgcrypt.so.20", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) open("/usr/local/lib/libgcrypt.so.20", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) open("/usr/lib/libgcrypt.so.20", O_RDONLY|O_CLOEXEC) = 3 fcntl(3, F_SETFD, FD_CLOEXEC) = 0 fstat(3, {st_mode=S_IFREG|0755, st_size=856824, ...}) = 0 read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\0\214\0\0\0\0\0\0"..., 960) = 960 mmap(NULL, 2957312, PROT_READ|PROT_EXEC, MAP_PRIVATE, 3, 0) = 0x7f7526a7d000 mmap(0x7f7526d45000, 40960, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED, 3, 0xc8000) = 0x7f7526d45000 mmap(0x7f7526d4e000, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f7526d4e000 close(3) = 0 open("/lib/libgpg-error.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) open("/usr/local/lib/libgpg-error.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) open("/usr/lib/libgpg-error.so.0", O_RDONLY|O_CLOEXEC) = 3 fcntl(3, F_SETFD, FD_CLOEXEC) = 0 fstat(3, {st_mode=S_IFREG|0755, st_size=67520, ...}) = 0 read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0p'\0\0\0\0\0\0"..., 960) = 960 mmap(NULL, 2166784, PROT_READ|PROT_EXEC, MAP_PRIVATE, 3, 0) = 0x7f752686c000 mmap(0x7f7526a7b000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED, 3, 0xf000) = 0x7f7526a7b000 close(3) = 0 open("/lib/libassuan.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) open("/usr/local/lib/libassuan.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) open("/usr/lib/libassuan.so.0", O_RDONLY|O_CLOEXEC) = 3 fcntl(3, F_SETFD, FD_CLOEXEC) = 0 fstat(3, {st_mode=S_IFREG|0755, st_size=67616, ...}) = 0 read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\2204\0\0\0\0\0\0"..., 960) = 960 mmap(NULL, 2166784, PROT_READ|PROT_EXEC, MAP_PRIVATE, 3, 0) = 0x7f752665b000 mmap(0x7f752686a000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED, 3, 0xf000) = 0x7f752686a000 close(3) = 0 mprotect(0x7f7526f63000, 4096, PROT_READ) = 0 mprotect(0x7f7526d45000, 4096, PROT_READ) = 0 mprotect(0x7f7526a7b000, 4096, PROT_READ) = 0 mprotect(0x7f752686a000, 4096, PROT_READ) = 0 mprotect(0x7f75271ec000, 4096, PROT_READ) = 0 mprotect(0x7f752749a000, 8192, PROT_READ) = 0 fstat(0, {st_mode=S_IFCHR|0600, st_rdev=makedev(136, 24), ...}) = 0 fstat(1, {st_mode=S_IFCHR|0600, st_rdev=makedev(136, 24), ...}) = 0 fstat(2, {st_mode=S_IFCHR|0600, st_rdev=makedev(136, 24), ...}) = 0 access("/etc/gcrypt/fips_enabled", F_OK) = -1 ENOENT (No such file or directory) open("/proc/sys/crypto/fips_enabled", O_RDONLY) = -1 ENOENT (No such file or directory) open("/etc/gcrypt/hwf.deny", O_RDONLY) = -1 ENOENT (No such file or directory) prlimit64(0, RLIMIT_CORE, NULL, {rlim_cur=0, rlim_max=RLIM64_INFINITY}) = 0 rt_sigprocmask(SIG_BLOCK, ~[RTMIN RT_1 RT_2], [], 8) = 0 rt_sigprocmask(SIG_BLOCK, ~[], NULL, 8) = 0 prlimit64(0, RLIMIT_CORE, {rlim_cur=0, rlim_max=RLIM64_INFINITY}, NULL) = 0 futex(0x7f75271f011c, FUTEX_WAKE_PRIVATE, 2147483647) = 0 rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0 rt_sigaction(SIGINT, NULL, {SIG_DFL, [], 0}, 8) = 0 rt_sigprocmask(SIG_UNBLOCK, [RT_1 RT_2], NULL, 8) = 0 rt_sigaction(SIGINT, {0x7f752726a170, [], SA_RESTORER, 0x7f7526fad1c2}, NULL, 8) = 0 rt_sigaction(SIGHUP, NULL, {SIG_DFL, [], 0}, 8) = 0 rt_sigaction(SIGHUP, {0x7f752726a170, [], SA_RESTORER, 0x7f7526fad1c2}, NULL, 8) = 0 rt_sigaction(SIGTERM, NULL, {SIG_DFL, [], 0}, 8) = 0 rt_sigaction(SIGTERM, {0x7f752726a170, [], SA_RESTORER, 0x7f7526fad1c2}, NULL, 8) = 0 rt_sigaction(SIGQUIT, NULL, {SIG_DFL, [], 0}, 8) = 0 rt_sigaction(SIGQUIT, {0x7f752726a170, [], SA_RESTORER, 0x7f7526fad1c2}, NULL, 8) = 0 rt_sigaction(SIGSEGV, NULL, {SIG_DFL, [], 0}, 8) = 0 rt_sigaction(SIGSEGV, {0x7f752726a170, [], SA_RESTORER, 0x7f7526fad1c2}, NULL, 8) = 0 rt_sigaction(SIGUSR1, {0x7f752726a0d4, [], SA_RESTORER, 0x7f7526fad1c2}, NULL, 8) = 0 rt_sigaction(SIGPIPE, {SIG_IGN, [], SA_RESTORER, 0x7f7526fad1c2}, NULL, 8) = 0 mmap(NULL, 32768, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f7527492000 getuid() = 0 mlock(0x7f7527492000, 32768) = 0 access("/root/.gnupg/gpg.conf-2.1.10", R_OK) = -1 ENOENT (No such file or directory) access("/root/.gnupg/gpg.conf-2.1", R_OK) = -1 ENOENT (No such file or directory) access("/root/.gnupg/gpg.conf-2", R_OK) = -1 ENOENT (No such file or directory) access("/root/.gnupg/gpg.conf", R_OK) = -1 ENOENT (No such file or directory) access("/root/.gnupg/options", R_OK) = -1 ENOENT (No such file or directory) stat("~/.gnupg", 0x7fff3556cc38) = -1 ENOENT (No such file or directory) stat("/root/.gnupg/gpg.conf", 0x7fff3556cc38) = -1 ENOENT (No such file or directory) open("/root/.gnupg/gpg.conf", O_RDONLY) = -1 ENOENT (No such file or directory) writev(2, [{"", 0}, {"gpg (GnuPG) 2.1.10; Copyright (C"..., 69}], 2gpg (GnuPG) 2.1.10; Copyright (C) 2015 Free Software Foundation, Inc.) = 69 writev(2, [{"", 0}, {"\n", 1}], 2 ) = 1 writev(2, [{"", 0}, {"This is free software: you are f"..., 121}], 2This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. ) = 121 writev(2, [{"", 0}, {"\n", 1}], 2 ) = 1 access("/root/.gnupg/random_seed", F_OK) = -1 ENOENT (No such file or directory) open("/root/.gnupg/pubring.gpg", O_RDONLY) = -1 ENOENT (No such file or directory) open("/root/.gnupg/pubring.kbx", O_RDONLY) = -1 ENOENT (No such file or directory) access("/root/.gnupg/pubring.kbx", F_OK) = -1 ENOENT (No such file or directory) access("/root/.gnupg", F_OK) = -1 ENOENT (No such file or directory) mkdir("/root/.gnupg", 0700) = 0 write(2, "gpg: directory '/root/.gnupg", 28gpg: directory '/root/.gnupg) = 28 write(2, "' created\n", 10' created ) = 10 open("/usr/share/gnupg/dirmngr-conf.skel", O_RDONLY) = 3 umask(077) = 022 open("/root/.gnupg/dirmngr.conf", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 4 ioctl(4, TIOCGWINSZ, 0x7fff3556c908) = -1 ENOTTY (Not a tty) umask(022) = 077 readv(3, [{"", 0}, {"# dirmngr-conf.skel - Skeleton t"..., 1024}], 2) = 1024 readv(3, [{"", 0}, {"nd receive keys to and from a ke"..., 1024}], 2) = 1024 writev(4, [{"# dirmngr.conf - Options for Dir"..., 1024}, {"L", 1}], 2) = 1025 readv(3, [{"", 0}, {" and only one is a Tor hidden\n# "..., 1024}], 2) = 704 writev(4, [{"DAP\n# support).\n#\n# Example HKP "..., 1024}, {"c", 1}], 2) = 1025 readv(3, [{"", 0}, {" and only one is a Tor hidden\n# "..., 1024}], 2) = 0 writev(4, [{"ally running or not (on a per se"..., 593}, {NULL, 0}], 2) = 593 close(4) = 0 close(3) = 0 write(2, "gpg: new configuration file '/ro"..., 54gpg: new configuration file '/root/.gnupg/dirmngr.conf) = 54 write(2, "' created\n", 10' created ) = 10 open("/usr/share/gnupg/gpg-conf.skel", O_RDONLY) = 3 umask(077) = 022 open("/root/.gnupg/gpg.conf", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 4 ioctl(4, TIOCGWINSZ, 0x7fff3556c908) = -1 ENOTTY (Not a tty) umask(022) = 077 readv(3, [{"", 0}, {"# These first three lines are no"..., 1024}], 2) = 1024 readv(3, [{"", 0}, {"\n\n# Uncomment the following opti"..., 1024}], 2) = 1024 writev(4, [{"# Options for GnuPG\n# Copyright "..., 1024}, {"o", 1}], 2) = 1025 readv(3, [{"", 0}, {"nce you may want to use this opt"..., 1024}], 2) = 1024 writev(4, [{"re than 1 secret key in your key"..., 1024}, {" ", 1}], 2) = 1025 readv(3, [{"", 0}, {"\n# \"0x12345678\". Note there is "..., 1024}], 2) = 1024 writev(4, [{"subkey, ensure that the cross\n# "..., 1024}, {"o", 1}], 2) = 1025 readv(3, [{"", 0}, {"r.\n#\n# verbose = show more infor"..., 1024}], 2) = 1024 writev(4, [{" another group. Note also that\n"..., 1024}, {"t", 1}], 2) = 1025 readv(3, [{"", 0}, {"ys to the keyserver.\n\n#keyserver"..., 1024}], 2) = 1024 writev(4, [{"o increase the amount\n# "..., 1024}, {"I", 1}], 2) = 1025 readv(3, [{"", 0}, {"c OS X and Windows, the default "..., 1024}], 2) = 413 writev(4, [{"Ds in key listings and\n# when a "..., 1024}, {"t", 1}], 2) = 1025 readv(3, [{"", 0}, {"c OS X and Windows, the default "..., 1024}], 2) = 0 writev(4, [{"o-viewer \"qiv %i\"\n# photo-viewer"..., 307}, {NULL, 0}], 2) = 307 close(4) = 0 close(3) = 0 write(2, "gpg: new configuration file '/ro"..., 50gpg: new configuration file '/root/.gnupg/gpg.conf) = 50 write(2, "' created\n", 10' created ) = 10 write(2, "gpg: WARNING: options in '/root/"..., 38gpg: WARNING: options in '/root/.gnupg) = 38 write(2, "' are not yet active during this"..., 37' are not yet active during this run ) = 37 access("/root/.gnupg", F_OK) = 0 getpid() = 17 uname({sysname="Linux", nodename="60fbb80a7ebb", ...}) = 0 getpid() = 17 open("/root/.gnupg/.#lk0x00007f7526f64f40.60fbb80a7ebb.17", O_WRONLY|O_CREAT|O_EXCL, 0644) = 3 write(3, " 17\n", 11) = 11 write(3, "60fbb80a7ebb", 12) = 12 write(3, "\n", 1) = 1 close(3) = 0 stat("/root/.gnupg/.#lk0x00007f7526f64f40.60fbb80a7ebb.17", {st_mode=S_IFREG|0644, st_size=24, ...}) = 0 link("/root/.gnupg/.#lk0x00007f7526f64f40.60fbb80a7ebb.17", "/root/.gnupg/.#lk0x00007f7526f64f40.60fbb80a7ebb.17x") = 0 stat("/root/.gnupg/.#lk0x00007f7526f64f40.60fbb80a7ebb.17", {st_mode=S_IFREG|0644, st_size=24, ...}) = 0 unlink("/root/.gnupg/.#lk0x00007f7526f64f40.60fbb80a7ebb.17x") = 0 link("/root/.gnupg/.#lk0x00007f7526f64f40.60fbb80a7ebb.17", "/root/.gnupg/pubring.kbx.lock") = 0 stat("/root/.gnupg/.#lk0x00007f7526f64f40.60fbb80a7ebb.17", {st_mode=S_IFREG|0644, st_size=24, ...}) = 0 access("/root/.gnupg/pubring.kbx", F_OK) = -1 ENOENT (No such file or directory) umask(077) = 022 open("/root/.gnupg/pubring.kbx", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 3 brk(0) = 0x7f7528fc5000 brk(0x7f7528fc8000) = 0x7f7528fc8000 umask(022) = 077 close(3) = 0 open("/root/.gnupg/pubring.kbx", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 3 ioctl(3, TIOCGWINSZ, 0x7fff3556c968) = -1 ENOTTY (Not a tty) writev(3, [{"\0\0\0 \1\1\0\2KBXf\0\0\0\0W\30+\243W\30+\243\0\0\0\0\0\0\0\0", 32}, {NULL, 0}], 2) = 32 close(3) = 0 write(2, "gpg: keybox '/root/.gnupg/pubrin"..., 37gpg: keybox '/root/.gnupg/pubring.kbx) = 37 write(2, "' created\n", 10' created ) = 10 open("/root/.gnupg/pubring.kbx.lock", O_RDONLY) = 3 read(3, " 17\n60fbb80a7ebb\n", 24) = 24 close(3) = 0 getpid() = 17 unlink("/root/.gnupg/pubring.kbx.lock") = 0 unlink("/root/.gnupg/.#lk0x00007f7526f64f40.60fbb80a7ebb.17") = 0 access("/root/.gnupg/secring.gpg", F_OK) = -1 ENOENT (No such file or directory) open("/dev/tty", O_RDWR) = 3 ioctl(3, TIOCGWINSZ, {ws_row=43, ws_col=174, ws_xpixel=0, ws_ypixel=0}) = 0 writev(3, [{"Note: Use \"gpg2 --full-gen-key", 30}, {"\" for a full featured key genera"..., 45}], 2Note: Use "gpg2 --full-gen-key" for a full featured key generation dialog. ) = 75 writev(3, [{"", 0}, {"\nGnuPG needs to construct a user"..., 59}], 2 GnuPG needs to construct a user ID to identify your key. ) = 59 writev(3, [{"Real name: ", 11}, {NULL, 0}], 2Real name: ) = 11 read(3,
這個問題似乎與 pinentry 和 tty 有關。相同的命令與 Ubuntu 完美配合。
tty
在 Alpine Linux 容器中顯示/0
,而tty
在 Ubuntu 容器中顯示/dev/console
通過首先為 gpg ( ) 導出正確的 tty,
export GPG_TTY=/dev/console
該命令起作用並顯示密碼對話框。
當連接到 Alpine Linux 容器或裸機機器時,重要的是不要
su -
連接到另一個$USER
,因為這也會導緻密鑰生成失敗。添加到您的遠端 Alpine
~/.profile
或者~/.bashrc
如果使用bash
:export GPG_TTY=$(tty) gpg-connect-agent updatestartuptty /bye >/dev/null unset SSH_AGENT_PID if [ "${gnupg_SSH_AUTH_SOCK_by:-0}" -ne $$ ]; then export SSH_AUTH_SOCK="$(gpgconf --list-dirs agent-ssh-socket)" fi
- & 再次登錄
- 用於
gpg --full-generate-key
生成4096
位gpg
密鑰