OpenWrt SNAPSHOT sing-box的tun模式、扩容和配置docker容器大杂烩记录

OpenWrt SNAPSHOT sing-box的tun模式、扩容和配置docker容器大杂烩记录

#openwrt,#sing-box,#tun,#docker,#扩容,#软路由,#旁路由,#raspberry pi 4b,#pi4b,#docker,

pi4B(op) 基本参数如下

pi@Raspberry-Pi-4-Model-B-Rev-1.5
-----------------------------------
Host: Raspberry Pi 4 Model B Rev 1.5
Kernel: 6.6.71
Shell: bash
CPU: ARMv8 rev 3 (v8l) (4) @ 1.800GHz
Memory: 338MiB / 7811MiB

主路由器ip信息

ip 192.168.255.254
netmask 255.255.255.0
dhcp 1~253

需求是主路+旁路全局代理,所以 旁pi4B(op) 配置旁路需要网段相同启用强制DHCP,因此旁pi4B(op) ip信息如下

ip 192.168.255.253
netmask 255.255.255.0
dhcp 1~252

路由器连接是这样的

(((·)))                                                                          
      \                                                                          
    (wifi 2.4g 中继热点)                                                              
        \                                                                        
          +----------------------+                                               
          |    主路由器           |                   +-------------------------+ 
          |----------------------|                   | my computer             | 
          | WAN: wifi网络中继热点  | - - - (lan) - - - | IP: 192.168.255.54      | 
          | LAN: 192.168.255.254 |                   | DNS: 8.8.8.8,...        | 
          | DHCP: 1~253          |                   | GATEWAY: 192.168.255.253| 
          | DNS: 192.168.255.254 |                   +-------------------------+ 
          +----------------------+\                                            
                    |              \                                           
                    |               \                                          
                  (lan)            (wifi 2.4/5g 连接)                             
                    |                            \                                       
                    |                             \                                      
 +------------------+-----------------+            \                                    
 | 树莓派 (旁路由)                      |            +-------------------------+          
 |------------------------------------|            | my iphone               |           
 | LAN: 192.168.255.253               |            | IP: 192.168.255.53      |           
 | DNS: 192.168.255.254               |            | DNS: 8.8.8.8,...        |           
 | GATEWAY: 192.168.255.254           |            | GATEWAY: 192.168.255.253|           
 | op 配置全局 DHCP: 1~252             |            +-------------------------+           
 | op 配置全局 DNS: 8.8.8.8,...        |                                             
 | op 配置全局 GATEWAY: 192.168.255.253|                                             
 +------------------------------------+                                             
                   \                                                             
                (wifi 5g 连接)                                                    
                     \                                                           
              +-------------------------+                                        
              | my other device         |                                        
              | IP: 192.168.255.55      |                                        
              | DNS: 8.8.8.8,...        |                                        
              | GATEWAY: 192.168.255.253|                                        
              +-------------------------+                                       

最新版本的 OpenWrt SNAPSHOT 使用 apk 命令更新安装软件

※ 注意 SNAPSHOT 版本没有 luci 界面下载前可以请求官方网站预构建一个带界面的镜像

可以在构建界面添加 luci 安装包
0

luci 界面配置网络,网段相同使其联网,构建的镜像时使用了脚本就跳过这个步骤吧,好吗?

web 访问 http://192.168.1.1 第一次没密码,可以先设置密码,比如 root ,也可以修改ssh端口比如 8022
点击 network -> interfaces -> lan -> edit
修改 IPv4 address 地址比如 192.168.255.253
修改 IPv4 gateway地址为主路由地址 192.168.255.254
点击 Advanced Settings
修改 Use custom DNS servers 为主路由地址 192.168.255.254
修改 IPv6 assignment length 为 64
修改 IPv6 suffix 为 random
点击 DHCP Server
修改 Start 为 1 Limit 为 252,这样相当于旁路 DHCP 1~252 用于接管主路由
点击 DHCP Server->Advanced Settings
勾选 Force 强制本地 DHCP
DHCP-Options 添加 3,192.168.255.253 和 6,8.8.8.8,114.114.114.114,1.1.1.1,223.5.5.5 作为主路由 网关和DNS 的依据
最后点击 save 并点击 Save & Apply 等待几秒断开连接并重新连接
等待主机在dhcp模式下网关变成 192.168.255.253,并通过 web 访问 http://192.168.255.253
这个访问一定要快,在1分钟内如果你没能访问成功,旁路pi4B(op)将恢复默认配置,切记
这个时候大概也许 pi4B(op) 就可以联网继续接下来的操作了

在联网状态下连接 ssh 安装软件包

# sshpass 和 ssh 配合免密连接 
# sshpass 需要你手动安装的程序,作用可以将密码传递给 ssh 等远程连接工具实现免密执行
# -p 'root' 旁路pi4B(op) 密码 root
# -p '8022' 旁路pi4B(op)  端口 8022
# -tt 伪终端模式
# root@192.168.255.253 表示用户为 root IP为 192.168.255.253 的 旁路pi4B(op)
sshpass -p 'root' ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -p '8022' -tt 'root@192.168.255.253'

# 安装软件包
apk update

# unzip 一种解压工具
# cfdisk block-mount rsync 用于扩容同步的工具
# kmod-inet-diag kmod-netlink-diag kmod-tun iptables-nft kmod-tcp-bbr sing-box 科学上网核心和网络工具
apk add unzip cfdisk block-mount rsync kmod-inet-diag kmod-netlink-diag kmod-tun iptables-nft kmod-tcp-bbr kmod-nft-tproxy sing-box

添加 sing-box tun0 接口

cat << 469138946ba5fa | tee -a /etc/config/network
config interface 'tun0'
        option proto 'none'
        option device 'tun0'
        option mtu '1500'
469138946ba5fa
/etc/init.d/network restart

防火墙 tun0 开口

cat << 469138946ba5fa | tee -a /etc/config/firewall

config zone
        option name 'tun0'
        option forward 'ACCEPT'
        option output 'ACCEPT'
        option input 'ACCEPT'
        option device 'tun0'
        list network 'tun0'
        option masq '1'  # 开启伪装
        option mtu_fix '1' # 修复 MTU

config forwarding
        option name 'lan'
        option dest 'tun0'
        option src 'lan'
469138946ba5fa
/etc/init.d/firewall restart

配置 DHCP DNS

主要是修改 dns 为 8.8.8.8, 1.1.1.1 这样能更好的提供解析

# /etc/config/dhcp
uci set dhcp.lan.force='1'
uci add_list dhcp.lan.dhcp_option='6,8.8.8.8,114.114.114.114,1.1.1.1,223.5.5.5'
uci add_list dhcp.lan.dhcp_option='3,192.168.255.253'
uci commit dhcp

配置 sing-box

# 启用 sing-box 配置
# 配置用户为 root
# 配置 config.json 路径
# 配置工作目录
cat << 469138946ba5fa | tee /etc/config/sing-box
config sing-box 'main'
    # option enabled '0'
    option enabled '1'
    # option user 'sing-box'
    option user 'root'
    option conffile '/usr/share/sing-box/config.json'
    option workdir '/usr/share/sing-box'
    # list ifaces 'wan'
    # list ifaces 'wan6'
    option log_stderr '1'
    option log_stdout '1'
469138946ba5fa

修改sing-box服务文件参数

cat << '469138946ba5fa' | tee /etc/init.d/sing-box
#!/bin/sh /etc/rc.common

USE_PROCD=1
START=99

script=$(readlink "$initscript")
NAME="$(basename ${script:-$initscript})"
PROG="/usr/bin/sing-box"

start_service() {
  config_load "$NAME"

  local enabled user group conffile workdir ifaces
  local log_stdout log_stderr
  config_get_bool enabled "main" "enabled" "0"
  [ "$enabled" -eq "1" ] || return 0

  config_get user "main" "user" "root"
  config_get conffile "main" "conffile"
  config_get ifaces "main" "ifaces"
  config_get workdir "main" "workdir" "/usr/share/sing-box"
  config_get_bool log_stdout "main" "log_stdout" "1"
  config_get_bool log_stderr "main" "log_stderr" "1"

  mkdir -p "$workdir"
  local group="$(id -ng $user)"
  chown $user:$group "$workdir"

  procd_open_instance "$NAME.main"
  procd_set_param command "$PROG" run -c "$conffile" -D "$workdir"

  # Use root user if you want to use the TUN mode.
  procd_set_param user "$user"
  procd_set_param limits core="unlimited"
  procd_set_param limits nofile="1000000 1000000"
  procd_set_param file "$conffile"
  [ -z "$ifaces" ] || procd_set_param netdev $ifaces
  procd_set_param stdout "$log_stdout"
  procd_set_param stderr "$log_stderr"
  procd_set_param respawn

  procd_close_instance
  echo "sing-box is started!"
}

service_triggers() {
  local ifaces
  config_load "$NAME"
  config_get ifaces "main" "ifaces"
  procd_open_trigger
  for iface in $ifaces; do
  	procd_add_interface_trigger "interface.*.up" $iface /etc/init.d/$NAME restart
  done
  procd_close_trigger
  procd_add_reload_trigger "$NAME"
}

stop_service() {
  service_stop $PROG
  echo "sing-box is stopped!"
}
 
reload_service() {
  stop
  echo "sing-box is restarted!"
  start
}
469138946ba5fa

创建 sing-box 工作目录

mkdir -pv /usr/share/sing-box/

上传配置文件

配置文件可以自定义配置ui管理面板请自行配置
建议配置文件 inbounds 明确指定 tun 监听接口和 /etc/config/network 里的 tun0 一致
并增大 mtu 和 /etc/config/network 里的 tun0 一致比如 1500
如下

    "inbounds": [
    ... 其他配置 ...
    {
        "type": "tun",
        "tag": "TUN入站_469138946ba5fa",
        "interface_name": "tun0",
        "auto_route": true,
        "strict_route": true,
        "stack": "mixed",
        "mtu": 1500,
        "endpoint_independent_nat": true,
        ... 其他配置 ...
    },
    ... 其他配置 ...
    ]
    "route": {
        "rules": [
        ... 其他配置 ...
        {
            "inbound": [
            "redir入站_469138946ba5fa",
            ... 其他配置 ...
            ],
            "action": "sniff"
        },
        ... 其他配置 ...
        ]
    }
# 本地测试好可用的配置文件 sing-box config.json 上传到 openwrt 工作目录
# 这里利用了 sshpass 配合 scp 免输入密码操作
# -p 'root' 为 openwrt 密码 root
# -P '8022' 为 openwrt 端口 8022
# 'singbox-config.json' 是本地文件 
# 'root@192.168.255.253:/usr/share/sing-box/config.json' 意思是用户为 root ip 为 192.168.255.253 路径为 /usr/share/sing-box/config.json 
sshpass -p 'root' scp -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -O -r -P '8022' $HOME'/Desktop/sing-box-subscribe/singbox-config.json' 'root@192.168.255.253:/usr/share/sing-box/config.json'

覆盖 sing-box 版本

# 本地下载最新版本 sing-box-linux 覆盖 openwrt sing-box 版本
sshpass -p 'root' scp -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -O -r -P '8022' $HOME'/Desktop/docker-workspace/docker-arch-sub-topfreeproxies/topfreeproxies/sing-box-linux' 'root@192.168.255.253:/usr/bin/sing-box'

启动 sing-box 及其相关命令

# 启动前检查配置文件,有错误就按照提示修改
sing-box -c /usr/share/sing-box/config.json check
# 自启动
/etc/init.d/sing-box enable
# 启动
/etc/init.d/sing-box start
# 重启
/etc/init.d/sing-box restart
# 运行状态
/etc/init.d/sing-box status

# 检查命令(排查用)
ip addr show tun0
ip route show table all | grep -E 'tun0|sing-box'
ip rule show
# 查看 nftables 规则
nft list ruleset | grep -E 'tun|sing'
# 实时日志,看是否有错误
logread -f | grep sing-box

扩容磁盘

# 我的磁盘刷入的镜像是 Sysupgrade 格式,需要扩容,还要给docker容器一部分空间
# 以下是我的磁盘信息,目标是希望将 238.7G 空闲空间分成 1.1G 和 237.6G 分别用于扩容装软件和docker容器存储运行
        Disk: /dev/sda
        Size: 239.02 GiB, 256641603584 bytes, 501253132 sectors
        Label: dos, identifier: 0x05bac124
        Device        Boot      Size    Id Type
        Free space                3M    
        /dev/sda1     *          64M    c W95 FAT32 (LBA)
        Free space                4M    
        /dev/sda2               300M    83 Linux
        Free space            238.7G    

创建新分区

# 执行以下命令,选择 238.7G 空闲空间
# 选择 New 输入大小 1.1G
# 选择 primary
# 选择 Write 输入 yes
# 重复以上步骤,选择 237.6G 空闲空间
# 选择 New 输入大小 237.6G
# 选择 primary
# 选择 Write 输入 yes
# 选择 Quit
cfdisk 

创建完之后的效果如下

        Disk: /dev/sda
        Size: 239.02 GiB, 256641603584 bytes, 501253132 sectors
        Label: dos, identifier: 0x05bac124
        Device        Boot      Size    Id Type
        Free space                3M    
        /dev/sda1     *          64M    c W95 FAT32 (LBA)
        Free space                4M    
        /dev/sda2               300M    83 Linux
        /dev/sda3               1.1G    83 Linux
        /dev/sda4             237.6G    83 Linux

格式化新分区

# 格式化两个空间为 ext4
mkfs.ext4 /dev/sda3
mkfs.ext4 /dev/sda4

创建挂载目录

# 为两个空间创建显眼的目录
mkdir -pv /mnt/sda3
mkdir -pv /mnt/sda4

挂载新分区

# 首先扩容,此时空间已经很小了,先挂载 1.1G 空间
mount /dev/sda3 /mnt/sda3

同步软件目录

rsync -aPtuvz /overlay/ /mnt/sda3/
# 同步磁盘状态
sync
# 解除挂载
umount /mnt/sda3/
# 删除无用目录 /mnt/sda3/
rm -frv /mnt/sda3/

web 访问 openwrt 界面,在 系统 挂载点 里配置 /dev/sda3 为 /overlay/ 并启用 保存并应用 重启 检查是否成功

安装 docker 环境

apk add docker dockerd docker-compose luci-app-dockerman
# 挂载 237.6G 空间
mount /dev/sda4 /mnt/sda4
# 同步 docker 主目录
rsync -aPtuvz /opt/docker /mnt/sda4/
# 同步磁盘状态
sync

web 访问 openwrt 界面,在 docker 配置 选择 /mnt/sda4/docker/ 作为docker容器根目录 保存并应用

web 访问 openwrt 界面,在 系统 挂载点 配置 /dev/sda4 为 /mnt/sda4 并启用 保存并应用 重启 检查是否成功

上传 docker-compose 配置文件目录

这些目录都是我本地运行的但是又不占用存储空间和内存,就想着迁移一下
你也可以将自己不太重要的需要长时间运行的项目放到openwrt上,做个迁移测试

# 将本地测试好的 watchtower docker-compose-arm64.yaml 上传到 openwrt docker 主目录
sshpass -p 'root' scp -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -O -r -P '8022' $HOME'/Desktop/docker-workspace/docker-arch-watchtower' 'root@192.168.255.253:/mnt/sda4/'
# 将本地测试好的 qinglong docker-compose-arm64.yaml 上传到 openwrt docker 主目录
sshpass -p 'root' scp -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -O -r -P '8022' $HOME'/Desktop/docker-workspace/docker-arch-ql' 'root@192.168.255.253:/mnt/sda4/'
# 将本地测试好的 qinglong 所生成的配置目录 docker-container/ql 上传到 openwrt docker 主目录
sshpass -p 'root' scp -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -O -r -P '8022' '/mnt/TOSHIBA3T/docker-container/ql' 'root@192.168.255.253:/mnt/sda4/docker-arch-ql/'
# 将本地测试好的 samba docker-compose-arm64.yaml 上传到 openwrt docker 主目录
sshpass -p 'root' scp -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -O -r -P '8022' $HOME'/Desktop/docker-workspace/docker-arch-samba' 'root@192.168.255.253:/mnt/sda4/'
# 将本地 .ssh 上传到 openwrt 主目录,为了以 ssh 方式 git clone 或 git push 方便
sshpass -p 'root' scp -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -O -r -P '8022' $HOME'/.ssh' 'root@192.168.255.253:~/'

Openwrt 安装 OpenSSH 和 Git

# 安装 openssh-client openssh-keygen git git-http 为了生成 ssh 密钥并使用 git 获取docker项目
apk add openssh-client openssh-keygen git git-http
# 当然也可以选择自己创建 ssh 密钥,并在 github 中配置允许 ssh 方式 git clone 或 git push
ssh-keygen -t ed25519
# 配置私钥仅 root 用户可读写
chmod 600 /root/.ssh/id_ed25519
# 将自己喜欢的项目 clone 到 openwrt docker 主目录
git clone 'https://github.com/af5ab649831964/docker-arch-sub-topfreeproxies' /mnt/sda4/docker-arch-sub-topfreeproxies

创建 Docker 项目

# 也可以创建自己喜欢的 docker 项目,比如 1panel 
mkdir -pv /mnt/sda4/docker-arch-1panel
# 写入配置文件,这个参考了 https://hub.docker.com/r/moelin/1panel 镜像,可能不是官方的可是很好用
# 默认端口:10086
# 默认入口:/entrance
# 默认账户:1panel
# 默认密码:1panel_password
cat << '469138946ba5fa' | tee /mnt/sda4/docker-arch-1panel/docker-compose-arm64.yml
services:
  1panel-app:
    platform: linux/arm64/v8
    container_name: 1panel-arm64v8-container
    environment:
      - TZ=Asia/Shanghai
      #- http_proxy=http://IP:PORT
      #- https_proxy=http://IP:PORT
      #- all_proxy=socks5://IP:PORT
    image: docker.io/moelin/1panel:latest
    #network_mode: bridge
    networks:
      - app-net
    ports:
      - "10086:10086"
    privileged: true
    restart: "always"
    logging:
      driver: json-file
      options:
        max-size: 1m
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - /mnt/sda4/docker/volumes:/var/lib/docker/volumes
      - ./opt:/opt
      - ./root:/root
networks:
  app-net:
    #driver: host
    driver: bridge
    #external: true
469138946ba5fa

进入 OpenWrt Docker 主目录

cd /mnt/sda4/

检查和配置 Docker Compose 文件

# 对每个 docker-compose-arm64.yml 进行检查和最终配置
vi /mnt/sda4/docker-arch-ql/docker-compose-arm64.yml
vi /mnt/sda4/docker-arch-samba/docker-compose-arm64.yml
vi /mnt/sda4/docker-arch-watchtower/docker-compose-arm64.yml
vi /mnt/sda4/docker-arch-sub-topfreeproxies/docker-compose-arm64.yml
vi /mnt/sda4/docker-arch-sub-topfreeproxies/topfreeproxies/utils/config.ini

批量启用 Docker 容器

# 备份当前的 IFS(内部字段分隔符)
IFS_BAK=$IFS
# 将 IFS 设置为换行符
IFS=$'\n'
# 查找 /mnt/sda4 目录下所有名称包含 "docker-arch" 的目录
for i in $(find /mnt/sda4 -type d -iname "docker-arch*")
do
        # 输出当前目录路径
        echo $i
        # 切换到当前目录
        cd $i
        # 停止当前目录下的 Docker 容器
        docker-compose -f docker-compose-arm64.yml stop
        # 删除当前目录下的 Docker 容器
        docker-compose -f docker-compose-arm64.yml rm -f
        # 重新创建并启动当前目录下的 Docker 容器
        docker-compose -f docker-compose-arm64.yml up -d --force-recreate
done
# 恢复原来的 IFS
IFS=$IFS_BAK

web 访问 openwrt 界面,在 网络 防火墙 常规设置 forward 改为 accept 以允许 docker 端口可被访问

crontab 自动化

crontab -e
34 4 * * * cd /mnt/sda4/docker-arch-sub-topfreeproxies/ ; docker-compose -f docker-compose-arm64.yml stop ; docker-compose -f docker-compose-arm64.yml rm -fv ; docker-compose -f docker-compose-arm64.yml up -d --force-recreate

参考

Comments