tessera

分享

一份分享是什么、能活多久、能被取几次

一次分享是一段文字,或一个以上的文件,加上一组取件码。码给对方,对方去 /s/<码> 取。

分享没有永久的。它会过期,也可以限制被取几次,两者在创建时决定,创建之后还能改。

上传完成后的页面
发件人拿到的:链接、二维码、期限与阅后即焚
分享页
收件人看到的

发送东西

一份分享装的是文本、文件,或一条链接。它们存的地方不同,行为也不同。

文本不管多大都在数据库里,上限是 share.max_text_bytes,默认 1 MB。超过会被拒绝,并让你改用文件发。1 MB 大约一百万个字,塞不进去的东西已经不是一段贴文了。

文件不管多大都存成对象,上限是 server.max_body_bytes,默认 100 MiB。一份分享可以放好几个。角色或单一账号可以被设一个比较小的单文件上限,见配额。

链接是一个网址,打开分享的人会被送过去。只收 http 和 https。密码、期限和次数限制跟其他分享一样能用,而且目的地拿不到取件码,因为跳转时不发 referrer。

有次数限制的链接会等人点

没有密码、没有次数限制的链接分享会直接把访客送过去。有次数限制的会先出一个页面,等人点一下才跳,因为聊天软件在链接被贴上的当下就会去抓,直接跳的话一次性的链接在任何人打开之前就被用掉了。

除了链接以外都可以端对端加密;链接要让服务器读得到才能跳转。

在终端里,用 tess 或单纯的 curl -T 也能上传。在任何网页上,则可以用浏览器扩展右键上传。

多个文件和文件夹

分享由第一个文件创建,其余一个一个加上去。没有草稿要收尾,所以传到一半断掉,留下的是已经到的那些,不是什么都没有。

上传过程中链接就是通的

在你传完之前打开它的人会看到不完整的分享。传完再把链接发出去。

文件名可以带路径,文件夹的结构就是这样保住的。每一段都会被清理,结果一定是一条爬不出压缩包的相对路径:

发进来存下来
holiday/2024/photo.jpg原样
../../etc/passwdetc/passwd
/etc/passwdetc/passwd
a\b\c.txta/b/c.txt

反斜杠也算分隔符,Windows 不收的字符会一起被拿掉。不同文件夹里的两个文件就是两个文件,a/photo.jpg 和 b/photo.jpg 都留得住。

大文件

上传可以续传。连接断掉的话会从最后一个完整的块接下去,不是从头来,而且最多只会重发一个块。

开了之后被放着不管的上传,在 store 上占着真的空间,而且算进配额。它会在 share.upload_session_ttl_hours 之后被清掉,默认一天。

用 S3 还要设一条生命周期规则

tessera 会清掉它找得到的,但清失败的话 S3 会留着并且计费。见文件放在哪里。

取件码

默认 8 个字符,字母表里没有 I、L、O、U。前三个是因为它们正是人们会跟 1、1、0 搞混的字;拿掉 U 之后,生成出来的码拼不出那些没有人想看到的字。

念出来再打回去会自动纠正。ozpq0123、OZPQ0123、0ZPQ-0123 都会到同一份分享:大小写、连字符、下划线、空格都处理掉,O 和 I 会变成 0 和 1。

share.code_length 可以设 4 到 32。8 个字符大约是 1.1 × 10¹² 种组合。

调短之前先看限流

4 个字符只有一百万种组合。同一来源查不到的码一分钟 60 次就会被挡,靠这个扫完要十一天左右。放在代理后面而 trusted_proxies 没配对的话,每个请求都算在代理那一个地址上,限流等于没有,见反向代理。

不存在的码和格式不对的码从外面看起来一样。分开回答等于告诉人哪种形状值得试。

取件

打开 /s/<码> 会看到这份分享是什么,不花掉任何东西。链接预览、浏览器预取、邮件扫描器跟着链接走,都不会毁掉一份阅后即焚的分享。

在浏览器里,页面还会直接显示文本分享,以及只有一张图片或一个视频的分享,而显示出来就算一次取件。只剩一次取件的分享会等你点了才显示,所以光是打开阅后即焚的链接,不会用掉它。图片支持 PNG、JPEG、GIF、WebP、AVIF、BMP 和 SVG,视频支持 MP4、M4V、WebM、MOV、MKV 和 OGV。视频在按下播放前会先遮住,浏览器解不了的视频会改为提供下载。

真的把它取走才会花掉一次,而且整段传输只算一次。一次下载不只一个请求,续传和断线之后重试都是,这些都不另外计费。

授权活得跟传输一样久

让它过期的是「没在用」,不是时间长短:默认闲置一小时,而且每用一次就往后推。还在传的授权要多久就有多久,传完的一小时内就死掉。share.ticket_ttl_hours 是压在上面的天花板,默认一天。

固定寿命必须长到让最慢的线路传完最大的文件,而那刚好长到让那份授权值得转手给别人。

如果这台机器有扫毒,分享要等文件扫完才能取件,试了也不花任何东西。

文本分享下载下来是一个纯文本文件,文件名用它的标题,没有标题就用取件码。

有好几个文件的分享会打包成一份下载。zip 是默认,也是三大桌面系统都不用装东西就打得开的;tar 和 7z 留给会让用户选的客户端。只有一个文件就发那个文件。

上传的内容永远不会用它声明的类型发回去

类型有记下来,但不会照着返回。返回了的话,一个 text/html 的上传就是同一个域名上的 stored XSS,而那个域名放着所有人的登录 cookie。

密码

分享可以加密码,最少 4 个字符。比账号密码宽松,因为它是加在一条本来就猜不到的链接上的第二道锁,而且常常要用电话念给对方。

上锁的分享只会告诉访客「这个存在,而且要密码」。文件名、大小、期限都要等密码给了才看得到,因为这三件事都在描述内容。

同一组码加同一来源猜错太多次会被挡一段时间。

能活多久,能取几次

活着 过期或用完 下一轮扫描清掉内容 retain_after_death_hours 之后链接不再存在

没特别指定的话一份分享活一个星期,最长可以要求三十天。也可以限制被取几次,限一次就是阅后即焚。

死掉的分享不会马上消失。记录还在的期间,点链接会说「已过期」而不是「没有这组码」,这两件事对人来说不一样,而且只有一个值得重打一次。内容本身在死掉之后的下一轮扫描就清掉,所以阅后即焚的分享不会在被取走之后,还占着它的完整大小一个星期。

扫描每小时一轮。

创建之后改

已经存在的分享可以换一个期限、换一个剩余次数,或是把密码拿掉。内容和取件码不会变。

次数是从现在算,不是从头算。一份已经被取过两次的分享设成 1,剩下的是一次,不是零次。

内容存在哪

文本是数据库里的一行,所以备份数据库就等于备份了它。文件一个存成一个对象,按年、月和一组随机编号归档。见文件放在哪里。

配额

上限有三层,最紧的那一层说了算。

  • 整台机器。 storage.max_total_bytes,默认没设。
  • 一个角色。 属于它的人总共能存多少,以及单一文件最大多大。
  • 单一账号。 这两个上限都可以为某一个人单独覆写。

三层计的都是还活着的内容,包括存在数据库里的文本。已经被清掉内容的死分享不算。

这是护栏不是账本

同时进行的上传各自读一次剩余额度,所以它们可能一起越线,下一个上传才会被挡。留跟磁盘一样的余量。

想压低占用,把默认期限缩短比设配额有效。磁盘上的量大约是上传速率乘以保存时间,缩短默认期限会拉低稳定值,而且不用拒绝任何人。

命令行用 tessera-server quota 设同样的数字,下一个请求就生效:

tessera-server quota list
tessera-server quota set role member 5000000000
tessera-server quota set-file user alice 100000000
tessera-server quota set user alice none

set 是总量,set-file 是单个文件上限,单位都是字节。none 把数字清掉,交回上一层决定;0 是这一层不设上限。匿名上传算在 guest 角色头上,所以开放匿名上传的实例一样管得住。

不登录也能上传

features.anonymous_upload 默认开着。没登录创建的分享会返回一个管理令牌,那是之后删掉它的唯一方法。

管理令牌只出现这一次

令牌本身不会被存下来,只留一段拿来核对的指纹。丢了就没有人删得掉那份分享,只能等它过期。

另一条路是先登录:账号本身就是令牌,而且分享会出现在你自己的列表里。

删一份不属于你的分享,看起来跟删一份不存在的一样。分开回答等于确认哪些码是真的。

链接预览

把链接贴进 Discord、Slack 这类地方会出现一张有图的卡片。图是服务器画的,因为 unfurler 不跑 JavaScript,页面自己组出来的图没有人看得到。卡片用这台机器设置的语言。

画好的卡片会留着,但是用卡片上写的内容当 key,所以写着「还能取两次」的卡片,在这句话不再成立的那一刻就会被换掉。文本分享的卡片会画出前几行,而且上色。

卡片透露什么,看分享是哪一种:

分享卡片显示
普通的标题或文件名、大小、还剩多少
有密码只说它有密码
端对端加密只说这件事,以及大小
链接说它是一条分享的链接。不显示网址
过期或用完说它已经不能用

预览是给整个频道看的,上锁的分享在那里讲出文件名,密码就是装饰品。抓预览不花任何东西。

你可以换成自己的版面,一台机器一个设计。不管版面要什么,上锁的分享照样什么都不透露:那些值在版面看到之前就被扣下来了。

图片分享的链接预览卡片
一般的分享
加锁分享的链接预览卡片
有密码的分享
文字分享的链接预览卡片
文字分享:前几行,而且上色

配置

配置

类型

默认期限比上限长会拒绝启动。

接下来

本页内容