绕过付费墙,拥有一个全功能的自托管Baserow

绕过付费墙,拥有一个全功能的自托管Baserow

Baserow的付费特性 #

上周写了一篇如何选择自托管开源多维表格的文章,没想到又被少数派推为首页推荐了——《如何选择自托管开源多维表格》。文中没提到我自用的是Baserow,免费版的Baserow使用限制其实比NocoDB和Teable多,但之前被Apitable伤过,比较惧怕AGPL协议的项目,因此用了MIT协议的Baserow。用了快两年,想看看付费功能,但奈何价格过高,也没足够强的需求,也吐槽一下各家起步价还是过高了,都在向Airtable看齐么,为什么不出一个个人版的定价。但最近发现了可以绕过Baserow许可验证机制的方法,完整使用Baserow的所有功能。

Baserow比较致命的限制是几种视图,实际使用下来免费版的Baserow可能也够使用了。但还是手痒痒想用看板Al promptRow coloringCharts功能,就翻了一下Baserow的源码,发现虽然都说Baserow是open core,但其付费特性的代码都已经包含在仓库里了,看起来只需要把许可验证改一下就可以了。

Baserow的付费特性有:

  • 视图,调查表单、看板、日历、甘特图和视图锁定;
  • 字段,Al prompt;
  • 导入导出,导出成XML、JSON;
  • 数据连接,Internal Base、iCal、Jira issues、GitLab issues、GitHub issues、HubSpot customers;
  • 其它,Single sign-on (SSO)、Audit logs、SAML、Roles、Row comments、Row coloring、Charts、Al Chat。

看板 视图 看板 视图

Baserow许可验证机制 #

Baserow使用了非对称加密的数字许可证验证机制,其中,

License内容:

  • 包含实例ID、许可证类型、有效时间、席位等关键授权信息;
  • 采用Base64编码进行传输;

加密签名:

  • 使用私钥(SHA256)对license进行数字签名;
  • 客户端使用公钥验证签名真实性;

验证流程:

  • 服务器生成并签名license;
  • 客户端验证签名并解码license;
  • 根据license内容解锁相应功能;

因此,我们要做的就是生成自己的公钥私钥对,自定义License内容并使用私钥签名,将远程认证服务器改成本地服务。

操作流程 #

以docker容器部署的Baserow为例,容器名为baserow

  • 1.更改宿主机hosts,将认证服务器指向本地,避免升级时对官方服务器发起请求;
# sudo vim /etc/hosts
127.0.0.1 api.baserow.io
ping api.baserow.io
# ping验证生效
# PING api.baserow.io (127.0.0.1) 56(84) bytes of data.
# 64 bytes from localhost (127.0.0.1): icmp_seq=1 ttl=64 time=0.019 ms
# 64 bytes from localhost (127.0.0.1): icmp_seq=2 ttl=64 time=0.029 ms
# ...
  • 2.生成密钥对python creat_pem.py
# creat_pem.py
from cryptography.hazmat.primitives.asymmetric import rsa
from cryptography.hazmat.primitives import serialization

private_key = rsa.generate_private_key(
    public_exponent=65537,
    key_size=2048,
)
public_key = private_key.public_key()

private_pem = private_key.private_bytes(
    encoding=serialization.Encoding.PEM,
    format=serialization.PrivateFormat.PKCS8,
    encryption_algorithm=serialization.NoEncryption()
)
print("=== PRIVATE KEY ===")
print(private_pem.decode())

public_pem = public_key.public_bytes(
    encoding=serialization.Encoding.PEM,
    format=serialization.PublicFormat.SubjectPublicKeyInfo
)
print("\n=== PUBLIC KEY ===")
print(public_pem.decode())
# 控制台将打印出私钥密钥,复制备用
# === PRIVATE KEY ===
# -----BEGIN PRIVATE KEY-----
# MIIEvQI........
# -----END PRIVATE KEY-----
# 
# === PUBLIC KEY ===
# -----BEGIN PUBLIC KEY-----
# MIIBIj........
# -----END PUBLIC KEY-----
  • 3.将公钥内容保存至public_key.pem文件并替换容器内的公钥;
docker cp public_key.pem baserow:/baserow/premium/backend/src/baserow_premium/
  • 4.修改容器内的认证服务器;
docker cp baserow:/baserow/backend/src/baserow/core/utils.py ./

base_url的值改为自建http服务器地址,如https://api.example.com,可以由n8n、nodered或flask等任意服务建立,如n8n服务器http://{N8N_EDITOR_BASE_URL}:{N8N_PORT}/{N8N_ENDPOINT_WEBHOOK}

# vim utils.py
base_url = "https://api.baserow.io"
# 替换覆盖容器内的源码
docker cp utils.py baserow:/baserow/backend/src/baserow/core/
  • 5.重启Baserow ;
docker compose restart
  • 6.生成证书,其中证书格式如下;
# creat_lic.py
import base64
import hashlib
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric import padding
from cryptography.hazmat.primitives.serialization import load_pem_private_key

data = '{"version": 1,"id": "1","valid_from": "2025-01-01T00:00:00","valid_through": "2035-12-31T23:59:59","product_code": "enterprise","seats": 5,"issued_on": "2025-01-01T00:00:00","issued_to_email": "[email protected]","issued_to_name": "Peter","instance_id": "abcdefghijklmn-U"}'

private_key_pem = b"""
-----BEGIN PRIVATE KEY-----
MIIEvQI........
-----END PRIVATE KEY-----
"""
private_key = load_pem_private_key(private_key_pem, password=None)

payload_base64 = base64.urlsafe_b64encode(data.encode())
pre_hashed = hashlib.sha256(payload_base64).hexdigest().encode()
signature = private_key.sign(
    pre_hashed,
    padding.PSS(
        mgf=padding.MGF1(hashes.SHA256()),
        salt_length=padding.PSS.MAX_LENGTH,
    ),
    hashes.SHA256(),
)
signature_base64 = base64.urlsafe_b64encode(signature)

license_payload = payload_base64 + b"." + signature_base64

print("Generated license_payload:", license_payload.decode())

根据实际修改以上data证书内容,各项含义如下:

{
	"version": 1, //请勿修改
	"id": "123-2-435-gfg-4tg54", //证书id,随意设置
	"valid_from": "2025-02-01T00:00:00", // 随意设置开始日期
	"valid_through": "2028-01-01T23:59:59", // 随意设置到期日期
	"product_code": "enterprise", // premium,advanced,enterprise,参考baserow.io/pricing,一般就设置为最高的enterprise
	"seats": 10, // 随意设置
	"application_users": 10, // 随意设置
	"issued_on": "2025-02-11T13:36:21.075873", // 随意设置
	"issued_to_email": "[email protected]", // 管理员邮箱, /admin/users中查看
	"issued_to_name": "Peter", // 管理员姓名Name, /admin/users中查看
	"instance_id": "abcdefghijklmn-U", //实例ID,/admin/licenses中查看'Your Baserow instance ID is'
}

生成证书python creat_lic.py

python creat_lic.py
# 将打印如下
# Generated license_payload: eyJ2......
  • 7.编写认证服务响应;
{
"{Generated license_payload}": //{Generated license_payload}为上一步生成的“eyJ2......”
    {
      "type": "ok", 
      "detail": ""
    }
}

可以用n8n的Webhook+Respond to Webhook节点配置响应。在Webhook节点中HTTP Method设置为POSTPATH设置为/api/saas/licenses/check/Respond 设置为Using Respond to Webhook Node;在Respond to Webhook节点中,Respond With改为JSONResponse Body填入上述json内容,Response Code设置为200

n8n workflow n8n workflow

  • 8.测试认证; 在Baserow中/admin/licenses,点击Register license按钮,在License key框中填入eyJ2......证书值,点击确认完成;我们在n8n的执行历史中即可看到请求记录。

认证完成 认证完成

  • 9.Baserow的升级,重复执行上述步骤3-5即可,也可以一劳永逸地在docker-compose.yml中映射上述两个文件至容器内;(注意utils.py可能随版本升级而有文件变动)

试用 #

/admin/licenses页面中能看到已经获得了高级权限,用OpenRouter的免费API试了一下AI字段生成,其它所有特性也都完美工作!

行着色、AI字段 行着色、AI字段

前一篇 闲来拾光 Vol.2 随机阅读