之前在另一篇文章里提到过 vCSA 的安装,这次又在另一台机器上重新做了一遍,特此记录一下。 首先在官网上下载 ESXi+VCSA 7.0 ,应该得到两个文件: 7.9G VMware-VCSA-all-7.0.1-16860138.iso 358M VMware-VMvisor-Installer-7.0U1-16850804.x86_64.iso 首先安装 ESXi,用 UNetBootin 制作 ESXi 的安装光盘。注意不能用 dd,因为它是 CDFS 格式的,不能直接 boot。启动以后,按照界面要求,一路安装即可。 接着,就可以用网页访问 ESXi 进行配置。比如安装一些 Linux 发行版,然后在 Linux 虚拟机里面 mount 上面的 VCSA 的 iso: sudo mount /dev/sr0 /mnt 接着,复制并修改 /mnt/vcsa-cli-installer/templates/install/embedded_vCSA_on_ESi.json,按照代码注释进行修改。需要注意几点: 密码都可以设为空,然后运行 cli 的时候输入 ESXi 的密码和 vCSA 的密码是不一样的 可以把 ceip 关掉,设置 ceip_enabled: false 接着,进行安装: /mnt/vcsa-cli-installer/lin64/vcsa-deploy install --accept-eula /path/to/customized.json -v 慢慢等待它安装成功即可。 安装完成后,进入 vCSA,新建一个 Datacenter,然后选择新建的 Datacenter,选择 Add host,输入 ESXi 的地址和用户密码信息即可。
IBM Power S822LC(8335-GTB) BMC 升级
背景 最近拿到一台 IBM Power S822LC(8335-GTB)机器的访问权限,这也是我第一次碰 ppc64le 指令集的服务器。然后发现,它的 BMC 版本比较老,我想连接 Remote Control 失败了,原因是 JViewer 不支持 macOS,我就想着能不能升级一下。 升级过程 首先,在网上找了一下文档,首先用 ipmitool 找一下机器型号: $ sudo ipmitool fru print 3 Chassis Type : Unknown Chassis Part Number : 8335-GTB Chassis Serial : REDACTED 可以看到,这台机器是 8335-GTB 型号,按照这个型号在 Fix Central 上搜索,可以找到若干个版本的 firmware,其中最老的版本是 OP8_v1.11_2.1,对比了一下,和原来的版本一致: $ sudo ipmitool fru print 47 Product Name : OpenPOWER Firmware Product Version : IBM-garrison-ibm-OP8_v1.11_2.1 Product Extra : op-build-da02863 Product Extra : buildroot-81b8d98 Product Extra : skiboot-5.
在 arm64 上使用 rust-analyzer
远程到 arm64 的机器上进行开发,发现没有 rust-analyzer 的支持。研究了一下,发现在 rustup 里面可以找到,不过要配置一下: > rustup toolchain add nightly > rustup component add --toolchain nightly rust-analyzer-preview 这个时候,应该可以找到 ~/.rustup/toolchains/nightly-aarch64-unknown-linux-gnu/bin/rust-analyzer 文件,接下来,配置 VSCode 插件即可: { "rust-analyzer.serverPath": "~/.rustup/toolchains/nightly-aarch64-unknown-linux-gnu/bin/rust-analyzer" } 路径在 ~/.vscode-server/data/Machine/settings.json。 参考:https://github.com/rust-analyzer/rust-analyzer/issues/5256
在 Rpi4 上运行 buildroot
背景 需要给 rpi 配置一个 pxe 的最小环境,在上一篇博文了提到可以用 alpine,但发现有一些不好用的地方,所以试了试 buildroot。 PXE 设置和路由器设置 见“在 Rpi4 上运行 Alpine Linux”文章。 Buildroot 配置 下载 buildroot: > wget https://buildroot.org/downloads/buildroot-2020.08.tar.gz > unar buildroot-2020.08.tar.gz > cd buildroot-2020.08 > make raspberrypi4_64_defconfig 然后运行 make menuconfig ,在 Filesystem images 中打开 initramfs,并设置 cpio 压缩为 gz。然后直接编译: > make -j4 $ ls -al target/images bcm2711-rpi-4-b.dtb* boot.vfat Image rootfs.cpio rootfs.cpio.gz rootfs.ext2 rootfs.ext4@ rpi-firmware/ sdcard.img 接着,在一个单独的目录里,把这些文件整理一下 > cd ~/rpi-buildroot > cp -r ~/buildroot-2020.08/output/images/rpi-firmware/* . > cp ~/buildroot-2020.08/output/images/bcm2711-rpi-4-b.dtb .
在 rpi4 上用 PXE 运行 Alpine Linux
背景 需要给 rpi 配置一个 pxe 的最小环境,然后看到 alpine 有 rpi 的支持,所以尝试给 rpi4 配置 alpine。 PXE 设置 第一步是设置 rpi4 的启动模式,打开 BOOT UART 并且打开 网络启动: > cd /lib/firmware/raspberrypi/bootloader/critical > rpi-eeprom-config pieeprom-2021-04-29.bin > config.txt $ cat config.txt [all] BOOT_UART=1 WAKE_ON_GPIO=1 POWER_OFF_ON_HALT=0 DHCP_TIMEOUT=45000 DHCP_REQ_TIMEOUT=4000 TFTP_FILE_TIMEOUT=30000 TFTP_IP= TFTP_PREFIX=0 BOOT_ORDER=0x1 SD_BOOT_MAX_RETRIES=3 NET_BOOT_MAX_RETRIES=5 [none] FREEZE_VERSION=0 > sed 's/BOOT_UART=0/BOOT_UART=1/;s/BOOT_ORDER=0x1/BOOR_ORDER=0x12/' config.txt > config-pxe.txt > rpi-eeprom-config --out pieeprom-2021-04-29-pxe.bin --config config-pxe.txt pieeprom-2021-04-29.bin > rpi-eeprom-update -d -f pieeprom-2021-04-29-pxe.bin > reboot 重启以后,可以用 vcgencmd bootloader_config 查看当前的启动配置,看是否正确地更新了启动配置。比较重要的是 BOOT_ORDER,0x12 表示先尝试网络启动,再尝试 SD 卡启动。
用 certbot 申请 route53 上的域名的 LetsEncrypt 证书并上传到 IAM
最近遇到了 AWS Certificate Manager 的一些限制,所以只能用 IAM 证书。于是上网找到了通过 certbot 申请 LE 证书,通过 route53 API 验证的方法。 首先配置 aws 的 credential。然后,按照 certbot: pip3 install -U certbot certbot_dns_route53 然后,就可以申请证书了: certbot certonly --dns-route53 --config-dir "./letsencrypt" --work-dir "./letsencrypt" --logs-dir "./letsencrypt" -d example.com --email a@b.com --agree-tos 如果申请成功,在当前目录下可以找到证书。然后上传到 IAM: aws iam upload-server-certificate --server-certificate-name NameHere \ --certificate-body file://letsencrypt/live/example.com/cert.pem \ --private-key file://letsencrypt/live/example.com/privkey.pem \ --certificate-chain file://letsencrypt/live/example.com/chain.pem \ --path /cloudfront/ 如果要用于 cloudfront,才需要最后的路径参数;否则可以去掉。这样就完成了 IAM 证书的上传。
在 k8s 中部署 Prometheus
实验了一下在 k8s 中部署 Prometheus,因为它和 k8s 有比较好的集成,很多 App 能在 k8s 里通过 service discovery 被 Prometheus 找到并且抓取数据。实践了一下,其实很简单。 用 helm 进行配置: helm upgrade --install prometheus stable/prometheus 这样就可以了,如果已经有 StorageClass(比如腾讯云的话,CBS 和 CFS),它就能自己起来了,然后在 Lens 里面也可以看到各种 metrics 的可视化。 如果是自建的单结点的 k8s 集群,那么还需要自己创造 PV,并且把 PVC 绑定上去。我采用的是 local 类型的 PV: apiVersion: v1 kind: PersistentVolume metadata: name: pv-volume-1 labels: type: local spec: storageClassName: manual capacity: storage: 10Gi accessModes: - ReadWriteOnce hostPath: path: "/srv/k8s-data-1" --- apiVersion: v1 kind: PersistentVolume metadata: name: pv-volume-2 labels: type: local spec: storageClassName: manual capacity: storage: 10Gi accessModes: - ReadWriteOnce hostPath: path: "/srv/k8s-data-2" 这样,结点上的两个路径分别对应两个 PV,然后只要让 PVC 也用 manual 的 StorageClass 就可以了:
各种 ecc 曲线
背景知识 椭圆曲线有如下的形式: 第一种: $$E: y^2 \equiv x^3 + ax + b \mod{p}$$ 曲线的参数共有 \((p, a, b, G, n, h)\)。\(G\) 是一个点 \((G_x, G_y)\),\(n\) 是 \(G\) 的阶。 第二种: $$E: y^2+xy=x^3+ax^2+1$$ 称为 Kbolitz curve。不同的曲线有不同的参数 \((m,f(x),a,b,G,n,h)\),对应不同的 \(GF(2^m)\) 域。 OpenSSL 看一下 openssl 支持的曲线参数(openssl ecparam -list_curves): secp112r1 : SECG/WTLS curve over a 112 bit prime field secp112r2 : SECG curve over a 112 bit prime field secp128r1 : SECG curve over a 128 bit prime field secp128r2 : SECG curve over a 128 bit prime field secp160k1 : SECG curve over a 160 bit prime field secp160r1 : SECG curve over a 160 bit prime field secp160r2 : SECG/WTLS curve over a 160 bit prime field secp192k1 : SECG curve over a 192 bit prime field secp224k1 : SECG curve over a 224 bit prime field secp224r1 : NIST/SECG curve over a 224 bit prime field secp256k1 : SECG curve over a 256 bit prime field secp384r1 : NIST/SECG curve over a 384 bit prime field secp521r1 : NIST/SECG curve over a 521 bit prime field prime192v1: NIST/X9.
FIDO U2F、FIDO2 和 CTAP 的关系
背景 2012 年,Yubico 和 Google 设计了 U2F 协议,第二年 U2F 成为 FIDO 组织的标准,之后加入了 NFC 的支持。之后,FIDO2 作为替代 U2F 的新标准产生,原来的 U2F 以兼容的方式成为了 CTAP1,而采用 CBOR 封装格式的 CTAP(CTAP2) 则是 FIDO2 的主要协议。 U2F 命令格式 U2F 定义了它的命令格式,基于 ISO7816-4 APDU(short APDU) : CLA INS P1 P2 Lc data Le 1 byte 1 byte 1 byte 1 byte 0-1 bytes variable length 0-1 bytes 比如 U2F_VERSION 就是: CLA INS P1 P2 Lc data Le 00 03 00 00 0 empty 00 返回的数据就是 U2F_V2 的 ASCII 加上 9000 的状态。
USB/IP 模拟 USB 设备
背景 2018 年的时候发过一篇博客,讲如何用 USB/IP 协议在两台 Linux 电脑之间共享 USB 设备。最近刚好有一个需求,就是针对一个现成的 USB device 的代码,通过 USB/IP 模拟出一个 USB 设备,然后进行调试。 USB/IP 协议 USB/IP 只有一个简略的文档,为数不多的使用 USB/IP 的代码,所以有一些细节没有说的很清楚,只能一点点去尝试。 首先,USB/IP 基于 TCP,端口号 3240。客户端向服务端发送请求,服务端向客户端进行回应。 请求的类型:OP_REQ_DEVLIST OP_REQ_IMPORT USBIP_CMD_SUBMIT 和 USBIP_CMD_UNLINK 回应的类型:OP_REP_DEVLIST OP_REP_IMPORT USBIP_RET_SUBMIT USBIP_RET_UNLINK 工作的过程大概如下: OP_REQ_DEVLIST 请求获取设备列表 OP_REP_DEVLIST 返回设备列表 OP_REQ_IMPORT 请求 USB 设备 OP_REP_IMPORT 返回 USB 设备 USBIP_CMD_SUBMIT 发送 URB USBIP_RET_SUBMIT 返回 URB (先不考虑 CMD_UNLINK 和 RET_UNLINK) 其中前面四个比较简单清晰,所需要的字段也都是 Descriptor 中对应的字段。后面两个就相对复杂一些:URB data 的长度需要根据 endpoint 类型和 direction 共同决定。URB 实际上是 Linux 内核里的一个数据结构。