跳到正文

出站代理

配置可复用的代理和路由规则,控制 Kiln 访问节目源、节目单和台标时使用的网络出口。

更新于 Markdown 版本

Kiln 用两层配置管理出站流量:[[proxies]] 定义可复用的代理,[egress] 决定哪些请求使用哪个出口。节目源、节目单和台标共用同一套路由,无需分别设置。

模型总览

每个待请求的地址都会独立走一次判定:

按优先级匹配规则

规则按 priority 升序遍历,命中的第一条决定出口,后面的规则不再参与。

使用默认出口

没有任何规则命中时使用 egress.default

解析线路

出口是 direct 就直连;是某条线路的 id 就走该线路;引用的线路不存在或已停用时退回直连。

kiln.tomltoml
[[proxies]]
id = "proxy-http"
name = "HTTP 线路"
url = "http://127.0.0.1:7890"

[[proxies]]
id = "proxy-socks"
name = "SOCKS5 线路"
url = "socks5h://127.0.0.1:7891"

[egress]
default = "direct"
playlist_policy = "rewrite"
# docker_proxy_host = "host.docker.internal"

[[egress.rules]]
id = "example-cdn"
priority = 10
kind = "host_suffix"
pattern = "example-cdn.com"
proxy = "proxy-http"

定义线路

  • id 唯一,被 egress.default、路由规则和节目单源引用;name 只用于界面显示。
  • url 支持 httphttpssocks5socks5h 四种 scheme,例如 http://127.0.0.1:7890socks5h://127.0.0.1:7891
  • 需要认证时把凭据放进 URL,例如 http://user:password@127.0.0.1:7890,控制台会显示该线路已配置凭据而不回显密码。
  • socks5h 由代理侧解析域名,socks5 先在本机解析再连接。回源地址依赖境外 DNS 时优先选 socks5h
  • 线路可以停用而不删除。被 egress.default 或启用中的规则引用的线路不允许处于停用状态。

默认出口与规则

egress.defaultdirect 或某条线路的 id,所有未命中规则的请求都走它。

规则由 idprioritykindpatternproxy 组成,可以单独停用。priority 数字越小越优先,proxy 也可以填 direct,用来在默认走代理的部署里为个别域名开一个直连口子。

kind 匹配对象
host_suffix 主机名后缀。example.com 同时命中 example.comcdn.example.com,不会命中 notexample.com
host_exact 完整主机名,需要完全相等
host_regex 对主机名做正则匹配
channel_id 频道 ID 完全相等
url_regex 对完整地址做正则匹配

省略 kind 时按 host_suffix 处理。正则类规则在保存前会做编译校验,编译失败的规则不会生效。

播放列表处理

playlist_policy 决定 Kiln 转发上游 HLS 播放列表时,里面的源站绝对地址如何呈现给播放器。

取值 行为
rewrite(默认) 全部改写回 Kiln,播放器只与 Kiln 通信
passthrough 原样保留源站地址,播放器直连源站
auto 只改写需要走代理的地址,其余保留源站地址

rewrite 的具体行为是:Kiln 把播放列表里的每条媒体地址,以及标签中的 URI="...",先解析成绝对地址,再替换成自身的 /v1/play/<频道 ID>/u/<编码后的地址>?sig=...;通过播放密钥分发时,前缀相应变成 /p/<密钥>/play/<频道 ID>/u/。地址用 URL-safe Base64 编码并保留可识别的扩展名,签名是按频道 ID 与目标地址计算的 HMAC,密钥在进程启动时随机生成,因此重启后旧地址立即失效。播放器取到这些地址后仍然只连 Kiln,回源由 Kiln 按出站路由完成。嵌套的变体播放列表在被取回时会再走一次同样的改写。

passthrough 让播放器直接访问源站,这些请求不会经过 Kiln 的代理线路,也不会带上频道自定义的请求头,只有在播放器自身能够直连源站时才适用。auto 是折中:需要走代理的地址改写回 Kiln,其余保持源站地址,让能直连的流量少绕一跳。

在容器里访问代理

Kiln 不会改写线路里的地址。在容器里运行时,url 必须是从 Kiln 容器内部连得上的地址:宿主机上好用的 127.0.0.1 在容器里指向容器自己,直接照抄会连不通。

代理跑在宿主机上

host.docker.internal 回连宿主机。这个名字在 Docker Desktop 上自带,Linux 上需要显式映射到网关:

compose.yamlyaml
services:
  kiln:
    image: ghcr.io/babywbx/kiln:core
    ports:
      - "8080:8080"
    extra_hosts:
      - "host.docker.internal:host-gateway"
    volumes:
      - ./kiln.toml:/etc/kiln/kiln.toml:ro
      - kiln-data:/var/lib/kiln/data
    restart: unless-stopped

volumes:
  kiln-data:

线路填这个主机名,端口用代理在宿主机上监听的端口:

kiln.tomltoml
[[proxies]]
id = "proxy-host"
name = "宿主机代理"
url = "http://host.docker.internal:7890"

代理是另一个容器

两个容器接在同一个 Docker 网络上时,直接用服务名寻址,代理不需要把端口映射到宿主机:

compose.yamlyaml
services:
  proxy:
    image: your-proxy-image
    container_name: proxy
    volumes:
      - ./proxy-config:/etc/proxy:ro
    restart: unless-stopped
    networks: [kiln-net]

  kiln:
    image: ghcr.io/babywbx/kiln:core
    depends_on: [proxy]
    ports:
      - "8080:8080"
    volumes:
      - ./kiln.toml:/etc/kiln/kiln.toml:ro
      - kiln-data:/var/lib/kiln/data
    restart: unless-stopped
    networks: [kiln-net]

networks:
  kiln-net:

volumes:
  kiln-data:

线路用服务名加代理在容器内监听的端口,这里不是它映射到宿主机的那个端口:

kiln.tomltoml
[[proxies]]
id = "proxy-sidecar"
name = "代理容器"
url = "http://proxy:7890"

[[proxies]]
id = "proxy-sidecar-socks"
name = "代理容器 SOCKS"
url = "socks5h://proxy:7891"

同一个网络内的流量不出宿主机,所以代理容器不必对外暴露端口,也不需要 extra_hosts

代理在局域网另一台机器上

这种情况不需要任何 Docker 侧的特殊配置。容器默认的 bridge 网络本来就能访问宿主机所在的局域网,把线路填成那台机器的地址即可:

kiln.tomltoml
[[proxies]]
id = "proxy-lan"
name = "局域网代理"
url = "http://192.168.1.100:7890"

既不需要 extra_hosts,也不需要和谁共享网络,写法与 Kiln 直接跑在宿主机上时完全一致。要求同样是那台机器上的代理必须监听 0.0.0.0 或对应网卡,并且防火墙放行该端口。

docker_proxy_host 不参与这件事

docker_proxy_host 只在 ffmpeg.mode = "docker" 时生效,作用是告诉 Kiln 拉起的 ffmpeg 子容器怎么回连 Kiln 进程自己,与线路地址无关。上面两种拓扑都不需要动它。

验证

控制台的「出站代理」页要求线路先通过一次连通性测试才允许应用,这次测试正是从 Kiln 容器内部发起的,通过即说明地址在容器视角可达。测试失败时按这个顺序排查:代理是否允许非本机连接、容器是否解析得到那个主机名或服务名、端口填的是不是容器视角的端口。

受路由控制的流量

流量 说明
频道回源 播放列表与分片的拉取,原生引擎与 ffmpeg 引擎都会应用路由结果
节目单抓取 仅当该源的出口设为 auto 时按规则路由,设为 direct 或具体线路时按源的设置执行,详见 EPG 节目单
频道台标 /v1/logo/{id} 的回源抓取,按频道 ID 参与规则匹配
管理端探测 频道探测、预览与出站连通性测试

规则里的 channel_id 匹配只在请求带有频道上下文时才可能命中,节目单抓取没有频道上下文,因此不会被这类规则选中。

控制台与连通性测试

「出站代理」页采用草稿式编辑:新增或修改线路与规则只会改动草稿,必须先运行一次通过的连通性测试,「应用」按钮才会可用;任何后续改动都会重置这个状态,需要重新测试。这样可以避免把一条填错的代理地址直接推送到运行中的服务。

测试对应 POST /v1/admin/egress/test,需要 refresh 权限,可选参数包括:

  • target:省略时使用内置的公共探测目标;填 sourcecustom 时必须给出 url,且目标必须是公网地址。
  • channel_id:带上频道后按该频道解析路由,用于验证 channel_id 类规则。
  • proxy_idproxy_url:只测某条线路或某个尚未保存的代理地址。
  • draft:直接用草稿配置解析路由,不影响正在运行的配置。

响应会给出实际选中的出口 proxy_id、命中原因 reason、是否会改写播放列表 rewrite、耗时 dur_ms,以及是否可达、HTTP 状态与最终地址。代理要求认证时会单独标记出来。

常见拓扑

默认直连,个别域走代理

default = "direct",为需要代理的域名加一条 host_suffix 规则指向线路。适合大部分源可直连、只有个别源需要绕行的部署。

默认代理,个别域直连

default = "proxy-http",再为内网或本地源加一条 proxy = "direct" 的规则。局域网上游不必绕出去,也避免代理看到内网地址。

Kiln 在容器里,代理在宿主机

线路填 http://host.docker.internal:7890,并给 Kiln 容器加上 host.docker.internal:host-gateway 映射。见 在容器里访问代理

Kiln 与代理各在一个容器

两者接同一个 Docker 网络,线路填 http://<服务名>:<容器内端口>,代理无需对外映射端口。见 在容器里访问代理

配置改动的排查思路与日志字段见 故障排查

导航

输入以搜索…

↑↓ 移动↵ 打开Esc 关闭