jsDelivr 在国内的访问时好时坏,导致网站的图标、字体加载很慢,索性自己建个镜像算了

域名

解析 cdn.diraw.top 指向服务器

请求证书:

sudo certbot certonly --nginx -d cdn.diraw.top

然后:

sudo vim /etc/nginx/sites-available/default

certbot 配置的关于 cdn.diraw.topserver 部分删掉

mginx反向代理

创建:

sudo vim /etc/nginx/sites-available/cdn.diraw.top
# 定义缓存存储路径
proxy_cache_path /var/cache/nginx/jsd_cache levels=1:2 keys_zone=my_jsd_cache:100m max_size=2g inactive=60d use_temp_path=off;

server {
listen 443 ssl;
server_name cdn.diraw.top;

ssl_certificate /etc/letsencrypt/live/cdn.diraw.top/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/cdn.diraw.top/privkey.pem;

location / {
# 防盗链
valid_referers none blocked server_names *.diraw.top diraw.top localhost 127.0.0.1;
if ($invalid_referer) {
return 403;
}

# 动态 CORS
set $cors_origin "";
if ($http_origin ~* "^https?://(.*\.)?diraw\.top$") { set $cors_origin $http_origin; }
if ($http_origin ~* "^https?://(localhost|127\.0\.0\.1)(:[0-9]+)?$") { set $cors_origin $http_origin; }

# 解析 npm 包信息
if ($uri ~* "^/npm/([^/]+)/([^/]+)/(.+)$") {
set $npm_package $1;
set $npm_version $2;
set $npm_path $3;
}

# Font Awesome 6 特殊处理
set $fa_fix "";
if ($npm_package = "font-awesome") {
set $fa_fix "Y";
}
if ($npm_version ~* "^6\.") {
set $fa_fix "${fa_fix}Y";
}
if ($fa_fix = "YY") {
set $npm_package "@fortawesome/fontawesome-free";
}

# 添加 dist 目录处理
set $should_add_dist "";
if ($npm_package ~* "^(aplayer|twikoo|typed\.js)$") {
set $should_add_dist "Y";
}
if ($npm_path ~* "^dist/") {
set $should_add_dist "${should_add_dist}N";
}
if ($should_add_dist = "Y") {
set $npm_path "dist/$npm_path";
}

if ($uri ~* "^/npm/[^/]+/[^/]+/.+$") {
rewrite ^(.*)$ /npm/$npm_package@$npm_version/$npm_path break;
}

proxy_pass https://cdn.jsdelivr.net;

proxy_hide_header 'access-control-allow-origin';
proxy_hide_header 'Access-Control-Allow-Origin';

add_header 'Access-Control-Allow-Origin' $cors_origin;
add_header 'Vary' 'Origin' always;

proxy_ssl_server_name on;
proxy_ssl_name cdn.jsdelivr.net;
proxy_set_header Host cdn.jsdelivr.net;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;

proxy_cache my_jsd_cache;
proxy_cache_valid 200 302 365d;
proxy_cache_valid 404 1h;
proxy_cache_background_update on;
proxy_cache_use_stale error timeout updating;

add_header X-Cache-Status $upstream_cache_status;
}
}

其中:

  • 针对 fortawesome 做了单独匹配
  • aplayer|twikoo|typed\.js 因为代码在 dist 目录中,单独做了处理
  • 可能需要添加新的逻辑,但其他的我没用到就先没管了
sudo ln -s /etc/nginx/sites-available/cdn.diraw.top /etc/nginx/sites-enabled/
sudo systemctl restart nginx
sudo nginx -t

防盗链

做了防盗链处理,可以通过下面的命令验证:

  1. 直接访问:
curl -I https://cdn.diraw.top/npm/font-awesome/6.6.0/webfonts/fa-solid-900.woff2
  • 结果:200 OK
  1. 非法引用:
curl -I -e "https://evil.com" https://cdn.diraw.top/npm/font-awesome/6.6.0/webfonts/fa-solid-900.woff2
  • 结果:403 Forbidden
  1. 合法引用(自己的网站):
curl -I -e "https://diraw.top" https://cdn.diraw.top/npm/font-awesome/6.6.0/webfonts/fa-solid-900.woff2
  • 结果:200 OK
  1. 非法跨域请求:
curl -I -H "Origin: https://evil.com" https://cdn.diraw.top/npm/font-awesome/6.6.0/webfont
  • 结果:Access-Control-Allow-Origin 为空
  1. 合法跨域请求(localhost):
curl -I -H "Origin: http://localhost:4000" https://cdn.diraw.top/npm/font-awesome/6.6.0/webfonts/
  • 结果:Access-Control-Allow-Origin:http://localhost:4000

Hexo Butterfly 配置

_config.yml 文件中,改为:

CDN:
internal_provider: local
third_party_provider: custom
version: true
custom_format: https://cdn.diraw.top/npm/${cdnjs_name}/${version}/${min_cdnjs_file}
  • 这里我在 cdn.diraw.top/ 之后加了 npm/,可根据自身需要修改