参考 附录 B. 使用预置自动进行安装 和 DebianInstaller/Preseed/EditIso - Debian Wiki准备工作安装依赖包安装 genisoimage, xorriso, qemu-system, 分别用于制作镜像，解压镜像和测试镜像apt install genisoimage xorriso qemu-system下载镜像wget https://cdimage.debian.org/debian-cd/current/amd64/iso-cd/debian-11.7.0-amd64-netinst.iso解压镜像xorriso -osirrox on -indev debian-12.*.iso -extract / isofiles制作全自动安全镜像创建自动安装配置文件将下面的内容保存为 preseed.cfg。可以看到root密码是123123，非常简单，但我关闭了ssh的密码登录，只能公钥登录，所以不用担心。#_preseed_V1 d-i debian-installer/language string en d-i debian-installer/country string CN d-i debian-installer/locale string en_US.UTF-8 d-i keyboard-configuration/xkb-keymap select us d-i netcfg/choose_interface select auto d-i netcfg/get_hostname string debian d-i netcfg/get_domain string d-i netcfg/wireless_wep string d-i mirror/protocol string http d-i mirror/country string maunal d-i mirror/http/hostname string mirrors.pku.edu.cn d-i mirror/http/directory string /debian/ d-i mirror/http/proxy string d-i passwd/root-login boolean true d-i passwd/make-user boolean false d-i passwd/root-password password 123123 d-i passwd/root-password-again password 123123 d-i clock-setup/utc boolean true d-i time/zone string Asia/Shanghai d-i clock-setup/ntp boolean true d-i partman-auto/method string regular d-i partman-auto-lvm/guided_size string max d-i partman-lvm/device_remove_lvm boolean true d-i partman-md/device_remove_md boolean true d-i partman-lvm/confirm boolean true d-i partman-lvm/confirm_nooverwrite boolean true d-i partman-auto/choose_recipe select atomic d-i partman-partitioning/confirm_write_new_label boolean true d-i partman/choose_partition select finish d-i partman/confirm boolean true d-i partman/confirm_nooverwrite boolean true d-i partman-md/confirm boolean true d-i partman-partitioning/confirm_write_new_label boolean true d-i partman/choose_partition select finish d-i partman/confirm boolean true d-i partman/confirm_nooverwrite boolean true d-i apt-setup/cdrom/set-first boolean false d-i apt-setup/non-free boolean true d-i apt-setup/contrib boolean true d-i apt-setup/disable-cdrom-entries boolean true d-i apt-setup/services-select multiselect security, updates, backports d-i apt-setup/enable-source-repositories boolean false d-i apt-setup/security_host string security.debian.org d-i debian-installer/allow_unauthenticated boolean false tasksel tasksel/first multiselect standard, ssh-server d-i pkgsel/include string vim curl wget git htop sudo tmux qemu-guest-agent d-i pkgsel/upgrade select full-upgrade popularity-contest popularity-contest/participate boolean false d-i grub-installer/only_debian boolean true d-i grub-installer/with_other_os boolean true d-i grub-installer/bootdev string default d-i finish-install/reboot_in_progress note d-i cdrom-detect/eject boolean true d-i preseed/late_command string \ in-target mkdir -p /target/root/.ssh; \ in-target chmod 700 /target/root/.ssh; \ in-target chown root:root /target/root/.ssh; \ >>/target/root/.ssh/authorized_keys echo ssh-rsa [binary] cardno:18_042_835; \ >>/target/etc/ssh/sshd_config.d/root.conf echo PermitRootLogin prohibit-password; \ >>/target/etc/ssh/sshd_config.d/root.conf echo PasswordAuthentication no; \ >>/target/etc/ssh/sshd_config.d/root.conf echo PubkeyAuthentication yes; \ >>/target/etc/ssh/sshd_config.d/root.conf echo AuthorizedKeysFile .ssh/authorized_keys;将预设文件添加到Initrdchmod +w -R isofiles/install.amd/ gunzip isofiles/install.amd/initrd.gz echo preseed.cfg | cpio -H newc -o -A -F isofiles/install.amd/initrd gzip isofiles/install.amd/initrd chmod -w -R isofiles/install.amd/ 修改启动屏幕超时修改启动参数vim isofiles/isolinux/isolinux.cfg 默认超时为0,这表示一直等待到用户操作，这里超时改为5秒，表示5秒之后自动开始安装#timeout 0 timeout 5修改启动屏幕默认菜单默认菜单选项是图形化安装，这里取消默认，修改图形化安装菜单vim isofiles/isolinux/gtk.cfg将内容改成以下label installgui menu label ^Graphical install kernel /install.amd/vmlinuz append vga=788 initrd=/install.amd/gtk/initrd.gz --- quiet把文本安装改为默认菜单选项，修改文本安装菜单vim isofiles/isolinux/txt.cfg将内容改成以下default install label install menu label ^Install menu default kernel /install.amd/vmlinuz append vga=788 initrd=/install.amd/initrd.gz --- quiet timeout 300 ontimeout /install.amd/vmlinuz vga=788 initrd=/install.amd/initrd.gz --- quiet menu autoboot Press a key, otherwise txt auto install will be started in # second{,s}...删除默认30s倒计时启动项rm isofiles/isolinux/spkgtk.cfg重新生成md5sum.txtcd isofiles chmod +w md5sum.txt find -follow -type f ! -name md5sum.txt -print0 | xargs -0 md5sum > md5sum.txt chmod -w md5sum.txt cd ..创建新的可启动ISO镜像genisoimage -r -J -b isolinux/isolinux.bin -c isolinux/boot.cat -no-emul-boot -boot-load-size 4 -boot-info-table -o preseed-debian-12.1.0-amd64-netinst.iso isofiles此时已经制作好了全自动安装镜像，可以用虚拟机测试一下，测试成功则可以传到服务器上进行安装了。一键脚本在当前目录准备好 Debian 安装镜像，preseed.cfg配置文件，以及修改后的 gtk.cfg, txt.cfg, isolinux.cfg 文件，然后执行下面的脚本即可。#/bin/bash set -ex rm -rf isofiles xorriso -osirrox on -indev debian-12.1.0-amd64-netinst.iso -extract / isofiles chmod +w -R isofiles/install.amd/ gunzip isofiles/install.amd/initrd.gz echo preseed.cfg | cpio -H newc -o -A -F isofiles/install.amd/initrd gzip isofiles/install.amd/initrd chmod -w -R isofiles/install.amd/ cp ./isolinux.cfg isofiles/isolinux/isolinux.cfg cp ./gtk.cfg isofiles/isolinux/gtk.cfg cp ./txt.cfg isofiles/isolinux/txt.cfg rm isofiles/isolinux/spkgtk.cfg cd isofiles chmod +w md5sum.txt find -follow -type f ! -name md5sum.txt -print0 | xargs -0 md5sum > md5sum.txt chmod -w md5sum.txt cd .. genisoimage -r -J -b isolinux/isolinux.bin -c isolinux/boot.cat -no-emul-boot -boot-load-size 4 -boot-info-table -o preseed-debian-12.1.0-amd64-netinst.iso isofiles
关于 GPG 的基本概念，这里就不过多阐述了，没有基础知识的同学建议先学一些网络上的基础教程。要先对 GPG 有一定的基础理解。[scode type="yellow"]本文中生成的 GPG 密钥仅为示例使用，本人并不使用文中的密钥，请注意鉴别。[/scode]准备工作了解 GPG 基本概念，熟悉命令行操作安装好虚拟机或/和下载 Tails 系统镜像一颗追求信息安全的 ❤️核心思想平时只使用子密钥，将主密钥存储在受信的地方例如TPM或进行加密。创建主密钥首先创建一个新的 GPG 密钥对，一定要在虚拟机或者 Tails 或者你信任的电脑上操作。使用 --full-generate-key 和 --expert 来生成密钥对，由于 RSA4096 比 ECC Curve 25519 要安全一点，这里我们的主密钥使用 RSA4096，且只用来 Certify。rainshaw@ubuntu:~$ gpg --full-generate-key --expert gpg (GnuPG) 2.2.19; Copyright (C) 2019 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. Please select what kind of key you want: (1) RSA and RSA (default) (2) DSA and Elgamal (3) DSA (sign only) (4) RSA (sign only) (7) DSA (set your own capabilities) (8) RSA (set your own capabilities) (9) ECC and ECC (10) ECC (sign only) (11) ECC (set your own capabilities) (13) Existing key (14) Existing key from card Your selection? 8选择 8 自定义用途Possible actions for a RSA key: Sign Certify Encrypt Authenticate Current allowed actions: Sign Certify Encrypt (S) Toggle the sign capability (E) Toggle the encrypt capability (A) Toggle the authenticate capability (Q) Finished Your selection? s Possible actions for a RSA key: Sign Certify Encrypt Authenticate Current allowed actions: Certify Encrypt (S) Toggle the sign capability (E) Toggle the encrypt capability (A) Toggle the authenticate capability (Q) Finished Your selection? e Possible actions for a RSA key: Sign Certify Encrypt Authenticate Current allowed actions: Certify (S) Toggle the sign capability (E) Toggle the encrypt capability (A) Toggle the authenticate capability (Q) Finished Your selection? q去掉 Sign 签名、Encrypt 加密用途，只保留 Certify 证明用途。RSA keys may be between 1024 and 4096 bits long. What keysize do you want? (3072) 4096使用 4096位 RSA 密钥更安全，基本无法破解。Requested keysize is 4096 bits Please specify how long the key should be valid. 0 = key does not expire <n> = key expires in n days <n>w = key expires in n weeks <n>m = key expires in n months <n>y = key expires in n years Key is valid for? (0) Key does not expire at all Is this correct? (y/N) y设置密钥的有效期，我们可以仔细的存放主密钥，这里可以选择永不过期，当然你也可以自己选择有效期，当有效期临近时，再根据需求自行决定是启用新密钥还是将旧密钥延长有效期。GnuPG needs to construct a user ID to identify your key. Real name: Rainshaw Email address: xxxx@live.com Comment: You selected this USER-ID: "Rainshaw <xxxx@live.com>" Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? o输入你的个人信息，Comment 注释可以不填。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: key 0xF2FE7008B02578B4 marked as ultimately trusted gpg: directory '/home/rainshaw/.gnupg/openpgp-revocs.d' created gpg: revocation certificate stored as '/home/rainshaw/.gnupg/openpgp-revocs.d/B5C100450331878DD5535261F2FE7008B02578B4.rev' public and secret key created and signed. pub rsa4096/F2FE7008B02578B4 2021-08-16 [C] Key fingerprint = B5C1 0045 0331 878D D553 5261 F2FE 7008 B025 78B4 uid Rainshaw <xxxx@live.com>接着输入你主密钥的密码，建议使用从未使用过的且易记的密码，长度越长越好。[scode type="blue"]如果你之前使用过 GPG，你可能有疑问，密码越长之后使用的时候不会很繁琐么，每次都要输入。不要担心，后面会教给大家怎么解决这个问题，方法是给子密钥设置与主密钥不同的密码，一方面方便日常使用，另一方面也是对主密钥的进一步保护。[/scode]格式化密钥如果你观察仔细的话，会发现我最终打印出来的密钥格式和你可能不太一样，不要担心，这只是格式化，下面教给大家如何格式化密钥输出，懒癌福利。不论你用什么编辑器，只需在 ~/.gnupg/gpg.conf 文件中输入以下内容即可keyid-format long with-fingerprint这样之后输出密钥时就会自动打印密钥的长ID和指纹啦。创建子密钥刚刚生成的主密钥名为 F2FE7008B02578B4 ，它只有 [C] 用途，只能用来签发子密钥，为了满足日常使用我们需要新建三个子密钥，分别用来 Sign 签名、Encrypt 加密、Authenticate 认证。Sign 签名密钥使用 --expert 和 --edit-key F2FE7008B02578B4 （将其中的密钥 id 换成你的）。rainshaw@ubuntu:~$ gpg --expert --edit-key F2FE7008B02578B4 gpg (GnuPG) 2.2.19; Copyright (C) 2019 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. Secret key is available. 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 sec rsa4096/F2FE7008B02578B4 created: 2021-08-16 expires: never usage: C trust: ultimate validity: ultimate [ultimate] (1). Rainshaw <xxxx@live.com> gpg> addkey Please select what kind of key you want: (3) DSA (sign only) (4) RSA (sign only) (5) Elgamal (encrypt only) (6) RSA (encrypt only) (7) DSA (set your own capabilities) (8) RSA (set your own capabilities) (10) ECC (sign only) (11) ECC (set your own capabilities) (12) ECC (encrypt only) (13) Existing key (14) Existing key from card Your selection? 8选 8 自定义用途。Possible actions for a RSA key: Sign Encrypt Authenticate Current allowed actions: Sign Encrypt (S) Toggle the sign capability (E) Toggle the encrypt capability (A) Toggle the authenticate capability (Q) Finished Your selection? e Possible actions for a RSA key: Sign Encrypt Authenticate Current allowed actions: Sign (S) Toggle the sign capability (E) Toggle the encrypt capability (A) Toggle the authenticate capability (Q) Finished Your selection? q RSA keys may be between 1024 and 4096 bits long. What keysize do you want? (3072) 4096 Requested keysize is 4096 bits只保留 Sign 签名用途，并输入长度为 4096.Please specify how long the key should be valid. 0 = key does not expire <n> = key expires in n days <n>w = key expires in n weeks <n>m = key expires in n months <n>y = key expires in n years Key is valid for? (0) 1y Key expires at Tue 16 Aug 2022 02:52:10 AM PDT Is this correct? (y/N) y Really create? (y/N) y输入子密钥有效期，建议不要选择永久有效，当子密钥临近过期或已过期时，我们可以使用主密钥对子密钥进行延长有效期，这样可以进一步保证安全。[scode type="yellow"]当然这样之后会更加麻烦一些，比如你需要替换 GitHub 上的签名公钥等。[/scode]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. sec rsa4096/F2FE7008B02578B4 created: 2021-08-16 expires: never usage: C trust: ultimate validity: ultimate ssb rsa4096/0E45187E21327343 created: 2021-08-16 expires: 2022-08-16 usage: S [ultimate] (1). Rainshaw <xxx@live.com> gpg> save最后不要忘记使用 save 命令保存。此时再看一下现在的密钥：rainshaw@ubuntu:~$ gpg -K /home/rainshaw/.gnupg/pubring.kbx --------------------------------- sec rsa4096/F2FE7008B02578B4 2021-08-16 [C] Key fingerprint = B5C1 0045 0331 878D D553 5261 F2FE 7008 B025 78B4 uid [ultimate] Rainshaw <xxxx@live.com> ssb rsa4096/0E45187E21327343 2021-08-16 [S] [expires: 2022-08-16]Encrypt 加密密钥同样使用 --expert 和 --edit-key F2FE7008B02578B4 （将其中的密钥 id 换成你的）。rainshaw@ubuntu:~$ gpg --expert --edit-key F2FE7008B02578B4 gpg (GnuPG) 2.2.19; Copyright (C) 2019 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. Secret key is available. sec rsa4096/F2FE7008B02578B4 created: 2021-08-16 expires: never usage: C trust: ultimate validity: ultimate ssb rsa4096/0E45187E21327343 created: 2021-08-16 expires: 2022-08-16 usage: S [ultimate] (1). Rainshaw <xxxx@live.com> gpg> addkey Please select what kind of key you want: (3) DSA (sign only) (4) RSA (sign only) (5) Elgamal (encrypt only) (6) RSA (encrypt only) (7) DSA (set your own capabilities) (8) RSA (set your own capabilities) (10) ECC (sign only) (11) ECC (set your own capabilities) (12) ECC (encrypt only) (13) Existing key (14) Existing key from card Your selection? 12 Please select which elliptic curve you want: (1) Curve 25519 (3) NIST P-256 (4) NIST P-384 (5) NIST P-521 (6) Brainpool P-256 (7) Brainpool P-384 (8) Brainpool P-512 (9) secp256k1 Your selection? 1 Please specify how long the key should be valid. 0 = key does not expire <n> = key expires in n days <n>w = key expires in n weeks <n>m = key expires in n months <n>y = key expires in n years Key is valid for? (0) 1y Key expires at Tue 16 Aug 2022 03:06:34 AM PDT Is this correct? (y/N) y Really create? (y/N) y 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. sec rsa4096/F2FE7008B02578B4 created: 2021-08-16 expires: never usage: C trust: ultimate validity: ultimate ssb rsa4096/0E45187E21327343 created: 2021-08-16 expires: 2022-08-16 usage: S ssb cv25519/7A3B9781DAD1C286 created: 2021-08-16 expires: 2022-08-16 usage: E [ultimate] (1). Rainshaw <xxxx@live.com> gpg> save这里尝试使用 ECC 作为加密解密的算法，速度会更快一点。来源于博主 ulyc 的介绍：[scode type="share"]美国国家标准与技术研究院（NIST）系列椭圆曲线、Brainpool系列椭圆曲线、secp256k1都存在不同的安全风险，不建议使用。ECC算法比RSA的优势在于，在同等强度下，ECC的密钥长度要小的多，性能也会好一些。不提密钥长度说安全性都是耍流氓 ，RSA 4096 的安全强度是要 好于 ed25519 的。[/scode]Authenticate 认证密钥认证密钥用处不多，平时我们连 SSH 使用普通的 RSA 密钥就可以了，当然如果你愿意也可以用 GPG 生成的子密钥。同样使用 --expert 和 --edit-key F2FE7008B02578B4 （将其中的密钥 id 换成你的）。rainshaw@ubuntu:~$ gpg --expert --edit-key F2FE7008B02578B4 gpg (GnuPG) 2.2.19; Copyright (C) 2019 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. Secret key is available. sec rsa4096/F2FE7008B02578B4 created: 2021-08-16 expires: never usage: C trust: ultimate validity: ultimate ssb rsa4096/0E45187E21327343 created: 2021-08-16 expires: 2022-08-16 usage: S ssb cv25519/7A3B9781DAD1C286 created: 2021-08-16 expires: 2022-08-16 usage: E [ultimate] (1). Rainshaw <xxx@live.com> gpg> addkey Please select what kind of key you want: (3) DSA (sign only) (4) RSA (sign only) (5) Elgamal (encrypt only) (6) RSA (encrypt only) (7) DSA (set your own capabilities) (8) RSA (set your own capabilities) (10) ECC (sign only) (11) ECC (set your own capabilities) (12) ECC (encrypt only) (13) Existing key (14) Existing key from card Your selection? 8 Possible actions for a RSA key: Sign Encrypt Authenticate Current allowed actions: Sign Encrypt (S) Toggle the sign capability (E) Toggle the encrypt capability (A) Toggle the authenticate capability (Q) Finished Your selection? a Possible actions for a RSA key: Sign Encrypt Authenticate Current allowed actions: Sign Encrypt Authenticate (S) Toggle the sign capability (E) Toggle the encrypt capability (A) Toggle the authenticate capability (Q) Finished Your selection? s Possible actions for a RSA key: Sign Encrypt Authenticate Current allowed actions: Encrypt Authenticate (S) Toggle the sign capability (E) Toggle the encrypt capability (A) Toggle the authenticate capability (Q) Finished Your selection? e Possible actions for a RSA key: Sign Encrypt Authenticate Current allowed actions: Authenticate (S) Toggle the sign capability (E) Toggle the encrypt capability (A) Toggle the authenticate capability (Q) Finished Your selection? q RSA keys may be between 1024 and 4096 bits long. What keysize do you want? (3072) 4096 Requested keysize is 4096 bits Please specify how long the key should be valid. 0 = key does not expire <n> = key expires in n days <n>w = key expires in n weeks <n>m = key expires in n months <n>y = key expires in n years Key is valid for? (0) 1y Key expires at Tue 16 Aug 2022 03:12:10 AM PDT Is this correct? (y/N) y Really create? (y/N) y 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. sec rsa4096/F2FE7008B02578B4 created: 2021-08-16 expires: never usage: C trust: ultimate validity: ultimate ssb rsa4096/0E45187E21327343 created: 2021-08-16 expires: 2022-08-16 usage: S ssb cv25519/7A3B9781DAD1C286 created: 2021-08-16 expires: 2022-08-16 usage: E ssb rsa4096/4FFFC7DA1ABE8BE5 created: 2021-08-16 expires: 2022-08-16 usage: A [ultimate] (1). Rainshaw <xxx@live.com> gpg> save操作大同小异，不再赘述。导出密钥复习下我们的核心思想，主密钥必须存储在安全的地方或被加密，子密钥用来日常使用。为了安全，我们将不会存储主密钥的明文，虽然这个明文也被我们之前设置的密码保护着，但为了更加安全，我们再套一层（有点吃饱了撑的）。刚才我们已经生成了加密密钥，所以只要加密密钥被保护好，我们就可以使用加密密钥给主密钥套一层。导出公钥第一种是导出所有的公钥，常用于公开到特定服务器。rainshaw@ubuntu:~/Desktop$ gpg -ao pk.key --export F2FE7008B02578B4 rainshaw@ubuntu:~/Desktop$ cat pk.key -----BEGIN PGP PUBLIC KEY BLOCK----- mQINBGEaMF8BEADD1NPg6UCRKEjLnVjYvMWzz26YTRWXmgux58hcFp3u+UE/o3Ji eJiNtAGMXYWrvl1f/KhpUxQHKmZ+C30Jh1Vhk3Tu9POXDQb10BfBNtHIj3+Ei+3k 中间很长很长 XGyiVo7R4BCiGHekJk8+jqqu1YcRWlimHGgyBhYDvOg88qovp5+fBRpZWA3gRSm4 BOBkecuPQJ7tcdXz1a++eECgUBVdmvPT4yR9jEJRJSPNcVXSqw5G =VhBK -----END PGP PUBLIC KEY BLOCK-----[scode type="yello"]注意这个公钥仅用于示例，请不要将这个公钥和博主关联起来 (●'◡'●)[/scode]第二种是导出某个子密钥的公钥，常用于当有多个同一用途的密钥时指定密钥用。rainshaw@ubuntu:~/Desktop$ gpg -a --export --output pk.key F2FE7008B02578B4 File 'pk.key' exists. Overwrite? (y/N) y rainshaw@ubuntu:~/Desktop$ gpg -a --export --output pk.key F2FE7008B02578B4! File 'pk.key' exists. Overwrite? (y/N) N Enter new filename: pk2.key rainshaw@ubuntu:~/Desktop$ gpg -a --export --output pk-sign.key 0E45187E21327343! rainshaw@ubuntu:~/Desktop$ gpg -a --export --output pk-enc.key 7A3B9781DAD1C286! rainshaw@ubuntu:~/Desktop$ gpg -a --export --output pk-auth.key 4FFFC7DA1ABE8BE5!导出主密钥私钥使用子加密密钥加密主密钥，注意将下面命令的 Rainshaw 改为你之前设置的名字，如果含有空格的话需要在两端加引号。rainshaw@ubuntu:~/Desktop$ gpg -a --export-secret-key F2FE7008B02578B4 | gpg -e -r Rainshaw | dd of=sk.key 17+2 records in 17+1 records out 9095 bytes (9.1 kB, 8.9 KiB) copied, 5.82587 s, 1.6 kB/s [scode type="green"]你可以分步执行，看看每步到底做了什么。[/scode]导出子密钥私钥使用子加密密钥加密 Sign 和 Authenticate 密钥，注意将下面命令的 Rainshaw 改为你之前设置的名字，如果含有空格的话需要在两端加引号。同时一定要注意密钥ID一定要改，且感叹号（英文）不能省略！rainshaw@ubuntu:~/Desktop$ gpg -a --export-secret-subkeys 0E45187E21327343! | gpg -e -r Rainshaw | dd of=sign.key 8+2 records in 8+1 records out 4508 bytes (4.5 kB, 4.4 KiB) copied, 5.10913 s, 0.9 kB/s rainshaw@ubuntu:~/Desktop$ gpg -a --export-secret-subkeys 4FFFC7DA1ABE8BE5! | gpg -e -r Rainshaw | dd of=auth.key 7+2 records in 7+1 records out 3935 bytes (3.9 kB, 3.8 KiB) copied, 5.79333 s, 0.7 kB/s对于加密子密钥就不能再用加密子密钥加密了（禁止套娃）。对于上面生成的这些文件，我们可以随意上传、复制，只要我们保证自己的加密子密钥是安全的即可。现在问题来了，怎么存储加密子密钥呢？这里我也没有什么特别好的方法，我采用的是使用DES对称加密对GPG加密子密钥加密（好绕口。。。），这样能保证子密钥比不加密安全一丢丢。rainshaw@ubuntu:~/Desktop$ gpg -a --export-secret-subkeys 7A3B9781DAD1C286! | openssl des3 -salt | dd of=enc.key enter des-ede3-cbc encryption password: Verifying - enter des-ede3-cbc encryption password: *** WARNING : deprecated key derivation used. Using -iter or -pbkdf2 would be better. 5+1 records in 5+1 records out 2640 bytes (2.6 kB, 2.6 KiB) copied, 18.5623 s, 0.1 kB/s过程中会先让你输入 GPG 的密码，然后再输入一个对称加密的密码，建议这两个采用不同的值（由于前者就是主密钥的密码，很复杂，所以我们可以对其稍作改动作为后者，比如更换其中的数字、符号，或者将密码顺序颠倒之类的。）导出吊销证书gpg: key 0xF2FE7008B02578B4 marked as ultimately trusted gpg: directory '/home/rainshaw/.gnupg/openpgp-revocs.d' created gpg: revocation certificate stored as '/home/rainshaw/.gnupg/openpgp-revocs.d/B5C100450331878DD5535261F2FE7008B02578B4.rev' public and secret key created and signed. pub rsa4096/F2FE7008B02578B4 2021-08-16 [C] Key fingerprint = B5C1 0045 0331 878D D553 5261 F2FE 7008 B025 78B4 uid Rainshaw <xxxx@live.com>在创建主密钥的同时，GPG 为我们生成了一个主密钥的吊销证书，位于 .gnupg/openpgp-revocs.d/ 目录下。我们需要对其更加精心备份和保护，为什么呢，因为如果你主密钥没丢，而这个吊销证书丢了，那你的主密钥就可能被攻击者吊销，这样一来，你对主密钥的精心保护还有啥用呢？这里偷个懒，使用的是之前生成的加密密钥。rainshaw@ubuntu:~/Desktop$ cat ~/.gnupg/openpgp-revocs.d/B5C100450331878DD5535261F2FE7008B02578B4.rev | gpg -e -r Rainshaw | dd of=rev.key 2+2 records in 2+1 records out 1376 bytes (1.4 kB, 1.3 KiB) copied, 0.00671809 s, 205 kB/s如果你追求更安全，那我建议你再生成一个 Encrypt 加密密钥，不导出它，只用它来加密这个吊销证书，这样只有在你的主密钥泄露之后，才有可能泄露这个吊销证书，而这时我们肯定是要吊销的，所以安全度很高。由于此时你的库中有两个加密密钥，导致在进行加密时会自动选择加密密钥（一般会用较新的），此时为了指定加密密钥，我们需要采用与上文不同的命令。rainshaw@ubuntu:~/Desktop$ gpg -K /home/rainshaw/.gnupg/pubring.kbx --------------------------------- sec rsa4096/F2FE7008B02578B4 2021-08-16 [C] Key fingerprint = B5C1 0045 0331 878D D553 5261 F2FE 7008 B025 78B4 uid [ultimate] Rainshaw <xxx@live.com> ssb rsa4096/0E45187E21327343 2021-08-16 [S] [expires: 2022-08-16] ssb cv25519/7A3B9781DAD1C286 2021-08-16 [E] [expires: 2022-08-16] ssb rsa4096/4FFFC7DA1ABE8BE5 2021-08-16 [A] [expires: 2022-08-16] ssb cv25519/82A36E1B874BE22B 2021-08-16 [E] [expires: 2022-08-16] rainshaw@ubuntu:~/Desktop$ gpg -a --export --output pk-enc2.key 82A36E1B874BE22B! rainshaw@ubuntu:~/Desktop$ cat ~/.gnupg/openpgp-revocs.d/B5C100450331878DD5535261F2FE7008B02578B4.rev | gpg -e -f pk-enc2.key | dd of=rev.key 2+2 records in 2+1 records out 1379 bytes (1.4 kB, 1.3 KiB) copied, 0.00649605 s, 212 kB/s[scode type="red"]如果你刚刚生成了一个新的加密子密钥，记得重新导出主密钥！[/scode]rainshaw@ubuntu:~/Desktop$ gpg -a --export-secret-key F2FE7008B02578B4 | gpg -e -f pk-enc.key | dd of=sk2.key 18+3 records in 19+1 records out 9774 bytes (9.8 kB, 9.5 KiB) copied, 6.38228 s, 1.5 kB/s[scode type="yellow"]注意这里使用的是第一个加密密钥！[/scode]传输文件好，到目前为止，我们生成了几个非常安全的文件，他们可以随意分发上传（但建议还是不要随意分发），之后每次使用时只需将所需的私钥文件下载然后解密安装即可。此时如果你使用虚拟机启动 Tails OS 作为生成密钥的系统，那你可能会发现好像无法把子密钥从虚拟机中复制出来，这就很蛋疼了，我的解决方法是在客户端电脑上开设一个 SSH Server，在 Tails 中使用 SCP 命令将文件传输出来，具体命令大家可以自行百度。如果你使用的是非虚拟机运行的 Tails OS，那你可以插入一个新的U盘存储这些文件。如果你是其他的情况，请自行解决。销毁原文件当你把上述文件成功传输出来之后，根据不同的情况，你可能需要销毁原始的密钥文件。如果是虚拟机，那你可以直接删除虚拟机即可，如果是 Tails 可以使用鼠标右键点击 .gnupg 文件夹然后选择 wipe 即可，如果是其他情况，请自行搜索擦除文件的方法。导入密钥导入密钥是十分简单的，首先对加密密钥进行解密，然后导入rainshaw@ubuntu:~/Desktop$ openssl des3 -d -in enc.key | gpg --import enter des-ede3-cbc decryption password: *** WARNING : deprecated key derivation used. Using -iter or -pbkdf2 would be better. gpg: key F2FE7008B02578B4: public key "Rainshaw <xxx@live.com>" imported gpg: To migrate 'secring.gpg', with each smartcard, run: gpg --card-status gpg: key F2FE7008B02578B4: secret key imported gpg: Total number processed: 1 gpg: imported: 1 gpg: secret keys read: 1 gpg: secret keys imported: 1然后利用这个加密密钥对你在某个机器上所要使用的子密钥进行解密然后导入如要导入签名密钥：rainshaw@ubuntu:~/Desktop$ gpg -d sign.key | gpg --import gpg: encrypted with 256-bit ECDH key, ID 7A3B9781DAD1C286, created 2021-08-16 "Rainshaw <xxx@live.com>" gpg: key F2FE7008B02578B4: "Rainshaw <xxx@live.com>" 1 new signature gpg: key F2FE7008B02578B4: "Rainshaw <xxx@live.com>" 1 new subkey gpg: To migrate 'secring.gpg', with each smartcard, run: gpg --card-status gpg: key F2FE7008B02578B4: secret key imported gpg: Total number processed: 1 gpg: new subkeys: 1 gpg: new signatures: 1 gpg: secret keys read: 1 gpg: secret keys imported: 1如要导入认证密钥：rainshaw@ubuntu:~/Desktop$ gpg -d auth.key | gpg --import gpg: encrypted with 256-bit ECDH key, ID 7A3B9781DAD1C286, created 2021-08-16 "Rainshaw <xxx@live.com>" gpg: key F2FE7008B02578B4: "Rainshaw <xxx@live.com>" 1 new signature gpg: key F2FE7008B02578B4: "Rainshaw <xxx@live.com>" 1 new subkey gpg: To migrate 'secring.gpg', with each smartcard, run: gpg --card-status gpg: key F2FE7008B02578B4: secret key imported gpg: Total number processed: 1 gpg: new subkeys: 1 gpg: new signatures: 1 gpg: secret keys read: 1 gpg: secret keys imported: 1修改信任级别由于我们导入的证书并不是生成的，所以其信任级别为未知，需要修改信任级别rainshaw@ubuntu:~/Desktop$ gpg --expert --edit-key Rainshaw gpg (GnuPG) 2.2.19; Copyright (C) 2019 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. Secret subkeys are available. pub rsa4096/F2FE7008B02578B4 created: 2021-08-16 expires: never usage: C trust: unknown validity: unknown ssb cv25519/7A3B9781DAD1C286 created: 2021-08-16 expires: 2022-08-16 usage: E ssb rsa4096/0E45187E21327343 created: 2021-08-16 expires: 2022-08-16 usage: S ssb rsa4096/4FFFC7DA1ABE8BE5 created: 2021-08-16 expires: 2022-08-16 usage: A [ unknown] (1). Rainshaw <xxx@live.com> gpg> trust pub rsa4096/F2FE7008B02578B4 created: 2021-08-16 expires: never usage: C trust: unknown validity: unknown ssb cv25519/7A3B9781DAD1C286 created: 2021-08-16 expires: 2022-08-16 usage: E ssb rsa4096/0E45187E21327343 created: 2021-08-16 expires: 2022-08-16 usage: S ssb rsa4096/4FFFC7DA1ABE8BE5 created: 2021-08-16 expires: 2022-08-16 usage: A [ unknown] (1). Rainshaw <xxx@live.com> Please decide how far you trust this user to correctly verify other users' keys (by looking at passports, checking fingerprints from different sources, etc.) 1 = I don't know or won't say 2 = I do NOT trust 3 = I trust marginally 4 = I trust fully 5 = I trust ultimately m = back to the main menu Your decision? 5 Do you really want to set this key to ultimate trust? (y/N) y pub rsa4096/F2FE7008B02578B4 created: 2021-08-16 expires: never usage: C trust: ultimate validity: unknown ssb cv25519/7A3B9781DAD1C286 created: 2021-08-16 expires: 2022-08-16 usage: E ssb rsa4096/0E45187E21327343 created: 2021-08-16 expires: 2022-08-16 usage: S ssb rsa4096/4FFFC7DA1ABE8BE5 created: 2021-08-16 expires: 2022-08-16 usage: A [ unknown] (1). Rainshaw <xxx@live.com> Please note that the shown key validity is not necessarily correct unless you restart the program. gpg> quit rainshaw@ubuntu:~/Desktop$ gpg -K 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 /home/rainshaw/.gnupg/pubring.kbx --------------------------------- sec# rsa4096/F2FE7008B02578B4 2021-08-16 [C] Key fingerprint = B5C1 0045 0331 878D D553 5261 F2FE 7008 B025 78B4 uid [ultimate] Rainshaw <xxx@live.com> ssb cv25519/7A3B9781DAD1C286 2021-08-16 [E] [expires: 2022-08-16] ssb rsa4096/0E45187E21327343 2021-08-16 [S] [expires: 2022-08-16] ssb rsa4096/4FFFC7DA1ABE8BE5 2021-08-16 [A] [expires: 2022-08-16]修改密码[scode type="yellow"]这个方法是在 GnuPG 2.2 的时候测试通过的，GnuPG 2.3 实测已无法只修改子密钥密码。[/scode]上面提到过，我们在生成主密钥时使用了一个非常非常不常用、非常非常复杂的密码，在上面的操作中，我们几乎每个操作都要输入至少一次这个密码，很不方便。这里教给大家如何修改子密钥的密码。如果你搜索 gpg subkey change passphrase 这些关键词的话，你会看到很多帖子说 GPG 无法实现这种需求，但在我实际操作后发现，虽然给子密钥修改密码会提示错误，但实际密码是修改成功了的。首先我们在机器上导入需要的子密钥，如上面操作就可，注意一定不要导入主密钥！！！然后我们直接修改密码：rainshaw@ubuntu:~/Desktop$ gpg --expert --edit-key Rainshaw gpg (GnuPG) 2.2.19; Copyright (C) 2019 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. Secret subkeys are available. pub rsa4096/F2FE7008B02578B4 created: 2021-08-16 expires: never usage: C trust: ultimate validity: ultimate ssb cv25519/7A3B9781DAD1C286 created: 2021-08-16 expires: 2022-08-16 usage: E ssb rsa4096/0E45187E21327343 created: 2021-08-16 expires: 2022-08-16 usage: S ssb rsa4096/4FFFC7DA1ABE8BE5 created: 2021-08-16 expires: 2022-08-16 usage: A [ultimate] (1). Rainshaw <xxx@live.com> gpg> passwd gpg: key F2FE7008B02578B4/F2FE7008B02578B4: error changing passphrase: No secret key gpg> save Key not changed so no update needed.注意到我们完成修改密码操作后虽然提示我们error changing passphrase，但你可以测试一下，密码是修改成功了的！导入主密钥[scode type="yello"]一定不要跳着看！！否则功亏一篑！！[/scode]当你完成上面的步骤后，此时如果机器是你信任的或者有TPM芯片或智能卡设备的话，你可以选择导入主密钥：rainshaw@ubuntu:~/Desktop$ gpg -d sk2.key | gpg --import gpg: encrypted with 256-bit ECDH key, ID 7A3B9781DAD1C286, created 2021-08-16 "Rainshaw <xxx@live.com>" gpg: key F2FE7008B02578B4: "Rainshaw <xxx@live.com>" 1 new signature gpg: key F2FE7008B02578B4: "Rainshaw <xxx@live.com>" 1 new subkey gpg: key F2FE7008B02578B4: secret key imported gpg: Total number processed: 1 gpg: new subkeys: 1 gpg: new signatures: 1 gpg: secret keys read: 1 gpg: secret keys imported: 1 gpg: secret keys unchanged: 1此时你可以发现主密钥的密码和子密钥的密码是不同的，我们能够很好的保护主密钥的同时，减少我们日常使用时的麻烦。如果有 TPM 芯片可以在 --edit-key 时，使用 keytotpm 命令，将密钥转移到 TPM 芯片上，博主未尝试，请自行测试。如果有智能卡设备如 YubiKey ，则可以使用 keytocard 命令。常见问题与解答是否应该上传自己的公钥到公钥服务器上？根据博主 ulyc 的博客，不推荐将公钥上传到公钥服务器上，除非你真的需要。该博主的博客里列举了公钥服务器的诸多问题，如滥用、投毒、签名Dos、爆破、隐私问题。如何公布自己的公钥？我们应该多途径、分散的公开自己的公钥，并在信任公钥时先确认指纹是否正确。你可以将公钥发布到 GitHub、个人博客、社交软件、公开论坛中。补充使用PGP为git commit 签名打开终端，运行$ gpg -K --keyid-format=long /Users/hubot/.gnupg/secring.gpg ------------------------------------ sec 4096R/3AA5C34371567BD2 2016-03-10 [C] uid Hubot ssb 4096R/42B317FD4BA89E7A 2016-03-10 [S]找到你要用的 GPG 密钥 ID，上面的这个示例中为 42B317FD4BA89E7A。然后设置 Git$ git config --global user.signingkey 42B317FD4BA89E7A $ git config --global commit.gpgsign true第一行是告诉 Git 用哪个密钥进行签名，第二行是告诉 Git 每次 commit 的时候自动签名，如果不加第二行，在每次 commit 时需要增加 -S 参数才会签名。[scode type="green"] 不要忘了把公钥上传到 GitHub 。 [/scode]使用PGP 进行SSH[scode type="blue"] 关于服务端如何启用密钥登陆，请自行查找教程，这里只介绍如何配置本地电脑。 [/scode]Win10CMD[post url="https://lab.jinkan.org/2021/08/01/using-gpg-for-ssh-authentication-on-windows-10/" title="在 Windows 10 上用 GPG 完成 SSH 认证" cover="https://lab.jinkan.org/wp-content/themes/kagami-master/assets/images/fallback_cover.jpg" /]Git Bash[scode type="blue"] 网上教程很多，我配置了好几次都没成功，最后按照下面这个步骤成功了，有很多注意事项。 [/scode][scode type="yellow"] 这个教程说不要用 CRLF 要用 LF，在 Win10 上你可以用 vscode 来设置换行符，设置的地方在 vscode 的右下角。 [/scode]首先，新建文件 ~/.gnupg/gpg.conf 内容如下，最后不要换行：$ cat ~/.gnupg/gpg.conf use-agent然后创建 ~/.gnupg/gpg-agent.conf 文件，内容如下，同样最后不要换行：$ cat ~/.gnupg/gpg-agent.conf enable-ssh-support然后创建 ~/.gnupg/sshcontrol 文件，内容如下，不要换行：$ gpg -K --with-keygrip sec rsa2048 2019-03-21 [C] [expires: 2021-03-20] 96F33EA7F4E0F7051D75FC208715AF32191DB135 Keygrip = 90E08830BC1AAD225E657AD4FBE638B3D8E50C9E uid [ultimate] Brian Exelbierd ssb rsa2048 2019-03-21 [E] [expires: 2021-03-20] Keygrip = 5FA04ABEBFBC5089E50EDEB43198B4895BCA2136 ssb rsa2048 2019-03-21 [A] Keygrip = 7710BA0643CC022B92544181FF2EAC2A290CDC0E $ cat ~/.gnupg/sshcontrol 7710BA0643CC022B92544181FF2EAC2A290CDC0E然后修改终端配置文件：$ cat .bashrc export GPG_TTY=$(tty) export SSH_AUTH_SOCK=$(gpgconf --list-dirs agent-ssh-socket) echo UPDATESTARTUPTTY | gpg-connect-agent 1> /dev/null重启终端。然后重启 gpg-agent， 注意每次修改配置后，都要执行这一步（不过一般这种东西配置一次也就够了）。$ gpg-connect-agent killagent /bye OK closing connection $ gpg-connect-agent /bye gpg-connect-agent: no running gpg-agent - starting 'C:\Program Files (x86)\Gpg4win\..\GnuPG\bin\gpg-agent.exe' gpg-connect-agent: waiting for the agent to come up ... (5s) gpg-connect-agent: connection to agent established然后检查你的配置是否成功：$ ssh-add -L # 这里会打印出你的公钥如果打印出你的公钥，如果没有输出说明还没有配置好，如你确定是按照本教程一步步做的，那可能本教程已过时，请再搜寻。将公钥传递到服务器端便可使用 GPG 认证密钥进行 SSH 登陆了！Linux(以 Ubuntu 为例)首先导入对应的私钥，然后启用 gpg-agent 接替 ssh-agent 处理 SSH 请求：cat enable-ssh-support >> ~/.gnupg/gpg-agent.conf然后指定我们要使用的密钥：$ gpg -K --with-keygrip sec rsa2048 2019-03-21 [C] [expires: 2021-03-20] 96F33EA7F4E0F7051D75FC208715AF32191DB135 Keygrip = 90E08830BC1AAD225E657AD4FBE638B3D8E50C9E uid [ultimate] Brian Exelbierd ssb rsa2048 2019-03-21 [E] [expires: 2021-03-20] Keygrip = 5FA04ABEBFBC5089E50EDEB43198B4895BCA2136 ssb rsa2048 2019-03-21 [A] Keygrip = 7710BA0643CC022B92544181FF2EAC2A290CDC0E $ echo 7710BA0643CC022B92544181FF2EAC2A290CDC0E >> ~/.gnupg/sshcontrol注意替换上面的 7710BA0643CC022B92544181FF2EAC2A290CDC0E 为你所要用的。然后我们修改默认的 SSH 工具：$ cat ~/.bashrc ... export SSH_AUTH_SOCK=$(gpgconf --list-dirs agent-ssh-socket) gpgconf --launch gpg-agent ...也就是将这两行加入到你的终端配置文件中，接下来你需要重启终端才能生效。此时你可以检查你的配置是否正确：$ ssh-add -L # 这里会打印出你的公钥将公钥传递到服务器端便可使用 GPG 认证密钥进行 SSH 登陆了！清理 PGP 密码缓存Linux:$ gpgconf --kill gpg-agentWindows:$ echo "RELOADAGENT" | gpg-connect-agent
问题在 centos 7 上面运行 django 3.2 开发服务器时出现：django.core.exceptions.ImproperlyConfigured: SQLite 3.8.3 or later is required (found 3.7.17).原因时系统自带 sqlite3 版本太低，解决方法是升级就可以了。升级由于 Centos 7 的 yum 源中 sqlite 版本过低，无法直接 yum update，所以才取编译升级。# 下载源码 wget https://www.sqlite.org/2021/sqlite-autoconf-3360000.tar.gz # 编译 tar zxvf sqlite-autoconf-3360000.tar.gz cd sqlite-autoconf-3360000 ./configure --prefix=/usr/local make && make install # 替换系统低版本 sqlite3 mv /usr/bin/sqlite3 /usr/bin/sqlite3_old ln -s /usr/local/bin/sqlite3 /usr/bin/sqlite3 echo "/usr/local/lib" > /etc/ld.so.conf.d/sqlite3.conf ldconfig sqlite3 -version再次启动运行 django 开发服务器就 ok 了。
在Django3中使用 pathlib.Path 生成 BASE_DIR 时，Pycharm 无法找到 静态文件
问题描述Django 从 3.1 版本开始，在 setting.py 文件中默认使用 pathlib 生成 BASE_DIR，而 pycharm 很久前就被人报告在支持 pathlib 有 bug，详见以下链接https://stackoverflow.com/questions/64036715/django-pycharm-2020-2-2-not-resolving-static-files-when-using-pathlib-path-tohttps://youtrack.jetbrains.com/issue/PY-45244https://youtrack.jetbrains.com/issue/PY-13911https://youtrack.jetbrains.com/issue/PY-46523解决方案[scode type="blue"]截至目前（2021年2月13日pycharm2020.3.3）pycharm仍未修复此bug[/scode]将 STATICFILES_DIRS 写成如下形式即可STATICFILES_DIRS = [ BASE_DIR / 'static', './static/' ]
Kitty 简介Kitty is an open-source modular and extensible fuzzing framework written in python, inspired by OpenRCE’s Sulley and Michael Eddington’s (and now Deja Vu Security’s) Peach Fuzzer.Kitty 是一个 python 版本的模糊测试框架。其目标是帮助模糊测试特定的受害者。受害者通常运行于非TCP/IP通道上的私有和内部协议。特性模块性：fuzzer的每一个部分都是独立的，这意味着你能够用相同的监视代码监控不同的程序，用相同的载荷生成工具（aka Data Model）生成的数据可以在不同的信道中传递；扩展性：如过你想测试新的东西，不需要修改Kitty的核心代码。即便不是所有，大部分功能应该在用户代码中实现。这包括监视，控制以及和被fuzz的目标的通信；丰富的数据模型：数据模型的核心要丰富，能够描述高级的数据结构，包括字符串，哈希，长度，条件及其它。而且和其它框架一样，还要设计好，将来需要的时候可以扩展；状态性：支持多阶段的模糊测试。不仅要能描述单独消息的载荷应该是什么样，还要能描述消息的顺序，甚至按照顺序进行fuzzing；客户端和服务端fuzzing：假设你有一个配对的程序栈，你可以对服务端和客户端进行fuzz。这听起来是一个很高的要求，但实际上不是：只需要你像通常一样能够和目标通信即可；跨平台：可以在Linux，OS X和Windows上运行。框架结构kitty 主要架构如下图所示：Fuzzer +--- Model *--- Template *--- Field | +--- Target +--- Controller | | | *--- Monitor | +--- InterfaceFuzzerFuzzer 是最高级的控制结构，由三部分组成 Interface(可视化)、Target(控制被测试的对象)、Model(数据模型)。Fuzzer 从 Model 获取改变后的数据，执行数据交换，从 Target 获取测试报告，在需要时执行更多的操作。一般我们采用自底向上的构造方法，即最后配置 Fuzzer。根据被测试对象的属性，我们可以分别使用 ClientFuzzer 和 ServerFuzzer. Fuzzer 类常用 api：set_model(model) 为 Fuzzer 设置数据模型set_target(target) 为 Fuzzer 设置控制结构set_interface(interface) 为 Fuzzer 设置可视化start() 开始模糊测试stop() 结束模糊测试set_delay_between_test(delay_secs) 设置测试之间的间隙Model数据模型定义了 Fuzzer 要发送的消息的结构。 通常将消息分成几个部分（如头部、长度、负载），并包含这几部分的类型（如字符串、校验码、十六进制编码的32位整数）和这些部分之间的关系。此外，数据模型还描述了不同消息被联系起来形成模糊会话的顺序。数据模型还可以指定模糊发送消息的顺序。TargetTarget 模块负责管理与受测者有关的一切。其主要功能包括：管理 Monitors 和 Controller当受测者是一个 server 时，Target 模块通过向服务器发送请求并处理服务器可能返回的响应来启动模糊会话。当受测者是一个 client 时，Target 模块通过使客户端向服务器发起请求来启动模糊会话。服务器在stack的帮助下将向 client 发送一个模糊的响应。Target 类常用 api:set_controller(controller) 为 Target 设置控制器add_monitor(monitor) 为 Target 添加一个监控器ControllerController 负责将受测者控制到合适的状态以做好测试的准备。 Controller 也需要执行基本的监控，并需要报告受测者是否准备好进行下一次测试。MonitorMonitor 监控受测者的行为，它可以监控网络流量、内存消耗、串行输出或者其它任何内容。kitty.monitors 包提供了基本的监视器类 BaseMonitor，一般需要对其进行继承而不要直接实例化。继承了 BaseMonitor 的子类，建议对以下函数进行继承：__init__() 函数应先调用父类的构造函数进行初始化setup() 函数应对子类新增的变量进行配置后再调用父类的setup函数_monitor_func()函数会在setup函数调用并在新线程内进行无限循环直至发送终止命令，所以此函数一般用来进行数据收集teardown() 函数应对子类新增变量进行清理工作，并调用父类构造函数pre_test() 函数应先调用父类函数再对子类新增变量进行每次测试前的初始化post_test() 函数应对收集到的数据进行处理生成报告，并调用父类构造函数在每次测试前，应对上次收集到的数据进行清理防止上次测试结束时数据清理工作不彻底，一般来说直接将私有变量初始化即可。每次测试后进行数据分析，然后也应对收集到的数据进行清理。启动过程分析一次模糊会话的测试过程主要由以下几步组成定义测试过程中发送给受测者的数据模型model实例化Controller子类实例化一系列Monitor子类实例化Target子类为 Target 设置 controller，并增加 monitors实例化Fuzzer类为Fuzzer设置model和target执行Fuzzer.start()开始测试执行Fuzzer.stop()停止测试对 Fuzzer.start() 进行分析这里只对受测者是server时进行分析进入 serverFuzzer.start()进行初始化工作打印start消息日志执行 target.setup()执行 controller.setup()对所有的monitor执行setup()进行环境测试执行 _start()进入循环，循环终止判断条件为_next_mutation()函数返回值根据model获取sequence执行_run_sequence(sequence)执行_check_pause()等待用户命令执行_pre_test()执行target.pre_test()执行 controller.pre_test()执行 monitor.pre_test()根据 sequence 里的数据执行 _transmit() 函数执行target.transmit()函数发送数据执行 _send_to_target()函数发送数据如果需要等待response并返回执行_post_test()执行target.post_test()执行controller.post_test()执行monitor.pre_test()生成报告获得报告进行报告分析打印end消息日志
前言由于之前一直玩黑苹果，老黄的显卡只能停留在 High Sierra 系统，所以我一直用的 AMD 的显卡 Vega 56，最近由于期末大作业要炼丹，不得不说 AI 届 A 卡无人权，几乎完全都是老黄 CUDA 的天下，老黄这一手提前布局，高啊。正值双十一和双十二的时期，本来打算入手一枚 3070 或 3080，但无奈，当猴当的太称职了，抢了好久都没有买到，只能用已有的显卡炼丹了。要用 A 卡炼丹，只能用 ROCm，但 ROCm 支持的框架很少，不过幸好 Tensorflow 是有社区分支支持的。在配置环境过程踩了不少坑，这里记录一下。安装 ROCm先给出官方文档地址更新系统安装依赖sudo apt update sudo apt dist-upgrade sudo apt install libnuma-dev sudo reboot重启后继续执行下一步添加 ROCm 的 ppa repowget -q -O - https://repo.radeon.com/rocm/rocm.gpg.key | sudo apt-key add - echo 'deb [arch=amd64] https://repo.radeon.com/rocm/apt/debian/ xenial main' | sudo tee /etc/apt/sources.list.d/rocm.list更新源并安装 rocm-dkmssudo apt update sudo apt install rocm-dkms源速度较慢，这里建议挂代理sudo vi /etc/apt/apt.conf.d/proxy.conf Acquire{ HTTP::proxy "http://127.0.0.1:1080"; HTTPS::proxy "https://127.0.0.1:1080"; }装好后记得删掉设置权限sudo usermod -a -G video $LOGNAME sudo usermod -a -G render $LOGNAME sudo reboot必须要重启！添加 ROCm 环境变量echo 'export PATH=$PATH:/opt/rocm/bin:/opt/rocm/rocprofiler/bin:/opt/rocm/opencl/bin' | sudo tee -a /etc/profile.d/rocm.sh sudo reboot测试/opt/rocm/bin/rocminfo /opt/rocm/opencl/bin/x86_64/clinfo你应该可以从结果中看到你的显卡安装 tensorflow-rocm同样，先给出官方文档地址首先就是在系统上安装 python 环境，随你喜欢就行，你可以用 conda 也可以用 pyenv 当然直接用系统自带的 python3 也可以创建符合 tensorflow 的虚拟环境，建议 python3.7安装依赖包sudo apt update sudo apt isntall rocm-libs miopen-hip rccl安装 tensorflow-rocmpip install tensorflow-rocm测试import tensorflow as tf tf.__version__ tf.test.is_gpu_available()可能遇到的错误添加 ROCm 的 ppa repo 时wget -q -O - http://repo.radeon.com/rocm/apt/debian/rocm.gpg.key | sudo apt-key add - echo 'deb [arch=amd64] http://repo.radeon.com/rocm/apt/debian/ xenial main' | sudo tee /etc/apt/sources.list.d/rocm.list不要自作聪明的把 xenial 改成 bionic重启出现 HSA_STATUS_ERROR_OUT_OF_RESOURCESFailed to get user name to check for video group membership hsa api call failure at: /data/jenkins_workspace/compute-rocm-rel-2.9/rocminfo/rocminfo.cc:1102 Call returned HSA_STATUS_ERROR_OUT_OF_RESOURCES: The runtime failed to allocate the necessary resources. This error may also occur when the core runtime library needs to spawn threads or create internal OS-specific events.相关 ISSUE ： https://github.com/RadeonOpenCompute/ROCm/pull/1005血红血红的。而且第一句特别蠢，怎么连用户名也没拿到啊（实际上这句话没什么影响）？这种情况下 clinfo 也无法执行，但是 rocm-smi 仍旧完全正常。根据上面那个 ISSUE 的说法，是用户组问题。我看也是。这个 ISSUE 关联的 Pull Request 中修改了 README.md ，提供了一套解决方法： https://github.com/RadeonOpenCompute/ROCm/pull/1005/files 但我测试并没有效果。我是怎么解决的呢？我翻遍了 Google 前三页都没解决，然后在 CSDN 上看到了一句话： sudo 一下试试。sudo rocminfo （其实这样是没有环境变量的，所以一开始应该是 sudo /opt/rocm/bin/rocminfo）……成了。天知道为什么可以，我的 root 肯定不在 video 组，更不要说上面 ISSUE 认为需要的 render 组了。反正今后 sudo su 就能用。何乐而不为啊！在 apt install rocm-dkms 过程中出现 Error! Bad return status for module build on kernelBuilding initial module for 5.3.0-46-generic Error! Bad return status for module build on kernel: 5.3.0-46-generic (x86_64) Consult /var/lib/dkms/amdgpu/3.3-19/build/make.log for more information.啥事都没有，放心好了。这个 log 又长又什么都看不出来。 ROCm 也安装好了也能用。忽略就行。至少我这行。官方 amdgpu / amdgpu-pro 驱动安装卸载相关问题这其实是一个根本不存在的问题，尤其是如果你从全新系统开始。 ROCm 是不需要提前手动装其他驱动的。不必要提前安装驱动。不是 docker 版本不需要提前屏蔽驱动。但是！也不能没有驱动。 ROCm 需要有一个 amdgpu 驱动在运行。屏蔽驱动的方法是：sudo vim /etc/modprobe.d/blacklist.conf #: blacklist amdgpu sudo vim /etc/modprobe.d/blacklist-radeon.conf #: blacklist radeon # 这一行也可以手动直接写在上面的文件，但是如果安装过官方驱动，就会自动创建这个文件告诉你这个是为了让你明白……不要屏蔽驱动。如果不知道什么情况下屏蔽了就去注释掉。不过如果你不知道为什么装过其中一个驱动，你就会在后面 sudo apt install rocm-dkms 的时候碰到：dpkg: error processing archive /var/cache/apt/archives/rock-dkms_1.8-151_all.deb (--unpack): trying to overwrite '/usr/share/dkms/modules_to_force_install/amdgpu', which is also in package amdgpu-dkms 18.10-572953 dpkg-deb: error: subprocess paste was killed by signal (Broken pipe)去网上搜一圈这里会有教你强制 overwrite 的。但恕我对 dpkg 一窍不通，我觉得并没有什么用。还是建议直接把驱动卸载掉。官方驱动安装方法以 Radeon VII 为例（应该都大同小异），VII 驱动下载地址 ，下载后 tar xf amdgpu-*-ubuntu-18.04.tar.xz 解压然后 cd amdgpu* 进入文件夹。如果你要安装普通版驱动，那么 ./amdgpu-install 。不需要提前 sudo ，后面会叫你输入密码的。如果是 Pro 驱动，那么 ./amdgpu-pro-install 就好了。就是这么简单，快捷，以及人性化。 AMD 万岁。……要是真的话就好了。官方驱动强制卸载方法这个脚本有一万种情况可以出错然后喊你用 amdgpu-uninstall / amdgpu-pro-uninstall 命令或者直接在安装脚本后面加 --uninstall 命令来清理不正确的安装否则就完全不能继续，包括但不限于你挂了代理（是的，以我个人经验，建议请务必在下载 rocm 的时候打开 apt 代理，而同时务必在安装驱动（不，你根本就不应该装，除非……你是为了完整的安装以便卸载干净它……）的时候关掉代理）， apt 缓存的包有问题，编译哪里掉了链子以及其他一切。虽然几率其实不高，但是一旦发生了 ……你会遇到这种错误：You might want to run 'apt --fix-broken install' to correct these. The following packages have unmet dependencies: amdgpu-dkms : Depends: amdgpu-core but it is not going to be installed amdgpu-lib-hwe : Depends: amdgpu-core (= 19.30-934563) but it is not going to be installed amdgpu-pro-core : Depends: amdgpu-core but it is not going to be installed gst-omx-amdgpu : Depends: amdgpu-core but it is not going to be installed libdrm-amdgpu-common : Depends: amdgpu-core but it is not going to be installed libdrm2-amdgpu:i386 : Depends: amdgpu-core:i386 libdrm2-amdgpu : Depends: amdgpu-core but it is not going to be installed libegl1-amdgpu-mesa:i386 : Depends: amdgpu-core:i386 libegl1-amdgpu-mesa : Depends: amdgpu-core but it is not going to be installed libgbm1-amdgpu:i386 : Depends: amdgpu-core:i386 libgbm1-amdgpu : Depends: amdgpu-core but it is not going to be installed ... E: Unmet dependencies. Try 'apt --fix-broken install' with no packages (or specify a solution).（有人会叫你 sudo dpkg -i --force-overwrite /var/cache/apt/archives/rock-dkms_2.10-14_all.deb ）还有这种错误：dpkg: error processing package amdgpu (--remove): dependency problems - not removing Errors were encountered while processing: amdgpu还有前面提过的 overwrite 错误：Preparing to unpack .../libdrm-amdgpu-common_1.0.0-633530_all.deb ... Unpacking libdrm-amdgpu-common (1.0.0-633530) ... dpkg: error processing archive /var/opt/amdgpu-pro-local/./libdrm-amdgpu-common_1.0.0-633530_all.deb (--unpack): trying to overwrite '/opt/amdgpu/share/libdrm/amdgpu.ids', which is also in package ids-amdgpu 1.0.0-606296 Errors were encountered while processing: /var/opt/amdgpu-pro-local/./libdrm-amdgpu-common_1.0.0-633530_all.deb（参考 askubuntu post ）…… 还有长成各种各样的。这不重要，总而言之，最为行之有效的解决方案是 StackExchange 的 某个帖子 藏在评论区的某个角落里的方法：sudo apt-get install synaptic是的你没看错，就是传说中的 新 立 德 。GUI，打开！ Edit > Fix Broken Packages ！然后在 Package 列表中用 Broken 过滤器，全部 Mark Completion Removal ！这还没完，去列表里定位 amdgpu 或者 amdgpu-pro ，刚才出错的是那个就右键 Mark for Installation 哪个，记得点顶上的 Apply ，安装！这可比 amdgpu-install 那脚本好使多了。吭哧吭哧安装上了，很好。那么，可以愉快的 amdgpu-install --uninstall 了…… （是的，这个安装不会在命令行添加 amdgpu-uninstall 命令）报 apt lock 冲突的话别忘记把 synaptic gui 关掉啊。elementrary 或者其他野鸡 OS 适配一个无足轻重的小问题。稍有常识的人都能自己想到的凑字数段落。如果安装脚本报告 Unsupported DEB-based OS: elementary ，那么用一个你趁手的编辑器打开脚本，搜索 ubuntu|linuxmint|debian 并改成 ubuntu|linuxmint|debian|elementary 。其他系统同理。
最近由于临近期末，开始做各种大作业，其中有一个炼丹项目，我就再次回到了 ubuntu 。这里记录一下各种压缩文件的压缩和解压的命令。.tar.tar 文件功能：对文件目录进行打包备份（仅打包不压缩）# 解包 $tar -xvf filename.tar # 打包目录 $tar -cvf filename.tar dirname.gz.gz 文件压缩# 解压 $gunzip filename.gz # 或 $gzip -d filename.gz # 压缩文件 $gzip filename.tar.gz .tgz# 解压 $tar -zxvf filename.tar.gz # 压缩目录 $tar -zcvf filename.tar.gz dirname # 解压到目录 $tar -C dirname -zxvf filename.tar.gz.bz2# 压缩文件 $bzip2 -zk filename # 解压 $bunzip2 filename.bz2 # 或 $bzip2 -d filename.bz2.tar.bz2# 解压 $tar -jxvf filename.tar.bz.Z# 解压 $ uncompress filename.Z # 压缩 $comporess filename.tar.Z# 解压 $ tar -Zxvf filename.tar.Z # 压缩 $ tar -Zcvf filename.tar.Z dirname.rar# 解压 $rar x filename.rar # 压缩 $rar a filename.rar dirname.zip# 解压 $unzip -O cp936 filename.zip # 压缩目录 $zip filename.zip dirname # 递归压缩 $zip -r filename.zip dirname[scode type="blue"]欢迎留言补充[/scode]
[scode type="red"]应原插件作者的要求, 本插件已下架.[/scode][collapse status="false" title="下架"]前言Handsome从 v7.3.1 开始支持 Vditor 这一 Markdown 解析器，但 CodePrettify 插件作者一直没有给出与 Vditor 兼容的方法，我之前魔改过一些地方使得两者能够共存，参见[post cid="85" /]但仍然存在一些小的问题，于是萌生了自己做一个代码语法高亮插件的想法，便有了 MacHighlight简介从插件的名字可以看出来，本插件主要是 Mac 风格的高亮样式，如果您有其他需求，可以自行定制 （其实直接将 CodePrettify 的 css 样式拷贝过来就能用，但为了减少兼容工作量，我这里就仅对三个 Mac 风格做兼容工作了）MacHighlight 是一款基于 prismjs 的代码语法高亮插件，支持众多常见的代码语言高亮显示，共提供3种代码高亮风格自由切换，支持显示代码语言类型、行号，以及支持复制代码到剪切板功能，需魔改 Handsome 以使得与 Vditor 兼容。使用方法前往Releases 下载最新版本插件解压后重命名文件夹为 MacHighlight ，再上传至网站的 /usr/plugins/ 目录下启用插件，选择喜欢的样式替换 /usr/themes/handsome/assets/css/handsome.min.css 和/usr/themes/handsome/assets/js/core.min.js文件，相关文件在下方给出。刷新 CDN 缓存，清除浏览器缓存，或者点击 Handsome 插件中的更新离线缓存按钮。下载[scode type="yellow"]仅针对 Handsome v7.3.1 版本进行了测试，如您遇到样式问题，请留言反馈，并附加演示地址。（评论区未启用 Markdown 解析，直接填写网站链接或截图链接即可）[/scode]举例[scode type="green"]绿色提示[/scode]php 代码正常高亮：\```php(语言类型必填) <?php echo 'hello jrotty!'; ?> \``` 删除上边代码中的\流程图正常渲染：sequenceDiagram participant Sender participant Receiver Receiver ->> Receiver: start, create files Sender ->> Sender: start loop send message Sender ->> Sender: read char, visit int(char) files Sender ->> Receiver: send the char(char) Receiver ->> Receiver: count visited files end Sender ->> Sender: end Receiver ->> Receiver: end致谢本插件样式代码来自 @Xcnte 大佬的 CodePrettify 插件，在此表示感谢🙏其他如您遇到样式问题或其他问题，均可在下方留言给出，记得附带演示地址哦～[/collapse]
Handsome 主题解决 CodePrettify 代码高亮插件与 Vditor 兼容问题
[scode type="red"]本文内容可能已经过期，或存在部分bug，新方法参见[/scode][post cid="89" /]前言CodePrettify 是一款基于prismjs的代码语法高亮typecho插件，支持众多常见的代码语言高亮显示，共提供11种代码高亮风格自由切换，支持显示代码语言类型、行号，以及支持复制代码到剪切板功能。Handsome 是友人C为 typecho开发的一款主题，Handsome最新版本引入了Vditor这一Markdown解析器，支持了许多新的语法。而据 CodePrettify 作者 Xcnte 的描述，近期内他不考虑做 Vditor.js的兼容，如果要用 CodePrettify 这一插件的话，就要使用 typecho 自带的 markdown 解析器。这样也就无法使用新解析器带来的诸多特性了。这对我来说简直无法忍受，于是花费了一些时间，做了下兼容工作。兼容方法启用 CodePrettify 插件，并进行相应配置（一定要设置成显示行号！）。删除原作者让您添加到主题插件中的 Pjax 回调函数。替换 /usr/themes/handsome/assets/css/handsome.min.css 和/usr/themes/handsome/assets/js/core.min.js文件，相关文件在下方给出。刷新 CDN 缓存，清除浏览器缓存，或者点击 Handsome 插件中的更新离线缓存按钮。下载[scode type="yellow"]仅针对 Handsome v7.3.1 版本进行了测试，如您遇到样式问题，请留言反馈，并附加演示地址。（评论区未启用 Markdown 解析，直接填写网站链接或截图链接即可）[/scode]举例\```php(语言类型必填) <?php echo 'hello jrotty!'; ?> \``` 删除上边代码中的\
前不久写了一篇如何在使用 Cloudflare 加速时获取用户的真实 IP[post cid="79" /]由于本博客域名已经备案，于是我使用的是 Cloudflare 国内合作商——百度云加速，为网站提供加速服务，整体使用感觉还不错。百度云加速免费版套餐每天 10G 流量，完全够使用，并且支持 cname 接入，很方便。不过仍然存在着和使用 Cloudflare 一样的问题，即网站的访问日志中都是百度云加速的 IP 地址，并不是客户的真实 IP 地址，这里给出解决办法。解决办法服务器使用的是宝塔面板编译安装的 nginx，默认编译了 gx_http_realip_module 模块，所以只需要到 /www/server/nginx/conf 目录下新建一个名为 baidusu.conf的文件，并将以下内容写入：set_real_ip_from 119.188.9.0/24; set_real_ip_from 42.236.93.0/24; set_real_ip_from 220.170.185.0/24; set_real_ip_from 115.231.186.0/25; set_real_ip_from 183.232.51.0/24; set_real_ip_from 61.182.137.0/25; set_real_ip_from 112.25.90.0/24; set_real_ip_from 59.51.81.128/26; set_real_ip_from 222.216.190.0/24; set_real_ip_from 122.190.2.0/24; set_real_ip_from 125.39.239.0/24; set_real_ip_from 183.61.177.0/24; set_real_ip_from 183.61.236.0/24; set_real_ip_from 124.95.168.128/26; set_real_ip_from 124.95.191.0/24; set_real_ip_from 58.211.2.0/24; set_real_ip_from 117.34.13.0/24; set_real_ip_from 150.138.150.0/24; set_real_ip_from 150.138.149.128/25; set_real_ip_from 157.255.25.0/24; set_real_ip_from 113.207.101.0/25; set_real_ip_from 111.32.135.0/25; set_real_ip_from 42.81.6.0/25; real_ip_header X-Forwarded-For;然后到 nginx 的配置文件中，在 http 模块下添加一行 include baidusu.conf 即可。