简介
根据官方说明,WARP
技术上是VPN
,但目标用户跟一般VPN不同。WARP不是让用户突破地区封锁(Geo-blocking)
,也不会隐藏用户的IP地址。WARP的目标用户是一般大众,保障数据传送的安全,防止用户跟应用之间的网络被监控。亦可以防止互联网服务供应商(ISP)收集用户的浏览习惯用以卖给广告商。
再加上1.1.1.1 DNS
的承诺:
用户数据不出售,不用作定向广告 用来防止滥用服务的Debug logs 会在24小时内清除
不储存任何个人数据/可识别个人的资料,包括用户IP和用户端口
只保留有限异动资料(transaction data)用作合法操作和研究用途(operational and research purposes),并会在24小时内清除
如需要更快速度,可每月付费无限使用WARP+,或通过分享1.1.1.1
给朋友取得免费的WARP+数据。
Cloudflare 的1.1.1.1+WARP算是个不错的免费VPN选择,安全、上网速度快、低耗电。但畸氏测试WARP时,有时IP地址或地理位置资料跟原本的一样,有时显示为Cloudflare的IP地址及地理位置在美国。所以对私隐要求高,需要隐藏IP地址、地理位置,或突破地区封锁的用家来说,其他VPN会比较适合。
使用注意
首次使用需改系统语言为英语.
分享获取流量
脚本分Nodejs
和Python
两种,这里我们介绍Nodejs
版本。
AFF ID
首先找到自己的AFF ID
:
进入Cloudflare WARP APP
,点击右上角的设置
按钮,进入更多设置More settings
- 诊断Diagnostics
,客户端配置CLIENT CONFIGURATION
里面的ID
即为AFF ID
。
脚本内容:
修改脚本中AFF ID
为自己的,timesToLoop
为次数(1次1G流量).
// Fake register for referrer to get warp plus bandwidth
const referrer = "AFF ID复制到这里";
const timesToLoop = 10; // 循环次数
const retryTimes = 5; // 重试次数
const https = require("https");
const zlib = require("zlib");
async function init() {
for (let i = 0; i < timesToLoop; i++) {
if (await run()) {
console.log(i + 1, "OK");
} else {
console.log(i + 1, "Error");
for (let r = 0; r < retryTimes; r++) {
if (await run()) {
console.log(i + 1, "Retry #" + (r + 1), "OK");
break;
} else {
console.log(i + 1, "Retry #" + (r + 1), "Error");
if (r === retryTimes - 1) {
return;
}
}
}
}
}
}
async function run() {
return new Promise(resolve => {
const install_id = genString(11);
const postData = JSON.stringify({
key: `${genString(43)}=`,
install_id: install_id,
fcm_token: `${install_id}:APA91b${genString(134)}`,
referrer: referrer,
warp_enabled: false,
tos: new Date().toISOString().replace("Z", "+07:00"),
type: "Android",
locale: "zh_CN"
});
const options = {
hostname: "api.cloudflareclient.com",
port: 443,
path: "/v0a745/reg",
method: "POST",
headers: {
"Content-Type": "application/json",
Host: "api.cloudflareclient.com",
Connection: "Keep-Alive",
"Accept-Encoding": "gzip",
"User-Agent": "okhttp/3.12.1",
"Content-Length": postData.length
}
};
const req = https.request(options, res => {
const gzip = zlib.createGunzip();
// const buffer = [];
res.pipe(gzip);
gzip
.on("data", function(data) {
// buffer.push(data.toString());
})
.on("end", function() {
// console.dir(JSON.parse(buffer.join("")));
resolve(true);
})
.on("error", function(e) {
// console.error(e);
resolve(false);
});
});
req.on("error", error => {
// console.error(error);
resolve(false);
});
req.write(postData);
req.end();
});
}
function genString(length) {
// https://stackoverflow.com/a/1349426/11860316
let result = "";
const characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
const charactersLength = characters.length;
for (let i = 0; i < length; i++) {
result += characters.charAt(Math.floor(Math.random() * charactersLength));
}
return result;
}
init();
在线运行
打开在线运行Nodejs:https://repl.it/languages/nodejs,在中间部分粘贴进脚本,然后点击RUN
,就跑起来了.
Python版本脚本
加入了异常处理和多线程, 运行速度飞快.REFFER CODE
改为自己的AFF ID
,脚本保存为1111.py
提前安装下requests
库,python3 -m pip install requests
,然后python3 1111.py
就可以了(建议使用screen
后台运行).
import requests
import json
import datetime
import random
import string
import threading
referrer = "REFFER CODE"
timesToLoop = 20
retryTimes = 5
poolSize = 10
def genString(stringLength):
letters = string.ascii_letters + string.digits
return ''.join(random.choice(letters) for i in range(stringLength))
url = 'https://api.cloudflareclient.com/v0a745/reg'
def run():
install_id = genString(11)
body = {
"key": "{}=".format(genString(42)),
"install_id": install_id,
"fcm_token": "{}:APA91b{}".format(install_id, genString(134)),
"referrer": referrer,
"warp_enabled": False,
"tos": datetime.datetime.now().isoformat()[:-3] + "+07:00",
"type": "Android",
"locale": "zh-CN"
}
bodyString = json.dumps(body)
headers = {
'Content-Type': 'application/json; charset=UTF-8',
'Host': 'api.cloudflareclient.com',
'Connection': 'Keep-Alive',
'Accept-Encoding': 'gzip',
'User-Agent': 'okhttp/3.12.1'
}
r = None
try:
r = requests.post(url, data=bodyString, headers=headers)
except Exception as e:
print(f"error occured !! {e}")
return r
def t_run() -> None:
for i in range(timesToLoop):
result = run()
if result is not None and result.status_code == 200:
print(i + 1, "OK")
else:
print(i + 1, "Error")
for r in range(retryTimes):
retry = run()
if retry.status_code == 200:
print(i + 1, "Retry #" + str(r + 1), "OK")
break
else:
print(i + 1, "Retry #" + str(r + 1), "Error")
if r == retryTimes - 1:
exit()
if __name__ == "__main__":
thds = []
for i in range(poolSize):
thds.append(threading.Thread(target=t_run, args=()))
for t in thds:
t.start()
for t in thds:
t.join()
php版脚本
请求一次循环10次。
同样替换掉AFF ID
,php
运行即可。
<?php
date_default_timezone_set('Asia/ShangHai');
$referrer = "REFFER CODE";
$for_num = 10;
function random($length)
{
$pattern = '1234567890abcdefghijklmnopqrstuvwxyz';
for ($i = 0; $i < $length; $i++) {
$key .= $pattern{mt_rand(0, 35)};
}
return $key;
}
for ($i = 0; $i < $for_num; $i++) {
$install_id = random(11);
$data = [
'key' => random(43) . '=',
'install_id' => $install_id,
'fcm_token' => $install_id . ":APA91b" . random(134),
'referrer' => $referrer,
'warp_enabled' => false,
'tos' => date('c'),
"type" => "Android",
"locale" => "zh-CN",
];
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.cloudflareclient.com/v0a745/reg",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode($data),
CURLOPT_HTTPHEADER => [
'Connection: Keep-Alive',
"Content-Type: application/json",
"Accept-Encoding: gzip",
"User-Agent: okhttp/3.12.1",
"Content-Length" => strlen(json_encode($data)),
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
if ($err) {
echo "cURL Error #:" . $err . "\r\n";
} else {
$response = json_decode($response, true);
if (!empty($response['referrer'])) {
echo "success \r\n";
} else {
echo "{$response['message']} \r\n";
}
}
curl_close($curl);
}
返回如下错误和公钥无效的时候看一下自己的referrer是否正确,正确的话等一段时间再试.
{"result":null,"success":false,"errors":[{"code":1005,"message":"Internal server error"}],"messages":[]}
生成WireGuard配置
Nodejs
脚本生成Cloudflare WARP
对应的WireGuard
配置文件
支持免费无限流量版Warp
(注册时不填写aff
). 之后可以通过aff
升级到Warp Plus
使用方法:
在WireGuard
中选择手动添加来生成密钥,生成方法:https://ae01.alicdn.com/kf/H9626347810d24fe38bf14c90ec14578d3.jpg
把Public Key
和Private Key
分别填入脚本中运行
然后把生成的配置文件导入WireGuard
就行, Allow ip
可以自行根据需要修改
const publicKey = "Public Key复制到这里";
const privateKey = "Private Key复制到这里";
const referrer = "Referrer ID复制到这里获取1G流量直接启用Warp+";
if (!publicKey.endsWith("=") || !privateKey.endsWith("=")) {
console.error("请正确填写密钥.");
process.exit(1);
}
const https = require("https");
const zlib = require("zlib");
const fs = require("fs");
const util = require("util");
let warpConf = null;
async function run() {
let userData = {};
if (fs.existsSync("./warp-conf.json")) {
warpConf = JSON.parse(fs.readFileSync("./warp-conf.json").toString());
} else {
warpConf = {
id: null,
publicKey: publicKey, // WireGuard pubic key
token: null, // Cloudflare access token
isWarpPlusEnabled: null
};
}
if (!warpConf.id) {
console.log("未读取到保存信息, 正在注册新帐号中...");
userData = await reg();
console.log("注册成功:");
console.log(util.inspect(userData, false, null, true));
} else {
console.log("正在获取用户信息...");
const res = await getInfo(warpConf.id, warpConf.token);
userData = res.result;
if (
!warpConf.isWarpPlusEnablsed && // If saved record indicate using free version of Cloudflare Warp
userData.account &&
(userData.account.premium_data || data.account.warp_plus)
) {
warpConf.isWarpPlusEnabled = true;
fs.writeFileSync("./warp-conf.json", JSON.stringify(warpConf));
}
console.log("成功获取用户信息:");
if (process.argv[2] && process.argv[2] === "q") {
if (warpConf.isWarpPlusEnabled) {
console.log(
"\x1b[36m%s\x1b[0m",
"WARP PLUS剩余流量:",
userData.account.quota / 1000000000,
"GB"
);
} else {
console.log(
"\x1b[36m%s\x1b[0m",
"您正在使用Cloudflare免费版Warp, 没有流量限制, 您可用自己的ID分享1.1.1.1来获取流量以升级到Warp Plus."
);
}
process.exit(0);
}
console.log(util.inspect(userData, false, null, true));
}
const wireGuardConf = `
[Interface]
PrivateKey = ${privateKey}
# PublicKey = ${publicKey}
Address = ${userData.config.interface.addresses.v4}
# Address = ${userData.config.interface.addresses.v6}
DNS = 1.1.1.1
[Peer]
PublicKey = ${userData.config.peers[0].public_key}
Endpoint = ${userData.config.peers[0].endpoint.v4}
# Endpoint = ${userData.config.peers[0].endpoint.v6}
# Endpoint = ${userData.config.peers[0].endpoint.host}
AllowedIPs = 0.0.0.0/0
`;
console.log("Config: ");
console.log(wireGuardConf);
fs.writeFileSync("./wireguard-cloudflare-warp.conf", wireGuardConf);
console.log(
"Config saved, check wireguard-cloudflare-warp.conf in current dir."
);
if (warpConf.isWarpPlusEnabled) {
console.log(
"\x1b[36m%s\x1b[0m",
"WARP PLUS剩余流量:",
userData.account.quota / 1000000000,
"GB"
);
} else {
console.log(
"\x1b[36m%s\x1b[0m",
"您正在使用Cloudflare免费版Warp, 没有流量限制, 您可用自己的ID分享1.1.1.1来获取流量以升级到Warp Plus."
);
}
}
async function getInfo(id, token) {
return new Promise(async resolve => {
const result = await httpRequest({
hostname: "api.cloudflareclient.com",
port: 443,
path: `/v0i1909221500/reg/${id}`,
method: "GET",
headers: {
Accept: "*/*",
Authorization: `Bearer ${token}`,
Host: "api.cloudflareclient.com",
"Accept-Encoding": "gzip",
"Accept-Language": "Language",
"User-Agent": "1.1.1.1/1909221500.1 CFNetwork/978.0.7 Darwin/18.7.0"
}
});
if (result.success) {
const data = result.payload;
resolve(data);
} else {
console.error("获取用户信息失败.");
process.exit(1);
}
});
}
async function reg() {
return new Promise(async resolve => {
const install_id = genString(11);
const postData = {
key: publicKey,
install_id: install_id,
fcm_token: `${install_id}:APA91b${genString(134)}`,
referrer: /^[0-9a-f]{8}-[0-9a-f]{4}-[0-5][0-9a-f]{3}-[089ab][0-9a-f]{3}-[0-9a-f]{12}$/.test(
referrer
)
? referrer
: "",
warp_enabled: true,
tos: new Date().toISOString().replace("Z", "+08:00"),
type: "Android",
locale: "en_US"
};
const result = await httpRequest(
{
hostname: "api.cloudflareclient.com",
port: 443,
path: "/v0a745/reg",
method: "POST",
headers: {
"Content-Type": "application/json",
Host: "api.cloudflareclient.com",
Connection: "Keep-Alive",
"Accept-Encoding": "gzip",
"User-Agent": "okhttp/3.12.1"
}
},
postData
);
if (result.success) {
const data = result.payload;
warpConf.id = data.id;
warpConf.token = data.token;
if (data.account && (data.account.premium_data || data.account.warp_plus))
warpConf.isWarpPlusEnabled = true;
fs.writeFileSync("./warp-conf.json", JSON.stringify(warpConf));
resolve(data);
} else {
console.error("注册帐号失败.");
process.exit(1);
}
});
}
function httpRequest(options, data = undefined) {
return new Promise(resolve => {
const bodyString = data ? JSON.stringify(data) : data;
const req = https.request(options, res => {
const gzip = zlib.createGunzip();
const buffer = [];
res.pipe(gzip);
gzip
.on("data", function(data) {
buffer.push(data.toString());
})
.on("end", function() {
const res = JSON.parse(buffer.join(""));
resolve({ success: true, payload: res });
})
.on("error", function(e) {
resolve({ success: false, payload: e });
});
});
req.on("error", e => {
resolve({ success: false, payload: e });
});
if (bodyString) req.write(bodyString);
req.end();
});
}
function genString(length) {
// https://gist.github.com/6174/6062387#gistcomment-2651745
return [...Array(length)]
.map(i => (~~(Math.random() * 36)).toString(36))
.join("");
}
run();
保存脚本。
可以尝试用上面提到的在线运行Nodejs,运行然后手动保存配置文件和口令文件。
也可以自己安装Nodejs运行:
nodejs -v //查看 Nodejs 版本
如果没有安装:
apt-get install -y nodejs //debian、ubuntu运行
yum install nodejs -y //centos
运行脚本:
node warp2wireguard.js
warp-conf.json
中保存了口令供之后重新获取配置和查询流量使用
怎样获取剩余流量?
运行
node warp2wireguard.js q
或者直接再次运行脚本。
Python版生成WireGuard一键通脚本
多协程自动注册,数据库持久化,然后你就有了一堆账户,还有神奇的mjj模式,可以干啥自己研究。
支持生成wireguard
配置。
import gevent.monkey
gevent.monkey.patch_all()
import requests
import json
import click
import random
import string
from gevent.subprocess import Popen, PIPE
import peewee
import datetime
import gevent
import sys
def _call(cmd):
child = Popen(cmd, shell=True, stdout=PIPE, stderr=PIPE)
result = child.communicate()[0]
return result
class Wireguard(object):
@staticmethod
def gen_key():
private_key = _call("wg genkey").decode('utf-8').strip()
public_key = _call("echo '{}' | wg pubkey".format(private_key)).decode('utf-8').strip()
return private_key, public_key
@staticmethod
def gen_config(private_key, public_key, address, endpoint):
r = """[Interface]
PrivateKey = {0}
Address = {1}
DNS = 1.1.1.1
[Peer]
PublicKey = {2}
Endpoint = {3}
AllowedIPs = 0.0.0.0/0
""".format(private_key, address, public_key, endpoint)
return r
class WarpCli(object):
def __init__(self):
self._session = requests.session()
@staticmethod
def _gen_string(n):
letters = string.ascii_letters + string.digits
return ''.join(random.choice(letters) for i in range(n))
def reg(self, public_key, referrer=None):
url = 'https://api.cloudflareclient.com/v0a745/reg'
install_id = self._gen_string(11)
data = {"key": public_key,
"install_id": install_id,
"fcm_token": "{}:APA91b{}".format(install_id, self._gen_string(134)),
"warp_enabled": True,
"tos": datetime.datetime.now().isoformat()[:-3] + "-07:00",
"type": "Android",
"locale": "en_US"}
if referrer:
data['referrer'] = referrer
headers = {
'Content-Type': 'application/json; charset=UTF-8',
'Connection': 'Keep-Alive',
'User-Agent': 'okhttp/3.12.1'
}
r = self._session.post(url, json=data, headers=headers, timeout=5)
return r.json()
@staticmethod
def get_info(client_id, token):
url = 'https://api.cloudflareclient.com/v0i1909221500/reg/{}'.format(client_id)
headers = {
"Accept": "*/*",
"Authorization": "Bearer {}".format(token),
"Accept-Encoding": "gzip",
"Accept-Language": "Language",
"User-Agent": "1.1.1.1/1909221500.1 CFNetwork/978.0.7 Darwin/18.7.0"
}
r = requests.get(url, headers=headers)
return r.json()
db = peewee.SqliteDatabase("warp.db")
class WarpAccount(peewee.Model):
id = peewee.PrimaryKeyField()
client_id = peewee.CharField(unique=True)
private_key = peewee.CharField(unique=True)
public_key = peewee.CharField()
token = peewee.CharField()
referrer = peewee.IntegerField()
info = peewee.CharField()
class Meta:
database = db
WarpAccount.create_table()
@click.group()
def cli():
pass
@cli.command()
@click.option('--client_id', required=True)
def account_config(client_id):
r = WarpAccount.select().where(WarpAccount.client_id == client_id)
for i in r:
data = json.loads(i.info)
r = Wireguard.gen_config(i.private_key, data['config']['peers'][0]['public_key'],
data['config']['interface']['addresses']['v4'],
data['config']['peers'][0]['endpoint']['host'])
print(r)
@cli.command()
@click.option('--client_id', required=True)
def account_info(client_id):
r = WarpAccount.select().where(WarpAccount.client_id == client_id)
for i in r:
print(json.dumps(json.loads(i.info), indent=4, sort_keys=True))
@cli.command()
@click.option('--limit', default=10)
def list_account(limit):
all_account = WarpAccount.select().limit(limit)
for i in all_account:
print(i.client_id)
do_count = 0
do_referrer = None
mjj_ids = []
@cli.command()
@click.option('--count', default=1)
@click.option('--referrer', default="")
@click.option('--thread', default=2)
@click.option('--mjj_mode', default=0)
def create_account(count, referrer, thread, mjj_mode):
global do_count
global do_referrer
do_count = count
do_referrer = referrer
def loop_reg(idx):
w = WarpCli()
while True:
global do_count
global do_referrer
do_count -= 1
if do_count == -1:
break
try:
if mjj_mode:
import random
referrer = random.choice(mjj_ids)
else:
referrer = do_referrer
private_key, public_key = Wireguard.gen_key()
r = w.reg(public_key, referrer)
if mjj_mode:
q = WarpAccount.update(referrer=WarpAccount.referrer + 1).where(WarpAccount.client_id == referrer)
q.execute()
print('tid: {} add referrer for {}'.format(idx, referrer))
else:
WarpAccount.create(client_id=r['id'], private_key=private_key, public_key=public_key,
token=r['token'],
info=json.dumps(r), referrer=0)
print('tid: {} reg success {}'.format(idx, r['id']))
except KeyboardInterrupt:
sys.exit(0)
except:
import traceback
traceback.print_exc()
gevent.sleep(1)
if mjj_mode:
r = WarpAccount.select()
if len(r) == 0:
print('please create account try again')
for i in r:
mjj_ids.append(i.client_id)
threads = [gevent.spawn(loop_reg, idx) for idx in range(thread)]
gevent.joinall(threads)
if __name__ == '__main__':
cli()
使用方法:
保存为warp.py
然后安装所需环境:
add-apt-repository ppa:wireguard/wireguard
apt-get update
apt-get install wireguard
apt install python3-dev python3-pip
pip3 install gevent requests click peewee
# use referrer add 100 account
python3 warp.py create-account --count 100 --thread 2 --referrer xxxxxxxxxxxxxxxxx
python3 warp.py list-account
python3 warp.py account-config --client_id xxxxxxxxxxxxxxxxx
thread太高会被ban!
iOS捷径脚本快速查询Warp+剩余流量
大佬分享的又一力作,穷逼没用过iOS,纯搬运:
只在iOS 12.4测试了
如果已经在更新前创建了第二个及以上配置的, 需要先删除全部配置
token是注册时返回的口令, 跟id长的一样
脚本地址 V2:
https://www.icloud.com/shortcuts/23f5481f71b3409197bc2ef8790258da
示例图片:
https://ae01.alicdn.com/kf/H1f97d631f949465682ce928103464c0an.png
来源
来源github:https://github.com/yyuueexxiinngg/some-scripts/tree/master/cloudflare
Nodejs版脚本:https://www.hostloc.com/thread-590354-1-1.html
Python版脚本:https://www.hostloc.com/forum.php?mod=redirect&goto=findpost&ptid=590354&pid=7171772
php版脚本:https://www.hostloc.com/thread-590703-1-1.html
WireGuard 配置:https://www.hostloc.com/thread-590733-1-1.html
Python版生成WireGuard:https://www.hostloc.com/thread-590825-1-1.html
iOS捷径脚本快速查询Warp+剩余流量:https://www.hostloc.com/thread-591055-1-1.html
本地环境使用时候会产生报错,可以把python中的def t_run() -> None: 修改为 def t_run() : print(f"error occured !! {e}"修改为 print("error occured !! ") 谢谢博主( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃