Shadowsocks 在本地创建的服务是一个 socks5 代理,Chrome 浏览器使用 SwitchyOmega 插件可以很方便的使用该代理,但绝大多数的 Linux 命令行程序都只支持 http(s) 代理,因此有必要把本地的 socks5 代理转成 http(s) 代理。
goproxy
Shadowsocks 转 http 通常会推荐 polipo[1],但 polipo 当前已经停止维护了,而且 goproxy 看上去乱七八糟的功能更齐全一些。
首先下载 goproxy,由于是 Go 写的,部署无比简单,解压之后即可使用。
直接在命令行上运行:
~$ ./proxy sps -S socks -T tcp -P 127.0.0.1:1080 -t tcp -p :12306
proxy free version 7.3 by snail , email : arraykeys@gmail.com
2019/04/03 20:25:32 stop domains loaded , 40213
2019/04/03 20:25:32 use tcp socks parent [127.0.0.1:1080] [ ROUNDROBIN ]
2019/04/03 20:25:32 ss udp on [::]:12306
2019/04/03 20:25:32 tcp http(s)+socks+ss proxy on [::]:12306
2019/04/03 20:25:37 CONNECT:www.google.com:443
2019/04/03 20:25:37 connect www.google.com:443
2019/04/03 20:25:37 conn 127.0.0.1:48586 - 127.0.0.1:1080 connected [www.google.com:443]
2019/04/03 20:25:39 conn 127.0.0.1:48586 - 127.0.0.1:1080 released [www.google.com:443]
其中选项 -P
指定已有的 socks5 代理,-p
指定待创建的 http(s) 代理服务的监听地址。
然后 export http_proxy 和 https_proxy 环境变量即可让命令行程序使用 http(s) 代理:
export http_proxy=http://localhost:12306
export https_proxy=http://localhost:12306
是的,就这么简单,当然,如果有需要的话可以创建 systemd 服务保持在后台长期运行。
创建 systemd 服务
编辑 systemd 服务环境变量文件:
~$ sudo vi /etc/default/s2h
SERVER=127.0.0.1
PORT=1080
LOCAL_PORT=12306
ENCRYPT=aes-256-cfb
编辑 systemd 服务文件:
~$ sudo vi /lib/systemd/system/s2h.service
[Unit]
Description=s2h
After=network.target
[Service]
EnvironmentFile=-/etc/default/s2h
ExecStart=/home/runsisi/Application/proxy-linux-amd64/proxy sps -S socks -T tcp -P ${SERVER}:${PORT} -t tcp -p :${LOCAL_PORT}
ExecReload=/bin/kill -HUP $MAINPID
KillMode=process
Restart=on-failure
RestartPreventExitStatus=255
Type=simple
[Install]
WantedBy=multi-user.target
启用服务:
~$ sudo systemctl daemon-reload
~$ sudo systemctl enable s2h
Created symlink /etc/systemd/system/multi-user.target.wants/s2h.service → /lib/systemd/system/s2h.service.
~$ sudo systemctl start s2h
~$ systemctl status s2h
● s2h.service - s2h
Loaded: loaded (/lib/systemd/system/s2h.service; enabled; vendor preset: enabled)
Active: active (running) since Wed 2019-04-03 21:47:04 CST; 1min 11s ago
Main PID: 28153 (proxy)
Tasks: 11 (limit: 4915)
CGroup: /system.slice/s2h.service
└─28153 /home/runsisi/Application/proxy-linux-amd64/proxy sps -S socks -T tcp -P 127.0.0.1:1080 -t tcp -p :12306
Apr 03 21:47:04 runsisi-hust systemd[1]: Started s2h.
Apr 03 21:47:04 runsisi-hust proxy[28153]: proxy free version 7.3 by snail , email : arraykeys@gmail.com
Apr 03 21:47:04 runsisi-hust proxy[28153]: 2019/04/03 21:47:04 use tcp socks parent [:1080] [ ROUNDROBIN ]
Apr 03 21:47:04 runsisi-hust proxy[28153]: 2019/04/03 21:47:04 ss udp on [::]:12306
Apr 03 21:47:04 runsisi-hust proxy[28153]: 2019/04/03 21:47:04 tcp http(s)+socks+ss proxy on [::]:12306
构建 goproxy
原始的 goproxy 代码已经被作者删除了,作者发布的二进制包在 systemd 下可能会出现如下的错误而导致进程退出:
~$ systemctl status s2h
● s2h.service - s2h
Loaded: loaded (/lib/systemd/system/s2h.service; enabled; vendor preset: enabled)
Active: inactive (dead) since Wed 2019-04-10 21:33:54 CST; 2s ago
Process: 3662 ExecStart=/home/runsisi/Application/proxy-linux-amd64/proxy sps -S socks -
Main PID: 3662 (code=exited, status=0/SUCCESS)
Apr 10 21:33:47 runsisi-hust systemd[1]: Started s2h.
Apr 10 21:33:47 runsisi-hust proxy[3662]: proxy free version 7.3 by snail , email : array
Apr 10 21:33:47 runsisi-hust proxy[3662]: 2019/04/10 21:33:47 use tcp socks parent [127.0.
Apr 10 21:33:47 runsisi-hust proxy[3662]: 2019/04/10 21:33:47 ss udp on [::]:12306
Apr 10 21:33:47 runsisi-hust proxy[3662]: 2019/04/10 21:33:47 tcp http(s)+socks+ss proxy o
Apr 10 21:33:54 runsisi-hust proxy[3662]: 2019/04/10 21:33:54 check update fail, please ch
lines 1-12/12 (END)...skipping...
因此只能取作者的最后一个可用版本进行构建:
~$ git clone -b wip-build https://github.com/runsisi/goproxy-1 goproxy
Cloning into 'goproxy'...
remote: Enumerating objects: 4, done.
remote: Counting objects: 100% (4/4), done.
remote: Compressing objects: 100% (3/3), done.
remote: Total 5281 (delta 1), reused 3 (delta 1), pack-reused 5277
Receiving objects: 100% (5281/5281), 4.14 MiB | 488.00 KiB/s, done.
Resolving deltas: 100% (3127/3127), done.
~$ go build github.com/snail007/goproxy
go: finding github.com/klauspost/cpuid v0.0.0-20170728055534-ae7887de9fa5
go: finding github.com/tjfoc/gmsm v0.0.0-20171124023159-98aa888b79d8
go: finding github.com/klauspost/reedsolomon v0.0.0-20171001120606-6bb6130ff6a7
go: finding github.com/juju/ratelimit v1.0.1
...
go: downloading github.com/templexxx/cpufeat v0.0.0-20170927014610-3794dfbfb047
go: extracting github.com/templexxx/cpufeat v0.0.0-20170927014610-3794dfbfb047
go: extracting golang.org/x/net v0.0.0-20180611182652-db08ff08e862
~$ file goproxy
goproxy: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, not stripped
源代码目录下 release.sh 脚本也可以用来进行构建,支持跨平台构建和链接时增加版本信息。
参考资料
[1] Convert Shadowsocks into an HTTP proxy
https://github.com/shadowsocks/shadowsocks/wiki/Convert-Shadowsocks-into-an-HTTP-proxy
[2] SOCKS5 to HTTP(S) + SOCKS5
https://github.com/runsisi/goproxy-1#63socks5-to-https--socks5
最后修改于 2019-04-03