分类: 没用的知识

  • 为阿里云 RDS MySQL 开启 SSL,并使用自签证书

    最近发现阿里云 99 计划的数据库,竟然包含香港地区,于是又冲动消费了。整了一个给 K3s 玩,试试它的 HA 模式。不过现有的节点很多都不在阿里云内网,需要开放数据库的公网访问才可以。开放数据库公网访问必然要开启 SSL 了,不然数据直接在公网上面明文传输十分危险。

    问题

    一开始我直接在阿里云 RDS 控制台上启用 SSL,使用默认的云端证书,然后先用 Grafana 去尝试连接,发现无法成功校验证书,报错:

    Error: ✗ failed to connect to database: tls: failed to verify certificate: x509: certificate relies on legacy Common Name field, use SANs instead

    猜测默认的云端证书只有在 Common Name 字段带上了数据库连接地址,而 Go 1.15 之后需要从 Subject Alternative Names 中进行校验,综合考虑后决定使用自签证书。

    自签证书

    平时 OpenSSL 用得不多,于是直接使唤 AI 干活:

    openssl genpkey -algorithm RSA -out ca-key.pem
    openssl req -new -x509 -key ca-key.pem -out ca-cert.pem -days 3650 -subj "/CN=MySQL CA"
    
    openssl genpkey -algorithm RSA -out server-key.pem
    openssl req -new -key server-key.pem -out server-req.pem -subj "/CN=rm-foo.mysql.rds.aliyuncs.com"
    openssl x509 -req -in server-req.pem -CA ca-cert.pem -CAkey ca-key.pem -CAcreateserial -out server-cert.pem -days 3650 -extfile <(printf "subjectAltName=DNS:rm-foo.mysql.rds.aliyuncs.com")

    然后在 RDS 控制台上传生成的服务端证书就可以了。

    在 Grafana 上配置

    我们需要先将上面生成的 CA 证书先挂载到 Grafana 容器中,然后参考官方文档进行配置,使其可以经由 TLS 连接数据库。

    我的 Grafana 是使用官方的 Helm Chart 部署的,其提供了一个可以注入 ConfigMap 的配置项,因此我们先创建一个包含了 CA 的 ConfigMap:

    apiVersion: v1
    kind: ConfigMap
    metadata:
      creationTimestamp: null
      name: grafana-database-tls-ca
      namespace: monitoring
    data:
      certificates.crt: |
        -----BEGIN CERTIFICATE-----
        -----END CERTIFICATE-----

    然后在 values.yaml 中配置挂载它:

    extraConfigmapMounts:
      - name: database-tls-ca
        mountPath: /etc/grafana/ssl/
        subPath: certificates.crt
        configMap: grafana-database-tls-ca
        readOnly: true

    这样的话,CA 就已经被挂载到 Grafana 容器中了。接下来我们需要配置 Grafana 以开启 TLS,同样,这里也是在 values.yaml 中配置就行。

    grafana.ini:
      database:
        type: mysql
        host: rm-foo.mysql.rds.aliyuncs.com
        ssl_mode: true
        ssl_sni: rm-foo.mysql.rds.aliyuncs.com
        server_cert_name: rm-foo.mysql.rds.aliyuncs.com
        ca_cert_path: /etc/grafana/ssl
        user: $__file{/etc/secrets/grafana-database/username}
        password: $__file{/etc/secrets/grafana-database/password}

    如果配置没有问题的话,此时执行更新之后应该就可以了。

    在 K3s 上配置

    同样,官方文档给出了配置项。我们需要先把刚才的 CA 证书复制到 K3s server 服务器上,然后修改启动脚本。

    curl -sfL https://get.k3s.io | INSTALL_K3S_EXEC="--flannel-backend=wireguard-native --disable=servicelb --disable=traefik --disable=metrics-server" \
            sh -s - server \
            --datastore-endpoint="mysql://username:password@tcp(host:3306)/database" \
            --datastore-cafile="/usr/local/share/ca-certificates/mysql.crt" \
            --flannel-external-ip \
            --node-ip 1.2.3.4 \
            --kubelet-arg=node-ip=0.0.0.0

    因为配置变化,安装脚本会更新配置并重启 K3s。如果配置没有问题,K3s 会正常启动。

    后记

    强制指定用户使用加密连接

    如果全部的工作负载已经迁移至 TLS 连接,那么我们就可以配置数据库特定用户必须使用加密连接。

    ALTER USER k3s@'%' REQUIRE SSL;
    FLUSH PRIVILEGES;

    配置生效之后,我们可以重启工作负载进行验证。

    为什么不通过一些 workaround 来使用默认的云端证书

    为了行文的连贯性,我把这段放到了这里。你可能会想到几个问题:

    Q:为什么不直接 skip-verify?省得折腾半天。

    A:不安全,这不是我的风格。而且根据 K3s 文档,其至今仍然暂时无法跳过证书检查。虽然 K3s 的数据库读写垫片 kine 项目已经有人实现了 skip-verify 选项并且已经合入主干+发布,但是当下等待 K3s 支持还早,感兴趣的可以看下面的链接。

    k3s can’t utilize tls option with mysql external database · Issue #1093 · k3s-io/k3s · GitHub

    Add support for TLS skip verification by tuxillo · Pull Request #306 · k3s-io/kine · GitHub

    Q:为什么不使用 GODEBUG=x509ignoreCN=0 环境变量使其可以校验 CN 而不是 SANs?

    A:Go 从 1.15 开始校验 SANs 而不是 CN,从 1.17 开始将会移除这个选项,出于长远考虑我不会这么做。

    x509: certificate relies on legacy Common Name field, use SANs or temporarily enable Common Name matching with GODEBUG=x509ignoreCN=0 · Issue #775 · rancher/rke2 · GitHub

    引用

    Configure Grafana | Grafana documentation

    Cluster Datastore | K3s

    certificates – Provide subjectAltName to openssl directly on the command line – Information Security Stack Exchange

    How do I use SANs with openSSL instead of common name? – Stack Overflow

  • 使用 FFmpeg 将内嵌字幕文件渲染到视频上

    最近有需要在即时通讯软件上传输视频文件,但是多数聊天软件在预览视频时,通常都不支持加载内嵌的字幕文件。考虑到要发给非技术型用户,能让对方直接在移动端预览,而不是跳转使用外部播放器会更方便一下。

    一番搜索下来发现官方文档里给出了这种场景下的案例:

    ffmpeg -i input.mkv -filter_complex "[0:v][0:s]overlay[v]" -map "[v]" -map 0:a <output options> output.mkv

    这里稍加修改,然后加上硬件编解码来加速重编码:

    .\ffmpeg-6.1.1-full_build-shared\bin\ffmpeg.exe -hwaccel cuda -i <input-video-path> -filter_complex "[0:v][0:s]overlay[v]" -map "[v]" -map 0:a -c:v hevc_nvenc -preset slow -profile:v main10 -pix_fmt p010le <output-video-path>

    引用

    HowToBurnSubtitlesIntoVideo – FFmpeg

    cuda – Understanding pixel format and profile when encoding 10-bit video in ffmpeg with nvenc – Super User

    video – How to use GPU to accelerate the processing speed of ffmpeg filter? – Stack Overflow

    Filter complex through CUDA hevc_cuvid with FFMPEG input 4k hevc, help needed – Graphics / Linux / Linux – NVIDIA Developer Forums

    GPU-accelerated video processing with ffmpeg – Stack Overflow

    audio – FFmpeg error when using –filter-complex with nvenc codec “Filter amerge has an unconnected output” – Super User

  • openSUSE Leap 下编译安装 Python 所需依赖

    使用 pyenv 编译安装 Python 时报错,文档中看起来没有 openSUSE 下的依赖安装指引,而且 Zypper 里也没有等价于 build-dep 的子命令,只好自己安装了。

    必选的依赖:

    sudo zypper in libopenssl-devel

    可选的:

    sudo zypper in libbz2-devel libffi-devel readline-devel sqlite3-devel tk-devel xz-devel

    如果安装 lzma-devel 会自动转为 xz-devel,具体见引用中的回答。

    引用

    Setup and building (python.org)

    Issue: Installing R on openSUSE Leap 15.0: “liblzma library and headers are required” – Stack Overflow

  • 酷比魔方 iPlay 50 Pro 刷机,安装 Magisk 获取 Root 权限,以及修复串号的经历

    最近刷张大妈的时候,看到酷比魔方的平板卖得还挺便宜的,而且还有卖老人关怀软件,可以在微信小程序上面进行一些远程操作。具体功能官方放了个视频:酷比魔方老人关怀系统,加入更多实用功能,你绝对想不到_哔哩哔哩_bilibili。考虑到长期在外面打工,于是乎决定买一个给家里长辈用用,平时还可以微信视频什么的。

    到手之后发现系统是刚适配不久的安卓 13,似乎厂家还没有测试好,非常多奇奇怪怪的小问题。而且国内版本的系统没有底部的三大金刚键,只能用手势操作,感觉很难教会老人;国际版本的系统是虚拟按键,但是客服说不支持使用老人关怀守护软件,只能放弃。基于上述原因,只好刷机降级到安卓 12,为了虚拟按钮和让平板更稳定一些。

    刷入官方安卓 12

    我们可以在官网 iPlay50Pro(T1030M)-Android12-20230815-固件及刷机教程 – 酷比魔方官网 (51cube.com) 找到刷机包和文档,按照压缩包内文档,安装驱动,然后关机刷入固件即可。

    这个线刷通常都比较顺利,官方给的文档也比较详细,这里就不展开了。不过要注意的是,除非有特殊需要,不然不要选择 Format All + Download。这个选项会清除串号 SN 和 WLAN MAC 地址,由于我不小心选到这个选项,这就有了后面重新写 SN 的经历。😅

    安装 Magisk 获取 Root 权限

    由于需要保活远程协助应用和进行其它一些骚操作,所以需要获取 Root 权限。安装 Magisk 以获取 Root 权限的过程,参考 Installation | Magisk (topjohnwu.github.io) 即可。对于酷比魔方这台机器来说,需要先解锁 Bootloader,然后 Patch 一下 boot.img 再刷入。

    解锁 BL

    首先获取 adb 用来解锁,本人不从事安卓程序开发,所以就不下载完整的 Android Studio 了,从 SDK 平台工具版本说明  |  Android Studio  |  Android Developers 这里获取单独的工具即可。

    然后在平板上反复点按关于平板中的版本号来打开开发者模式,并启用其中的 USB 调试。完成设定后即可将平板连接到电脑上。电脑上执行 .\adb.exe devices 后,平板会弹窗询问调试授权,此时点按同意即可。

    随后执行 .\adb.exe reboot bootloader 重启到 Bootloader,成功后再执行 .\fastboot.exe flashing unlock 进行解锁,此时平板上会刷出几行字询问是否解锁,要按音量下键确认解锁,重启平板后其将会自动恢复出厂设置。

    Patch 并刷入 boot.img

    在平板上面安装最新的 Magisk,并从上文中用过的官方刷机包里找到 boot.img 并传到平板上面,然后在 Magisk 界面中进行 Patch。

    Patch 完成后,我们将生成的新 boot.img 传到电脑上。还是执行 .\adb.exe reboot bootloader 重启到 Bootloader,进入 Bootloader 后执行 .\fastboot.exe flash boot .\magisk_patched-26400_bQzZo.img 刷入,成功后即可重启,最后在 Magisk 应用中检查成效。

    刷写串号(SN)

    刷完机之后,可以从 iPlay50 Pro 老人关怀系统软件(安卓13) – 酷比魔方官网 (51cube.com) 安装关怀系统。然后我就发现了一件非常糟糕的事情,由于前面线刷的时候点到了 Format All,平板的串号和 WLAN MAC 地址都被清掉了,没有串号就没法激活花了 100 块钱买的这个关怀系统。可以在电脑上执行 .\adb.exe shell 打开一个平板的终端,然后通过 getprop ro.serialno 来确认串号是否丢失,或者直接使用 getprop 命令再进行过滤。

    由于这个平板是 MTK 方案的设备,而且前面用到的官方刷机包里给了 AP Database,那么应该还是可以用 MTK SN Write Tool 写回去的。在关于X的救砖 – 酷比魔方官网 (51cube.com) 这个帖子里,管理员亦确认了修复的可行性。

    我们从 Download SN Write Tool (all versions) – Mediatek IMEI Tool (androidmtk.com) 获取到 SN Writer,当前最新版本在 Windows 11 上运行缺少动态链接库,提示缺少 mfc100.dll,安装后还是报错。为了更快解决主要问题,这里用的是 v1.1924 的版本,内含 mfc90.dll 不会有这种问题。

    启动 SN Writer 之前,需要先修改配置文件 SN_Setup.ini 中的 Enable Serial No 以允许烧写串号。如下图所示。

    此时应该已经可以在设置中看到烧写串号选项了。

    还需要在固件包中找到 MDDB 和 APDB。

    在配置中选中它们。

    点按 Save 保存,然后点按 Start 烧写包装盒上的串号即可。

    将普通 App 转为系统 App

    这里听同学的建议,本来是想写个 Magisk 模块,然后把 apk 直接挂进 /system/priv-app 和 /system/app 下面的。但是这样其实缺少权限等文件,部分 apk 直接挂进 /system/priv-app 之后平板直接启动不了了。后面发现其实可以直接用现成的模块转换已安装的应用,这里直接放文章,就不赘述了。

    聊聊关怀系统OS

    仅仅是一些个人观点,随时间推移,状况可能发生变化。

    这个系统,更准确地说是一个有较高权限的软件,可以自行从官网上下载安装。划线价 200 元 5 年,现在是 100 元 5 年。价格不贵,但槽点也挺多,还不是非常完善,总感觉这个项目的产品经理像是微信相框一类的业务过来的。

    激活并绑定后,在微信小程序上可以操作声音、亮度等设定还是不错的。这些东西看起来没有知名的竞品厂商在做,以往要实现这些东西还得上远控软件。

    然而,小问题也不少。首先,首页几乎不可定制,只能固定若干个应用在快捷应用卡片上,而且这些应用的范围也比较迷。系统应用是没法固定到首页的,这也就意味着打电话等操作是要移动到第二屏的,我很难确认是否能教会 80 多岁的老人这么操作。这个电话里面的通讯录可以在小程序上面下发,但是下发之后是跟外面的通讯录不同步的,这就有点难受了。

    其次,第二屏的应用没法整理。对于部分预装应用来说,长按会提示移入“日常应用”,确定的话,实际上是移入“更多应用”里面;对于用户安装的应用,甚至包括预装的应用宝、输入法,长按虽然是提示移入“日常应用”,但是一确认就直接没了,原来的桌面直接崩溃了,在哪里都找不到。只能在小程序里面找到隐藏的应用恢复出来,不论是预装的安卓 13 还是后面我自己刷的安卓 12 均是如此,难以想象 QA 是怎么放过这些常见用例的。

    还有,刚到手的时候,我点一下关怀系统里的一键加速,过了一小会儿平板竟然自己触发了紧急呼叫,多次尝试均是如此。这些奇奇怪怪的现象让人很难对这个产品有足够的信心。😥

    总之,在我看来这个平板从定位、价格、做工和特色功能等方面来看都是算这个档次里面比较有竞争力的,但是这个价位的产品各种小毛病是真的不少,还需要等待厂商慢慢打磨了。

    引用

    [MODULE][Terminal] App Systemizer v17.3.1 | XDA Forums

    [MODULE] App Systemizer for Magisk v9-v14 — DEPRECATED | XDA Forums

    How do I systemize apps on Android 11 with root access? : r/AndroidQuestions (reddit.com)

    Magisk-Modules-Repo/terminal_systemizer: terminal_systemizer (github.com)

    stangri/AppSystemizer: AppSystemizer (github.com)

    【iPlay20】国际版/解锁/救砖/Magisk/Xposed – 第 2 页 – 酷比魔方官网 (51cube.com)

    获取android SN码 安卓sn码_mob6454cc634aa4的技术博客_51CTO博客

    [2021.04.13]给联发科(MediaTek)平台设备写入串号(IMEI)、MAC地址等设备标识信息 – Hiiragiの咖啡厅 (hiirachan.moe)

    Developer Guides | Magisk (topjohnwu.github.io)

    开发者指南 | Magisk (e7kmbb.github.io)

    Magisk 刷入方法及模块推荐 – Ojhdt’s Blog

    Android 11 刷入 Magisk 模块后无法开机的解决方法 – 搞机男 (gaojinan.com)

    刷了 Magisk 之后装什么?我推荐这 20+ 个模块 – 少数派 (sspai.com)

  • WordPress 接入 CDN 后升级插件或 WP 失败

    现象

    近期将博客接入腾讯云 CDN 后发现更新插件和更新 WordPress 版本这种耗时较长的请求都会失败。一开始还没在意,以为是后端请求的下载地址不在国内所以下载超时。

    后面发现 Grafana 的服务在没有预热 CDN 缓存的时候,很多大的 JS 文件也都会请求失败,页面无法打开,F12 控制台有一些 net::ERR_INCOMPLETE_CHUNKED_ENCODING 200 (OK)。此时考虑 CDN 上面是否有限制回源请求的超时限制。

    解决方案

    如果使用腾讯云 CDN

    发现腾讯云 CDN 有给出回源超时时间配置,见内容分发网络 CDN 回源超时时间配置-配置指南-文档中心-腾讯云 (tencent.com)

    默认 TCP 超时限制 5 秒没有问题,但是回源加载时间 10 秒这个限制,对于更新插件和 WP 这种场景,以及 1Mbps 带宽加载 JS 大文件(开启 Gzip 后仍然有 4M+)的情况来说完全不够,因此酌情将回源时间限制放宽。在 CDN 控制台上刷新缓存之后,再次验证更新 WP 版本和访问 Grafana 已没有问题。

    如果使用腾讯云 EdgeOne

    先前往控制台选择相应站点,然后可以找到规则引擎。在匹配类型为 Host 的规则里新增操作来延长超时时间即可。

    更新历史

    24/3/12

    新增 EdgeOne 相关。

  • openSUSE Wicked 重新获取 DHCP 分配的地址

    最近发现,如果在 DHCP 服务器上向 openSUSE 下发了 IPv4 地址,在该地址的老化时间内,即使是重新开启网卡接口、重启系统、重新插拔网线等行为,Wicked 也不会重新获取 IP 地址,查看 wickedd-dhcp4.service 的日志可以发现其检查了 IP 的有效时间,有效期内没有再重新获取一次。

    解决方案

    先删除 /var/lib/wicked 下的所有文件:

    sudo rm -rf /var/lib/wicked/*

    或者是只删除 /var/lib/wicked/lease-eth0-dhcp-ipv4.xml 也可以。

    然后,重启该网卡接口:

    sudo wicked ifdown eth0
    sudo wicked ifup eth0

    此时应该可以观察到 IP 地址已经刷新。

    引用

    Wicked keeps DUID on SLES15 even when NIC is replaced | Support | SUSE

  • Docker Compose 创建的容器无法访问 host.docker.internal

    在 docker-compose.yml 中的 extra_hosts 字段中加上 host.docker.internal:host-gateway 即可。是的,一个魔法字符串。

    这个并非由 Docker Compose 处理,而是传给 Docker Engine 这层来处理,具体见引用链接中的源码。

    引用

    https://github.com/docker/compose/issues/9768#issuecomment-1570319324

    https://github.com/moby/moby/blob/9dbdbd4b6d7681bd18c897a6ba0376073c2a72ff/daemon/container_operations.go#L112-L129

  • 创建 Docker Buildx 多架构构建节点

    前置条件

    1 台 linux/amd64 的机器 A,1 台 linux/arm64 的机器 B。A 可以通过密钥对直接 SSH 连接 B。

    实施

    在 A 执行命令以创建名为 multiarch 的构建实例,并将本机加入该实例:

    docker buildx create --name multiarch --driver docker-container --config /etc/buildkitd.toml --node amd64 --platform=linux/amd64

    在 A 执行命令以将 B 加入该构建实例:

    docker buildx create --append --name multiarch --driver docker-container --config /etc/buildkitd.toml --node aarch64 --platform=linux/arm64 ssh://<user>@<ip>:<port>

    启动该构建实例:

    docker buildx inspect --bootstrap --builder multiarch

    上述命令会在两个机器上都启动一个容器,并且输出构建节点的信息。

    可以随时通过下面的命令来查看本机上的构建实例:

    docker buildx ls

    如果上面创建的 multiarch 构建实例不是默认被使用的,可以通过该命令进行修改:

    docker buildx use --default --builder multiarch

    buildkitd 配置文件

    上述命令中提及的 /etc/buildkitd.toml 可用于指定 Registry Mirrors,例如:

    debug = true
    [registry."docker.io"]
      mirrors = ["mirror.gcr.io"]

    其它具体配置项请参阅官方文档,见引用。

    测试

    可以任意编写一个 Dockerfile,然后执行命令进行构建测试:

    docker buildx build -t <image-tag> --platform=linux/arm64 --load .

    引用

    How to Rapidly Build Multi-Architecture Images with Buildx | Docker

    Configure BuildKit

    docker buildx

  • 使用代理工具 Burp Suite 或 whistle 移除 HSTS 响应头

    在某些时候,例如出于某些环境调试目的,可能需要阻止服务端响应 HSTS 头(Strict-Transport-Security),此时可以使用代理工具将该响应头移除。请注意,不正确的配置可能会影响正常访问网站的安全性,请务必在必要时启用如下功能或特性,或使用独立的开发者版本浏览器。

    如果使用 Burp Suite,则可以直接使用内置规则:

    如果使用 whistle,则可以增加一条规则,这里以要匹配的站点为 xie.sh.cn 进行举例:

    xie.sh.cn delete://res.headers.strict-transport-security

    移除已经被浏览器记住的安全策略

    如果浏览器已经记住了服务端下发的 HSTS 响应头,则需要先将其删除。以 Chrome 浏览器为例,可以访问 chrome://net-internals/#hsts,然后进行查询或删除。部分 HSTS 响应头会使用 includeSubDomains 来包含子域,删除无效时可以留意一下。

    如果浏览器试图升级 HTTPS 连接

    某些情况下,即使后端没有发送 HSTS 响应头,浏览器也可能试图同时发送 HTTP 和 HTTPS 请求来升级连接,此时可以考虑访问 chrome://flags/#https-upgrades,然后将其禁用。

    引用

    delete · GitBook (wproxy.org)

  • Linux 不重启验证 /etc/fstab

    直接终端执行:

    sudo findmnt --verify --verbose

    这个工具应该是属于 util-linux,正常情况下都不需要额外进行安装操作。

    引用

    fedora – How do you validate fstab without rebooting? – Server Fault

目录