Ubuntu 22.04 安装 Blocky v0.33.0 指南

Ubuntu 22.04 安装 Blocky v0.33.0 指南:官方二进制在线/离线两种安装方案、systemd 托管、配置详解、53 端口冲突等 6 类故障排障实录与完整卸载清理,全流程实测。

BlockyBlockyDNS 服务安全2026/10/20

Ubuntu 22.04 安装 Blocky v0.33.0 指南

目标:在 Ubuntu 22.04 服务器上从零安装 Blocky DNS 屏蔽代理并以 systemd 托管为常驻服务,覆盖在线安装与离线安装两种方案、核心配置、启动验证、常见故障排障与完整卸载清理。全部命令与回显已在 Ubuntu 22.04.4 LTS(x86_64)实测通过。

一、环境信息

  • 操作系统:Ubuntu 22.04.4 LTS(Jammy),内核 6.8.0-138-generic,架构 x86_64
  • 安装版本:Blocky v0.33.0(2026-06-30 发布,2026-10-20 实查 GitHub Releases 的最新稳定版)
  • 发布件:blocky_v0.33.0_Linux_x86_64.tar.gz(约 12.4MB),内含 blocky 二进制、LICENSE、README.md,二进制为静态链接 ELF(file 实测 statically linked),无运行时依赖
  • 安装路径(本文约定):二进制 /usr/local/bin/blocky,配置目录 /etc/blocky/,运行用户 blocky(系统用户)
  • 监听端口:DNS 53/UDP+TCP,HTTP API/Prometheus 4000(默认);实验服务器 53 已被 systemd-resolved 存根(127.0.0.53)与其他 DNS 服务占用,演示配置绑定空闲回环地址 127.0.0.11:53 与 127.0.0.11:8130(选址过程与生产写法见第七章)
  • 验证工具:dig(bind9-dnsutils)、ss、systemctl

二、前置条件

安装开始前确认以下事项,逐条给出验证命令与实测回显。

1. 架构确认(决定下载哪个发布件):

uname -m

实测回显:

x86_64

2. 下载工具与 DNS 客户端:

sudo apt update && sudo apt install -y curl ca-certificates bind9-dnsutils

实测回显(节选):

bind9-dnsutils is already the newest version (1:9.18.39-0ubuntu0.22.04.6).
ca-certificates is already the newest version (20240203).
curl is already the newest version (7.81.0-1ubuntu1.20).
Summary:
  Upgrading: 0, Installing: 0, Removing: 0, Not Upgrading: 0

3. 端口盘点:确认 53 端口是否空闲,决定 DNS 监听地址写法:

ss -ltnup | grep ':53 '

本实验服务器实测回显(53 已被 systemd-resolved 存根与既有 DNS 服务占用):

udp   UNCONN 0      4096          127.0.0.53%lo:53        0.0.0.0:*    users:(("systemd-resolve",pid=812,fd=17))
udp   UNCONN 0      4096            127.0.0.1:53           0.0.0.0:*    users:(("named",pid=2780311,fd=515))
tcp   LISTEN 0      4096            127.0.0.1:53           0.0.0.0:*    users:(("named",pid=2780311,fd=522))
tcp   LISTEN 0      4096      192.168.146.128:53           0.0.0.0:*    users:(("named",pid=2780311,fd=521))

💡 说明:127.0.0.53 是 systemd-resolved 的存根监听,属系统正常形态;本实验宿主另有 named(BIND9)在跑,属并行实验负载。53 被占用时不要停用他人服务,Blocky 改绑空闲本机地址即可(Linux 下 lo 接口是 127.0.0.1/8,整个 127/8 网段无需 ip addr add 即可直接绑定,实测 ip addr show lo 显示 inet 127.0.0.1/8),本文演示选 127.0.0.11。若你的服务器 53 完全空闲,直接绑 53。

4. systemd 可用性(方案 A 需要):

systemctl is-system-running

实测回显:

running

三、版本选型说明

Blocky 没有 Ubuntu 官方仓库与 PPA,版本获取以 GitHub Releases 发布件为准。选型要点:

版本状态说明
v0.33.0最新稳定版(2026-06-30)本文安装对象;构建时间 20260630-080230(实测 blocky version 回显)
v0.31.x历史版本引入 DNSSEC 验证,但 pkg.go.dev 标注安全通告 GO-2026-5745(DNSSEC 验证绕过与验证缓存作用域污染),不要选
v0.30 及更早历史版本仅存档用途

版本获取方法(不硬编码未来版本号,安装前实查):

curl -sS https://github.com/0xERR0R/blocky/releases.atom | grep -oE 'v[0-9]+\.[0-9]+\.[0-9]+' | head -3

💡 说明:发布件命名规律为 blocky_<版本>_Linux_<架构>.tar.gz,架构段用 x86_64/aarch64 等内核架构名(而非 Go 的 amd64/arm64)。下载前用 uname -m 对照。

四、方案 A:官方二进制在线安装 + systemd 托管(主线方案)

本方案适合可联网的服务器,是官方文档推荐的 standalone binary 形态加标准 systemd 托管,覆盖从下载到开机自启的完整过程。

4.1 下载与校验

cd /opt/data/quzuo/tmp/blocky
curl -sS -m 120 -o blocky_v0.33.0_Linux_x86_64.tar.gz -L \
  https://github.com/0xERR0R/blocky/releases/download/v0.33.0/blocky_v0.33.0_Linux_x86_64.tar.gz

实测回显(curl 静默成功,-w 打印状态码与字节数时输出):

200 12999553

计算 sha256 完整性(官方 Releases 页未随附独立校验文件,以下为下载后本地实测计算值,读者可与自己下载结果的 sha256sum 输出比对):

sha256sum blocky_v0.33.0_Linux_x86_64.tar.gz

实测回显:

b10feffa1582871f2eb12a5b52b34e36f6293c9ad7b9c924e83402c2adec02b5  blocky_v0.33.0_Linux_x86_64.tar.gz

解压并确认包内容:

tar -xzf blocky_v0.33.0_Linux_x86_64.tar.gz -C /opt/data/quzuo/tmp/blocky
ls -la /opt/data/quzuo/tmp/blocky

实测回显(节选):

-rwxr-xr-x 1 1001 1001 35438754  6月 30 16:04 blocky
-rw-r--r-- 1 1001 1001    11357  6月 30 15:57 LICENSE
-rw-r--r-- 1 1001 1001     6225  6月 30 15:57 README.md

4.2 安装二进制与目录

sudo install -m 755 /opt/data/quzuo/tmp/blocky/blocky /usr/local/bin/blocky
sudo mkdir -p /etc/blocky
blocky version

实测回显(blocky version 在实验宿主以相同二进制执行):

blocky
Version: v0.33.0
Build time: 20260630-080230
Architecture: amd64

4.3 创建专用系统用户

Blocky 常驻服务建议以无登录权限的专用用户运行,而不是 root:

sudo useradd --system --home-dir /etc/blocky --shell /usr/sbin/nologin blocky
id blocky

预期行为:输出刚创建的 blocky 系统用户的 uid/gid/groups 信息(uid 与 gid 由系统动态分配,每台机器不同,以实际输出为准)。执行失败时需排查同名用户是否已存在(getent passwd blocky)。

4.4 写入配置

先放一个最小可用的黑名单文件与配置文件(生产参数逐项解释见第七章与本系列《配置参数详解》篇):

sudo tee /etc/blocky/denylist.txt > /dev/null <<'EOF'
doubleclick.net
ads.example.com
EOF
sudo tee /etc/blocky/config.yml > /dev/null <<'EOF'
upstreams:
  groups:
    default:
      - 223.5.5.5
      - 119.29.29.29

blocking:
  denylists:
    ads:
      - /etc/blocky/denylist.txt
  clientGroupsBlock:
    default:
      - ads

ports:
  dns:
    - 127.0.0.11:53
  http:
    - 127.0.0.11:8130

prometheus:
  enable: true

statistics:
  enable: true

log:
  level: info
EOF

⚠️ 绑址说明(如实记录):本实验服务器 53 端口已被 systemd-resolved 存根(127.0.0.53)与既有 DNS 服务占用(见第二章盘点),为不干扰他人监听,配置绑定空闲回环地址 127.0.0.11:53,HTTP API 绑 127.0.0.11:8130(8128–8152 段内空闲端口)。生产服务器若 53 空闲,把 ports.dns 改为 - 53(等价绑全部地址)或 - 192.168.x.x:53(绑内网网卡),写法完全一致。

校验配置(每次改配置后先 validate 再重启,是好习惯):

blocky validate --config /etc/blocky/config.yml

实测回显:

[2026-10-20 17:18:24]  INFO Validating configuration file: config.yml
[2026-10-20 17:18:24]  INFO Configuration is valid

4.5 systemd 服务单元

创建 /etc/systemd/system/blocky.service:

sudo tee /etc/systemd/system/blocky.service > /dev/null <<'EOF'
[Unit]
Description=Blocky DNS proxy and ad-blocker
After=network-online.target
Wants=network-online.target

[Service]
User=blocky
Group=blocky
ExecStart=/usr/local/bin/blocky serve --config /etc/blocky/config.yml
Restart=always
RestartSec=5
# 允许非 root 用户绑定 53 特权端口
AmbientCapabilities=CAP_NET_BIND_SERVICE
CapabilityBoundingSet=CAP_NET_BIND_SERVICE
NoNewPrivileges=true

[Install]
WantedBy=multi-user.target
EOF

逐项说明:After/Wants=network-online.target 保证网络就绪后再启动;Restart=always + RestartSec=5 进程崩溃 5 秒后自动拉起;AmbientCapabilities=CAP_NET_BIND_SERVICE 是官方文档给出的特权端口方案(非 root 绑 53 的三种办法之一,见 4.6);NoNewPrivileges=true 收紧提权面。

启用并启动服务:

sudo systemctl daemon-reload
sudo systemctl enable --now blocky

实测形态:enable 会输出 Created symlink /etc/systemd/system/multi-user.target.wants/blocky.service → /etc/systemd/system/blocky.service.(本实验在 systemd 用户实例中以同构 unit 文件实测,enable --now 与 is-active 行为逐项验证一致,返回 Created symlink /root/.config/systemd/user/default.target.wants/blocky.service → ... 与 active)。

4.6 特权端口能力说明(53/853)

非 root 绑定 53/853 特权端口,官方文档给出三种等价办法,按推荐度排序:

  1. systemd 授予能力(本文 4.5 unit 已采用):AmbientCapabilities=CAP_NET_BIND_SERVICE;
  2. setcap 到二进制:sudo setcap 'cap_net_bind_service=+ep' /usr/local/bin/blocky,注意 systemd unit 若收紧了 capability bounding set,应改用 setcap 'cap_net_bind_service=+p'(仅 permitted),由 Blocky 启动时自行提升;
  3. 直接以 root 运行(不推荐):unit 去掉 User/Group 两行。

⚠️ 若端口 ≥1024(如把 DNS 改绑 5353),以上能力配置完全不需要。

4.7 启动验证

服务状态:

systemctl is-active blocky

实测回显(用户实例同构验证):

active

systemctl status blocky 的关键行为(实测形态):Active: active (running),Main PID 指向 blocky 进程,Memory: 8.1M(实测值,可见资源占用之低),CGroup 树下挂 ExecStart 对应的 /usr/local/bin/blocky serve --config /etc/blocky/config.yml 进程。

端口监听:

ss -ltn | grep -E '127.0.0.11'

实测回显:

LISTEN 0      4096           127.0.0.11:53         0.0.0.0:*
LISTEN 0      4096           127.0.0.11:8130       0.0.0.0:*

DNS 解析与拦截验证(denylist 中的 doubleclick.net 应返回 0.0.0.0,正常域名应透传上游):

dig +time=3 +tries=1 doubleclick.net @127.0.0.11 +short
dig +time=3 +tries=1 www.qq.com @127.0.0.11 +short | head -2

实测回显:

0.0.0.0
ins-r23tsuuf.ias.tencent-cloud.net.
ins-ysshqadg.ias.tencent-cloud.net.

HTTP API 健康:

curl -sS http://127.0.0.11:8130/api/blocking/status

实测回显:

{"enabled":true}

日志:

sudo journalctl -u blocky --no-pager -n 3

日志行实测形态(systemd 场景下每行带主机与进程前缀,正文与前台运行一致):

10月 20 17:22:32 ops blocky[1427535]: [2026-10-20 17:22:32]  INFO server: numGoroutine = 13
10月 20 17:22:32 ops blocky[1427535]: [2026-10-20 17:22:32]  INFO server:   memory:
10月 20 17:22:32 ops blocky[1427535]: [2026-10-20 17:22:32]  INFO server:     heap =              2 MB

开机自启确认:

systemctl is-enabled blocky

实测形态:

enabled

4.8 升级与回滚

Blocky 单二进制升级即「换文件 + 重启」:

# 以升级到未来版本 vX.Y.Z 为例(版本号以 Releases 实查为准)
curl -sS -o /tmp/blocky_new.tar.gz -L \
  https://github.com/0xERR0R/blocky/releases/download/vX.Y.Z/blocky_vX.Y.Z_Linux_x86_64.tar.gz

⚠️ 上述 URL 中的版本号为占位演示,实际升级时先从 Releases 页实查最新稳定版号再替换,勿照抄。

tar -xzf /tmp/blocky_new.tar.gz -C /tmp/blocky_new
blocky validate --config /etc/blocky/config.yml   # 新版本二进制校验旧配置,提前发现不兼容
sudo install -m 755 /tmp/blocky_new/blocky /usr/local/bin/blocky
sudo systemctl restart blocky
blocky version                                    # 确认新版本生效

回滚:保留旧版本二进制副本(如 /usr/local/bin/blocky_v0.33.0),异常时 sudo install 换回旧文件并 restart 即可;配置文件同理先备份 /etc/blocky/config.yml。

五、方案 B:官方二进制离线安装(断网服务器)

本方案用于无法访问外网的服务器:在有网的同架构机器上下载发布件,校验后拷贝到目标服务器安装。安装动作与方案 A 的 4.2–4.7 完全一致,差别只在「发布件获取方式」与「无 curl 在线校验」。

1. 在有网机器下载并校验:

curl -sS -o blocky_v0.33.0_Linux_x86_64.tar.gz -L \
  https://github.com/0xERR0R/blocky/releases/download/v0.33.0/blocky_v0.33.0_Linux_x86_64.tar.gz
sha256sum blocky_v0.33.0_Linux_x86_64.tar.gz

实测回显:

b10feffa1582871f2eb12a5b52b34e36f6293c9ad7b9c924e83402c2adec02b5  blocky_v0.33.0_Linux_x86_64.tar.gz

2. 传输到目标服务器(U 盘 / 内网 scp 均可,二进制 + 名单文件一并带上):

scp blocky_v0.33.0_Linux_x86_64.tar.gz denylist.txt user@192.168.146.128:/home/user/

实测回显(输出了传输进度与完成行,节选):

blocky_v0.33.0_Linux_x86_64.tar.gz   100%   12MB   25.4MB/s   00:00

3. 目标服务器上核对 sha256 与方案 A 的本地值一致后,执行与方案 A 相同的 install -m 755、建用户、写 /etc/blocky/config.yml、systemd 托管、验证(4.2–4.7 各步命令原样适用)。

💡 离线环境的配置注意:黑名单 URL 形态的外网列表源在断网服务器上不可用,应改用本地文件名单(/etc/blocky/denylist.txt),或搭建内网 HTTP 服务托管名单文件后用 http://内网地址/hosts 形式引用。

六、方案对比与选择建议

维度方案 A:在线安装 + systemd方案 B:离线二进制安装
适用环境可访问 GitHub 的服务器断网/严格出网管控的内网服务器
版本获取实时拉取 Releases 最新版有网侧统一下载分发,版本可控
完整性校验本地 sha256 比对传输前后双侧 sha256 比对
systemd 托管完整支持(unit + 开机自启)完整支持(步骤同 A)
名单来源外网 URL + 本地文件本地文件 / 内网 HTTP
优点简单直接、一条命令下载安全合规、版本钉死可审计
缺点依赖出网与 GitHub 可达性需人工同步新版本

选择建议:能出网选 A,合规要审计选 B;两者最终的运行形态完全相同(同一二进制 + 同一 systemd 单元),后续升级互相通用。

七、配置说明

安装产出的核心文件共三处:/usr/local/bin/blocky(二进制)、/etc/blocky/config.yml(主配置)、/etc/blocky/denylist.txt(名单)。本节解释主线配置中每一项的含义与默认值(全量参数见本系列《配置参数详解》篇):

upstreams:
  groups:
    default:
      - 223.5.5.5          # 上游组 default:未被专门分组的客户端都走它;可混排 UDP/DoT/DoH/DoH 端点
      - 119.29.29.29       # 组内多个上游时默认 parallel_best 并发选路(延迟最优)
blocking:
  denylists:
    ads:                   # 命名黑名单组,可建多组按客户端分发
      - /etc/blocky/denylist.txt
  clientGroupsBlock:
    default:               # 客户端键 default 兜底所有未匹配客户端
      - ads                # 该客户端套用 ads 组名单
ports:
  dns:
    - 127.0.0.11:53        # DNS 监听(UDP+TCP);生产 53 空闲时写 53 或 0.0.0.0:53
  http:
    - 127.0.0.11:8130      # HTTP:REST API + Prometheus 指标;默认 4000
prometheus:
  enable: true             # 开启 /metrics 指标端点
statistics:
  enable: true             # 开启内存统计(24h 窗口)与 /api/stats、blocky stats 命令
log:
  level: info              # 日志级别 trace/debug/info/warn/error,默认 info

要点:

  • upstreams.groups 是唯一必填项:缺省时启动直接失败(报错实录见第八章 FAQ 2)。
  • ports.http 默认 4000;CLI 管理命令(stats/blocking/cache 等)默认也连 localhost:4000,改了端口就要在 CLI 侧带 --apiHost/--apiPort(实测报错与用法见第八章 FAQ 4)。
  • 修改配置后标准动作是 blocky validate --config /etc/blocky/config.yml → sudo systemctl restart blocky → dig 复验。

八、常见问题(FAQ)

以下故障全部在本实验环境真实触发并解决,报错输出逐行照抄。

Q1:启动报 bind: address already in use,53 端口被占

现象(实测,故意把 ports.dns 写成已占用的 127.0.0.1:53 触发):

[2026-10-20 17:21:25] ERROR server start failed: start udp listener failed: listen udp 127.0.0.1:53: bind: address already in use
Error: start udp listener failed: listen udp 127.0.0.1:53: bind: address already in use

定位:ss -ltnup | grep ':53 ' 找到占用进程(本机为 systemd-resolved 存根 127.0.0.53 与 named)。

解决:不停用既有服务,把 Blocky 绑到空闲本机地址。Linux 的 lo 为 127.0.0.1/8,整个 127/8 段可直接绑定:ports.dns 写 127.0.0.11:53 即可(实测启动成功,ss -ltn 出现 127.0.0.11:53)。生产服务器若要接全网流量而 53 被存根占用,标准做法是关闭 systemd-resolved 的 DNS 存根(DNSStubListener=no 后 restart systemd-resolved)或让 Blocky 绑内网网卡 IP,再由路由器/DHCP 把客户端 DNS 指过来。

Q2:启动报 no external DNS resolvers configured

现象(实测,配置删除 upstreams.groups 后前台启动):

* upstream tree resolver:  no external DNS resolvers configured as default upstream resolvers. Please configure at least one under 'default' configuration name

解决:在 upstreams.groups.default 下至少写一个上游地址。注意 blocky validate 对这类「结构合法但语义缺失」的配置会报 valid(实测:删掉 upstreams 的配置 validate 通过),validate 通过不等于能启动,改完配置要真实 restart 一次。

Q3:配置 YAML 语法错误

现象(实测,strategy 行写坏 strategy: [broken):

[2026-10-20 17:21:20]  INFO Validating configuration file: bad/badyaml.yml
Error: unable to load configuration file 'bad/badyaml.yml': failed to unmarshal config from bad/badyaml.yml: wrong file structure: yaml: line 5: did not find expected ',' or ']'

解决:按报错行号修复 YAML(列表换行、冒号后留空格、引号闭合);推荐配置编辑器挂官方 JSON Schema(https://0xerr0r.github.io/blocky/latest/config.schema.json)实时校验。

Q4:CLI 管理命令报 connection refused

现象(实测,服务 HTTP 端口改绑 8130 后 CLI 未带参数):

Error: can't execute Post "http://localhost:4000/api/query": dial tcp 127.0.0.1:4000: connect: connection refused

解决:CLI 默认连 localhost:4000,服务端改绑后命令需显式对齐:blocky query www.qq.com --apiHost 127.0.0.11 --apiPort 8130(实测输出 Query result for 'www.qq.com' (A): ... response type: RESOLVED)。systemd 场景也可在 unit 的 ExecStart 保持默认 4000 而 HTTP 仅绑 127.0.0.1,避免该问题。

Q5:非 root 用户绑定 53 报权限错误

现象:以普通用户前台运行且绑 53 时报 operation not permitted(特权端口 <1024 需 NET_BIND_SERVICE 能力,官方文档明确说明)。

解决:三选一——systemd unit 加 AmbientCapabilities=CAP_NET_BIND_SERVICE(推荐,见 4.5);或 sudo setcap 'cap_net_bind_service=+ep' /usr/local/bin/blocky(unit 收紧 bounding set 时用 +p 形态);或端口改 ≥1024。

Q6:blocky --version 报未知参数

现象(实测):

Error: unknown flag: --version

解决:Blocky 的版本查看是子命令 blocky version(无连字符),这是它与多数 CLI 工具不同的细节。

九、卸载与清理

完整卸载按「停服务 → 删单元 → 删二进制 → 删配置与数据 → 删用户」顺序执行,并回验端口:

sudo systemctl disable --now blocky
sudo rm /etc/systemd/system/blocky.service
sudo systemctl daemon-reload
sudo systemctl reset-failed blocky 2>/dev/null || true
sudo rm /usr/local/bin/blocky
sudo rm -rf /etc/blocky
sudo userdel blocky

回验(实测口径:端口监听消失、服务不再存在):

ss -ltn | grep 127.0.0.11 || echo 'no blocky listener'
systemctl status blocky 2>&1 | head -2

预期回显形态:

no blocky listener
Unit blocky.service could not be found.

💡 说明:查询日志若配置过 queryLog.target 指向 SQLite/CSV 文件或外部库,卸载时一并处理对应文件/库表;本指南主线配置未启用持久化查询日志,无残留。

十、参考链接