2024年7月

前几天的博文“设置了CF全站缓存” 中,我说有空的时候来设做一下这个功能。现在补上,咱不是只会放空炮的人。 :)
用处我大概说一下。 这样修改后,可以设置一个非常大的全站缓存时间,比如几天甚至更长。因为典型的Typecho仅在新增博文和新增评论时页面发生变更,没页面变更是不需要刷缓存的。新增博文可以博主手动刷新缓存,但新增评论就需要自动进行了。如果不这样,人家读者来发一篇评论要几天后才显示出来,胸闷坏啊。

修改 var/Widget/Base/Comments.php
在 public function insert(array $rows): int 这行前增加函数:

//调用CLOUDFLARE API刷新全站缓存,即 缓存->配置->清除所有内容 功能。 如果你不想这么暴力可以改一下参数,让gpt改就可以了,我就不写了。事实上,这段代码就是gpt写的。
private function purgeCloudflareCache($email, $apiKey, $zoneId, $purgeEverything = true, $files = []) {
    $apiUrl = 'https://api.cloudflare.com/client/v4/zones/' . $zoneId . '/purge_cache';

    // 构建请求负载
    if ($purgeEverything) {
        $payload = json_encode(['purge_everything' => true]);
    } else {
        $payload = json_encode(['files' => $files]);
    }

    // 初始化 cURL
    $ch = curl_init($apiUrl);

    // 设置 cURL 选项
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
    curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
    curl_setopt($ch, CURLOPT_HTTPHEADER, [
        'Content-Type: application/json',
        'X-Auth-Email: ' . $email,
        'X-Auth-Key: ' . $apiKey,
    ]);

    // 执行请求并获取响应
    $response = curl_exec($ch);
    $error = curl_error($ch);
    curl_close($ch);

    // 检查请求是否成功
    if ($error) {     //刷新有问题时把die注释取消看看怎么回事
        //die('cURL Error: ' . $error);
    } else {
        $responseData = json_decode($response, true);
        if ($responseData['success']) {
            //die( 'Cache purge successful!');
        } else {
            //die( 'Cache purge failed: ' . $responseData['errors'][0]['message']);
        }
    }
}

然后,在 public function insert(array $rows): int 函数的末尾行,即 return $insertId 前面,加入一行:
$this->purgeCloudflareCache("你的cf登录email", "Global API Key", "区域ID");
这两个参数,是在这个域名的 “概述”页面,右下角,“区域ID”,和 “获取您的API令牌”->Global API Key->查看 中获得。

具体的事情就不重复了,v2ex和52pojie上都有详细的分析。
看到这个我吓了一跳,赶紧自查,还好,我们就只用过bootcdn,但前段时间已经改成了自己的cdn。
解决办法,就是需要将:
bootcss.com
bootcdn.net
staticfile.net
staticfile.org
全部替换掉,或者用自己的cdn,或者用第三方的,比如 s4.zstatic.net/ajax/libs。

*科普一条linux常用命令:
grep -r 'bootcss.com' 查找当前目录及子目录下,所有包含 bootcss.com 的文件。

这个blog每天就百十个IP,还大多数是机器人/搜索引擎等,当然是不需要这么玩的。 这个只是拿来示范一下防CC。
有的时候,需要把自己的网站地址放出去,但一放出去就很容易遭到无聊的人的CC攻击。当然,可以把CF的安全级别拉高,然而这样对用户体验会很差,也许本就是去想弄流量的,结果,把已经有的用户都一起赶跑了。
所以,缓存的用处就来了。比如全站缓存一下不回源,再怎么CC也是CC去CF那里,关咱啥事呢。能把CF都放倒,那咱们也没办法了。
第一步,设置需要缓存的URL。
既然是全站,那就只是设一下例外了。
对这个blog(typecho)来说,后台管理 /admin 评论/comment 登出/logout 搜索 .../search/...需要是动态的,不能缓存。
s2.jpg
非常重要! 在Cache key设置中,需要激活 Ignore query string,就是忽略查询字符串。
缓存过期时间TTL根据自己情况设一下,我设的2个小时。其实对blog来说,设置24小时都不是问题,毕竟更新不频繁。
第二步,上面放的几个不缓存的例外口子需要加固一下,就是设置人机验证。这个影响体验,然而大多数人是不会出现的,无所谓。
s1.jpg
完工。
这样一弄,人家再怎么DD怎么CC都无所谓了,对吧? 而且对用户体验也没太大影响。如果稍微对Typecho二开一下,就是有新评论后清除一下缓存是最好,毕竟现在的评论也一起被缓存2个小时了。哪天我无聊的时候来给typecho打个补丁。

**说明一下,CF的rate limit是没太大用处的,因为它只能限制同IP来源。然而,现在的CC攻击都是动用大量的IP,比如1万台肉鸡,每分钟10次请求,这个rate limit通常都会允许的,然而,实际情况是,每分钟10万次请求,服务器和网络已经崩了。
**缺陷: 如果服务器性能太差以及带宽太小,可以被404攻击打死。就是,CC攻击来的链接都是不重复的不存在的。

C语言小代码,占用1核的CPU资源,以及2G内存。
解释一下原理。C是单线程的,所以,最后那个while死循环将占用完一核的CPU所有资源。
malloc分配2G这个不用解释了,后面的for填充,是因为编译器和操作系统会优化malloc分配的内存,如果你没有用到分配的空间,它并不会真的实际分配。
编译: cc waste.c -o waste 啥? cc不存在? 那就 apt install gcc啦。
运行: nohup ./waste > /dev/null 2>&1
如果想占用更多,就多运行几个呗。当然,想写成service也可以,配置文件我就不贴了。

#include <stdio.h>
#include <stdlib.h>

int main() {
    long long int size = 2LL * 1024LL * 1024LL * 1024LL; // 2GB
    char *memory = (char *)malloc(size);
    if (memory == NULL) {
        printf("内存分配失败!\n");
        return 1;
    }
    long long i;
    unsigned char ch;
    for (i=0;i<size;i++) {
      ch=i%2;
      *(memory+i)=ch;
    }
    while (1) {
    }
    return 0;
}

运行实例(2C12G的vps):

root@sin1:~# uptime
 00:45:47 up 12 days, 11:12,  2 users,  load average: 1.00, 1.00, 1.00

root@sin1:~# free
               total        used        free      shared  buff/cache   available
Mem:        12237708     2523608     7098556        3912     2839040     9714100
Swap:         999420           0      999420

随便找了个3杂的net来替换,字面上没任何意义,当然,换成米虫还是可以硬拼一气,但我不会。
以前那个域名我其实不想用,因为是我的网名,拿着做blog还行,但做任何其它的就不妥了,而新的域名没啥感觉,没感觉总好过不想用了。