Skip to content

Blog

MacOS下Supervisor运行指令权限问题

在MacOS下使用Supervisor来运行命令时,会出现与在终端中直接运行结果不一致的问题

比如之前在运行mcp-proxy时,在终端运行非常正常,但改到Supervisor后,mcp-proxy可以正常启动,但配置的mcp server始终无法正常运行

这个问题就是Supervisor运行的command环境与直接在终端运行时不一样导致的

首先获取环境变量

Terminal window
env | grep -E "(NODE|NPM|NVM|PYTHON|PATH)" | sort

例如返回内容的内容如下:

Terminal window
INFOPATH=/opt/homebrew/share/info:
PATH=/opt/homebrew/opt/node@22/bin:/opt/homebrew/bin:/opt/homebrew/sbin:/usr/local/bin

然后将返回的PATH复制到Supervisor配置文件的environment里

[program:test]
command='/Users/test/go/bin/mcp-proxy' --config '/Users/test/go/config/mcp-proxy.config.json'
directory=/Users/test/go/bin ; 工作目录
autostart=true ; 随 Supervisor 启动
startsecs=10 ; 延迟启动60秒
autorestart=true ; 自动重启
startretries=3 ; 启动失败重试次数
environment= HOME="/Users/test",
PATH="/opt/homebrew/opt/node@22/bin:/opt/homebrew/bin:/opt/homebrew/sbin:/usr/local/bin"
user=test ; 运行用户(可选)

最后更新Supervisor配置

Terminal window
supervisorctl update

这样就可以正确使用终端的环境来运行指令

MacOS配置NAT转发规则

Terminal window
# 启用IPv4转发
sudo sysctl -w net.inet.ip.forwarding=1

为了重启后依然有效,比较好的方式是创建启动项:

Terminal window
# 创建一个plist文件
sudo vim /Library/LaunchDaemons/com.lc.ipforwarding.plist

com.lc.ipforwarding.plist文件内容如下

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.custom.ipforwarding</string>
<key>ProgramArguments</key>
<array>
<string>/usr/sbin/sysctl</string>
<string>-w</string>
<string>net.inet.ip.forwarding=1</string>
</array>
<key>RunAtLoad</key>
<true/>
</dict>
</plist>

设置权限并加载:

Terminal window
# 设置正确的权限
sudo chown root:wheel /Library/LaunchDaemons/com.lc.ipforwarding.plist
sudo chmod 644 /Library/LaunchDaemons/com.lc.ipforwarding.plist
# 立即加载
sudo launchctl load -w /Library/LaunchDaemons/com.lc.ipforwarding.plist

验证设置:

Terminal window
# 检查当前状态
sysctl net.inet.ip.forwarding
# 检查启动项状态
sudo launchctl list | grep ipforwarding
Terminal window
# 编辑配置文件
sudo vim /etc/pf.conf
# 基本NAT配置示例,表示转发IP段192.168.1.0/24
nat on en0 from 192.168.1.0/24 to any -> (en0)

直接添加转发配置到pf.conf文件的最下面会有问题,应用配置文件时会报错

Terminal window
pfctl: Use of -f option, could result in flushing of rules
present in the main ruleset added by the system at startup.
See /etc/pf.conf for further details.
No ALTQ support in kernel
ALTQ related functions disabled
/etc/pf.conf:31: Rules must be in order: options, normalization, queueing, translation, filtering
pfctl: Syntax error in config file: pf rules not loaded

解决办法是重新组织整个文件里内容的顺序

/etc/pf.conf
# 1. 定义变量
ext_if = "en0"
internal_net = "192.168.1.0/24"
# 2. 选项 (options)
set skip on lo0
set block-policy return
# 3. 规范化 (normalization)
scrub-anchor "com.apple/*"
# 4. 队列 (queueing)
dummynet-anchor "com.apple/*"
# 5. 转换 (translation)
nat-anchor "com.apple/*"
rdr-anchor "com.apple/*"
# 添加自定义NAT规则
nat on $ext_if from $internal_net to any -> ($ext_if)
# 6. 过滤 (filtering)
anchor "com.apple/*"
load anchor "com.apple" from "/etc/pf.anchors/com.apple"
Terminal window
# 检查语法
sudo pfctl -nf /etc/pf.conf
# 应用规则(使用-F清除旧规则)
sudo pfctl -F all -f /etc/pf.conf
# 启用pf
sudo pfctl -e