近期,我的Cloudflare账号因为做Onedrive的反向代理加速下载而被暂停,被暂停的理由是使用cf进行钓鱼网络欺诈。我花了几天,在不同的论坛上询问了许多的网友,才终于明白了我的账户到底发生了什么。
开端
自从2022年年初以来,我便搭建了Onemanager的网盘,并挂上了我的Micrsoft E5号,方便我在学校的时候能够通过学校电脑访问到我的文件。
但是众所周知,Onedrive在国内的下载速度一直非常一般。为了提速,我在网上找来了通用的Cloudflare Worker代码,为我的Sharepoint(Onedrive)设置了反向代理,通过cf来加速在中国大陆的下载速度。
2022年11月15日,我用来做反向代理的Cloudflare Worker收到了1.3k的请求,我本来以为这并不会发生什么,毕竟他的免费用量有100k。
但是随即,我便收到了一封来自Netcraft的举报邮件,内容大意是说我的网站涉及钓鱼欺诈,Cloudflare也随即将我的账号暂停(禁止添加新域名,现有域名不影响)。
那时因为是在工作日,而我被封控在学校,用手机的时间较少,所以并没有特别在意。
争论
到了12月,我的联考结束了,我也有时间去处理这件事情。我向客服申诉了,我用Cloudflare是用来加速中国大陆的下载速度,主观上并没有欺骗任何人,拒绝承认我违反了他们的服务条款(事实上服务条款也没有禁止用作反代,只是禁止用于欺诈)。然而客服还是认定我涉及了网络欺诈钓鱼,违反了他们的条款,拒绝给我解封。
对于一个没有付费的用户,我也不奢求他们会给我什么,也不指望他们能用领着工资的客服为我服务,只能自认倒霉。
总结
在本次事件发生之后,我询问了各种论坛上的网友。虽然遇到过这样情况的人不多,但是还是有几位热心网友回复了我的疑问。
首先就是欺诈的判定理由,根据网友们的分析和推测,认为是因为我的网站和原本的官网长得非常的相似导致被判定为仿冒官网。然而对于任何一个反代站点来说,所有的内容都是在源网站上获取,并不会改动任何的内容。因此和源网站相似,这一点是不可避免的。
那是否意味着,任何的反向代理都不能用Cloudflare托管了呢?倒也未必。因为举报我欺诈的公司并不位于中国,而我的加速的目标仅仅只是中国的下载速度。因此我们可以通过一个非常简单的方法:限制地区访问
来解决这个问题。我们可以进入到我们自己域名的管理页面,找到 安全性
选项,点击 WAF
,便可以限制特定地区或者IP等的访问,不符合的地区可以全部封禁。这样即使我的使用量比较多,但因为他们的公司不在中国(应该总部在英国),他们也发现不了我的证据,从取证途径上避免了被举报。
再者,如果这个反代站点只是我们自己个人使用,我们可以添加Basic Auth来阻止其他人访问,代码如下:
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 176 177 178 179 180 181 182 183 184 185
| const upstream = 'google.com'
const upstream_mobile = 'm.google.com'
const openAuth = false const username = 'username' const password = 'password'
const blocked_region = ['RU']
const blocked_ip_address = ['0.0.0.0', '127.0.0.1']
const replace_dict = { '$upstream': '$custom_domain', '//google.com': '' } function unauthorized() { return new Response('Unauthorized', { headers: { 'WWW-Authenticate': 'Basic realm="goindex"', 'Access-Control-Allow-Origin': '*' }, status: 401 }); } function parseBasicAuth(auth) { try { return atob(auth.split(' ').pop()).split(':'); } catch (e) { return []; } } function doBasicAuth(request) { const auth = request.headers.get('Authorization'); if (!auth || !/^Basic [A-Za-z0-9._~+/-]+=*$/i.test(auth)) { return false; } const [user, pass] = parseBasicAuth(auth); return user === username && pass === password; } async function fetchAndApply(request) { if (request.method === 'OPTIONS') return new Response('', { status: 200, headers: { 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Headers': '*', 'Access-Control-Allow-Methods': 'GET, POST, PUT, HEAD, OPTIONS' } }); if (openAuth && !doBasicAuth(request)) { return unauthorized(); } const region = request.headers.get('cf-ipcountry').toUpperCase(); const ip_address = request.headers.get('cf-connecting-ip'); const user_agent = request.headers.get('user-agent'); let response = null; let url = new URL(request.url); let url_host = url.host; if (url.protocol == 'http:') { url.protocol = 'https:' response = Response.redirect(url.href); return response; } if (await device_status(user_agent)) { upstream_domain = upstream } else { upstream_domain = upstream_mobile } url.host = upstream_domain; if (blocked_region.includes(region)) { response = new Response('Access denied: WorkersProxy is not available in your region yet.', { status: 403 }); } else if(blocked_ip_address.includes(ip_address)){ response = new Response('Access denied: Your IP address is blocked by WorkersProxy.', { status: 403 }); } else{ let method = request.method; let request_headers = request.headers; let new_request_headers = new Headers(request_headers); new_request_headers.set('Host', upstream_domain); new_request_headers.set('Referer', url.href); let original_response = await fetch(url.href, { method: method, headers: new_request_headers }) let original_response_clone = original_response.clone(); let original_text = null; let response_headers = original_response.headers; let new_response_headers = new Headers(response_headers); let status = original_response.status; new_response_headers.set('access-control-allow-origin', '*'); new_response_headers.set('access-control-allow-credentials', true); new_response_headers.delete('content-security-policy'); new_response_headers.delete('content-security-policy-report-only'); new_response_headers.delete('clear-site-data'); const content_type = new_response_headers.get('content-type'); if (content_type.includes('text/html') && content_type.includes('UTF-8')) { original_text = await replace_response_text(original_response_clone, upstream_domain, url_host); } else { original_text = original_response_clone.body } response = new Response(original_text, { status, headers: new_response_headers }) } return response; } addEventListener('fetch', event => { event.respondWith(fetchAndApply(event.request).catch(err => { console.error(err); new Response(JSON.stringify(err.stack), { status: 500, headers: { 'Content-Type': 'application/json' } }); })); }) async function replace_response_text(response, upstream_domain, host_name) { let text = await response.text() var i, j; for (i in replace_dict) { j = replace_dict[i] if (i == '$upstream') { i = upstream_domain } else if (i == '$custom_domain') { i = host_name } if (j == '$upstream') { j = upstream_domain } else if (j == '$custom_domain') { j = host_name } let re = new RegExp(i, 'g') text = text.replace(re, j); } return text; } async function device_status (user_agent_info) { var agents = ["Android", "iPhone", "SymbianOS", "Windows Phone", "iPad", "iPod"]; var flag = true; for (var v = 0; v < agents.length; v++) { if (user_agent_info.indexOf(agents[v]) > 0) { flag = false; break; } } return flag; }
|
希望我的经历能给大家提个醒,意识到反向代理并不是能随便使用,希望大家不要再因此而造成cf账户使用限制。
更多
有群友报告,一个WordPress生成的Procces.zip也于近期遭到了Netcraft的举报,并且此用户在WAF设置了海外IP需要检验浏览器确保是真人访问的选项,目前被举报原因尚不明确。