Routr 2.25.1 配置参数详解

面向已跑通部署的运维工程师,解析 Routr 2.25.1 配置体系——routr-one 双轨配置(环境变量 + edgeport/log4j2 YAML)、模块化部署逐服务 config/*.yaml 逐字段解析、官方环境变量全表与源码级补充(RECORD_MESSAGES 家族)、IGNORE_LOOPBACK_FROM_LOCALNETS/TLS_ON/RECORD_MESSAGES 容器行为实测与高频配置错误速查。

RoutrRoutrSIPVoIP2026/10/26

Routr 2.25.1 配置参数详解

目标:面向已按《Routr 2.25.1 Docker Compose 部署指南》跑通 Routr 的运维工程师,把 2.25.1 的配置体系讲透——routr-one 的"环境变量 + 两个 YAML"双轨配置、模块化部署的逐服务 config/*.yaml 逐字段解析(EdgePort / Dispatcher / Location / Registry / RTPRelay / Auth / 日志)、官方环境变量全表与源码级补充(RECORD_MESSAGES 家族),并对 IGNORE_LOOPBACK_FROM_LOCALNETS、TLS_ON、RECORD_MESSAGES 做容器内行为实测。全部配置文件与回显均来自本地容器实测。

一、实验环境与取证说明

项目取值
版本2.25.1(fonoster/routr-one:2.25.1,与部署篇同一栈)
运行环境Linux x86_64 + Docker 28,compose 项目 routr-2-25-1-stack
取证来源 1运行中的 routr-one 容器(进程树、/service、/etc/routr 实测)
取证来源 2源码构建树的 config/*.yaml(Node.js 22 + JDK 17 构建产物,含模块化部署全部配置模板)
取证来源 3官方环境变量文档页(docs.routr.io/reference/environment-variables,查询日 2026-10-26)
取证来源 4镜像内 dist/*.js 与 node_modules/@routr/*/dist 源码交叉验证
示例账号鉴权用户 admin / 密码 q1w2e3r4,Agent 1001(与部署篇一致)

二、配置体系总览:routr-one 的双轨制

2.25.1 的配置分两种部署形态,规则完全不同:

routr-one(all-in-one)模块化部署(routr-* 镜像 / 源码构建)
配置载体环境变量为主 + 2 个 YAML每个服务一份 config/*.yaml
YAML 文件edgeport.yaml、log4j2.yamldispatcher.yaml、location.yaml、registry.yaml、rtprelay.yaml、auth.yaml、edgeport.yaml、log4j2.yaml
服务地址代码内写死 localhost:*,不可改各服务独立 bindAddr,靠 gRPC 互连
环境变量仍生效(尤其 EdgePort 组)每服务组件页另有一组

关键结论(官方文档明示 + 源码佐证):在 routr-one 内部,BIND_ADDR、LOCATION_ADDR、API_ADDR 三个变量无效——gRPC 地址是固定的(51901/51902/51904/51907 内部、51908 外部)。runner.js(Node 服务启动器)按固定配置依次拉起 dispatcher、connect、location、pgdata,再 spawn(EDGEPORT_RUNNER) 启动 Java EdgePort:

tini → ① init-postgres.sh(initdb + prisma migrate deploy,仅 START_INTERNAL_DB=true)
     → ② pg_ctl start -D /var/lib/postgresql/data
     → ③ npx prisma@6.12.0 migrate deploy --schema=/service/schema.prisma(幂等)
     → ④ node ./dist/runner
          ├─ messageDispatcher(0.0.0.0:51901)
          ├─ connectProcessor(0.0.0.0:51904)
          ├─ locationService(0.0.0.0:51902,cache 默认 MEMORY)
          ├─ pgDataService(0.0.0.0:51907 + 外部口 51908)
          └─ spawn /service/edgeport.sh → java io.routr.Launcher(5060–5063)

还有两处入口脚本行为值得记住:每次启动都会把 $PKCS12_PASSWORD 用 sed 写进 config/edgeport.yaml 的 keyStorePassword/trustStorePassword(实测文件中两行均为 changeme,与容器环境变量一致);证书由 convert-to-p12.sh 在缺失时自动生成自签 signaling.p12。

三、EdgePort:config/edgeport.yaml 逐字段解析

routr-one 容器内实测原文(/service/config/edgeport.yaml,CONFIG_PATH 可覆盖路径):

kind: EdgePort
apiVersion: v2beta1
ref: default                      # routr-one 固定为 default;模块化部署按实例命名(如 edgeport-01)
metadata:
  region: default                 # 多 EdgePort 场景的区域标签
spec:
  unknownMethodAction: Discard    # 收到不在 methods 白名单里的 SIP 方法时的动作:Discard 丢弃
  processor:
    addr: localhost:51901         # 转发目标:Message Dispatcher(routr-one 写死 localhost)
  securityContext:
    client:
      authType: DisabledAll       # 对客户端 TLS 客户端证书的校验策略(默认全禁用)
    keyStorePassword: changeme    # ★ 入口脚本由 $PKCS12_PASSWORD sed 注入,生产必改
    trustStorePassword: changeme  # ★ 同上
    keyStore: "/etc/routr/certs/signaling.p12"
    trustStore: "/etc/routr/certs/signaling.p12"
    keyStoreType: pkcs12
  methods:                        # SIP 方法白名单
    - REGISTER
    - MESSAGE
    - INVITE
    - ACK
    - BYE
    - CANCEL
    - REFER
    - NOTIFY
  transport:                      # 监听传输与端口
    - protocol: tcp
      port: 5060
    - protocol: udp
      port: 5060
    - protocol: tls
      port: 5061
    - protocol: ws
      port: 5062
    - protocol: wss
      port: 5063

字段速查:

字段说明
refEdgePort 实例引用。多 EdgePort 组网时每实例唯一,配合 Registry 的 edgePorts[].address 使用
metadata.region区域标签,多区域部署时用于归属
spec.unknownMethodAction未白名单方法的处置(Discard)。模块化部署还支持按场景调整
spec.processor.addrEdgePort → Dispatcher 的 gRPC 地址。routr-one 固定 localhost:51901,模块化部署填 dispatcher:51901
spec.securityContextSIP over TLS 的 keystore/truststore(pkcs12)。client.authType 控制是否要求客户端证书
spec.methods方法白名单,超出 unknownMethodAction 处置
spec.transport五种传输的端口,可增删(如关闭 ws 只留 udp/tcp/tls)

externalAddrs / localnets 在哪配? 模块化部署直接写进 YAML(源码模板实测):

spec:
  externalAddrs:            # 对外通告地址,写入 Via/Contact/Record-Route
    - 10.111.220.2
    - sip01.edgeport.net
  localnets:                # 本地网段:命中则通告内网地址
    - 127.0.0.1/8
    - 10.111.221.2/24

routr-one 不让你改文件里这两项(改了也会被环境变量换算覆盖):由 EXTERNAL_ADDRS、LOCALNETS、IGNORE_LOOPBACK_FROM_LOCALNETS 在启动时换算(第六节实测)。官方还提供 edgeport.alt.yaml 多实例模板(第二实例用 6060–6063 端口、独立 ref: edgeport-02),是多 EdgePort 组网的现成参考。

四、模块化部署其余 YAML 逐文件解析

以下文件取自源码构建树的 config/ 目录(routr-one 不内置这些文件,仅 EdgePort 两份)。

4.1 dispatcher.yaml —— 消息分发与路由挂载

kind: MessageDispatcher
apiVersion: v2beta1
ref: message-dispatcher
spec:
  bindAddr: 0.0.0.0:51901
  processors:                     # 按序匹配,第一个 matchFunc 命中即接管
    - ref: connect-processor
      addr: connect:51904
      matchFunc: req => true      # JS 谓词:可按方法/头部写路由条件
      methods: [REGISTER, MESSAGE, INVITE, ACK, BYE, CANCEL, REFER, NOTIFY]

开发版模板(dispatcher.dev.yaml)多一段 消息录制:

  recording:
    enabled: true
    path: /var/routr/traces
    mode: all                     # all=全录;flagged=只录标记会话(枚举见 5.7)
    redact: false
    lint:
      profiles: [sip, sip-connect]

redact: false 是 dev 栈的取值:routr-one 的录制固定红摘凭据(源码注释"Credentials are always redacted",第六节实测日志 redact: true)。从文件配置的 dispatcher 才能改它并启用 lint 规则。

4.2 location.yaml —— 注册信息存储

kind: Location
apiVersion: v2beta1
metadata:
  region: default
spec:
  bindAddr: 0.0.0.0:51902
  cache:
    provider: memory    # memory(单实例,重启即失)或 redis(多实例共享)

这就是部署篇"重启即全量重注册"的配置根源。要多实例共享注册,改 provider: redis 并按 Location 组件页补连接参数。

4.3 registry.yaml —— 运营商周期注册

kind: Registry
apiVersion: v2beta1
spec:
  requesterAddr: requester:51909   # 借道 EdgePort 发 SIP
  apiAddr: apiserver:51907         # 读 Trunk 资源
  registerInterval: 20             # 周期重注册(秒)
  cache:
    provider: memory
  methods: [INVITE, MESSAGE]       # 允许经 Trunk 出去的方法
  edgePorts:                       # 用哪些 EdgePort 出局
    - address: sip01.edgeport.net:5060
      region: us-east1
    - address: sip02.edgeport.net:6060

4.4 rtprelay.yaml —— RTPEngine 中间件

kind: RTPRelay
apiVersion: v2beta1
spec:
  # bindAddr: 0.0.0.0:51903
  # rtpengine:
  #   host: rtpengine
  #   port: 22222
  profiles:
    phone-to-secure-phone:
      SDES:
        - only-AES_CM_128_HMAC_SHA1_80

合并语义(文件头注释明示):同名 profile 逐键覆盖默认值,列表字段整体替换而非追加;不提供该文件时按内置默认 profiles 运行。注意 routr-one 的 RTPRELAY_CONFIG_PATH 默认指向 /etc/routr/rtprelay.yaml——该文件在 one 镜像里不存在,因此 one 的 RTPRelay 永远用默认 profiles;要定制需自行挂载文件并把 RTPRELAY_CONFIG_PATH 指过去。

4.5 auth.yaml —— SimpleAuth 处理器

源码模板内容只有一个 []:SimpleAuth 中间件默认不配置任何处理器,即关闭。Connect 模式的注册鉴权由 Credentials/Agent 资源驱动(部署篇 401→200 握手实测),不经过 SimpleAuth。

4.6 log4j2.yaml —— EdgePort(Java)日志

routr-one 实际加载的是 /etc/routr/log4j2.yaml(LOG4J2 可覆盖),要点:

配置项取值与含义
Console pattern%d [level]: (${sys:serviceName}) %c{1}.java %msg%n——这就是日志里 (edgeport)、(one) 前缀的来源
RollingFilelogs/routr.log,10 MB 滚动,保留 10 份
io.routr loggerone 版 info,源码模板 debug
routr loggerJAIN-SIP 协议栈日志,默认 debug 但注释明确:设 JAIN_SIP_TRACE_LEVEL 环境变量才会真正输出,排查 SIP 协议级问题时打开
OpenTelemetry appenderone 版新增,Telemetry.init 装好 SDK 后经 OTLP 外发(无 endpoint 时无副作用)

五、环境变量全表(routr-one,按组件)

下表为官方环境变量文档(2026-10-26)与容器内 env 实测合并;"默认"列即缺省值。

5.1 容器与数据库

变量默认说明
DATABASE_URLpostgres://postgres:postgres@localhost:5432/routr外部 PostgreSQL 连接串
START_INTERNAL_DBtruefalse 时不初始化/启动内置 PG(配外部库时用)
HEPLIFY_OPTIONS空设了就拉起 heplify,把 SIP 流量镜像到 Homer
EDGEPORT_RUNNER/service/edgeport.shEdgePort 启动脚本路径

5.2 EdgePort

变量默认说明
EXTERNAL_ADDRS空必填。对外通告地址,逗号分隔多个
LOCALNETSOS 探测本地网段 CIDR,逗号分隔
IGNORE_LOOPBACK_FROM_LOCALNETStrueOS 兜底 localnets 时剔除 127.0.0.1(第六节实测)
HOSTNAME容器主机名作为 EdgePort 的 ref
PROCESSOR_ADDR配置文件值EdgePort → Dispatcher 地址(one 内固定 localhost:51901)
CONFIG_PATH/service/config/edgeport.yamlEdgePort YAML 路径
PKCS12_PASSWORDchangeme启动时 sed 注入 keystore 密码,生产必改
PATH_TO_CERTS/etc/routr/certs证书目录,缺自签生成
CA_CERT_SUBJECT / SERVER_CERT_SUBJECT/CN=Self Signed CA / /CN=localhost自签证书主题
STRIP_SESSION_PROGRESS_SDPfalse摘除 183 响应的 SDP 体
ENABLE_HEALTHCHECKSfalse开 8080 /healthz(one 内仅 EdgePort 进程支持)
CONSOLE_PUBLISHER_ENABLED / NATS_PUBLISHER_ENABLED / NATS_PUBLISHER_URL / NATS_PUBLISHER_SUBJECTfalse / false / nats://localhost:4222 / routr呼叫事件外发(控制台/NATS)
LOG4J2/etc/routr/log4j2.yamlJava 日志配置
JAVA_HOME/service/jreEdgePort 的 JRE

5.3 Connect 处理器

变量默认说明
ENFORCE_E164falseFrom/To/Request-URI 强制 E.164 归一化,并校验新建 Number
ENFORCE_E164_WITH_MOBILE_PREFIXfalse追加手机号前缀校验
CONNECT_VERIFIER_PUBLIC_KEY_PATH空本地校验 X-Connect-Token JWT 的公钥
CONNECT_VERIFIER_OPTIONS{"expiresIn":"1h","algorithm":["RS256"]}本地校验选项(JSON)
CONNECT_VERIFIER_ADDR空远程 gRPC 校验服务地址
UNTRUSTED_HEADERS_TO_STRIP平台头列表对不可信请求剥离的头,置空关闭剥离
TRUSTED_EDGEPORTS / TRUSTED_EDGEPORT_ADDRESSES空允许发送 X-Edgeport-Ref 的对等 EdgePort(ref / IP·CIDR)

5.4 API Server(pgdata)

变量默认说明
TLS_ONfalse外部口 51908 启 TLS(第六节实测)
VERIFY_CLIENT_CERTfalse强制客户端证书(CA 用 CACERT)
CACERT / SERVER_CERT / SERVER_KEY/etc/routr/certs/ 下外部口证书三件套
CLOAK_ENCRYPTION_KEY空字段级加密(Cloak)密钥

5.5 RTPRelay

变量默认说明
RTPENGINE_HOST空设了即拉起 RTPRelay 并作为后置中间件挂进 dispatcher
RTPENGINE_PORT22222RTPEngine ng 控制端口
RTPENGINE_TIMEOUT5000请求超时(ms)
RTPRELAY_CONFIG_PATH/etc/routr/rtprelay.yamlprofiles 文件;one 内默认无此文件 → 用内置默认(见 4.4)

5.6 日志与追踪(Node.js 服务)

变量默认说明
LOGS_LEVEL空如 verbose / info
OTEL_EXPORTER_OTLP_ENDPOINT / ..._TRACES_ENDPOINT空OTLP/HTTP 端点,设了即开追踪(后者优先)
OTEL_SERVICE_NAMEone追踪上报的服务名
OTEL_SDK_DISABLED空true 关闭追踪

5.7 源码级补充:RECORD_MESSAGES 家族(官方环境变量页未收录)

镜像内 dist/recording.js 实测发现一组文档页未列的变量,用于在 routr-one 里启用消息录制:

变量默认说明
RECORD_MESSAGES未设(关)true 开启 dispatcher 消息录制
RECORD_MESSAGES_PATH/var/routr/traces录制文件目录(必须对 UID 5000 可写,见第六节崩溃实测)
RECORD_MESSAGES_MODEflagged枚举 all / flagged(源码 RecordingMode),其他值直接报错拒启

行为规则(源码级):只要三个变量任一出现即视为"配置了录制";routr-one 下凭据固定红摘、lint 规则固定关闭——比 dispatcher.dev.yaml 的文件配置少两项能力。录制产物为 JSONL(每行一条消息记录),可用 rctl trace 系列命令消费(见《Routr 2.25.1 常用 CLI 命令与工具详解》)。

六、行为实测

6.1 LOCALNETS 的 OS 兜底与 IGNORE_LOOPBACK

一次性容器(-e EXTERNAL_ADDRS=10.89.57.11 -e IGNORE_LOOPBACK_FROM_LOCALNETS=false,不设 LOCALNETS):

(edgeport) GRPCSipListener.java starting edgeport ref = 8e6607060fc0 version = 2.25.1 at 0.0.0.0
(edgeport) GRPCSipListener.java localnets list [10.89.57.2/24,127.0.0.1/8]
(edgeport) GRPCSipListener.java external hosts list [10.89.57.11]

结论:LOCALNETS 未设时 OS 探测兜底(10.89.57.2/24 为容器自身所在网段);IGNORE_LOOPBACK_FROM_LOCALNETS=false 使 127.0.0.1/8 进入列表。对照部署篇主容器(默认 true)日志为 localnets list [10.89.57.0/24]——无回环项,行为一致。

6.2 TLS_ON=true:51908 变 TLS

同一测试容器设 TLS_ON=true 后:

$ docker exec <容器> openssl s_client -connect localhost:51908
subject=CN=localhost
New, TLSv1.3, Cipher is TLS_AES_256_GCM_SHA384
Verify return code: 21 (unable to verify the first certificate)   ← 自签 CA,符合预期

客户端相应切换:rctl 从 -i 改为 -c(实测 rctl domains get -e localhost:8129 -c ca.crt 退出码 0);SDK 构造参数从 insecure: true 改为 cacert: "<ca.crt 路径>"(实测创建资源成功)。CA 文件即 $PATH_TO_CERTS/ca.crt,docker cp 出容器即可用。

6.3 RECORD_MESSAGES:默认路径直接崩,需显式给可写目录

按源码默认路径开启录制(-e RECORD_MESSAGES=true -e RECORD_MESSAGES_MODE=all,不给 PATH):

[error]: errno: -13, code: 'EACCES', syscall: 'mkdir', path: '/var/routr/traces'
[INFO  tini (1)] Main child exited normally (with status '1')      ← 容器直接退出

根因:/var/routr/traces 由服务进程(UID 5000 fonoster)创建,而 /var 属 root——routr-one 里开录制必须给一个 fonoster 可写的目录。改为 RECORD_MESSAGES_PATH=/tmp/routr-traces 后正常:

(dispatcher) message recording enabled {"path":"/tmp/routr-traces","mode":"all","redact":true,"lint":"off"}

随后一次带鉴权的 REGISTER(401 → 200)即落盘一个 JSONL 文件,redact:true 印证"one 下凭据固定红摘"。该文件在 CLI 篇中被 rctl trace validate/lint/replay 完整消费。

七、高频配置错误速查

现象根因与处置
注册/呼叫单通、对端看不到正确地址EXTERNAL_ADDRS 缺失或填了容器内网地址。填"话机可达地址"后重建容器
开录制就崩(EACCES)默认路径 /var/routr/traces 不可写。挂卷或 RECORD_MESSAGES_PATH 指向 UID 5000 可写目录
RECORD_MESSAGES_MODE 拒启取值只能 all / flagged
rctl 报 TLS 错误TLS_ON=false 时用 -i;true 时用 -c <ca.crt>,SDK 用 cacert
内部口想改地址不生效routr-one 内 BIND_ADDR/LOCATION_ADDR/API_ADDR 无效,地址写死;要自定义拓扑用模块化部署
RTPRelay profiles 不生效one 内默认无 /etc/routr/rtprelay.yaml,挂载文件并设 RTPRELAY_CONFIG_PATH
想看 JAIN-SIP 协议栈日志log4j2 里 routr logger 就绪但需设 JAIN_SIP_TRACE_LEVEL
keystore 密码改了仍告警密码在启动时注入 YAML;改 PKCS12_PASSWORD 必须重建容器(docker compose up -d)而非仅 restart 配置

八、参考