EVN 随写 - Linux
type: channel
link: https://shan.ink/category/linux/
items: 使用 Find My 实时位置查询 API
items: EB5 PCIe/有线网迁移测试记录（主线 6.19）
items: Certimate 部署 SSL 证书到 aaPanel (宝塔面板) 指南
items: uinetd：一個更現代的 rinetd 替代品
items: 在Kubernetes上自部署ShareLaTeX并启用中文支持
items: Upgrade Docker Postgres Version
items: Intergrate linux and mikrotik gre tunnel with keepalive
items: Deploy DeepSeek-R1 on 8x H200 Device.
items: 基于龙芯新世界的Elasticflow移植
items: Issue Step CA Certificate with PromoxVE with ACME

使用 Find My 实时位置查询 API
type: item
date: 2026-04-07T00:52:00+08:00
description: 使用 Find My 实时位置查询 API通过本教程，你可以搭建一个 HTTP API，实时查询 Apple Find My 设备（包括 AirTag）的位置，支持逆地理编码地址显示。最终效果curl -H "X-API-Key: your-key" http://your-server:8000/items/airtag-name/address # 返回：时代广场, 1 Matheson Street, 銅鑼灣 Causeway Bay, 香港 Hong Kong整体架构┌─────────────────────────────────────────────────────────┐ │ 你的服务器 (Linux/Mac) │ │ │ │ findmy_api (FastAPI) │ │ ├── Apple Account Session (account.json) │ │ ├── FindMyAccessory Keys (accessories/*.json) │ │ └── Nominatim 逆地理编码 │ └──────────────┬──────────────────────────────────────────┘ │ Apple API (HTTPS) ▼ Apple Find My Server注意：整个方案需要一台 Mac 来提取密钥。服务器可以是 Linux。核心原理Find My 加密体系Apple Find My 使用非对称加密保护设备隐私：Master Key：设备配对时生成的 EC 私钥（28字节），设备端永不联网SKN / SKS：基于时间的滚动对称密钥（每15分钟轮换），用于加密位置报告advertisedLocationId：公开广播的公钥哈希，用于在 Apple 服务器查找设备位置报告流程：设备广播 → 用 SKS 加密位置 → 上传 Apple 服务器 ↓ 查询者 → Apple API → 用 Master Key 派生解密密钥 → 解密位置报告只有持有 Master Key 才能解密位置报告，这就是为什么需要从 Mac 提取密钥。为什么需要 Mac？BeaconStoreKey 和 accessory Master Key 都存储在 macOS Keychain 中，受 SIP/AMFI 保护。提取需要：SIP disabled — 允许 lldb 附加到 Apple 系统进程AMFI disabled — 允许读取受保护的系统密钥两个关键工具1. findmy-key-extractor提取三组 Find My 加密密钥：密钥用途加密方式LocalStorage.key解密 LocalStorage.dbAES-256 XORFMIPDataManager.bplist设备/物品/成员缓存ChaCha20-Poly1305FMFDataManager.bplist朋友元数据缓存ChaCha20-Poly1305通过 lldb 附加到 findmylocateagent 和 FindMy.app 进程，在密钥传递到系统函数时从寄存器中截取。2. beaconstorekey-extractor提取 BeaconStore AES-256 密钥，用于解密 searchpartyd 的 .record 文件。这些文件中包含每个设备的 Master Key（即 FindMyAccessory.from_plist() 需要的 privateKey、sharedSecret、secondarySharedSecret）。从 macOS Tahoe (26+) 开始，searchpartyd 数据从：~/Library/com.apple.icloud.searchpartyd/迁移到了：~/Library/Group Containers/group.com.apple.icloud.searchpartyuseragent/Library/Storage/需要手动修改源码中的路径。提取流程第一步：禁用 SIP重启进入 Recovery Mode终端运行：csrutil disable重启后添加启动参数：sudo nvram boot-args="amfi_get_out_of_my_way=1"再重启第二步：提取 BeaconStoreKeygit clone https://github.com/pajowu/beaconstorekey-extractor.git cd beaconstorekey-extractor make run # 输出类似：<your-beaconstore-key>保存这个64字符的 hex 字符串。第三步：解密 beacon 数据macOS…

EB5 PCIe/有线网迁移测试记录（主线 6.19）
type: item
date: 2026-03-09T09:46:00+08:00
description: 环境目标板：QRB5165 EB5基线：qrb5165-eb5.dts 继承 qrb5165-rb5.dts目标：恢复 pcie1 下有线网卡 endpoint 枚举主线 dts// SPDX-License-Identifier: BSD-3-Clause /* * Qualcomm Robotics EB5 platform based on QRB5165/RB5 */ /dts-v1/; #include "qrb5165-rb5.dts" / { model = "Qualcomm Technologies, Inc. qrb5165 IOT EB5"; compatible = "qcom,kona-iot", "qcom,kona", "qcom,iot", "qcom,eb5", "qcom,qrb5165-rb5", "qcom,sm8250"; aliases { ufshc1 = &ufs_mem_hc; pci-domain0 = &pcie0; pci-domain1 = &pcie1; pci-domain2 = &pcie2; }; }; &pcie1 { status = "okay"; max-link-speed = <3>; num-lanes = <2>; wake-gpios = <&tlmm 84 GPIO_ACTIVE_HIGH>; vdda-supply = <&vreg_l9a_1p2>; vddpe-3v3-supply = <&vreg_l11c_3p3>; /* * Remove iommu-map so qcom_pcie_config_sid_1_9_0() returns early * and never clears BDF_TO_SID_BYPASS. With bypass ON (hardware * default), inbound PCIe completions skip SMMU BDF-to-SID lookup. * * Background: during PCI bus walk the SMMU has no context banks for * downstream-device SIDs yet (iommu_attach_device() is called only * after device_add(), i.e. AFTER the first config read). The vendor * msm_pcie driver never touches BDF_TO_SID_CFG, so bypass stays ON * there and ASM2806 completions flow through unblocked. */ /delete-property/ iommu-map; /* * Append the helper as an extra clock entry so fw_devlink ensures * the helper probes (and gpio141 is driven) before qcom-pcie probes. * qcom-pcie only requests clocks by the names it knows; "lan-en" is * silently ignored by the driver but honored by fw_devlink. */ clocks = <&gcc GCC_PCIE_1_PIPE_CLK>, <&gcc GCC_PCIE_1_AUX_CLK>, <&gcc GCC_PCIE_1_CFG_AHB_CLK>, <&gcc GCC_PCIE_1_MSTR_AXI_CLK>, <&gcc GCC_PCIE_1_SLV_AXI_CLK>, <&gcc GCC_PCIE_1_SLV_Q2A_AXI_CLK>, <&gcc GCC_PCIE_WIGIG_CLKREF_EN>, <&gcc GCC_AGGRE_NOC_PCIE_TBU_CLK>, <&gcc GCC_DDRSS_PCIE_SF_TBU_CLK>, <&eb5_pcie1_helper>; clock-names = "pipe", "aux", "cfg", "bus_master", "bus_slave", "slave_q2a", "ref", "tbu", "ddrss_sf_tbu", "lan-en"; pinctrl-0 = <&pcie1_default_state>; pcie@0 { }; }; /* * Lightweight anchor …

Certimate 部署 SSL 证书到 aaPanel (宝塔面板) 指南
type: item
date: 2025-12-21T10:58:41+08:00
description: 前置准备Certimate ：已安装并配置好，能够成功申请/续期证书。aaPanel ：面板已安装并正在运行。已在面板中创建了需要部署证书的 网站 。Python 3 环境（aaPanel 通常自带 Python 3）。第一步：配置 aaPanel API为了让脚本能够通过接口操作面板，需要在宝塔面板中开启 API 功能。登录 aaPanel/宝塔面板。点击左侧菜单的 面板设置 (Settings) 。找到 API 接口 (API Interface) 选项，点击开启。记录关键信息 ：接口密钥 (API Secret Key) ：复制并保存，稍后会用到。面板地址 (Panel URL) ：通常是 http://IP:端口。配置 IP 白名单 ：在 API 设置中的“IP 白名单”栏，填入部署 Certimate 的服务器 IP 地址。第二步：准备部署脚本我们将使用一个 Python 脚本来完成“上传证书”和“部署到站点”两个动作。该脚本会自动处理宝塔 API 需要的签名验证。脚本文件在 Certimate 的部署目标服务器上（或 Certimate 容器内），创建一个文件，例如 deploy_aapanel.py，并将以下代码粘贴进去：#!/usr/bin/env python3 # -*- coding: utf-8 -*- import json import os import ssl import sys import time import hashlib import urllib.parse import urllib.request import urllib.error # --- 工具函数 --- def is_true(value: str | None) -> bool: if value is None: return False return value.strip().lower() in {"1", "true", "yes", "y", "on"} DEBUG = is_true(os.getenv("DEBUG")) def debug(msg: str) -> None: if DEBUG: print(f"[DEBUG] {msg}", file=sys.stderr) def require_env(name: str) -> str: value = os.getenv(name) if not value: print(f"❌ 错误: 环境变量 [{name}] 未设置。", file=sys.stderr) raise SystemExit(1) return value def md5_hex(text: str) -> str: return hashlib.md5(text.encode("utf-8")).hexdigest() def add_auth_query(url: str, api_secret_key: str) -> tuple[str, int, str]: # 生成宝塔 API 认证所需的 request_token now = int(time.time() * 1000) request_token = md5_hex(str(now) + md5_hex(api_secret_key)) parts = urllib.parse.urlsplit(url) existing = urllib.parse.parse_qsl(parts.query, keep_blank_values=True) existing.extend([("request_time", str(now)), ("request_token", request_token)]) new_query = urllib.parse.urlencode(existing) return urllib.parse.urlunsplit((parts.scheme, parts.netloc, parts.path, new_query, parts.fragment)), now, request_token def http_post_form(url: str, form: dict[str, str], headers: dict) -> tuple[int | None, str, dict | None]: data = urllib.parse.urlencode(form).encode("utf-8") ctx = ssl._create_unverified_context() # 忽略面板自签证书错误 try: req = urllib.request.Req…

uinetd：一個更現代的 rinetd 替代品
type: item
date: 2025-10-08T02:09:12+08:00
description: The English version will be available after the Chinese version:uinetd：更現代的 rinetd 替代品uinetd 是一個輕量、現代的端口轉發服務，目標是成為 rinetd 的即插即用替代品，同時提供 rinetd 缺失的 UDP 轉發能力，(比如 支持 IPv4 與 IPv6 互相端口轉發）。並在 IPv6、可觀測性與易用性方面做了增強。它保持了與 rinetd 相近的配置格式，遷移成本很低。為什麼替換 rinetdUDP 支持 ：傳統 rinetd 通常只做 TCP 轉發，uinetd 同時支持 TCP/UDP/雙協議。IPv6 友好 ：原生支持 IPv4 與 IPv6 互相端口轉發。更易用的发行 ：单一二进制、支持打包为 deb/rpm。低改动迁移 ：配置格式与 rinetd 接近，仅新增“协议”一列。主要特性协议支持 ：tcp、udp、both/all（同时启两个监听）IPv4/IPv6 ：靈活的地址格式，IPv6 使用 2001:db8::1、[2001:db8::1]轻量单文件 ：无外部依赖，部署简单清晰日志 ：可配置 loglevel，便于排障最小可用配置编辑 /etc/uinetd.conf（与 rinetd 类似，结尾多一列“协议”）：# bindaddr bindport connectaddr connectport protocol 0.0.0.0 8080 127.0.0.1 80 tcp 0.0.0.0 53 1.1.1.1 53 udp [::] 443 [2001:db8::1] 8443 both # 日志等级：1=错误，2=简要，3=阻止日志+错误，4=连接明细+错误 loglevel 1启动：uinetd -c /etc/uinetd.conf可选 systemd（简化示例）：[Unit] Description=uinetd - internet redirection server After=network.target [Service] ExecStart=/usr/local/bin/uinetd -c /etc/uinetd.conf Restart=on-failure [Install] WantedBy=multi-user.target從 rinetd 平滑遷移新增協議列 ：rinetd 的四列規則，遷移到 uinetd 時在末尾加上協議即可。例：0.0.0.0 8080 127.0.0.1 80 → 0.0.0.0 8080 127.0.0.1 80 tcp同時轉發 TCP+UDP ：把協議寫為 both 或 all。IPv6 ：使用方括號，如 [::]、[2001:db8::1]。域名 ：目標地址可直接使用域名。常見用例DNS 代理（UDP） ：0.0.0.0 53 1.1.1.1 53 udpWeb 反向轉發（TCP） ：0.0.0.0 8080 127.0.0.1 80 tcpIPv6→IPv6（both） ：[::] 443 [2001:db8::1] 8443 both總結如果你在尋找一個與 rinetd 體驗相近、卻能原生支持 UDP/IPv6、並具備更好包發行與可觀測性的工具，uinetd 是一個穩妥的現代替代方案。歡迎試用並在生產環境中逐步替換現有 rinetd 配置。項目地址 ：GitHub 倉庫uinetd: A More Modern Alternative to rinetduinetd is a lightweight, modern port forwarding service designed to be a plug-and-play replacement for rinetd, while also providing UDP forwarding capabilities that rinetd lacks (such as native IPv4 and IPv6 mutual port forwarding). It enhances IPv6 support, observability, and usability. It maintains a similar configuration format to rinetd, making migration easy and low-cost.Why Replace rinetdUDP Support : Traditional rinetd typically only forwards TCP. uinetd supports TCP, UDP, and dual-protocol forwar…

在Kubernetes上自部署ShareLaTeX并启用中文支持
type: item
date: 2025-07-25T02:56:00+08:00
description: 引言最开始的时候，论文无法显示中文:本着"亲自指挥，亲自部署(SaaS)"的原则，以及 LaTeX 在 Overleaf 端不是很支持中文字体，并且有很多的编译限制，协作功能也存在问题。因此，在 Kubernetes 集群上部署一个自托管的 ShareLaTeX 来实现多用户同时使用。本项目不仅提供了完整的部署方案，还配置了 GitHub Actions CI/CD 流程，实现每日自动构建包含中文字体支持的 Docker 镜像。主要的痛点GitHub Actions 自动化构建：每周自动构建 Docker 镜像，实时更新最新的 Overleaf中文支持：集成 fandol 字体和完整的 TeX Live 中文包，及宋体，仿宋等中文环境云原生架构：基于 Kubernetes 的高可用部署容器化部署：使用 Helm Charts 简化部署过程架构概览ShareLaTeX 由三个核心组件构成：Redis：缓存和会话存储MongoDB：文档和用户数据存储ShareLaTeX：主应用服务（包含中文字体支持）开始部署准备环境1. 安装 Bitnami Helm Repository前两个组件（Redis 和 MongoDB）已经有 Bitnami 提供的稳定镜像，我们直接使用 Helm 安装：# 添加 bitnami repo helm repo add bitnami https://charts.bitnami.com/bitnami helm repo update2. 创建命名空间kubectl create namespace latex部署数据层2.1 部署 MongoDB创建 values-mongodb.yaml 配置文件：auth: ## 启用认证 enabled: true ## MongoDB root 用户 rootUser: root ## MongoDB root 密码（建议使用 Secret 管理） rootPassword: "your-secure-password" ## 自定义用户和数据库 usernames: ["sharelatex"] passwords: ["sharelatex-password"] databases: ["sharelatex"] # 持久化存储配置 persistence: enabled: true size: 10Gi # 副本集配置（高可用） replicaCount: 2 architecture: replicaset # 外部访问配置（可选，用于调试） externalAccess: enabled: true service: type: LoadBalancer autoDiscovery: enabled: true # RBAC 配置 serviceAccount: create: true automountServiceAccountToken: true rbac: create: true部署 MongoDB：helm install mongo-mongodb bitnami/mongodb \ --namespace latex \ --values values-mongodb.yaml2.2 部署 Redis创建 values-redis.yaml 配置文件：global: redis: password: "your-redis-password"部署 Redis：helm install redis-master bitnami/redis \ --namespace latex \ --values values-redis.yaml部署应用层3.1 自定义 ShareLaTeX 镜像我们的项目提供了一个增强版的 ShareLaTeX 镜像，包含仿宋等常见中文论文场景的中文字体支持。如果需要其他字体，可以留言给我，我可以酌情添加.Dockerfile 特点：FROM sharelatex/sharelatex:latest # 设置环境变量避免交互式安装 ENV DEBIAN_FRONTEND=noninteractive # 安装中文字体和 TeX Live 包 RUN apt-get update && apt-get install -y \ latex-cjk-all \ texlive-lang-chinese \ texlive-lang-english \ git \ && rm -rf /var/lib/apt/lists/* # 安装中文字体库 RUN git clone https://github.com/Haixing-Hu/latex-chinese-fonts \ /usr/share/fonts/o…

Upgrade Docker Postgres Version
type: item
date: 2025-07-14T11:57:00+08:00
description: Step-by-Step Upgrade Workflow### STEP 1: BACKUP CURRENT DATABASE # Connect to existing container docker compose exec plausible_db bash # Internal dump to container volume pg_dumpall -U postgres > /var/lib/postgresql/backup.sql # Exit container exit ### STEP 2: EXTRACT BACKUP FROM VOLUME # Copy SQL backup to host via docker compose cp docker compose cp db:/var/lib/postgresql/backup.sql ./backup_$(date +%F).sql ### STEP 3: MIGRATE TO NEW CONTAINER # Verify backup integrity before migration head -n 20 backup_*.sql # Check header # Update compose.yaml image tag version: '3.8' services: plausible_db: image: postgres:16-version # Updated here assume you upgrade to pg16 # Launch new container docker compose up -d db # Insert backup into new container docker compose cp backup_date.sql db:/restore.sql # Execute under db docker compose exec -it db cat restore.sql | psql -U postgres exit docker compose down && docker compose up🔧 Best Practicesgraph TD A[Stop Services] --> B[pg_dumpall Backup] B --> C[Spin up New Container] C --> D[Restore Backup] D --> E[Test Compatibility] E --> F[Update compose.yaml] F --> G[Restart Stack]🔍 Pro TipsUse ephemeral containers for testing migrations:docker run --rm -v $(pwd)/backup.sql:/backup.sql postgres:15 \ bash -c "psql -U postgres -f /backup.sql"After migrate, make sure delete old volumes incase redundated file!💡 Key Resources:Official PostgreSQL Upgrade GuideDocker Postgres Image Docspg_upgrade Deep DiveTest your upgrade in staging first!

Intergrate linux and mikrotik gre tunnel with keepalive
type: item
date: 2025-05-30T21:23:00+08:00
description: 啟動 ping-endpoint.timer:[Unit] Description=Timer to ping endpoint every 10s after network is up BindsTo=sys-subsystem-net-devices-eth0.device After=sys-subsystem-net-devices-eth0.device [Timer] OnActiveSec=0 OnUnitActiveSec=10s Unit=ping-endpoint.service [Install] WantedBy=timers.target啟動 ping-endpoint.service:[Unit] Description=Ping specified endpoint After=network.target network-online.target Wants=network-online.target [Service] Type=oneshot ExecStart=/usr/bin/ping -c 1 [ENDPOINT IP] SuccessExitStatus=0 1 2sudo systemctl daemon-reload sudo systemctl enable --now ping-endpoint.timer

Deploy DeepSeek-R1 on 8x H200 Device.
type: item
date: 2025-03-22T23:26:00+08:00
description: 首先，安装 SGLang。可以通过以下命令安装：pip install uv pip install "sglang[all]>=0.4.3" --find-links https://flashinfer.ai/whl/cu124/torch2.5/flashinfer-python -i https://pypi.tuna.tsinghua.edu.cn/simple模型文件需要从 deepseek-ai/DeepSeek-R1 下载，假设放在 /mnt/models/DeepSeek-R1。初始尝试和问题第一次启动服务器时，使用以下命令：python3 -m sglang.launch_server \ --model /mnt/models/DeepSeek-R1 \ --tp 8 \ --dtype auto \ --trust-remote-code \ --enable-torch-compile \ --disable-cuda-graph \ --mem-fraction-static 0.7 \ --served-model-name deepseek --api-key 123但遇到错误：RuntimeError: expected mat1 and mat2 to have the same dtype, but got: c10::BFloat16 != c10::Half这是因为 DeepSeek-R1 使用混合数据类型（如 BFloat16 和 F8_E4M3），而 --dtype half 强制转换为 float16，导致不兼容。解决问题通过将 --dtype 改为 auto，问题解决：python3 -m sglang.launch_server \ --model /mnt/models/DeepSeek-R1 \ --tp 8 \ --dtype auto \ --trust-remote-code \ --enable-torch-compile \ --disable-cuda-graph \ --mem-fraction-static 0.7 \ --served-model-name deepseek --api-key 123解决问题通过将 --dtype 改为 auto，问题解决：python3 -m sglang.launch_server \ --model /mnt/models/DeepSeek-R1 \ --tp 8 \ --dtype auto \ --trust-remote-code \ --enable-torch-compile \ --disable-cuda-graph \ --mem-fraction-static 0.7 \ --served-model-name deepseek --api-key 123这允许模型以原始数据类型加载，成功启动 sglang。性能优化为加快 token 生成，建议启用推测解码，设置如下：--speculative-num-steps 3--speculative-num-draft-tokens 4--mem-fraction-static 0.7--schedule-conservativeness 0.01在issue中， 低并发（如 1 个请求）时可达到每秒 65 token 的速度。参考性能优化策略基于 issue #4616 和相关讨论，以下是影响 token 生成速度的关键参数：参数描述/影响推荐值/注意事项已知问题--speculative-algorithm启用 Next-N 推测解码，生成草稿 token 树，减少前向传递次数设置为 "NEXTN"高并发（>32）时性能下降--speculative-num-steps推测解码步骤数，影响吞吐量推荐 3，测试显示最高吞吐量---speculative-num-draft-tokens草稿 token 数量，影响性能推荐 4，测试显示最佳性能---speculative-eagle-topkEAGLE策略的 top-k 值，影响推测解码效率推荐 1---speculative-draft草稿模型目录，需指定正确路径设置为 ``---mem-fraction-static静态内存分配比例，防止 OOM 错误推荐 0.7---schedule-conservativeness调度保守性，影响吞吐量推荐 0.01，高性能设置-CUDA Graph减少内核启动开销和同步延迟，提升推理性能，增加内存使用默认启用，可用 --disable-cuda-graph 禁用，参数 --cuda-graph-max-bs: 160, 512, 1024与 DP-Atten…

基于龙芯新世界的Elasticflow移植
type: item
date: 2024-11-28T01:41:00+08:00
description: 编译ELK过程OS: Debian sid/trixeapt install ant openjdk-8-jdk texinfo libboost-dev cmake选定 java8 来替代 jdk21sudo update-alternatives --config javaElasticsearchgit clone https://github.com/elastic/elasticsearch -b v8.16.1 --depth=1查看依赖version.properties检查依赖:确定 jna 版本 5.12.1git clone https://github.com/java-native-access/jna -b 5.12.1 --depth=1 ant distML-CPPgit clone https://github.com/elastic/ml-cpp/ -b v8.16.1 --depth=1WIP...

Issue Step CA Certificate with PromoxVE with ACME
type: item
date: 2024-09-09T22:08:00+08:00
description: Install Step CA Certificate with PromoxVE with ACMEPrerequisitesYou have already have a step ca running on your other devices.You used a FQDN(Fully Qualified Domain Name) for your step ca.Your Step CA can be accessiable to your ProxmoxVE server's FQDN.Step 1: Install CA CertificateUse step ca to get the root certificate.step ca root ca.crt ``Copy the root certificate to your ProxmoxVE server.scp ca.crt root@<ProxmoxVE-IP>:/root/On your ProxmoxVE server, move the root certificate to the correct location.mv /root/ca.crt /usr/local/share/ca-certificates/Update the CA certificates.update-ca-certificatesConfiguring ACME Directory URL to ProxmoxVEpvenode acme account register default <your email here> --directory https://your-acme-endpointSetup the fqdn and prepare to get the certificate.pvenode config set --acme domains=<ProxmoxVE-FQDN>Get the certificate.pvenode acme cert order