WSS注入
WSS注入
正常情况下,Sekiro使用裸tcp进行通信,但是在浏览器、rn、weex等环境中,由于没有标准的tcp通道,而只能使用websocket。
一般情况下,受限于浏览器的安全机制,可能不允许https网页环境下创建不安全的ws通道,而是要求使用带有ssl证书的tsl连接(即wss通道)
老版本方法
在sekiroV1和sekiroV2,我们都是建议使用nginx给sekiro的wss通道增加https证书,这要求一定的运维能力、增加了一个nginx中间件、并且要求去申请https证书。 我认为他是一个比较复杂的操作过程,所以在sekiroV3我们直接在系统内部解决这个问题。
我们提供两种方法解决ssl的问题
Sekiro自动生成证书
这是Sekiro最为推荐的方式,他的原理是Sekiro将会作为CA机构,具备给任意网站颁发和伪造证书的能力,所以你只需要给你的服务器配置你的服务器域名(或者IP),
但是使用这种方式,那么需要Sekiro成为被浏览器认可的CA机构,所以需要您手动将Sekiro的根证书(root certificate) 安装到你的电脑中。这个过程和我们通过fiddler
或charles
抓包是一样的原理。
安装CA证书
点击这里 pem格式 或者 crt格式下载证书,并跟随系统引导安装根证书
配置域名列表
Sekiro可以动态生成所有ssl证书,但是不知道如何设定ssl证书内的域名列表(可能存在代理,以及在解密ssl流量前无法知道访问域名内容),对于完整的ssl host列表可以由系统独立维护。
Sekiro将会默认在如下场景收集host和IP,自动完成内容填充
- 通过sekiro tcp协议传递过来的ip
- 访问sekiro网站http接口时,收集http header的host字段
- 通过ws连接时sekiro时,收集http header的host字段
- sekiro通过出口ip解析,得到的sekiro出口IP
如果你的服务器ip绑定了其他域名,无法被上述四种机制感知到,那么可以在:《系统设置->CA host列表》配置你的新域名
内容安全策略(Content Security Policy)
如果你的注入网站有wss的同源检测拦截,那么就算是可以创建wss连接,也可能因为同源问题被阻断。
- 假定访问网站:
https://xxx.abc.com
- 使用wss连接sekiro:
wss://sekiro.iinti.cn/business/register?group=ws-group&clientId=1221
- 如果 www.abc.com , 存在同源策略拦截,则可能报错:
refused to connect to 'wss://sekiro.iinti.cn/business/register?group=ws-group&clientId=1221' because of it violates the following Content Security Policy directive: xxxxxx
使用代理解决CSP
Sekiro的端口服务实现了http/https代理,你可以直接将Sekiro的端口设定为你的浏览器的代理
如果你的注入网站由wss的同源检测拦截,那么可以通过将浏览器的代理设定到sekio服务器上,此时由于流量都能经过sekiro服务器,并且sekiro拥有CA根证书可以解密和伪造流量。 那么此时wss连接可以直接使用对应主网页的域名构造wss连接,此时sekiro可以感知这个连接需要转发到sekiro服务器,将会全自动在内部处理。
此时可以完美解决wss同源拦截问题
请注意,当通过代理的方式访问Sekiro,那么Sekiro必然开启ssl解密,请注意此时一定需要安装Sekiro的CA证书,否则https网页将会全部因为证书不被信任而被阻断
使用浏览器代理插件解决CSP(SwitchyOmega)
如果整体将Sekiro服务器设置为代理服务器,则会将所有的流量打入到Sekiro服务器,在考虑多浏览器集群控制的时候,多IP聚集可能带来风控问题,以及Sekiro服务器作为出口ip也可能带来风控问题。 此时可以使用pac
脚本单独控制Sekiro的WebSocket连接进入sekiro服务器,其余的流量则正常通过。
下载代理插件:
https://github.com/FelisCatus/SwitchyOmega
配置PAC脚本
function FindProxyForURL(url, host) {
if (shExpMatch(url,"wss://*")) {
// 只要是wss协议,则代理到sekiro.iinti.cn:5612
// 这里实现比较粗暴,具体规则可根据网站实际调整
return "PROXY sekiro.iinti.cn:5612";
}
return "DIRECT";
}
构造和目标网站完全一致的同域名websocket连接
var client = new SekiroClient("wss://xxx.abc.com/business/register?group=test-ws&clientId=" + Math.random());
client.registerAction("testAction", function (request, resolve, reject) {
resolve("ok");
});
构造子域名解决CSP
- 假定网站sekiro部署在:
47.93.16.121:443
- 配置hosts文件:
sekrio.xxx.abc.com 47.93.16.121
使得域名sekiro.xxx.abc.com
解析到47.93.16.121
( 也即模拟申请一个域名,绑定在sekiro服务器上,并且让这个域名在目标网站的子域名) - 跟随步骤《安装CA证书》,确保系统根证书完成安装,并且设置信任sekirio证书
- 使用构造子域名的wss连接:
wss://sekiro.xxx.abc.com/business/register?group=ws-group&clientId=1221
创建连接
条件:需要CSP规则中支持wss: connect-src wss:
,否则只能使用代理的方式,这是因为CSP规则认为http的网页不应该被websocket加载:https://csplite.com/csp118/
风险
使用伪造证书的方式可能导致你的电脑存在安全风险,这是因为CA机构具备给任意网站伪造证书的能力,这导致您的https流量可以被具备sekiro根证书的系统拦截。 Sekiro目前是固定内容的CA证书(代码硬编码,在或者Sekiro源码之时才可以修改)。
一般情况下使用sekiro websocket的场景都是生产电脑,此时不需要关心数据安全
使用CA证书
如果你考虑安全问题,或者对注入环境的控制能力有限导致无法安装CA证书,那么你可以考虑使用标准的CA证书(在阿里云、腾讯云等云厂商哪里申请), 此时你可以配置证书文件,类似之前的nginx方案一样,只是Sekiro帮你在内部处理了。
这种方案系统直接使用用户上传证书完成https流量握手。
请注意,CA根证书伪造和用户手动上传ssl证书两种方法只能选择一种,且在《系统设置》中选择二选一的开关
源码部署方式
将证书文件存储到 conf/
目录下,命名为:ssl_key_store_file.pfx
,在config/application.properties
文件中追加下列配置(请注意对照文件名称,证书类型,证书密码是否正确):
server.ssl.key-store=classpath:ssl_key_store_file.pfx
server.ssl.key-store-type=PKCS12
server.ssl.key-store-password=the-password
docker部署方式:
修改docker-compose.yaml
文件,
environment:
SPRING_DATASOURCE_USERNAME: root
SPRING_DATASOURCE_PASSWORD: sekiro
SPRING_DATASOURCE_URL: jdbc:mysql://sekiro-mysql-local:3306/sekiro_v3?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&autoConnect=true
# 这是证书额外配置,请注意对照证书类型和证书密码是否正确
SPRING_SERVER_SSL_KEY-STORE: file:/opt/ssl_key_store_file.pfx
SPRING_SERVER_SSL_KEY-STORE-TYPE: PKCS12
SPRING_SERVER_SSL_KEY-STORE-PASSWORD: the-password
ports:
- "5612:5612"
volumes:
# 这是证书额外配置,这里将证书文件映射到外部,请将证书文件命名为ssl_key_store_file.pfx,并且放置到和docker-compose.yaml同级目录
- ./ssl_key_store_file.pfx:/opt/ssl_key_store_file.pfx #