Bose SoundTouch 30 II 迁移至 AfterTouch 完整指南
环境信息
| 项目 | 说明 |
|---|---|
| 音箱型号 | Bose SoundTouch 30 Series II |
| 音箱固件 | 27.0.6(从 7.2.21 升级) |
| 音箱 IP | 10.0.0.249 |
| AfterTouch 服务器 | Debian 12,IP: 10.0.0.6 |
| 主路由 | MikroTik RouterOS,IP: 10.0.0.1 |
| 旁路由 | iStoreOS(v2rayA),IP: 10.0.0.251 |
| 无线 AP | Netgear Orbi,IP: 10.0.0.200(WAN),192.168.88.1(LAN) |
前置条件
升级音箱固件
音箱出厂固件为 7.2.21(2014年),该版本太老,无法通过网页界面或 AfterTouch 启用 SSH。需要先通过 USB 方式升级到 27.x。
USB 升级步骤:
-
在 下载固件,选择
Firmware/Non-Bluetooth/目录下的最新版本(27.x) -
将
Update.stu文件复制到 FAT32 格式的 U 盘根目录 -
音箱断电,同时按住顶部 4 键 + Volume-,插电
-
等待音箱完成更新并重启
命令行升级:
!!7.2固件太过陈旧,网页端总是升级失败,我用的是curl命令行把固件传到音箱升级成功的,升级固件之后最好恢复出厂设置一下,我就是因为没有恢复出厂设置而出现一些问题的。
启用音箱 SSH
固件升级到 27.x 后,通过 AfterTouch CLI 启用 SSH:
# 安装 soundtouch-cli go install github.com/gesellix/bose-soundtouch/cmd/soundtouch-cli@latest # 启用 SSH(通过 17000 端口) SOUNDTOUCH_HOST=<音箱IP> soundtouch-cli setup enable-ssh
成功后可无密码 SSH 登录:
ssh -o HostKeyAlgorithms=+ssh-rsa,ssh-dss root@<音箱IP>
在 RouterOS 里通过 DHCP 静态租约绑定 IP 和 MAC。在 RouterOS 终端执行:
/ip dhcp-server lease print
找到音箱的租约后:
/ip dhcp-server lease make-static [find mac-address=08:DF:1F:0C:B0:D2] /ip dhcp-server lease set [find mac-address=08:DF:1F:0C:B0:D2] address=10.0.0.249
或者在 Winbox 里:IP → DHCP Server → Leases,找到音箱的 MAC,右键 Make Static,然后修改 IP 为 10.0.0.249。
AfterTouch 安装(Docker)
docker-compose.yml
services:
soundtouch-service:
image: ghcr.io/gesellix/bose-soundtouch:${SOUNDTOUCH_VERSION:-latest}
container_name: soundtouch-service
network_mode: host # Linux 必须开启,用于 UPnP 设备发现
environment:
- PORT=8000
- HTTPS_PORT=8443
- DATA_DIR=/app/data
- LOG_PROXY_BODY=false
- REDACT_PROXY_LOGS=true
- RECORD_INTERACTIONS=true
- DISCOVERY_INTERVAL=5m
- SERVER_URL=http://${SOUNDTOUCH_HOSTNAME:-soundtouch.local}:8000
- HTTPS_SERVER_URL=https://${SOUNDTOUCH_HOSTNAME:-soundtouch.local}:8443
- HTTPS_PROXY=http://10.0.0.251:20171 # v2rayA 代理,用于访问被墙域名
- https_proxy=http://10.0.0.251:20171
- NO_PROXY=localhost,127.0.0.1,10.0.0.0/8,*.bose.com,aftertouch.lan
- no_proxy=localhost,127.0.0.1,10.0.0.0/8,*.bose.com,aftertouch.lan
volumes:
- ./data:/app/data
restart: unless-stopped
!!注意:这里用了代理,因为brows和search功能被墙,用代理让这两个功能恢复
.env
SOUNDTOUCH_HOSTNAME=aftertouch.lan SOUNDTOUCH_VERSION=latest PREFERRED_DEVICES="SoundTouch [email protected]"
启动服务
docker compose up -d docker compose logs -f
AfterTouch 配置
Settings 配置
打开 http://10.0.0.6:8000/admin,进入 1. Settings:
-
Target Domain:
http://aftertouch.lan:8000 -
DNS Discovery Server: 启用
-
DNS Bind Address:
0.0.0.0:53 -
Upstream DNS:
10.0.0.251:53
aftertouch.lan 域名解析
在 iStoreOS 的 DHCP/DNS 里添加静态解析:
uci add_list dhcp.@dnsmasq[0].address='/aftertouch.lan/10.0.0.6' uci commit dhcp /etc/init.d/dnsmasq restart
音箱迁移
通过 AfterTouch 向导迁移
-
打开
http://10.0.0.6:8000/admin -
进入 2. Devices,点 Sync Data
-
点 Migrate,查看迁移摘要
-
在 Plan 部分确认 Target service URL 为
http://aftertouch.lan:8000 -
点 Apply Custom Plan(选择 XML over SSH)
-
按提示重启音箱
迁移成功后状态应为:
-
✅ URL Configuration: AfterTouch URLs
-
✅ DNS Interception: /etc/resolv.conf hook active
-
✅ CA / TLS: Local root CA installed
-
✅ SSH enabled (persistent)
音箱端配置
/etc/hosts(持久化,重启不丢失)
SSH 进音箱后添加以下记录:
mount -o remount,rw / cat >> /etc/hosts << 'EOF' 10.0.0.6 marge.bose.com 10.0.0.6 updates.bose.com 10.0.0.6 bmx.bose.com 10.0.0.6 streaming.bose.com 10.0.0.6 worldwide.bose.com 10.0.0.6 music.api.bose.com 10.0.0.6 stats.bose.com 10.0.0.6 content.api.bose.io 10.0.0.6 bosecm.com 10.0.0.6 events.api.bosecm.com 10.0.0.6 downloads.bose.com 10.0.0.6 streamingoauth.bose.com 10.0.0.6 bose-prod.apigee.net 10.0.0.6 bose-test.apigee.net 10.0.0.6 all.api.radio-browser.info 10.0.0.6 aftertouch.lan EOF
CA 证书安装
# 在 Debian 上下载 AfterTouch CA 证书 curl -k https://10.0.0.6:8443/api/setup/ca.crt -o /tmp/aftertouch-ca.crt # 传到音箱并安装 cat /tmp/aftertouch-ca.crt | ssh -o HostKeyAlgorithms=+ssh-rsa,ssh-dss [email protected] \ "mount -o remount,rw / && cat >> /etc/pki/tls/certs/ca-bundle.crt"
RadioBrowser 代理配置
RadioBrowser 的域名 all.api.radio-browser.info 在国内被墙,需要通过 nginx 代理转发到可用节点。
生成自签名证书
sudo mkdir -p /etc/nginx/ssl sudo openssl req -x509 -nodes -days 3650 -newkey rsa:2048 \ -keyout /etc/nginx/ssl/radiobrowser.key \ -out /etc/nginx/ssl/radiobrowser.crt \ -subj "/CN=all.api.radio-browser.info" \ -addext "subjectAltName=DNS:all.api.radio-browser.info"
nginx 配置
sudo vim /etc/nginx/sites-available/radiobrowser
server {
listen 80;
server_name all.api.radio-browser.info;
location /soundtouch/ {
proxy_pass https://de1.api.radio-browser.info/soundtouch/;
proxy_ssl_server_name on;
proxy_set_header Host de1.api.radio-browser.info;
proxy_ssl_verify off;
}
}
server {
listen 8444 ssl;
server_name all.api.radio-browser.info;
ssl_certificate /etc/nginx/ssl/radiobrowser.crt;
ssl_certificate_key /etc/nginx/ssl/radiobrowser.key;
location /soundtouch/ {
proxy_pass https://de1.api.radio-browser.info/soundtouch/;
proxy_ssl_server_name on;
proxy_set_header Host de1.api.radio-browser.info;
proxy_ssl_verify off;
}
}
sudo ln -s /etc/nginx/sites-available/radiobrowser /etc/nginx/sites-enabled/ sudo nginx -t && sudo systemctl reload nginx
把 nginx 证书安装到音箱
cat /etc/nginx/ssl/radiobrowser.crt | ssh -o HostKeyAlgorithms=+ssh-rsa,ssh-dss [email protected] \ "mount -o remount,rw / && cat >> /etc/pki/tls/certs/ca-bundle.crt"
把 AfterTouch CA 证书安装到 Debian(避免 nginx 自连接失败)
curl -k https://aftertouch.lan:8443/api/setup/ca.crt -o /tmp/aftertouch-ca-docker.crt sudo cp /tmp/aftertouch-ca-docker.crt /usr/local/share/ca-certificates/aftertouch-ca.crt sudo update-ca-certificates sudo systemctl reload nginx
iptables 规则
音箱的 443 流量需要根据目标地址分别转发:
# all.api.radio-browser.info(10.0.0.6) 的 443 转到 nginx 8444 sudo iptables -t nat -A PREROUTING -s 10.0.0.249 -d 10.0.0.6 -p tcp --dport 443 -j REDIRECT --to-port 8444 # 其他 443 流量(Bose 域名)转到 AfterTouch 8443 sudo iptables -t nat -A PREROUTING -s 10.0.0.249 -p tcp --dport 443 -j REDIRECT --to-port 8443 # 持久化保存 sudo netfilter-persistent save
v2rayA 代理配置
AfterTouch 访问 RadioBrowser API 需要代理。在 iStoreOS 的 v2rayA 界面:
-
Address and Ports → Port of HTTP:
20171 -
启用 Port Sharing
-
Transparent Proxy:
On: Proxy only GFWList -
Save and Apply
功能状态
| 功能 | 状态 | 说明 |
|---|---|---|
| RadioBrowser 搜索 | ✅ | 通过代理访问 API |
| RadioBrowser 播放 | ✅ | nginx 代理 + iptables |
| 直接 URL 播放 | ✅ | 完全正常 |
| 预设按钮 | ✅ | 完全正常 |
| TuneIn 搜索 | ✅ | 可以搜索 |
| TuneIn 播放 | ❌ | TuneIn 关闭了免费流地址 API |
| AirPlay | ✅ | 不依赖云服务 |
| Bluetooth | ✅ | 不依赖云服务 |
| Spotify Connect | ✅ | 不依赖云服务 |
播放流程说明
用户选择电台
↓
AfterTouch 通过代理(v2rayA) 查询 RadioBrowser API 获取流地址
↓
AfterTouch 通知音箱播放
↓
音箱直接连接电台服务器播放音频(不经过代理)
音频流由音箱直接从电台服务器获取,代理只用于 AfterTouch 查询电台信息,带宽占用极小。
数据备份
AfterTouch 所有数据存储在 ./data/ 目录,定期备份即可:
tar -czf aftertouch-backup-$(date +%Y%m%d).tar.gz /home/will/AfterTouch/data/
重启恢复清单
系统重启后需要确认以下内容自动恢复:
- AfterTouch Docker 容器(
restart: unless-stopped) - iptables 规则(
netfilter-persistent) - nginx 服务(
systemctl enable nginx) - 音箱
/etc/hosts配置(固件 27.x 持久化) - 音箱
/etc/resolv.conf
