用 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 证书的上传。

Read More

在 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 就可以了:

Read More

各种 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.

Read More

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 的状态。

Read More

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 内核里的一个数据结构。

Read More

MIFARE Classic 上配置 NDEF

背景 最近买了一堆 NFC 的智能卡拿来测试,其中一张 MIFARE Classic 的总是在 iOS 上读不出来,无论是以 Tag 模式还是 NDEF 模式。于是通过一系列的研究,终于知道上怎么一回事,然后成功地把一个 MIFARE Classic 卡配置成了 NDEF。 背景知识 NFC 有很多协议,其中 MIFARE Classic 基于 ISO 14443-3 Type A 标准,里面有一些 MIFARE 的命令。通过这些命令,就可以控制 MIFARE Classic 卡的内容。具体来说,以我使用的 MIFARE Classic EV1 4K S70 为例,这篇文章会涉及到如下的背景知识: MIFARE Classic 内存布局 在 MIFARE Classic 中,有 Sector 和 Block 的概念,每个 Sector 有若干个 Block,其中最后一个 Block 是特殊的(称为 Sector Trailer),保存了这个 Sector 的一些信息:Key A、Access Bits、GPB 和 Key B。对于 Classic 4K,首先是 32 个有 4 blocks 的 sector,然后是 8 个 有 16 blocks 的 sector, 整体的内存布局大概是:

Read More

解释 BB84 协议

背景 这周密码学课程,来自 BUPT 的高飞老师讲了一下 qkd 里的 BB84 协议,老师讲得很好,我也想记录一下这个协议的流程和方法。我不是这方面的专业人士,如果有什么问题请指出。 背景知识 QKD(Quantum Key Distribution)目的是让通信双方获得同一个密钥,它需要同时需要量子信道和经典信道。其中经典信道被认为是可信的,它可以被监听,但不能被中间人攻击。 在 BB84(Charles H. Bennett and Gilles Brassard (1984))协议中,传输的是一个光子,它具有如下的特性: 可以用两个基去测量光子:➕️和✖️️,然后光子有四个偏振角度,分别是 ⬆️️ ⬇️️ ↘️️ ↗️️。定义一个二进制位和偏振角度的对应关系如下: 位 0 1 0 1 基 ➕️ ➕️ ✖️️ ✖️️ 偏振角度 ⬆️️ ⬇️️ ↗️️ ↘️️ 对于一个未知光子,可以用两种基进行测量,测量的结果: 偏振角度 ⬆️️ ⬇️️ ↗️️ ↘️️ 用➕️测量 0 1 0/1 0/1 用✖️️测量 0/1 0/1 0 1 这里的 0/1 表示有 50% 概率测得 0,有 50% 概率测得 1 。

Read More

在 k8s 中部署 code-server

实验了一下在 k8s 中部署 code-server,并不复杂,和之前几篇博客的配置是类似的: apiVersion: extensions/v1beta1 kind: Deployment metadata: name: code labels: app: code spec: selector: matchLabels: app: code replicas: 1 template: metadata: labels: app: code spec: volumes: - name: code-volume persistentVolumeClaim: claimName: code-pvc initContainers: - name: home-init image: busybox command: ["sh", "-c", "chown -R 1000:1000 /home/coder"] volumeMounts: - mountPath: "/home/coder" name: code-volume containers: - image: codercom/code-server:latest imagePullPolicy: Always name: code volumeMounts: - mountPath: "/home/coder" name: code-volume resources: limits: cpu: "0.

Read More

在 k8s 中部署 Drone 用于 CI

实验了一下在 k8s 中部署 CI,在 drone gitlab-ci 和 jenkins 三者中选择了 drone,因为它比较轻量,并且基于 docker,可以用 GitHub 上的仓库,比较方便。 首先,配置 helm: helm repo add drone https://charts.drone.io kubectl create ns drone 参考 drone 的文档,编写 drone-values.yml: ingress: enabled: true annotations: kubernetes.io/ingress.class: "nginx" cert-manager.io/cluster-issuer: "letsencrypt-prod" hosts: - host: drone.example.com paths: - "/" tls: - hosts: - drone.example.com secretName: drone-tls env: DRONE_SERVER_HOST: drone.example.com DRONE_SERVER_PROTO: https DRONE_USER_CREATE: username:YOUR_GITHUB_USERNAME,admin:true DRONE_USER_FILTER: YOUR_GITHUB_USERNAME DRONE_RPC_SECRET: REDACTED DRONE_GITHUB_CLIENT_ID: REDACTED DRONE_GITHUB_CLIENT_SECRET: REDACTED 需要首先去 GitHub 上配置 OAuth application,具体参考 drone 的文档。然后,生成一个 secret,设置 admin 用户并只允许 admin 用户使用 drone,防止其他人使用。然后应用:

Read More

在 k8s 内用 Cert Manager 配合 Nginx Ingress Controller 配置 Let's Encrypt HTTPS 证书

上一篇博客讲了 nginx ingress 的配置,那自然第一步要配上 https。首先配置 cert-manager: $ kubectl create namespace cert-manager $ kubectl apply --validate=false -f https://github.com/jetstack/cert-manager/releases/download/v0.14.1/cert-manager.crds.yaml $ helm repo add jetstack https://charts.jetstack.io $ helm repo update $ helm install \ cert-manager jetstack/cert-manager \ --namespace cert-manager \ --version v0.14.1 然后,配置 Cluster Issuer,应用以下的 yaml: apiVersion: cert-manager.io/v1alpha2 kind: ClusterIssuer metadata: name: letsencrypt-prod namespace: cert-manager spec: acme: email: example@example.com server: https://acme-v02.api.letsencrypt.org/directory privateKeySecretRef: name: letsencrypt-prod solvers: - http01: ingress: class: nginx 然后在 ingress 里面进行配置:

Read More