Mac 配置 Trojan 代理完整教程 - 终端自动代理

前言

Mac 上配置 Trojan 代理,实现终端自动代理,方便命令行工具(git、curl、brew 等)自动走代理下载。

核心配置:

  • Trojan SOCKS5 代理:127.0.0.1:1080
  • HTTP 代理(可选):127.0.0.1:8118

一、安装 Trojan

方式 1:使用 WestWorldSS4(推荐)

WestWorldSS4 是一个图形化的 Trojan 客户端,安装后自带 Trojan。

  1. 下载安装 WestWorldSS4
  2. 导入 Trojan 配置或订阅链接
  3. 启动 Trojan

安装位置:/Users/你的用户名/Library/Application Support/WestWorldSS4/trojan-latest/trojan

方式 2:手动安装

1
2
3
4
5
6
# 下载 Trojan
brew install trojan

# 或手动下载
curl -LO https://github.com/trojan-gfw/trojan/releases/download/v1.16.0/trojan-1.16.0-macos-x64.tar.xz
tar -xf trojan-1.16.0-macos-x64.tar.xz

二、配置 Trojan

2.1 Trojan 配置文件

创建或编辑配置文件 client.json

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
{
"run_type": "client",
"local_addr": "127.0.0.1",
"local_port": 1080,
"remote_addr": "your-server.com",
"remote_port": 443,
"password": [
"your-password"
],
"ssl": {
"verify": true,
"cert": "",
"sni": "your-server.com"
}
}

关键参数:

  • local_addr:本地监听地址
  • local_port:SOCKS5 代理端口(默认 1080)
  • remote_addr:Trojan 服务器地址
  • remote_port:服务器端口(通常 443)

2.2 测试 Trojan

1
2
3
4
5
# 启动 Trojan
./trojan -c client.json

# 测试 SOCKS5 代理
curl --proxy socks5://127.0.0.1:1080 https://www.google.com

三、配置开机自启

3.1 创建 LaunchAgent

创建文件 ~/Library/LaunchAgents/com.trojan.client.plist

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<?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.trojan.client</string>
<key>ProgramArguments</key>
<array>
<!-- 方式1:使用 WestWorldSS4 的 Trojan -->
<string>/Users/你的用户名/Library/Application Support/WestWorldSS4/trojan-latest/trojan</string>
<string>-c</string>
<string>/Users/你的用户名/Library/Application Support/WestWorldSS4/trojan-config.json</string>

<!-- 方式2:使用手动安装的 Trojan -->
<!-- <string>/usr/local/bin/trojan</string> -->
<!-- <string>-c</string> -->
<!-- <string>/usr/local/etc/trojan/client.json</string> -->
</array>
<key>RunAtLoad</key>
<true/>
<key>KeepAlive</key>
<true/>
<key>StandardOutPath</key>
<string>/tmp/trojan.log</string>
<key>StandardErrorPath</key>
<string>/tmp/trojan.log</string>
</dict>
</plist>

3.2 加载 LaunchAgent

1
2
3
4
5
6
7
8
# 加载服务
launchctl load ~/Library/LaunchAgents/com.trojan.client.plist

# 检查状态
launchctl list | grep trojan

# 停止服务
launchctl unload ~/Library/LaunchAgents/com.trojan.client.plist

四、配置终端自动代理

4.1 编辑 Shell 配置

编辑 ~/.zshrc(或 ~/.bash_profile):

1
2
3
4
5
6
7
8
9
# 添加以下内容到文件末尾

# Trojan SOCKS5 代理配置
export ALL_PROXY=socks5://127.0.0.1:1080
export http_proxy=http://127.0.0.1:8118
export https_proxy=http://127.0.0.1:8118
export HTTP_PROXY=http://127.0.0.1:8118
export HTTPS_PROXY=http://127.0.0.1:8118
export NO_PROXY=localhost,127.0.0.1,::1

4.2 使配置生效

1
2
3
4
5
6
# 重新加载配置
source ~/.zshrc

# 验证环境变量
echo $ALL_PROXY
# 输出: socks5://127.0.0.1:1080

4.3 测试代理

1
2
3
4
5
6
7
8
# 测试 SOCKS5 代理
curl -I https://www.google.com

# 测试 git
git clone https://github.com/google/mediapipe.git

# 测试 brew
brew update

五、SOCKS5 转 HTTP 代理(可选)

某些工具不支持 SOCKS5 代理,需要转换为 HTTP 代理。

5.1 创建 HTTP 代理脚本

创建文件 /tmp/http_proxy.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
#!/usr/bin/env python3
"""
SOCKS5 to HTTP Proxy Converter
将 Trojan SOCKS5 代理转换为 HTTP 代理

SOCKS5: 127.0.0.1:1080 -> HTTP: 127.0.0.1:8118
"""

import socket
import select
import struct
import threading
import sys

SOCKS5_HOST = '127.0.0.1'
SOCKS5_PORT = 1080
HTTP_PORT = 8118
BUFFER_SIZE = 65536

def connect_socks5(target_host, target_port):
"""通过 SOCKS5 代理连接目标"""
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(10)

try:
# 连接 SOCKS5 代理
sock.connect((SOCKS5_HOST, SOCKS5_PORT))

# 发送 SOCKS5 握手
sock.send(b'\x05\x01\x00')
response = sock.recv(2)

if response != b'\x05\x00':
return None

# 发送连接请求
request = b'\x05\x01\x00\x03'
request += bytes([len(target_host)]) + target_host.encode()
request += struct.pack('>H', target_port)
sock.send(request)

response = sock.recv(10)
if response[1] != 0:
return None

return sock
except Exception as e:
print(f"SOCKS5 连接失败: {e}", file=sys.stderr)
return None

def handle_client(client_socket):
"""处理客户端请求"""
try:
# 读取 HTTP 请求
request = client_socket.recv(BUFFER_SIZE).decode('utf-8', errors='ignore')

if not request:
client_socket.close()
return

# 解析请求
lines = request.split('\r\n')
if not lines:
client_socket.close()
return

# 解析请求行
request_line = lines[0]
parts = request_line.split(' ')

if len(parts) < 3:
client_socket.close()
return

method = parts[0]
url = parts[1]

# 处理 CONNECT 方法(HTTPS)
if method == 'CONNECT':
host_port = url.split(':')
target_host = host_port[0]
target_port = int(host_port[1]) if len(host_port) > 1 else 443

# 连接目标
target_socket = connect_socks5(target_host, target_port)

if target_socket:
# 发送 200 响应
client_socket.send(b'HTTP/1.1 200 Connection Established\r\n\r\n')

# 转发数据
def forward(src, dst):
try:
while True:
data = src.recv(BUFFER_SIZE)
if not data:
break
dst.send(data)
except:
pass

# 双向转发
t1 = threading.Thread(target=forward, args=(client_socket, target_socket))
t2 = threading.Thread(target=forward, args=(target_socket, client_socket))
t1.daemon = True
t2.daemon = True
t1.start()
t2.start()
t1.join()
t2.join()
else:
client_socket.send(b'HTTP/1.1 502 Bad Gateway\r\n\r\n')
client_socket.close()
else:
# 处理普通 HTTP 请求
if url.startswith('http://'):
url_part = url[7:]
if '/' in url_part:
host_port = url_part.split('/')[0]
path = '/' + '/'.join(url_part.split('/')[1:])
else:
host_port = url_part
path = '/'
else:
client_socket.close()
return

if ':' in host_port:
target_host, port = host_port.split(':')
target_port = int(port)
else:
target_host = host_port
target_port = 80

# 连接目标
target_socket = connect_socks5(target_host, target_port)

if target_socket:
# 发送修改后的请求
new_request = f"{method} {path} HTTP/1.1\r\n"
new_request += '\r\n'.join(lines[1:]) + '\r\n\r\n'
target_socket.send(new_request.encode())

# 接收响应
while True:
data = target_socket.recv(BUFFER_SIZE)
if not data:
break
client_socket.send(data)

target_socket.close()

client_socket.close()
except Exception as e:
print(f"处理请求失败: {e}", file=sys.stderr)
client_socket.close()

def main():
"""主函数"""
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server.bind(("0.0.0.0", HTTP_PORT))
server.listen(100)

print(f"HTTP 代理服务器启动: 127.0.0.1:{HTTP_PORT}")
print(f"转发到 SOCKS5: {SOCKS5_HOST}:{SOCKS5_PORT}")

while True:
client_socket, addr = server.accept()
thread = threading.Thread(target=handle_client, args=(client_socket,))
thread.daemon = True
thread.start()

if __name__ == "__main__":
main()

5.2 创建 HTTP 代理 LaunchAgent

创建文件 ~/Library/LaunchAgents/com.http-proxy.server.plist

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<?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.http-proxy.server</string>
<key>ProgramArguments</key>
<array>
<string>/usr/local/bin/python3</string>
<string>/tmp/http_proxy.py</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>KeepAlive</key>
<true/>
<key>StandardOutPath</key>
<string>/tmp/http_proxy.log</string>
<key>StandardErrorPath</key>
<string>/tmp/http_proxy.err</string>
<key>EnvironmentVariables</key>
<dict>
<key>PATH</key>
<string>/usr/local/bin:/usr/bin:/bin</string>
</dict>
</dict>
</plist>

5.3 启动 HTTP 代理

1
2
3
4
5
# 加载服务
launchctl load ~/Library/LaunchAgents/com.http-proxy.server.plist

# 测试 HTTP 代理
curl --proxy http://127.0.0.1:8118 https://www.google.com

六、验证配置

6.1 检查服务状态

1
2
3
4
5
6
7
8
9
# 检查 Trojan 进程
ps aux | grep trojan

# 检查端口监听
lsof -i :1080 # SOCKS5
lsof -i :8118 # HTTP

# 检查 LaunchAgent
launchctl list | grep trojan

6.2 测试代理

1
2
3
4
5
6
7
8
9
10
11
# 测试 SOCKS5
curl --proxy socks5://127.0.0.1:1080 https://www.google.com -I

# 测试 HTTP
curl --proxy http://127.0.0.1:8118 https://www.google.com -I

# 测试 git
git clone https://github.com/google/mediapipe.git --depth 1

# 测试 brew
brew update

七、常见问题

7.1 Trojan 无法启动

1
2
3
4
5
6
7
8
# 检查配置文件语法
./trojan -c client.json --test

# 查看日志
cat /tmp/trojan.log

# 检查端口占用
lsof -i :1080

7.2 代理不生效

1
2
3
4
5
6
7
8
# 检查环境变量
env | grep -i proxy

# 手动设置代理
export ALL_PROXY=socks5://127.0.0.1:1080

# 临时禁用代理
unset ALL_PROXY http_proxy https_proxy HTTP_PROXY HTTPS_PROXY

7.3 LaunchAgent 加载失败

1
2
3
4
5
6
# 检查 plist 语法
plutil -lint ~/Library/LaunchAgents/com.trojan.client.plist

# 卸载后重新加载
launchctl unload ~/Library/LaunchAgents/com.trojan.client.plist
launchctl load ~/Library/LaunchAgents/com.trojan.client.plist

7.4 Bazel 编译代理配置

1
2
3
4
5
6
7
8
# Bazel 需要特殊配置代理
export ALL_PROXY=socks5://127.0.0.1:1080
bazel build //your:target

# 或使用 HTTP 代理
export HTTP_PROXY=http://127.0.0.1:8118
export HTTPS_PROXY=http://127.0.0.1:8118
bazel build //your:target

八、配置总结

配置项 文件位置 说明
Trojan 配置 ~/Library/Application Support/WestWorldSS4/trojan-config.json Trojan 客户端配置
Trojan 自启 ~/Library/LaunchAgents/com.trojan.client.plist 开机自动启动 Trojan
HTTP 代理 /tmp/http_proxy.py SOCKS5 转 HTTP 代理
HTTP 自启 ~/Library/LaunchAgents/com.http-proxy.server.plist 开机自动启动 HTTP 代理
Shell 代理 ~/.zshrc~/.bash_profile 终端自动代理环境变量

九、一键配置脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#!/bin/bash
# Trojan 一键配置脚本

# 1. 创建 LaunchAgent 目录
mkdir -p ~/Library/LaunchAgents

# 2. 创建 Trojan LaunchAgent(使用 WestWorldSS4)
cat > ~/Library/LaunchAgents/com.trojan.client.plist << 'EOF'
<?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.trojan.client</string>
<key>ProgramArguments</key>
<array>
<string>/Users/$USER/Library/Application Support/WestWorldSS4/trojan-latest/trojan</string>
<string>-c</string>
<string>/Users/$USER/Library/Application Support/WestWorldSS4/trojan-config.json</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>KeepAlive</key>
<true/>
</dict>
</plist>
EOF

# 3. 添加 Shell 代理配置
cat >> ~/.zshrc << 'EOF'

# Trojan SOCKS5 代理配置(自动添加)
export ALL_PROXY=socks5://127.0.0.1:1080
export http_proxy=http://127.0.0.1:8118
export https_proxy=http://127.0.0.1:8118
export HTTP_PROXY=http://127.0.0.1:8118
export HTTPS_PROXY=http://127.0.0.1:8118
export NO_PROXY=localhost,127.0.0.1,::1
EOF

# 4. 加载 LaunchAgent
launchctl load ~/Library/LaunchAgents/com.trojan.client.plist

# 5. 使配置生效
source ~/.zshrc

echo "✅ Trojan 代理配置完成!"
echo "SOCKS5: 127.0.0.1:1080"
echo "HTTP: 127.0.0.1:8118"

参考资料


最后更新:2026-03-15


Mac 配置 Trojan 代理完整教程 - 终端自动代理
https://dapalm.com/2026/03/15/2026-03-15-Mac配置Trojan代理完整教程-终端自动代理/
作者
Mars
发布于
2026年3月15日
许可协议