Blog

  • NanoPC T6/NanoPi R6s Android Rebuild Kernel

    内核在 kernel-6.1 里,基本与 github 仓库里的差不多,参数有些许差异。

    以tablet模式为例,文档给出的编译工作,第一步 echo "ROCKCHIP_DEVICE_DIR := device/rockchip/rk3588/nanopi6" > .rockchip_device.mk
    对应的配置文件是 kernel-6.1/arch/arm64/configs/nanopi6_android_defconfig

    修改内核配置重新编译内核之后,会面临问题,硬件驱动全都是预编译好放到 vendor/rockchip 里的,安装就会发现版本不一致,所有设备都用不了。

    修改好内核参数,按wiki说明编译一次

    . setenv.sh
    ./build.sh -FMu

    如果一切顺利,内核会在 out/target/product/nanopi3/kernel 出现,过程中也能看到内核编译的一些日志。

    但是,kernel-6.1 里不会有.ko 文件,out 里除了 vendor_dlkm 里有,其他都没有,而 vendor_dlkm 里的都是从 vendor/rockchip 里安装过来的。而且,out 里也找不到 Module.symvers

    所以下一步任务是重新编译内核模块。

    cd kernel-6.1
    
    export CLANG_BIN=$(pwd)/../prebuilts/clang/host/linux-x86/clang-r487747c/bin
    export PATH=$CLANG_BIN:$PATH
    
    # 可以不用执行
    make ARCH=arm64 LLVM=1 CROSS_COMPILE=aarch64-linux-gnu- nanopi6_android_defconfig
    
    make ARCH=arm64 LLVM=1 CROSS_COMPILE=aarch64-linux-gnu- modules_prepare
    
    make ARCH=arm64 LLVM=1 CROSS_COMPILE=aarch64-linux-gnu- modules -j$(nproc)

    其中,clang 的目录,参考 build/soong/cc/config/global.go 里的定义。

    下一步,从 github 把网络相关的模块都clone出来,逐个按照 6.1 内核 和 安卓做适配,都在aosp项目外编译。再把ko 文件和 kernel-6.1 里的ko,按照 vendor_dlkm 里已有的,逐个覆盖到 vendor/rockchip 里,再次运行 ./build.sh -FMu 完成编译和打包。

  • NanoPC T6/NanoPi R6s Android with Dropbear

    不要相信别人的二进制,编译参数不可靠,我本来是直接基于二进制安装,结果对方的二进制编译参数错误,根本没有使用openpty(),导致连不上 /system/bin/sh .

    基本步骤如下:

    1. 下载源码,准备环境
    2. device/ 建立目录,准备dropbear 源码
    3. 创建二进制相关的 Android.bp,按 multi 的方式准备,需要提前 configure 并修改 config.h,也需要注意libtommath 和 libtomcrypt 与各种.h的相互依赖
    4. 准备 selinux 的policy文件
    5. 准备 .rc文件,包括创建key,如果二进制要装在 system_ext 且准备预设公钥,公钥文件也得考虑放到 system_ext
    6. 准备device.mk 声明模块安装文件

  • sing-box 实现v4 in v6 out

    一个实验需求,要搭建简单的v4转v6代理,考虑到客户端分流的需求,用了 sing-box。背景信息是,我的服务器有 v4/v6 双栈,但是很多云服务商v4的IP什么都干不了,但是v6目前还干净。

    本身sing-box能做的很少,配置仅增加了 routing_mark,这样outbound 流量能搭配上PBR进行流量调度,我的配置如下:

      "outbounds": [
        {
          "tag": "direct",
          "type": "direct",
          "routing_mark": 13001
        }
      ]

    下一步需要完成PBR并做两件事情,1 阻断v4,2 配置v6路由:

    
    #!/bin/bash
    # singbox-pbr.sh
    # sing-box outbound routing_mark=13001 IPv6 出口,阻断 IPv4 fallback
    TABLE_ID=13001
    TABLE_NAME=singbox_v6
    DEV=venet0  # VPS 虚拟接口
    
    # --- 1. 确保 rt_tables 有记录 ---
    grep -q "$TABLE_NAME" /etc/iproute2/rt_tables || \
        echo "$TABLE_ID $TABLE_NAME" >> /etc/iproute2/rt_tables
    
    # --- 2. 清理旧规则和表 ---
    ip rule del fwmark $TABLE_ID lookup $TABLE_NAME 2>/dev/null
    ip rule del fwmark $TABLE_ID unreachable 2>/dev/null
    ip -6 route flush table $TABLE_NAME 2>/dev/null
    
    # --- 3. 添加 IPv6 默认路由 ---
    # VPS venet0 接口通常是点对点,不需要指定网关
    ip -6 route add default dev $DEV table $TABLE_NAME
    
    # --- 4. 添加 fwmark 规则 ---
    ip rule add fwmark $TABLE_ID lookup $TABLE_NAME priority 100
    ip rule add fwmark $TABLE_ID unreachable priority 101

    我是用 rc.local 启动的,各种启动方式都可以。

  • 海康威视R1 的容器服务换成containerd + nerdctl 了

    好久没连上去看,本来想手动更新plex的镜像版本,结果发现docker命令不好使了,提示

    root@HikSemi-R1-3078:~# docker ps -a
    Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?

    看了下进程,有containerd,文件在 /usr/local/bin 下,并且有 nerdctl。把脚本更新成 nerdctl 就行了。

  • android manage default launcher

    1 Query current launcher

    $ cmd package resolve-activity -c android.intent.category.HOME -a android.intent.action.MAIN                                                                                                                                             
    priority=0 preferredOrder=0 match=0x108000 specificIndex=-1 isDefault=true
    ActivityInfo:
      name=com.android.launcher3.Launcher
      packageName=com.android.launcher3
      enabled=true exported=true directBootAware=false
      taskAffinity=null targetActivity=null persistableMode=PERSIST_ROOT_ONLY
      launchMode=2 flags=0x4214 theme=0x0
      screenOrientation=5 configChanges=0x73 softInputMode=0x20
      lockTaskLaunchMode=LOCK_TASK_LAUNCH_MODE_DEFAULT
      resizeMode=RESIZE_MODE_RESIZEABLE
      ApplicationInfo:
        packageName=com.android.launcher3
        labelRes=0x7f10000a nonLocalizedLabel=null icon=0x7f020015 banner=0x0
        processName=com.android.launcher3
        taskAffinity=com.android.launcher3
        uid=10017 flags=0x3ccbbe45 privateFlags=0x8 theme=0x7f120002
        requiresSmallestWidthDp=0 compatibleWidthLimitDp=0 largestWidthLimitDp=0
        sourceDir=/system/priv-app/MtkLauncher3/MtkLauncher3.apk
        resourceDirs=[/vendor/overlay/framework-res__auto_generated_rro.apk]
        seinfo=default:privapp:targetSdkVersion=23
        seinfoUser=:complete
        dataDir=/data/user/0/com.android.launcher3
        deviceProtectedDataDir=/data/user_de/0/com.android.launcher3
        credentialProtectedDataDir=/data/user/0/com.android.launcher3
        enabled=true minSdkVersion=21 targetSdkVersion=23 versionCode=27 targetSandboxVersion=1
        supportsRtl=true
        fullBackupContent=@xml/2131230720
    

    2 List all launchers

    $ cmd package query-activities -c android.intent.category.HOME -a android.intent.action.MAIN

    List of responses similar to resolve-activity

    3 Update default

    For the

    ActivityInfo:
      name=com.android.launcher3.Launcher
    

    Run

    cmd package set-home-activity com.android.launcher3/.Launcher -c android.intent.category.HOME -a android.intent.action.MAIN
  • VyOS Set up Port Forwarding for PPPoE to LAN

    Set up PPPoE(WAN) :8022 to LAN host 1921.68.1.119:22

    WAN and LAN are firewall zones.

    Step 1, DNAT

    set nat destination rule 11000 destination port '8022'
    set nat destination rule 11000 inbound-interface name 'pppoe0'
    set nat destination rule 11000 log
    set nat destination rule 11000 protocol 'tcp'
    set nat destination rule 11000 translation address '192.168.1.119'
    set nat destination rule 11000 translation port '22'

    Step 2, Firewall

    show firewall zone-policy to get firewall policy from WAN to LAN, in my case WAN_IN.

    
    set firewall ipv4 name WAN_IN rule 100 action 'accept'
    set firewall ipv4 name WAN_IN rule 100 destination address '192.168.1.119'
    set firewall ipv4 name WAN_IN rule 100 destination port '22'
    set firewall ipv4 name WAN_IN rule 100 protocol 'tcp'

    No need to set WAN_LOCAL

  • VyOS-1x build script on VyOS

    Put vyos/vyos-1x code to /config/build/vyos-1x

    Script as /config/build/build.sh

    #!/bin/sh
    
    
    cat << 'EOF' > /etc/apt/sources.list.d/debian.sources
    Types: deb deb-src
    URIs: https://mirrors.tuna.tsinghua.edu.cn/debian
    Suites: bookworm bookworm-updates
    Components: main contrib non-free non-free-firmware
    Signed-By: /usr/share/keyrings/debian-archive-keyring.gpg
    
    Types: deb deb-src
    URIs: https://mirrors.tuna.tsinghua.edu.cn/debian-security
    Suites: bookworm-security
    Components: main contrib non-free non-free-firmware
    Signed-By: /usr/share/keyrings/debian-archive-keyring.gpg
    EOF
    
    
    podman pull docker.io/vyos/vyos-build:current
    
    mkdir -p /config/build
    cd /config/build
    
    rm -f /config/build/vyos-1x-* /config/build/vyos-1x_*
    
    chown -R vyos: /config/build
    chmod 777 /config/build
    
    podman run --rm -it --privileged --network host -v /config/build:/vyos -w /vyos/vyos-1x vyos/vyos-build:current dpkg-buildpackage -uc -us -tc -b
    
    
    dpkg -i vyos-1x_1.5dev0-*_amd64.deb
    
    systemctl restart vyos-configd
    
    chown -R vyos: /config/build
    chmod 777 /config/build
    
    
  • VyOS Debug PBR & NAT

    As ROOT.

    Keyword: nftrace

    Edit VyOS generated NFT files: /run/nftables*.

    Enable nftrace on full chain

    table ip vyos_mangle {
        chain VYOS_PBR_PREROUTING {
            type filter hook prerouting priority -150; policy accept;
            meta nftrace set 1
            iifname { eth2,eth0 } counter jump VYOS_PBR_UD_MY_PBR_RULES
        }
    }

    Make sure nftrace is enabled before other rules!

    Enable nftrace on SINGLE RULE.

    table ip vyos_mangle {
        chain VYOS_PBR_PREROUTING {
            type filter hook prerouting priority -150; policy accept;
            iifname { eth2,eth0 } counter jump VYOS_PBR_UD_MY_PBR_RULES
        }
    
        chain VYOS_PBR_UD_MY_PBR_RULES {
            ip saddr  @A_SRC_HIJACK_MITMPROXY counter meta mark set 2147483628 meta nftrace set 1 return comment "ipv4-route-ROUTE_CLASH_TUN-50"
        }
    }

    Test & Apply

    # Test
    nft --check --file /run/nftables_policy.conf
    # Apply
    nft --file /run/nftables_policy.conf

    Monitor

    nft monitor trace 

    Example Result

    trace id 0abb78f9 ip vyos_mangle VYOS_PBR_PREROUTING packet: iif "eth2" ether saddr bc:24:11:27:72:1b ether daddr bc:24:11:35:1c:c5 ip saddr 192.168.27.100 ip daddr 192.168.27.1 ip dscp cs0 ip ecn not-ect ip ttl 64 ip id 64190 ip length 68 udp sport 58012 udp dport 53 udp length 48 @th,64,96 0x990701200001000000000001
    trace id 0abb78f9 ip vyos_static_nat PREROUTING packet: iif "eth2" ether saddr bc:24:11:27:72:1b ether daddr bc:24:11:35:1c:c5 ip saddr 192.168.27.100 ip daddr 192.168.27.1 ip dscp cs0 ip ecn not-ect ip ttl 64 ip id 64190 ip length 68 udp sport 58012 udp dport 53 udp length 48 @th,64,96 0x990701200001000000000001
    trace id 0abb78f9 ip vyos_nat PREROUTING packet: iif "eth2" ether saddr bc:24:11:27:72:1b ether daddr bc:24:11:35:1c:c5 ip saddr 192.168.27.100 ip daddr 192.168.27.1 ip dscp cs0 ip ecn not-ect ip ttl 64 ip id 64190 ip length 68 udp sport 58012 udp dport 53 udp length 48 @th,64,96 0x990701200001000000000001
    trace id 0abb78f9 ip vyos_conntrack PREROUTING_HELPER packet: iif "eth2" ether saddr bc:24:11:27:72:1b ether daddr bc:24:11:35:1c:c5 ip saddr 192.168.27.100 ip daddr 10.0.0.53 ip dscp cs0 ip ecn not-ect ip ttl 64 ip id 64190 ip length 68 udp sport 58012 udp dport 53 udp length 48 @th,64,96 0x990701200001000000000001
    trace id 0abb78f9 ip raw VYOS_TCP_MSS packet: iif "eth2" oif "pppoe0" ether saddr bc:24:11:27:72:1b ether daddr bc:24:11:35:1c:c5 ip saddr 192.168.27.100 ip daddr 10.0.0.53 ip dscp cs0 ip ecn not-ect ip ttl 63 ip id 64190 ip length 68 udp sport 58012 udp dport 53 udp length 48 @th,64,96 0x990701200001000000000001
    trace id 0abb78f9 ip vyos_mangle VYOS_PBR_FORWARD packet: iif "eth2" oif "pppoe0" ether saddr bc:24:11:27:72:1b ether daddr bc:24:11:35:1c:c5 ip saddr 192.168.27.100 ip daddr 10.0.0.53 ip dscp cs0 ip ecn not-ect ip ttl 63 ip id 64190 ip length 68 udp sport 58012 udp dport 53 udp length 48 @th,64,96 0x990701200001000000000001
    trace id 0abb78f9 inet mangle FORWARD packet: iif "eth2" oif "pppoe0" ether saddr bc:24:11:27:72:1b ether daddr bc:24:11:35:1c:c5 ip saddr 192.168.27.100 ip daddr 10.0.0.53 ip dscp cs0 ip ecn not-ect ip ttl 63 ip id 64190 ip protocol udp ip length 68 udp sport 58012 udp dport 53 udp length 48 @th,64,96 0x990701200001000000000001
    trace id 0abb78f9 ip vyos_filter VYOS_FORWARD_filter packet: iif "eth2" oif "pppoe0" ether saddr bc:24:11:27:72:1b ether daddr bc:24:11:35:1c:c5 ip saddr 192.168.27.100 ip daddr 10.0.0.53 ip dscp cs0 ip ecn not-ect ip ttl 63 ip id 64190 ip length 68 udp sport 58012 udp dport 53 udp length 48 @th,64,96 0x990701200001000000000001
    trace id 0abb78f9 ip vyos_filter VYOS_ZONE_FORWARD packet: iif "eth2" oif "pppoe0" ether saddr bc:24:11:27:72:1b ether daddr bc:24:11:35:1c:c5 ip saddr 192.168.27.100 ip daddr 10.0.0.53 ip dscp cs0 ip ecn not-ect ip ttl 63 ip id 64190 ip length 68 udp sport 58012 udp dport 53 udp length 48 @th,64,96 0x990701200001000000000001
    trace id 0abb78f9 ip vyos_mangle VYOS_PBR_POSTROUTING packet: iif "eth2" oif "pppoe0" ether saddr bc:24:11:27:72:1b ether daddr bc:24:11:35:1c:c5 ip saddr 192.168.27.100 ip daddr 10.0.0.53 ip dscp cs0 ip ecn not-ect ip ttl 63 ip id 64190 ip length 68 udp sport 58012 udp dport 53 udp length 48 @th,64,96 0x990701200001000000000001
    trace id 0abb78f9 ip nat VYOS_PRE_SNAT_HOOK packet: iif "eth2" oif "pppoe0" ether saddr bc:24:11:27:72:1b ether daddr bc:24:11:35:1c:c5 ip saddr 192.168.27.100 ip daddr 10.0.0.53 ip dscp cs0 ip ecn not-ect ip ttl 63 ip id 64190 ip length 68 udp sport 58012 udp dport 53 udp length 48 @th,64,96 0x990701200001000000000001
    trace id 0abb78f9 ip vyos_static_nat POSTROUTING packet: iif "eth2" oif "pppoe0" ether saddr bc:24:11:27:72:1b ether daddr bc:24:11:35:1c:c5 ip saddr 192.168.27.100 ip daddr 10.0.0.53 ip dscp cs0 ip ecn not-ect ip ttl 63 ip id 64190 ip length 68 udp sport 58012 udp dport 53 udp length 48 @th,64,96 0x990701200001000000000001
  • Protected: VyOS MiTMPROXY Using WireGuard

    This content is password-protected. To view it, please enter the password below.

  • 海康威视 R1 安全迁移 Docker Root

    桌面App 直接迁移,会提示数据要重新下载和配置。

    systemctl stop containerd
    mv /drives/raid_a1/.docker /drives/nvme_e1/
    
    # 
    cd /tmp/nand_config
    cp docker.json docker.json.bak
    # 修改 docker.json
    # 看后边说明 
    
    
    # 修改 /etc/docker/daemon.json,配置不能持久化
    # 直接修改路径,可以不重启生效,但是务必按说明修改持久化配置
    systemctl start containerd

    桌面客户端可以改配置(Docker设置 / 装载目录),建议顺手先改掉。

    固件里 /tmp/nand_config/docker.json 是自动生成的,里边定义了 disk_pathdisk_uuid,前者的值是类似 /drives/raid_a1,后者是用 disk_get_uuid_byfilepath 的函数生成的,有重建逻辑,删掉即可。