中兴B760h 盒子折腾笔记
联通IPTV送的电视盒子 B760h 一直闲置,最近给它刷了一下固件,当作一个小型nas给手机使用。这个盒子国内的固件不多,我下载马来西亚的固件,直接线刷,一次性成功。重启后发现这个盒子居然有wifi和蓝牙。这个盒子使用的MTK8685 芯片,支持的安卓版本是4.4.2,我找遍全网也没发现更新的估计版本。termux 是不能安装了,只能尝试chroot 的方式了。安装Simple SSHD 过后,就可以使用putty 远程连接盒子,尝试过linux deploy 但是没有成功。最后成功在chroot 中运行apline linux ,但是使用的不是linux deploy,而是shell 脚本。这个脚本是从网络上找的,然后我修改成使用国内的镜像源。
#!/system/bin/sh
INSTALL='/mnt/sdcard2'
APKTOOLS='2.10.6-r0'
ARCH='armhf'
MIRROR='http://mirrors.ustc.edu.cn/alpine'
VER='v3.9'
RED='\033[0;31m'
NC='\033[0m'
set -e
mkdir -p $INSTALL/etc
printf "${RED}remounting /system as writable to write /etc/resolv.conf${NC}"
mount -o remount,rw $(mount | grep '/system' | awk '{ print $1 }') /system
printf "${RED}initing DNS settings"
echo -e "nameserver $(getprop net.dns1)\nnameserver $(getprop net.dns2)" > /etc/resolv.conf
set +e; mkdir $INSTALL/etc; set -e
cp /etc/resolv.conf $INSTALL/etc/.
printf "${RED}Downloading Static installer apk...${NC}\n"
set -x
wget $MIRROR/$VER/main/$ARCH/apk-tools-static-$APKTOOLS.apk
tar -xzf apk-tools-static-*.apk
rm apk-tools-static-*.apk
rm .PKGINFO
printf "\n${RED}Installing Base Alpine...${NC}\n"
./sbin/apk.static -X $MIRROR/$VER/main -U --allow-untrusted --root $INSTALL --initdb add alpine-base
rm -r ./sbin/
printf "\n${RED}Adding Repos to chroot${NC}\n"
echo "$MIRROR/$VER/main" > $INSTALL/etc/apk/repositories
echo "$MIRROR/$VER/community" >> $INSTALL/etc/apk/repositories
echo "http://mirrors.ustc.edu.cn/alpine/edge/testing/" >> $INSTALL/etc/apk/repositories
printf "\n\n${RED} Done! Logging into chroot..${NC}\n"
echo "in the future you can do this using: chroot $INSTALL bash"
chroot $INSTALL apk update
运行完上面那个脚本和就可以在chroot 中运行apline linux了。
在apline 中安装一些常用的软件
apk add curl jq samba nginx
就可以运行cloudflare ddns的脚本了,原脚本使用grep 和正则表达式来拆解cloudflare 发过来的json,busybox 的grep 的正则表达式功能比较弱,索性改成jq了。
#!/usr/bin/env bash
set -o errexit
set -o nounset
#set -o pipefail
# Automatically update your CloudFlare DNS record to the IP, Dynamic DNS
# Can retrieve cloudflare Domain id and list zone's, because, lazy
# Sparkle version
# Place at:
# sudo wget https://raw.githubusercontent.com/zanjie1999/cloudflare-api-v4-ddns/master/cf-v4-ddns.sh -O /usr/local/bin/cf-ddns.sh
# sudo chmod +x /usr/local/bin/cf-ddns.sh
# sudo nano /usr/local/bin/cf-ddns.sh
# run `crontab -e` and add next line:
# */2 * * * * /usr/local/bin/cf-ddns.sh >/dev/null 2>&1
# or you need log:
# */2 * * * * /usr/local/bin/cf-ddns.sh >> /var/log/cf-ddns.log 2>&1
# Usage:
# cf-ddns.sh -k cloudflare-api-token \
# -h host.example.com \ # fqdn of the record you want to update
# -z example.com \ # will show you all zones if forgot, but you need this
# -t A|AAAA # specify ipv4/ipv6, default: ipv4
# -p cache file path # default /$HOME/.cf
# Optional flags:
# -f false|true \ # force dns update, disregard local stored ip
# default config
# API Token, see https://dash.cloudflare.com/profile/api-tokens,
CFTOKEN=xxxxxxxxxxxxxxxxxxxxxxxxxxx
# Zone name, eg: example.com
CFZONE_NAME=example.com
# Hostname to update, eg: homeserver.example.com or example.com
CFRECORD_NAME=redmi6a.cwyyprog.com
# Record type, A(IPv4)|AAAA(IPv6), default IPv4
CFRECORD_TYPE=AAAA
# Cloudflare TTL for record, between 120 and 86400 seconds
CFTTL=120
# Ignore local file, update ip anyway
FORCE=false
CFFILE_PATH=/$HOME/.cf
WANIPSITE="http://v4.ipv6-test.com/api/myip.php"
NOW_DATE_TIME=$(date "+%Y-%m-%d %H:%M:%S")
# Site to retrieve WAN ip, other examples are: bot.whatismyipaddress.com, https://api.ipify.org/ ...
if [ "$CFRECORD_TYPE" = "A" ]; then
:
elif [ "$CFRECORD_TYPE" = "AAAA" ]; then
WANIPSITE="http://v6.ipv6-test.com/api/myip.php"
else
echo "$NOW_DATE_TIME $CFRECORD_TYPE specified is invalid, CFRECORD_TYPE can only be A(for IPv4)|AAAA(for IPv6)"
exit 2
fi
# get parameter
while getopts k:h:z:t:f:p: opts; do
case ${opts} in
k) CFTOKEN=${OPTARG} ;;
h) CFRECORD_NAME=${OPTARG} ;;
z) CFZONE_NAME=${OPTARG} ;;
t) CFRECORD_TYPE=${OPTARG} ;;
f) FORCE=${OPTARG} ;;
p) CFFILE_PATH=${OPTARG} ;;
esac
done
# mkdir if CFFILE_PATH not exist
if [ ! -d "$CFFILE_PATH" ];then
mkdir -p $CFFILE_PATH
fi
# If required settings are missing just exit
if [ "$CFTOKEN" = "" ]; then
echo "$NOW_DATE_TIME Missing api-key, get at: https://dash.cloudflare.com/profile/api-tokens"
echo "$NOW_DATE_TIME and save in ${0} or using the -k flag"
exit 2
fi
if [ "$CFRECORD_NAME" = "" ]; then
echo "$NOW_DATE_TIME Missing hostname, what host do you want to update?"
echo "$NOW_DATE_TIME save in ${0} or using the -h flag"
exit 2
fi
# If the hostname is not a FQDN
if [ "$CFRECORD_NAME" != "$CFZONE_NAME" ] && ! [ -z "${CFRECORD_NAME##*$CFZONE_NAME}" ]; then
CFRECORD_NAME="$CFRECORD_NAME.$CFZONE_NAME"
echo "$NOW_DATE_TIME => Hostname is not a FQDN, assuming $CFRECORD_NAME"
fi
# Get current and old WAN ip
WAN_IP=`curl -s ${WANIPSITE}`
WAN_IP_FILE=$CFFILE_PATH/.cf-wan_ip_$CFRECORD_NAME.txt
if [ -f $WAN_IP_FILE ]; then
OLD_WAN_IP=`cat $WAN_IP_FILE`
else
echo "$NOW_DATE_TIME No file, need IP"
OLD_WAN_IP=""
fi
# If WAN IP is unchanged an not -f flag, exit here
if [ "$WAN_IP" = "$OLD_WAN_IP" ] && [ "$FORCE" = false ]; then
echo "$NOW_DATE_TIME WAN IP Unchanged, to update anyway use flag -f true"
exit 0
fi
# Get zone_identifier & record_identifier
ID_FILE=$CFFILE_PATH/.cf-id_$CFRECORD_NAME.txt
if [ -f $ID_FILE ] && [ $(wc -l $ID_FILE | cut -d " " -f 1) == 4 ] \
&& [ "$(sed -n '3,1p' "$ID_FILE")" == "$CFZONE_NAME" ] \
&& [ "$(sed -n '4,1p' "$ID_FILE")" == "$CFRECORD_NAME" ]; then
CFZONE_ID=$(sed -n '1,1p' "$ID_FILE")
CFRECORD_ID=$(sed -n '2,1p' "$ID_FILE")
else
echo "$NOW_DATE_TIME Updating zone_identifier & record_identifier"
CFZONE_ID=$(curl -s -X GET "https://api.cloudflare.com/client/v4/zones?name=$CFZONE_NAME" -H "Authorization: Bearer $CFTOKEN" -H "Content-Type: application/json" | grep -Po '(?<="id":")[^"]*' | head -1 )
CFRECORD_ID=$(curl -s -X GET "https://api.cloudflare.com/client/v4/zones/$CFZONE_ID/dns_records?name=$CFRECORD_NAME" -H "Authorization: Bearer $CFTOKEN" -H "Content-Type: application/json" | grep -Po '(?<="id":")[^"]*' | head -1 )
echo "$CFZONE_ID" > $ID_FILE
echo "$CFRECORD_ID" >> $ID_FILE
echo "$CFZONE_NAME" >> $ID_FILE
echo "$CFRECORD_NAME" >> $ID_FILE
fi
# If WAN is changed, update cloudflare
echo "$NOW_DATE_TIME Updating DNS to $WAN_IP"
RESPONSE=$(curl -s -X PUT "https://api.cloudflare.com/client/v4/zones/$CFZONE_ID/dns_records/$CFRECORD_ID" \
-H "Authorization: Bearer $CFTOKEN" \
-H "Content-Type: application/json" \
--data "{\"id\":\"$CFZONE_ID\",\"type\":\"$CFRECORD_TYPE\",\"name\":\"$CFRECORD_NAME\",\"content\":\"$WAN_IP\", \"ttl\":$CFTTL}")
if [ "$RESPONSE" != "${RESPONSE%success*}" ] && [ "$(echo $RESPONSE | grep "\"success\":true")" != "" ]; then
echo "$NOW_DATE_TIME Updated succesfuly!"
echo "$WAN_IP" > $WAN_IP_FILE
exit
else
echo "$NOW_DATE_TIME Something went wrong :("
echo "$NOW_DATE_TIME Response: $RESPONSE"
exit 1
fi
可以使用android 系统自带的crond 来运行上面这个ddns 更新脚本。
user@ztemt85_bx_kk:/data/data/org.galexander.sshd/files $ cat /system/crontab/root
*/2 * * * * chroot /storage/sdcard1 /bin/bash -l /usr/local/bin/cloudflare_ddns.sh -t AAAA >> /mnt/sda1/ddns.log 2>&1
*/2 * * * * chroot /storage/sdcard1 /bin/bash -l /usr/local/bin/cloudflare_ddns.sh -t A >> /mnt/sda1/ddns.log 2>&1
aria2c 1.34 版本还支持armhf,下载下来放上去可以正常运行。
最后是启动crond的init 脚本。
user@ztemt85_bx_kk:/data/data/org.galexander.sshd/files $ cat /etc/init.d/99apline
#!/system/bin/sh
mount -t ext4 /dev/block/mmcblk1p1 /storage/sdcard1
mount -o bind /dev /storage/sdcard1/dev
mount -o bind /proc /storage/sdcard1/proc
ntfs-3g /dev/block/sda1 /storage/sdcard1/mnt
chroot /storage/sdcard1 /usr/sbin/nmbd -D
chroot /storage/sdcard1 /usr/sbin/smbd -D
chroot /storage/sdcard1 /usr/sbin/nginx
crond -b -c /system/crontab
aria2c --conf-path /etc/aria2.conf > /tmp/aria2.log 2>&1
MTK8685 芯片由于没有开源的驱动代码,可玩性也就这样了。
感谢分享 赞一个