avatar🌌
seewhyseewhy的小木屋

宠辱不惊,看庭前花开花落。 去留无意,望天空云卷云舒。

用 Debian 搭建家庭服务器:透明代理、去广告和自建服务

背景

最近入手了一台小主机,折腾了快一个月,记录一下过程。 主要需求:

  • 旁路由/透明代理
  • 去广告
  • 手机照片同步备份
  • Mac Time Machine 备份
  • 笔记、配置文件同步
  • 各种自建服务和 RSS

硬件配置

硬件没有研究太多,感觉性能应该是过剩的,买得比较随意。

  • 主机:天钡 WTR Pro,1350 RMB
  • 机械硬盘:官换新盘希捷银河 16T,1080 RMB
  • SSD:光威 256G,119 RMB
  • 内存:英睿达 16G DDR4,210 RMB

debian 安装

系统安装比较常规,先在官网 https://www.debian.org/releases/bookworm/releasenotes 下载 amd64 位版本镜像。

最开始选了 minimal 版本,安装时需要从网络下载依赖,结果下了很久都没下好,最后还是重新下载了 DVD 版本。然后刻录到 U 盘,开机时按 DEL 进入 BIOS,选择从 U 盘启动。

最终架构

目前这台 Debian 小主机主要承担三类角色:

  • 旁路由:需要代理的设备把网关和 DNS 指到 Debian。
  • DNS 和去广告:AdGuard Home 负责 DNS 查询和过滤,上游指向 sing-box 的 530 端口。
  • Docker 主机:CasaOS 负责管理常用容器,Cloudflared 和 WireGuard Easy 负责外部访问,其他应用按需跑在 Docker 里。

整体链路大概是:

text
手机 / 电脑
  -> Debian 小主机网关
  -> sing-box 透明代理
  -> AdGuard Home 处理 DNS
  -> 路由器出网

家里的主路由还是官方系统,没有再刷 OpenWrt。这样主路由保持稳定,折腾都放在 Debian 这台机器上,出问题时也比较容易回退。

透明代理

之前在路由器上刷了 OpenWrt,但是最终感觉不稳定,也不想继续折腾路由器本身,就又刷回了官方系统。

现在直接用 Debian 做旁路由。需要代理的设备,把网关和 DNS 改成 Debian 的 IP,就可以走透明代理。

主要步骤:

首先通过 ip a 查看设备网卡名,这里为 enp3s0,然后编辑 /etc/network/interfaces 文件,其中 gateway 是路由器 ip。

# This file describes the network interfaces available on your system
# and how to activate them. For more information, see interfaces(5).

source /etc/network/interfaces.d/*

# The loopback network interface
auto lo
iface lo inet loopback

auto enp3s0
iface enp3s0 inet static
        address 192.168.6.16
        netmask 255.255.255.0
        gateway 192.168.6.1
	dns-nameservers 192.168.6.16

iface enp3s0 inet6 auto

接着重启网络服务 sudo systemctl restart networking.service。 最后编辑 /etc/sysctl.conf ,将 net.ipv4.ip_forward=1 取消注释,允许流量转发。 再执行 sudo sysctl -p 使配置生效。

singbox 配置

执行 bash <(curl -fsSL https://sing-box.app/deb-install.sh) 安装 sing-box。然后在 /etc/sing-box 目录创建 config.json 文件,最后执行 sudo systemctl start sing-box.service

注意点:

  1. 开启 tun 模式会与 docker 网络冲突,开启 tun 后局域网无法访问 docker 端口,原因还未知,目前只能先 exclude docker0 网卡。
  2. stack 为 mixed 时,Debian 机器无法访问外网,其他设备可以,改为 gvisor 解决。
  3. inbound 中监听 530 端口,作为 ADGuard Home 的上游 dns 服务器。

完整配置放在文末附录。可以用 clash2sfa 将机场订阅链接结合模板,生成一份新的配置文件。

配置完之后,将需要代理的设备,网关和 DNS 设置成 Debian 的 IP 即可进行透明代理。

docker 应用

这里主要记录最近折腾的一些 Docker 容器。

CasaOS

CasaOS 是一个家庭服务器管理面板,包含容器管理、文件管理、文件分享、服务器状态展示等功能。

我主要用它管理 Docker 容器,以及发现一些好玩的镜像。它的应用市场包含了很多镜像和推荐配置,支持一键安装,也能通过第三方市场安装更多应用。

第三方市场入口比较隐蔽,一开始没找到,路径在 app store -> 右上角 x apps -> more apps -> 问号,可以把里面的三方市场链接都配置上。

AdGuard Home

AdGuard Home 用来去广告,也顺便作为家里的 DNS 入口。

network 为 bridge 时,似乎会和 tun 模式冲突,导致无法查看 DNS 记录,所以这里改为 host。安装完之后,把上游 DNS 服务器改为本地 530 端口,配合 sing-box 使用。

Cloudflared

Cloudflared 是 Cloudflare Tunnel 的客户端,用于内网穿透。

原本我是使用 Cloudflare CDN 加 rules,再配合本地 nginx 做公网访问,但是速度太慢。换成 tunnel 后访问速度好了很多,也少维护一层 nginx 配置。

rsshub + freshrss

RSSHub 将不支持 RSS 的内容转成 RSS 格式,FreshRSS 用来管理订阅。安卓上使用 FeedMe 作为阅读器。

这套主要解决公众号、网站、社区内容统一订阅的问题,比到处刷信息流舒服很多。

WireGuard Easy

WireGuard Easy 是组网工具,用来在外面访问家里的服务。

Cloudflared 更适合暴露少量 Web 服务,WireGuard 更适合把自己的设备接回家里网络。两者用途不完全一样,所以都保留了。

immich+nextcloud

Nextcloud 用来把手机照片同步到服务器,Immich 用来浏览照片。

Nextcloud 更像同步工具,Immich 的相册浏览体验更好,所以这里把同步和浏览拆开处理。

Syncthing

Syncthing 用来在多个设备之间同步配置文件、Obsidian 笔记等内容。

它不依赖云盘,设备之间直接同步,适合放一些经常改但不想走第三方云服务的文件。

memos

Memos 用来记录短笔记,可以当做个人版微博。

一些不适合放进正式笔记、但又不想丢掉的想法,会先扔到这里。

附录:sing-box 配置

json
{
  "dns": {
    "disable_cache": false,
    "disable_expire": false,
    "final": "google",
    "independent_cache": false,
    "rules": [
      {
        "outbound": "any",
        "server": "default-dns"
      },
      {
        "query_type": "HTTPS",
        "server": "block-dns"
      },
      {
        "clash_mode": "direct",
        "server": "default-dns"
      },
      {
        "clash_mode": "global",
        "server": "google"
      },
      {
        "rule_set": "cnsite",
        "server": "default-dns"
      }
    ],
    "servers": [
      {
        "address": "223.5.5.5",
        "detour": "direct",
        "tag": "default-dns"
      },
      {
        "address": "local",
        "detour": "direct",
        "tag": "system-dns"
      },
      {
        "address": "rcode://name_error",
        "tag": "block-dns"
      },
      {
        "address": "https://dns.google/dns-query",
        "address_resolver": "default-dns",
        "address_strategy": "ipv4_only",
        "client_subnet": "1.0.1.0",
        "strategy": "ipv4_only",
        "tag": "google"
      }
    ],
    "strategy": "ipv4_only"
  },
  "experimental": {
    "cache_file": {
      "enabled": true
    },
    "clash_api": {
      "default_mode": "rule",
      "external_controller": "192.168.6.16:9090"
    }
  },
  "inbounds": [
    {
      "listen": "0.0.0.0",
      "listen_port": 530,
      "tag": "dns-in",
      "type": "direct"
    },
    {
      "auto_route": true,
      "exclude_interface": [
        "docker0"
      ],
      "gso": true,
      "inet4_address": "172.19.0.1/30",
      "mtu": 9000,
      "sniff": true,
      "sniff_override_destination": false,
      "stack": "gvisor",
      "strict_route": false,
      "tag": "tun-in",
      "type": "tun"
    }
  ],
  "log": {
    "disabled": true,
    "level": "trace",
    "output": "/etc/sing-box/singbox.log",
    "timestamp": true
  },
  "outbounds": [

  ],
  "route": {
    "auto_detect_interface": true,
    "rule_set": [
      {
        "download_detour": "direct",
        "format": "binary",
        "tag": "cnip",
        "type": "remote",
        "url": "https://github.com/MetaCubeX/meta-rules-dat/raw/sing/geo-lite/geoip/cn.srs"
      },
      {
        "download_detour": "direct",
        "format": "binary",
        "tag": "cnsite",
        "type": "remote",
        "url": "https://github.com/MetaCubeX/meta-rules-dat/raw/sing/geo-lite/geosite/cn.srs"
      }
    ],
    "rules": [
      {
        "inbound": "dns-in",
        "outbound": "dns-out"
      },
      {
        "outbound": "dns-out",
        "protocol": "dns"
      },
      {
        "outbound": "block",
        "protocol": "quic"
      },
      {
        "clash_mode": "direct",
        "outbound": "direct"
      },
      {
        "outbound": "direct",
        "rule_set": [
          "cnip",
          "cnsite"
        ]
      }
    ]
  }
}
we-mp-rss 的自动化扫码登录方案
在Android实现语音播报金额的功能
Valaxy v0.28.10 驱动|主题-Yunv0.28.10