V2ray MITM

2023-08-15

一、用 OpenSSL 签发

$ openssl genrsa -des3 -out ca.old.key 2048
$ openssl req -new -key ca.old.key -out ca.req
$ openssl x509 -req -days 365 -signkey ca.old.key -in ca.req -out ca.cer

最后转换一下密钥格式

$ openssl rsa -in ca.old.key -out ca.key 这样就得到了我们需要的 ca.key 和 ca.cer

二、用 v2ctl 签发 v2ctl 是自某个版本开始从 v2ray 主程序分离出来的辅助程序,主要功能是将 json 配置转换为供主程序使用的 pb,而它也包含了很多面向用户的命令行功能,例如生成 uuid,自签证书等。不过 v2ctl 生成的 ca 证书是给 v2ray 配置文件用的 json 格式的,我们还需要手动转换一下保存以便导入进浏览器:

如果你是用官方提供的一键脚本安装的话 v2ctl 就是在 /usr/bin/v2ray/

生成证书并将输出保存为 test.json

$ /usr/bin/v2ray/v2ctl cert –ca –expire=114514h > test.json

将 test.json 转换为 ca.cer 和 ca.key

$ python -c “(lambda g: [[[(f.close(), [(f.write(‘‘.join((lambda __iter, __l: ((__l[‘i’] + ‘\n’) for __l[‘i’] in __iter))(d[‘key’], {}))), (f.close(), [(f.write(‘‘.join((lambda __iter, __l: ((__l[‘i’] + ‘\n’) for __l[‘i’] in __iter))(d[‘certificate’], {}))), (f.close(), None)[1])[1] for __g[‘f’] in [(open(‘ca.cer’, ‘w’))]][0])[1])[1] for __g[‘f’] in [(open(‘ca.key’, ‘w’))]][0])[1] for __g[‘d’] in [(json.load(f))]][0] for __g[‘f’] in [(open(‘test.json’, ‘r’))]][0] for __g[‘json’] in [(__import(‘json’, __g, __g))]][0])(globals())” 最后一步用到了一个非常有趣的小工具,可以把几行 python 脚本浓缩成一行,强烈安利:oneliner-izer

如果你想正常一点的话,也可以自己执行这个 python 脚本:

import json

with open("test.json", "r") as f:
    d = json.load(f)
with open("ca.key", "w") as f:
    f.write("".join(i + "\n" for i in d["key"]))
with open("ca.cer", "w") as f:
    f.write("".join(i + "\n" for i in d["certificate"]))

现在我们把生成好的证书和密钥拖回本地以后,在浏览器里导入证书:

Chrome: 打开 chrome://settings/certificates ,在“授权中心”里导入 ca.cer

Firefox: 打开 about:preferences#privacy 并拉到最下面,在 View Certificates 里导入 ca.cer

导入成功后以上两种证书生成方法就可以看出不同了,使用 openssl 生成的你可以在已信任的 CA 列表里找到自己设置的 ORG 名称,而 v2ctl 生成的你则会看到 V2Ray Inc.

准备工作做好了就可以开始配置 v2ray 了,以下配置文件由 Shelikhoo 提供,其实我也没仔细看(复杂的 V2Ray 配置真的太可怕了),照抄基本就行了:

client.json server.json 上面配置中,你应该修改的有:证书和密钥的位置,服务器的 IP 和 端口以及 UUID。都已经开始想做这些骚操作了,怎么改也不需要我多说了吧~

该配置将在 vTemplate 同步更新。

成功后,你将可以正常地打开网页,并且查看被代理网页的证书时将会看到已经是自己魔改的 CA 了。

最后提几点我对这个操作的看法吧。在我看来,尽管确实可能在一定程度上提高了浏览网页时的用户体验,可是缺点和令人担忧的地方却也很明显,总的来说有点得不偿失。例如:

无法在浏览器上直接查看网站的真实证书了。这对 web 工作者/爱好者 无疑是灭顶之灾;

在服务端的 V2Ray 与目标服务器的通讯中,V2Ray 相当于客户端,而 Go 的 TLS 库作为客户端的行为是否能满足所有需求值得商榷,例如目标服务器仅支持 TLS 1.3 时就很可能出现问题;

浏览器对发生了什么事的掌控能力下降了。例如浏览器失去了对哪些 CA 值得信任的选择权,当真的遭到 MITM 时也不知道会怎么样。

这个配置简直完美地体现了 V2Ray 饱受诟病的缺点——它过于复杂了。尽管它是严格按照文档来写的,依然让它的可读性非常差。

那么,我们下期再见~~

参考资料:

V2Ray 官方网站