解决Cloudflare CDN对我的网站的访问限制问题

我的这个博客网站使用Cloudflare CDN。

今天上午,Cloudflare给我发了一封电子邮件:
您好, 经我们确定,您有一个或多个 Web 资产似乎在未使用相应付费服务的情况下提供视频或数量不相称的大型文件,如 R2、Stream 或 Cloudflare Images。 针对这一情况,我们暂时停止了对部分出现问题的流量的服务。在此问题解决之前,您的有些访问者可能会感觉到性能上的变化。如果我们认为此问题仍未解决,我们可能会采取进一步措施,包括继续更改性能或在网络中停用有问题的区域。 受影响的资产有: - zuotijia.me
意思是,Cloudflare检测到我的这个博客网站在“免费计划”下提供了大量视频或大文件下载,这违反了 Cloudflare 的使用规则,因此他们已经开始限制部分流量。

Cloudflare认为,我在利用免费 CDN 当做文件分发网络 / 下载站,这是 Cloudflare 免费计划不允许的。然后他们限制我这个网站的某些文件的 CDN 加速,导致我这个网站访问起来很卡。

使用curl命令获取我这个网站的响应头信息:

$ curl -I https://www.zuotijia.me
HTTP/2 302 
date: Sat, 07 Mar 2026 06:44:20 GMT
location: https://www.cloudflare-terms-of-service-abuse.com/stream.ts
access-control-allow-origin: *
cache-control: private, max-age=0, no-store, no-cache, must-revalidate, post-check=0, pre-check=0
expires: Thu, 01 Jan 1970 00:00:01 GMT
server: cloudflare
cf-ray: 9d87a18c0e060be4-AMS

可以看到:

HTTP/2 302
location: https://www.cloudflare-terms-of-service-abuse.com/stream.ts
server: cloudflare

这表示 Cloudflare 已经对我的域名启用了 “Terms of Service Abuse” 拦截。所有访问都会被 302 重定向到他们的滥用提示页面。

Cloudflare 的风控系统已经把我的站点标记为 CDN滥用状态,现在处于 强制限制模式。

那么如何解除这个强制限制模式?

首先要确定是哪些网站文件触发了这个Cloudflare的风控。前天我用一张120kb大小的图片设置为网站头像,应该是它引起的。然后我看了一下Cloudflare管理面板->分析和日志->Web Analytics页面,发现网站的首屏图片
#wp-custom-header>img

www.zuotijia.me/wp-content/themes/twentyseventeen/assets/images/header.jpg
它的LCP达到10,660 毫秒!那么它就是引起这一问题的罪魁祸首。

以前一直使用这个默认主题,为啥今天就触发Cloudflare的风控了呢?因为我这个网站的流量大起来了。

既然确定了引发问题的原因,那么解决步骤如下。

进入WordPress的管理后台->外观->自定义,在主题编辑页面,点击页眉媒体->隐藏页眉图片,再点击“发布”按钮保存更改。很多现代站点都不再用这种巨图。

再进入WordPress的管理后台->设置->常规页面,移除站点图标,然后点击最下方的“保存更改”按钮保存更改。

在Cloudflare的DNS配置页面中把网站的域名的CDN配置从Proxied(橙云)改为DNS only(灰云),绕过 Cloudflare 拦截,临时恢复网站的正常访问。

给Cloudflare回复以下邮件:

Hello,

We have identified the issue that triggered the abuse detection.

The large image resource causing excessive CDN traffic has been optimized and caching rules have been configured. The website is no longer serving large files through Cloudflare CDN.

Could you please review the restriction on the domain zuotijia.me and remove the abuse limitation?

Thank you.

意思是我已经移除了触发CDN限制的网站图片,请解除对我的域名的限制。

一般等个6到24小时,Cloudflare就能解除对我的域名的限制。

过段时间我给网站换个美观一点的主题。

使用Cloudflare CDN免费功能优化网站访问速度

如果我们的网站使用Cloudflare CDN,那么Cloudflare免费提供了几个优化网站访问速度的功能,可以利用起来。

优化一、开启Smart Shield

在Cloudflare管理面板的“速度”->”Smart Shield”页面,启用Smart Shield功能,保护源服务器、提高内容可用性并缩短网络延迟时间。

优化二、免费加速网站的访问

在Cloudflare管理面板的“速度”->“设置”页面,应用 Cloudflare 的标准建议设置,优化我们的站点。

优化三、创建缓存规则Cache Rules

对于免费版的Cloudflare,我们总共可以创建10个Cache Rules。

缓存规则1:缓存所有内容(Cache Everything)

创建一条缓存规则,把“绕过缓存”改成 “缓存所有内容(Cache Everything)”。

缓存规则2:对于WordPress网站,新增一条规则不缓存/wp-admin

具体做法如下图所示:

缓存规则3:对于WordPress网站,再新增一条规则不缓存/wp-login

做法同上。

如果缓存/wp-admin/wp-login,WordPress网站后台功能可能会有问题,例如不能实时看到对媒体文件的更改。

霍夫施塔特定律(Hofstadter’s Law):即使你考虑到了霍夫施塔特定律,项目的实际完成时间总是比预期的要长

霍夫施塔特定律(Hofstadter’s Law)由 Douglas Hofstadter 提出,并以他的名字命名。这个定律指出:即使你考虑到了霍夫施塔特定律,项目的实际完成时间总是比预期的要长。

这个“定律”是关于准确预估完成复杂任务所需时间的难度。这个定律具有递归性,反映了预估复杂项目的难度,尽管你可能已经做出了最大的努力,而且也知道任务的复杂性。

这就是为什么在制定项目工期时,必须要留有一个缓冲区。

另请参见侯世达定律 (Hofstadter’s Law)

参考

https://cloud.tencent.com/developer/article/1421055?from=article.detail.1525574

Linux系统命令行终端使用V2Ray翻墙(代理)的方法

我使用VirtualBox安装了Ubuntu 24虚拟机,执行一些需要访问外网的命令时,经常由于网络问题导致执行失败。那么Ubuntu命令行终端是否可以走V2Ray代理呢?答案是可以的,以下是具体步骤。

V2Ray服务器

外网VPS怎么购买,V2Ray服务器端怎么搭建,我暂时不介绍,网上有很多免费的V2Ray节点,你自己去找找。

先使用Windows的v2rayN、Android的v2rayNG App或者苹果系统的小火箭,测试一下你的V2Ray节点是否能连接成功,是否能访问google.com网站。

本教程的V2Ray服务器端使用v2ray+ws+tls+nginx搭建,使用VMess协议和V2Ray客户端通信。

安装V2Ray客户端

先更新一下系统依赖包的最新信息:

sudo apt update

安装要用到的一些命令:

sudo apt install curl unzip

下载V2Ray安装脚本,如果由于网络问题下载不下来的话,也可以去github上手动下载:

curl -O https://raw.githubusercontent.com/v2fly/fhs-install-v2ray/master/install-release.sh

运行这个安装脚本安装V2Ray:

sudo bash install-release.sh

然后作为客户端的V2Ray就安装成功了。使用systemctl工具管理v2ray服务:

systemctl enable v2ray      #设置开机自启动
systemctl status v2ray      #查看服务状态
systemctl start v2ray       #开启服务
systemctl stop v2ray        #停止服务
systemctl restart v2ray     #重启服务

注意,V2Ray的客户端版本和服务端版本最好一样,至少大版本必须一样,否则使用的网络协议的版本可能不一致,造成客户端和服务端沟通失败。

配置V2Ray客户端

Ubuntu系统使用安装脚本安装的V2Ray,配置文件位置在/usr/local/etc/v2ray/config.json。

可以手动编辑这个配置文件,但是更推荐的方法是从v2rayN、v2rayNG或者小火箭导出正常连通的节点的V2Ray客户端配置。

以v2rayN为例,在正常连通的节点上鼠标右键,然后选择导出所选服务器为客户端配置,就能够导出我们需要的V2Ray客户端配置文件config.json了。

将导出的V2Ray客户端配置文件config.json的内容写进Ubuntu系统的/usr/local/etc/v2ray/config.json文件里。

注意,客户端和服务器配置中的alterId的值都必须是0,这是V2Ray 5版本推荐的设置,否则客户端连不上服务器。

测试一下配置文件语法是否有错:

/usr/local/bin/v2ray test -config=/usr/local/etc/v2ray/config.json

如果配置文件没有语法错误,就重启v2ray服务以使配置生效:

systemctl restart v2ray

在命令行终端使用V2Ray代理网络访问

可以使用proxychains4工具代理大多数命令的网络访问走V2Ray,用法是:

proxychains4 <你要执行的命令>

我们先下载安装proxychains4工具:

sudo apt update
sudo apt install proxychains4 -y

注意,不要安装Ubuntu 24.04 软件源中默认的 proxychains,因为proxychains是旧版 3.1,使用它执行命令会报以下错误:

ERROR: ld.so: object 'libproxychains.so.3' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.

编辑proxychains4的配置文件/etc/proxychains4.conf,启用以下配置项:

dynamic_chain
proxy_dns
quiet_mode

在ProxyList配置节添加如下配置:

[ProxyList]
socks5 127.0.0.1 10808

注意,proxychains-ng 只支持 socks4、socks5、http 三种协议类型,不存在 https 类型。

这样proxychains4就配置完成了,我们访问以下Google看看:

$ proxychains4 curl -I https://www.google.com
[proxychains] config file found: /etc/proxychains4.conf
[proxychains] preloading /usr/lib/x86_64-linux-gnu/libproxychains.so.4
[proxychains] DLL init: proxychains-ng 4.17
HTTP/2 200
…

在输出中看到HTTP/2 200,就表示我们成功访问到了Google。

让当前命令行终端的网络操作都走V2Ray代理

既然我们已经配置好 proxychains4 并且能正常访问 Google,最简单、最可靠的方式就是继续用它,直接在当前终端的命令加上proxychains4前缀使用,适用于任何命令。例如:

proxychains4 curl https://ipinfo.io/ip
proxychains4 wget -O- https://ipinfo.io/ip
proxychains4 git clone https://github.com/xxx/yyy.git
proxychains4 apt update   # 注意,apt 部分命令可能不完全兼容,慎用

每次在执行命令时加都上proxychains4前缀,太麻烦了,如何在执行命令时不用加上proxychains4前缀就能走代理?

方案一、使用proxychains4前缀起一个新的shell

如果想让当前 shell 的所有后续命令都自动走代理(不推荐频繁用),可以使用proxychains4前缀起一个新的 shell:

proxychains4 bash

现在在这个子 shell 里,任何命令都走V2Ray代理,退出子 shell 用 exit 即可回到原 shell,原 shell 不受代理影响。

优点:

  • 支持几乎所有 TCP 程序(包括不支持代理的环境变量的程序,如 ping、nslookup、部分 git 操作等)
  • UDP 支持好(V2Ray socks5 开启了 udp:true)

方案二、设置环境变量(适用于支持http_proxy/https_proxy 的程序)

很多命令行工具(curl、wget、git、python requests、apt 等)会读取这些变量:

# 在当前终端执行(只影响当前会话)
export ALL_PROXY="socks5://127.0.0.1:10808"
export all_proxy="socks5://127.0.0.1:10808"   # 小写版,有些程序认这个

# 或者分开设置(更常见)
export http_proxy="socks5://127.0.0.1:10808"
export https_proxy="socks5://127.0.0.1:10808"
export ftp_proxy="socks5://127.0.0.1:10808"    # 可选

# 排除本地地址(防止循环)
export no_proxy="localhost,127.0.0.1,::1"

测试一下:

curl -I https://www.google.com

退出当前终端后这些环境变量会失效(只影响当前会话),要想每次登陆终端都生效,可以把这些环境变量写入~/.bashrc文件里。

常见问题及解决方法

若遇到问题,先查看v2ray服务(客户端)的日志:

journalctl -u v2ray -f -o cat

当proxychains4执行命令时,以上命令会输出v2ray服务(客户端)的日志,可以在配置文件中把日志级别改为debug,以查看更加详细的日志数据:

"log": {
    "access": "",
    "error": "",
    "loglevel": "debug"
  },

查看代理服务器的公网IP地址:

curl --socks5 127.0.0.1:10808 --connect-timeout 20 https://ipinfo.io/ip

或者用proxychains4:

proxychains4 curl https://ipinfo.io/ip

proxychains4对PHP(例如wp命令)程序支持得不好的解决方法

proxychains4 对原生 C 程序(如 curl、wget、ping)支持很好,但对 PHP 脚本(如 wp-cli)支持不稳定,经常出现超时、连接重置或下载中断。

为什么 proxychains4 + wp-cli 经常出问题?

wp-cli 内部大量使用 PHP 的 cURL 扩展来下载包、更新、安装插件/主题等,而 proxychains-ng(proxychains4)通过 LD_PRELOAD 方式劫持系统级的 socket 调用,主要针对 C/C++ 程序或直接使用系统 socket 的程序。

PHP 的 cURL 扩展有几种常见实现方式:

  • 使用系统 libcurl(大多数情况)
  • 但在很多 Linux 发行版(包括 Ubuntu)的 PHP 包里,cURL 是通过 PHP 自己的网络栈 或 线程模型 来处理的

这会导致下面几种常见冲突:

  • LD_PRELOAD 被 PHP 内部忽略或不完全生效(PHP 用了自己的 resolver 或多线程 cURL handle)。
  • DNS 解析被 proxychains 接管了,但后续的 TCP 连接超时(因为 PHP cURL 的超时、重试机制和 proxychains 的链路不完全兼容)。
  • wp-cli 下载 Git 仓库时会多次发起请求(clone + fetch),proxychains 的 dynamic_chain 在某些情况下会造成连接不稳定或被上游服务器限速/封禁。
  • GitHub 对代理 IP(尤其是 Cloudflare 出口)有时有严格的 rate limit 或连接超时检测。

推荐的解决/绕过方式(按优先级排序)

一、直接用环境变量代替 proxychains4(最推荐,成功率最高)

wp-cli 支持标准的代理环境变量,而且 PHP cURL 能很好识别它们。在当前终端执行:

export ALL_PROXY="socks5://127.0.0.1:10808"
export all_proxy="socks5://127.0.0.1:10808"

# 或者分开写(有时更稳)
export http_proxy="socks5://127.0.0.1:10808"
export https_proxy="socks5://127.0.0.1:10808"

# 建议加上这个,避免本地循环
export no_proxy="localhost,127.0.0.1,::1"

# 然后运行 wp 命令试试
wp package install schlessera/wp-cli-psysh

用完后可以unset这些环境变量:

unset ALL_PROXY all_proxy http_proxy https_proxy no_proxy

这个方法在大多数情况下都能让 wp-cli 正常走代理,且不会出现超时。

二、如果环境变量无效,强制指定代理给 wp-cli

wp-cli 本身支持 –http-proxy 参数(但只支持 http/https 代理,不直接支持 socks5)。 所以可以先把 socks5 转成 http 代理(用 v2ray 自带的 http 入站 10809):

wp --http-proxy=http://127.0.0.1:10809 package install schlessera/wp-cli-psysh

如果你没开 http 入站,就在 v2ray config.json 的 inbounds 里确认有 10809 的 http。

proxychains4无法用于Ping命令

注意,几乎所有基于 ICMP 协议的工具(如 ping、traceroute)都无法通过 SOCKS5 或 HTTP 代理正常工作,是协议本身的限制。

proxychains4(proxychains-ng)只能劫持和转发 TCP 和 UDP 流量。ICMP 不属于 TCP/UDP 范畴,所以 proxychains4 无法干预 ping 的数据包。这些包会直接从你的本地网络发出,走的是你的真实公网 IP,而不是代理服务器。

WordPress网页顶部出现警告信息“使用参数调用函数WP_Dependencies->add_data()已弃用”的解决方法

我升级WordPress的版本到6.9后,访问网站的文章,发现网页顶部有如下警告信息:

PHP Deprecated:  自 6.9.0 版本起,使用参数调用函数 WP_Dependencies-&gt;add_data() <strong>已弃用</strong>!所有支持的浏览器都会忽略 IE 条件注释。 in /var/www/blog/wp-includes/functions.php on line 6131

解决这个警告的方法是,升级当前使用的WordPress主题到最新版。

我升级当前使用的WordPress主题到最新版后,整个网站的访问速度似乎也提升了不少。

WordPress Site Clone: The One Thing That Will Save You From Infinite Redirect Hell

You just copied a full WordPress site — files + MySQL dump — fired it up on a shiny new domain, and… nothing works.

  • Browser spins forever (infinite redirect loop)
  • CSS/JS/images all 404
  • wp-admin is a white screen of death

Classic symptom: the database is still shouting the old domain everywhere.

Here’s exactly what you need to do, in order of preference (fastest → most manual).

Method 1: WP-CLI (the nuclear option, do this first)

cd /var/www/your-new-site

# Hit both http and https variants because WP loves to store both
wp search-replace 'https://old-domain.com' 'https://new-domain.com' --all-tables --precise
wp search-replace 'http://old-domain.com'  'https://new-domain.com' --all-tables --precise

# Clean everything up
wp cache flush
wp rewrite flush --hard

Done in 10 seconds. Most reliable.

Method 2: Straight SQL (when WP-CLI isn’t available)

UPDATE wp_options 
SET option_value = 'https://new-domain.com'
WHERE option_name IN ('home', 'siteurl');

After running that:

  • Hard-refresh your browser (Ctrl+Shift+R)
  • Restart Nginx/Apache
  • If you use Redis/Object Cache → flush it

Method 3: wp-config.php override (quick & dirty, works even if DB is broken)

Drop these two lines at the very top of wp-config.php (right after <?php):

define('WP_HOME',    'https://new-domain.com');
define('WP_SITEURL', 'https://new-domain.com');

WordPress will automatically update the database on first load. Super handy for emergency rescues.

Pro tips from someone who’s cloned way too many sites:

  • Always use https in the new domain unless you have a very good reason not to.
  • Search-replace both http and https versions — WP stores them separately.
  • If you’re on a staging → production move, also run the search-replace on any serialized data (WP-CLI’s –precise flag handles most of it).
  • After everything works, remove the two define() lines from wp-config.php so future changes go through the normal Settings → General screen.

Do this once and your cloned site will behave like a real, healthy WordPress install instead of a haunted redirect zombie.

WordPress克隆站点必须要做的事情

克隆站点是指从一个现有的WordPress网站复制源代码和MySQL数据库中的数据,然后搭建成另外一个网站,使用不同的域名。

克隆站点因为是从另一个站点完整复制的,数据库里还存着旧域名,使用浏览器访问它大概率会出现以下问题:

  • 无限重定向
  • 资源加载 404
  • 后台打不开

因此需要把旧域名替换为新域名,有以下几种方式。

方式1,使用WP-CLI

cd /var/www/clone-site # 进入克隆站点的web根目录
wp search-replace 'https://旧域名.com' 'http://新域名.com' --all-tables --precise
wp search-replace 'http://旧域名.com' 'http://新域名.com' --all-tables --precise
wp cache flush
wp rewrite flush --hard

方式2,使用SQL更新数据库

UPDATE wp_options SET option_value = 'http://新域名.com' 
WHERE option_name IN ('home', 'siteurl');

替换完后,清浏览器缓存 + 重启 Nginx + 清 WP 对象缓存(如果用了 Redis/Object Cache)。

方式3,在wp-config中更改配置

把以下两行代码放在 wp-config.php 文件里的顶部:

define('WP_HOME', 'http://新域名.com');
define('WP_SITEURL', 'http://新域名.com');

这会更新数据库。

侯世达定律 (Hofstadter’s Law):即使考虑到侯世达定律,开发周期也总是比你预期的要长

侯世达定律 (Hofstadter’s Law):即使考虑到侯世达定律,开发周期也总是比你预期的要长。——侯世达 (Douglas Hofstadter)

在估计需要多长时间开发时,你可能会听到此定律。软件开发似乎有这样一条定理,即我们往往不能准确地估计需要多长时间才能完成。

语出《哥德尔、艾舍尔、巴赫:集异璧之大成》

侯世达定律(英语:Hofstadter’s law)是一句自指的格言,由侯世达在《哥德尔、埃舍尔、巴赫》一书中提出:做事所花费的时间总是比你预期的要长,即使你的预期中考虑了侯世达定律。

侯世达定律指做复杂任务需要花费的时间总是很难预计的。程序员经常会引用这一定律,特别是在进行有关提高效率的讨论时(如《人月神话》和极限编程)。其自指的特征反映了即便意识到任务的复杂性,预计花费的时间仍是困难的。

这一定律最初是描述早年国际象棋人机对弈的现象。侯世达写道:“计算机下国际象棋的早期阶段,有人曾估计再要十年的时间计算机(或程序)就能得到世界冠军。可是,十年过去之后,计算机要成为世界冠军似乎还要再过十年……”他将这一现象看作是递归化的侯世达定律的一个例证。

参考

https://github.com/nusr/hacker-laws-zh

https://en.wikipedia.org/wiki/Hofstadter%27s_law

https://zh.wikipedia.org/wiki/%E4%BE%AF%E4%B8%96%E8%BE%BE%E5%AE%9A%E5%BE%8B

auth.json文件的作用

auth.json 是 Composer(PHP 的依赖管理工具)在某些情况下生成的私有包认证配置文件。

使用场景
当你的项目需要从私有 Composer 仓库(如公司内部的 Packagist、私有 Git 仓库、Satis、Toran Proxy、Artifactory 等)安装包时,Composer 会要求你提供认证信息(用户名/密码、token、SSH 密钥等)。

为了避免每次 composer update/install 都手动输入凭证,Composer 会把这些认证信息保存到项目根目录下的 auth.json 文件中。

内容示例

{
    "http-basic": {
        "packages.example.com": {
            "username": "my-company-user",
            "password": "super-secret-token-123456"
        }
    },
    "github-oauth": {
        "github.com": "ghp_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
    },
    "gitlab-token": {
        "gitlab.example.com": "glpat-xxxxxxxxxxxxxxxxxxxx"
    }
}

存放位置
项目根目录(和 composer.json 同级)。有时也会出现在用户全局目录:~/.composer/auth.json(旧版 Composer)或 ~/.config/composer/auth.json(新版)

是否需要提交到 Git?
绝对不要提交!必须忽略。因为里面包含明文凭证(用户名、密码、token),提交到 Git 仓库会导致严重的安全泄露(任何人拉代码都能看到你的私有仓库凭证)。并且不同开发者的凭证不同,提交后会互相冲突

如何正确管理 auth.json?
1 个人开发机:让 Composer 自动生成(运行 composer config –auth … 时会创建)
2 CI/CD 环境(GitHub Actions、GitLab CI、Jenkins 等):不要提交文件,而是通过环境变量注入凭证,例如:

composer config --auth http-basic.packages.example.com.username "${COMPOSER_USERNAME}"
composer config --auth http-basic.packages.example.com.password "${COMPOSER_PASSWORD}"


或使用 COMPOSER_AUTH 环境变量(JSON 字符串):

export COMPOSER_AUTH='{"http-basic":{"packages.example.com":{"username":"xxx","password":"yyy"}}}'

3 团队协作:把认证信息写到 .env 或 CI 变量中,项目中只保留 auth.json.example(空模板)。