mirror of
https://gitcode.com/JianFeeeee/ModelRouter.git
synced 2026-10-03 23:54:06 +00:00
上一版把线上单元拷进来后又追加了一份英文注释的加固指令,导致 NoNewPrivileges / ProtectSystem / SystemCallFilter 等在同一个 unit 里 出现两次。systemd 对重复指令取最后一个,行为上不会坏,但文件本身是错的 (读的人会以为有两套加固),且 packaged 与 deployed 不再一致。 现在 packaged/llmsproxy.service 与线上 /etc/systemd/system/llmsproxy.service 逐字节相同,每条指令只出现一次。
62 lines
2.9 KiB
Desktop File
62 lines
2.9 KiB
Desktop File
[Unit]
|
||
Description=LLMSProxy - unified OpenAI-compatible multi-source LLM gateway
|
||
After=network.target
|
||
|
||
[Service]
|
||
Type=simple
|
||
# Memory tuning (measured, see README "内存占用"):
|
||
# MALLOC_ARENA_MAX=2 caps glibc per-thread malloc arenas. LuaJIT allocates
|
||
# through cgo -> glibc malloc, and glibc defaults to 8*nproc arenas, so every
|
||
# OS thread that touches malloc reserved its own ~1 MB arena that is never
|
||
# returned. Measured: 8-12 arenas -> 0.
|
||
# GOGC=50 halves the Go heap growth target. On its own it does NOT help (the
|
||
# saved heap is immediately eaten by extra glibc arenas); combined with
|
||
# MALLOC_ARENA_MAX it cut settled RSS by ~19%. This gateway is I/O bound, so
|
||
# the extra GC cycles are free.
|
||
Environment=GOGC=50
|
||
Environment=MALLOC_ARENA_MAX=2
|
||
ExecStart=/usr/local/bin/llmsproxy -config /etc/llmsproxy/config.yaml
|
||
WorkingDirectory=/etc/llmsproxy
|
||
Restart=always
|
||
RestartSec=5
|
||
|
||
# ---- 加固(2026-10-01 逐条实测后加入,不是照抄文档)----
|
||
#
|
||
# 为什么仍然以 root 运行:master.key 是 0600 root。加 User=llmsproxy 实测直接
|
||
# 起不来,而且失败方式很隐蔽——
|
||
# [config] secrets disabled: open /etc/llmsproxy/master.key: permission denied
|
||
# 只是**一行日志**,服务会带着"敏感值将以明文落盘"继续跑起来。
|
||
# 也就是说降权在当前文件权限下不是加固,而是把密钥降级。要降权必须先把
|
||
# master.key 交给服务用户并统一 /etc/llmsproxy 的属主,那是一次独立的、有回滚
|
||
# 需求的变更,不该和加固混在一起。
|
||
#
|
||
# 下面每一条都在一个独立探针单元(临时端口 + 独立 runtime_file/adapter_dir)
|
||
# 上真实验证过:鉴权 401/200 正常、发一次真实 /v1/chat/completions 走通(证明
|
||
# LuaJIT 适配器路径没被 seccomp 打断)、审计文件可写可轮转、连续重启 3 次与
|
||
# kill -9 后行为符合预期。systemd 对非法指令值不报错只"忽略",逐条实测是唯一
|
||
# 可靠做法。
|
||
NoNewPrivileges=yes
|
||
# 读路径全部落在 /etc/llmsproxy;写路径经核对只有 config.yaml / runtime.json /
|
||
# audit.jsonl / adapters/*.lua / master.key,全在该目录下(internal/{config,gateway,
|
||
# core,lua} 里的 WriteFile|Rename|Remove 调用点)。
|
||
ProtectSystem=strict
|
||
ReadWritePaths=/etc/llmsproxy
|
||
ProtectHome=yes
|
||
PrivateTmp=yes
|
||
ProtectKernelTunables=yes
|
||
ProtectKernelModules=yes
|
||
ProtectControlGroups=yes
|
||
RestrictSUIDSGID=yes
|
||
RestrictRealtime=yes
|
||
LockPersonality=yes
|
||
RestrictAddressFamilies=AF_INET AF_INET6 AF_UNIX
|
||
# CapabilityBoundingSet 置空:本服务不需要任何 capability(不建 netns、不改
|
||
# 资源限制、不 chown)。留空即"一个都不给",比列一份允许清单更难写错。
|
||
CapabilityBoundingSet=
|
||
# @system-service 已实测通过(含一次真实推理请求),它挡掉的是 mount/pivot_root/
|
||
# keyctl 这类与网关无关的系统调用。
|
||
SystemCallFilter=@system-service
|
||
SystemCallArchitectures=native
|
||
|
||
[Install]
|
||
WantedBy=multi-user.target |