Tokinx 发布的文章

一大早收到腾讯云漏洞通知的邮件,显示 1Panel 命令注入漏洞 CVE-2025-54424,等级是高危,查了下这是 V2 版本才有的漏洞,我 V1 你提示个 der?

不过几个服务器基本都是 Proxy 用,没放什么东西,看了下官方更新记录 V2.0.6 已经修复了这个问题,索性花一点时间把 1Panel 升级到 V2 尝尝鲜。

CVE-2025-54424 目前影响返回仅 V2.0.0 ~ V2.0.5,V1 用户不在此次楼都影响范围内,可以不用升级。当然跟我一样想升级 V2 尝鲜除外。

因为我现在还是 V1.10.32,所以还得先想办法升级到 V2 再升级 2.0.6,好在查了下官方已经有迁移脚本了:

郑重提醒

升级有风险,操作需谨慎。一切操作请提前备份好文件或创建磁盘快照。

安装升级脚本

此处以 X86 架构为例,升级版本为 v2.0.6,如果使用其它加购或要升级到其它版本请参考官方数据迁移脚本 1panel-migrator

# 1. 进入临时目录
cd /tmp

# 2. 下载适用于您服务器架构的二进制文件(以 amd64 架构为例)
wget https://gitee.com/fit2cloud-feizhiyun/1panel-migrator/releases/download/v2.0.6/1panel-migrator-linux-amd64

# 3. 添加执行权限
chmod +x 1panel-migrator-linux-amd64

# 4. 移动至系统 PATH 中并重命名
mv 1panel-migrator-linux-amd64 /usr/local/bin/1panel-migrator

升级1Panel

V2 版本开始,1Panel 划分了主节点和从节点,简单解释如下:

主节点从节点
支持外部访问
包含 1panel-core 和 1panel-agent 两个服务
包含V1社区版所有功能
受主节点管理,不支持外部访问
仅包含 1panel-agent 服务
没有付费购买专业版就可以忽略这个功能了

升级过程分为两步:升级服务 和 升级网站,务必先完成服务升级,再进行网站升级。

# 升级服务
1panel-migrator upgrade core

# 升级网站,需确保 V2 服务启动成功后再执行该命令。
1panel-migrator upgrade website

问题及解决方案

升级指令参见:upgrade.md,过程其实还算顺利,只是我也遇到了一些问题,在此也记录一下我的修复方案,仅供参考:

Q1:升级后PHP网站会更新为静态网站。

这是因为V2开始支持多个PHP网站共用一个PHP容器了,是一个比较大的改动升级,升级1Panel后建议卸载旧的PHP运行环境,重新安装一个新的PHP运行环境,再编辑网站重新设置PHP版本即可。

Q2:升级后反向代理网站的缓存全部关闭了。

此处也是V2版本的一处大改动,重新开启缓存即可。

Q3:升级过程遇到 -bash: docker-compose: command not found 相关错误?

遇到这个问题首先试一下 docker compose --version 能否执行,如果可以建议直接挂在软链接 sudo ln -s $(which docker) /usr/local/bin/docker-compose 重试,否则可能需要重新安装compose。

Q4:升级过程遇到 migrator v1 to v2 core failed, err: SQL logic error: no such table: mcp_servers (1) 相关错误?

这个错误是我 飞牛NAS 里的 1Panel 升级时遇到的,因为飞牛应用商店安装的 1Panel 版本非常陈旧,当初根据飞牛论坛的帖子升级到 V1 最新版后一直没有发现问题,但是其实升级后的 1Panel 是没有 AI 菜单的。

根据错误信息我搜索到了 1Panel 论坛有相关的帖子以及修复方案

# 下载新版v1 1Panel
wget https://resource-fit2cloud-com.oss-cn-hangzhou.aliyuncs.com/1panel/package/stable/v1.10.32-lts/release/1panel-v1.10.32-lts-linux-amd64.tar.gz
# 解压
tar -xzvf 1panel-v1.10.32-lts-linux-amd64.tar.gz
# 然后找到其中的 1panel 二进制文件 替换到你 /usr/loca/bin 下面 然后重启

需要注意的是如果你是 飞牛NAS 应用商店安装的 1Panel 可能重启后会发现依然没有 AI 菜单,此时可以尝试拷贝 1panel 文件到 /vol1/@appcenter/1Panel/bin 再重启应该就有AI菜单并可以升级了。

Enjoy 1Panel V2

虽然虚惊一场,但是也借此机会花了大概一早上的时间。将三台服务器的 1Panel 升级到了 V2,前段时间把博客丢到 NAS 里了,结果今天因为 Q4 那个问题导致博客宕机了一上午,不过问题不大,总算都升级完毕了。

参考链接

前段时间不小心把服务器搞墙了,临时想办法套了下CF,顺便研究了下大善人家里都有哪些服务可以白嫖,正好看到R2有免费10G的存储空间,想着服务器也没有设置自动备份,不如把这空间拿来做数据备份吧。

谨慎选择“不频繁访问”

说干就干,结果创建存储桶时看着“默认存储类”,想着备份数据确实是“不频繁访问”的数据,就选这个吧(明明下面那么明显的颜色提示免费层不适用于不频繁访问存储的使用,愣是完全忽略掉了)

愉快了自动备份了一段时间,结果8号收到银行卡的扣费通知,扣费9.92刀

好嘛,总共就用了10来天,结果原本是来白嫖的,结果居然被反嫖了

仔细翻了下文档才发现,只有Standard storage 标准存储桶免费!!!

行吧,钱也扣了,就当免费用CF的嫖资了,也顺便把存储桶改成标准存储桶,以免再次扣费。

Cloudflare又称赛博大善人,我也一直用CF的DNS解析服务,今年陆陆续续把域名都转到CF了,托管到CF可以非常丝滑的白嫖他们家各种服务,Catch-all Email、Workers、D1 database、Tunnels都正在免费使用中,这次R2误操作被扣费完全是手太快导致,下次还是得多加注意才行呐

最近主题想实现一个分享链接自动解析 URL,并以卡片形式展示目标链接内容的功能,几经调研发现这个需求早在10多年前就已经有相应的标准了,它就是有 FaceBook 提出的 OpenGraph 协议(开放图谱协议)

OpenGraph是什么

我们知道,构建一个网站采用的技术和实现方式并不相同,普通方法无法完美地解析目标页面的基本信息,导致没有 OpenGraph 协议时分享的链接展示形式相当有限,而且看起来没有非常大的点击欲望。

OpenGraph 协议简单来说就是向网页 head 下插入一些统一标准的 meta 元信息,支持标题、描述、缩略图等信息,大大方便了第三方网站和应用地解析出目标页面的基本信息,并加以优化展示链接的目标页面,使其点击率可以大大提升。

比较直观的讲就是,网页只需要加入 OpenGraph 元信息,当页面被分享到微博、FB、Twitter 时,URL 会被智能地解析成一个非常精美地卡片显示:

实际应用

了解了这么多,我们自己的网站和应用如果想要优化链接展示让然也可以读取 OpenGraph 元信息。

其中PHP就可以使用 get_meta_tags 方法从一个URL中提取所有的 meta 标签 content 属性,并返回一个数组:

<?php
    $tags = get_meta_tags('https://biji.io/about');

    // 注意所有的键(key)均为小写,而键中的‘.’则转换成了‘_’。
    echo $tags['title'];
    echo $tags['description'];
    echo $tags['image'];
    echo $tags['geo_position'];
?>

WordPress如何添加OpenGraph元信息

// 附加元信息
function head_append_meta() {
    $metas = [
        'og:title'     => get_the_title(),
        'og:site_name' => get_bloginfo( 'name' ),
        'og:type'      => 'website',
    ];
    if ( is_single() || is_page() ) {
        $metas['og:url']         = get_permalink();
        $metas['og:description'] = get_the_excerpt();
        if ( has_post_thumbnail() ) {
            $meta_image_url = wp_get_attachment_image_src( get_post_thumbnail_id(), 'full' );
            if ( $meta_image_url ) {
                $metas['og:image'] = $meta_image_url[0];
            }
        }
        $metas['og:type'] = 'article';
    }
    foreach ( $metas as $key => $value ) {
        echo '<meta property="' . $key . '" content="' . $value . '" />' . "\n";
    }
}

add_action( 'wp_head', 'head_append_meta', 1 );

当然,你也可以访问 The Open Graph protocol (ogp.me) 来了解所有 OpenGraph 元信息和其含义,并灵活地运用到你的网站上。

可以 FaceBook 的分享调试器来调试和预览 OpenGraph 元信息展示能力:分享调试器 - Facebook 开发者

本文参考资料:

【WordPress教程】 什么是 Open Graph(property=”og:type”)_细说外贸推广_杭州 SEO 研究_ISEOer (rrdaj.com)
前端应该知道的:开放图谱协议(The Open Graph protocol) - SegmentFault 思否
The Open Graph protocol (ogp.me)

Image()函数将会创建一个新的HTMLImageElement实例。它的功能等价于 document.createElement('img')

正常情况下,我们使用下面方法加载图片,是能能够获取到onload事件的:

const img = new Image();
img.src = 'picture.jpg';
img.onload = () => {
  console.log('success');
}

但是如果你需要加载的图片是base64图片时,可能是因为没有请求发出,onload事件是无法执行的。

几经尝试,最终考虑将base64图片转位ObjectUrl再加载,好处是无需后端,纯前端即可兼容。移动端兼容性也非常不错。

具体实现如下:

// base64转Blob
const base64ToBlob = (base64Data) => {
  const arr = base64Data.split(','),
    type = arr[0].match(/:(.*?);/)[1],
    bstr = atob(arr[1]),
    len = bstr.length,
    u8Arr = new Uint8Array(l);

  while (len--) u8Arr[l] = bstr.charCodeAt(len);

  return new Blob([u8Arr], { type });
}

const base64 = "data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==";
const imgBlob = base64ToBlob(base64)

const img = new Image();
img.src = window.URL.createObjectURL(imgBlob); // blob:http://xxx
img.onload = function () {
  console.log('success')
}

URL.createObjectURL 可能有一些兼容性问题,如果你在使用过程遇到,可以hack兼容一下

function getObjectURL(blob) {
  var url = null;
  if (window.createObjectURL != undefined) {
    url = window.createObjectURL(blob);
  } else if (window.URL != undefined) {
    url = window.URL.createObjectURL(blob);
  } else if (window.webkitURL != undefined) {
    url = window.webkitURL.createObjectURL(blob);
  }
  return url;
}

本文参考资料:

Image() - Web API 接口参考 | MDN (mozilla.org)
使用img.onload事件加载base64图片的兼容问题 - 简书 (jianshu.com)
vue 上传图片,转base64取不到.onload的值 - 小蘑菇123 - 博客园 (cnblogs.com)

不知不觉来上海已经快一周年了,当初种种原因选了一份过渡性质的工作,最近感觉是时候换一份适合长期发展的工作了,难免有些感触,开一篇文章算是个回顾与展望吧。

上海

这是上海给我最初的印象,光鲜靓丽的外滩与陆家嘴、高耸入云的上海中心大厦映入眼帘,我对自己未来职业规划真的满腹憧憬。

  • 东方明珠俯瞰
  • 陆家嘴三高
  • 路过陆家嘴
  • 下班路上

工作

上篇文章交代了来上海前我的一些经历,虽然当初选了一份外包工作做为过渡,但是在PA科技做前端开发依然学到了非常多的东西,我也从之前的全栈开发完全地转到了纯前端开发的角色参与项目开发。

因为近期也正在积极准备面试工作,对于未来职业的规划或者发展方向我一直只有一个大概的想法,明确的方向一直没有制定,也正好近期面试,也算是给我一些警醒或者说是一些方向吧。

展望

首先可能是自己的一些前端基础问题,我觉得自己目前顶多算是一个中级,业务上暂时可能不会遇到什么问题,但是这次面试让我想冲击高级前端来了一次狠狠地打击,也算是充分认识到自己的不足吧,打算沉下心好好钻研一下设计模式和高级 JavaScript 编程。

另外还有一件事情,之前我一直觉得维护一段感情是一件非常麻烦的事情,而且我也不喜欢麻烦别人,但是当同学Q靠积累的人脉拿到22K的工作,我真的不再对“人脉”抱嗤之以鼻的态度了,只能感叹:牛逼!。。。希望自己后面可以做一些或者参与一些开源项目结识一些大佬吧。

  • 撸码环境
  • 员工关怀
  • 发版加班结束
  • 离职前的工位

生活

这是我来上海租的房子,可能这个月月底就要考虑搬走了,视野开阔的环境,虽然朝北但却奇怪地采光良好,下午2点之后还能晒到太阳,我很喜欢这里,但是冬天超冷,出行不便,只是我坐公交上下班,站台离小区不远还可以接受,如果换工作可能就要换房子了。

因为有一些同学在上海,偶尔也会约饭、打麻将之类的活动,6月也一起去了浙江漂流,也挺多姿多彩的吧,虽然我一直认为我很宅,但是脑袋里回忆一下好像也宅的不那么纯粹了。

生活上我也不知道写些什么,记录一下从来上海到现在我手边数码设备变迁吧。

电脑:RedmiBook 16' -> MacMini M1 -> MacBook Air M1,这让我想到了项目里的组件封装过程,只基于现阶段业务需求实现组件,却没有充分考虑业务未来发展而封装组件的后果就是——不!断!重!构!不过实际情况可能还是要基于财力的。加油,努力实现电脑自由。。。

手表:Apple Watch 3 -> Amazfit POP -> Amazfit NEO,为了摆脱一天一充的噩梦更换到了pop,又为了摆脱被误认为iWatch的尴尬更换到NEO。只能说,能看时间就是好手表吧。

手机:iPhone11 -> iPhone12,换手机真的是一时脑热,因为iPhone11我是按揭24期计划用2年届时更换到iPhone13的,结果某天不凑巧等公交时手机摔碎了屏幕,从修好的那天起,我是怎么看它都不顺眼,在按揭没结束的情况下,亦然地更换到了iPhone12,新手机。。。舒服了。。。

其它的一些设备

  • 为了更好听音乐,入坑HomePod Mini
  • 为了随时喝热水,入坑米家即热饮水机
  • 为了更好的带饭,入坑小米电饭煲 1.6L版
  • 为了躺着刷抖音,入坑小米扫地机器人
  • 2021留沪年夜饭
  • 我的桌面
  • 麻将
  • 闺房

暂时就记录这么些吧,很久没有写些什么了,写这篇文章的时候打开WordPress发现功能变强大了好多,块级文本编辑器还挺好用的,就是很多功能Adams还需要适配,等新工作确定下来打算继续完成这篇文章的更新计划吧,先把样式好哈用Less或者Sass重写一下,我倾向于用Less。。。

这篇文章样式回头再改一下,大家先凑合看吧。