tessera

共有

共有とは何か、どれだけ持つか、何回受け取れるか

共有は、ひとつのテキスト、または一つ以上のファイルと、受け取りコードの組み合わせです。コードを渡すと、相手は /s/<コード> で受け取ります。

共有はどれも永久ではありません。期限が来れば切れ、受け取り回数にも上限をかけられます。どちらも作るときに決め、あとから変えることもできます。

アップロード後の画面
送る側に表示されるもの:リンク、QR コード、期限、一度きりの設定
共有ページ
受け取る側に見える画面

送る

共有に入れられるのはテキスト、ファイル、リンクです。保存のされ方も動きもそれぞれ違います。

テキストは大きさに関係なくデータベースに入ります。上限は share.max_text_bytes で、デフォルトは 1 MB です。超えるとアップロードは断られ、ファイルとして送るよう案内されます。1 MB はおよそ百万文字なので、収まらないものは貼り付けで送る量ではありません。

ファイルは大きさに関係なくオブジェクトとして保存されます。上限は server.max_body_bytes で、デフォルトは 100 MiB です。ひとつの共有に複数入れられます。ロールやアカウント単位で、1 ファイルあたりの上限をもっと小さくできます。容量制限を見てください。

リンクは、共有を開いた人を転送する先のアドレスです。受け付けるのは http と https だけです。パスワード、期限、受け取り回数はほかと同じように使えます。転送ではリファラーを送らないので、転送先に受け取りコードは伝わりません。

回数制限のあるリンクはクリックを待つ

パスワードも回数制限もないリンク共有は、開いた人をそのまま転送します。回数制限があると、先にページを出してクリックを待ちます。チャットアプリは貼られた瞬間にリンクを取得するので、そのままだと誰も開く前に一回限りのリンクを使い切ってしまうからです。

リンク以外はどれもエンドツーエンド暗号化できます。リンクはサーバーが読めないと転送できません。

ターミナルからは、tess か素の curl -T でも同じようにアップロードできます。どの Web ページからでも、ブラウザ拡張機能で右クリックしたものをアップロードできます。

複数のファイルとフォルダ

共有は最初のファイルで作られ、残りのファイルが一つずつ追加されていきます。完成させる下書きはないので、途中で止まったアップロードでも、何もない共有ではなく、届いた分だけを持つ共有が残ります。

アップロード中でもリンクは使える

終わる前に開いた人には、途中までの共有が見えます。リンクは終わってから渡してください。

ファイル名にはパスを含められます。フォルダの構造はこれで保たれます。各部分は整えられ、結果は必ずアーカイブの外に出られない相対パスになります。

送った名前保存される名前
holiday/2024/photo.jpgそのまま
../../etc/passwdetc/passwd
/etc/passwdetc/passwd
a\b\c.txta/b/c.txt

バックスラッシュも区切りとして扱い、Windows が受け付けない文字も取り除きます。別のフォルダにある同じ名前のファイルは別のファイルなので、a/photo.jpg と b/photo.jpg は両方残ります。

大きなファイル

アップロードは再開できます。接続が切れても最初からやり直さず、最後に完了したブロックから続けます。送り直すのは最大でもブロック一つ分です。

始めたまま放置したアップロードは、ストレージの容量を実際に使い、容量制限にも数えられます。share.upload_session_ttl_hours が過ぎると片付けられます。デフォルトは 1 日です。

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 文字だと百万通りです。同じ送信元は 1 分に 60 回失敗すると拒否されるので、総当たりにはおよそ 11 日かかります。プロキシの後ろで trusted_proxies を設定していないと、すべてのリクエストがプロキシのアドレスひとつに数えられ、この制限は効きません。リバースプロキシを見てください。

存在しないコードと形式がおかしいコードは、外からは同じに見えます。区別すると、どんな形を試せばいいかを教えてしまうからです。

受け取る

/s/<コード> を開くと、何も消費せずに共有の中身がわかります。リンクプレビュー、ブラウザのプリフェッチ、URL をたどるメールスキャナーが一回限りの共有を消すことはありません。

ブラウザで開くと、ページはテキストの共有と、画像か動画が一つだけの共有の中身も表示します。表示するのは受け取りにあたります。受け取りが残り 1 回の共有はクリックを待つので、一度きりのリンクを開いただけで使い切ることはありません。画像は PNG、JPEG、GIF、WebP、AVIF、BMP、SVG、動画は MP4、M4V、WebM、MOV、MKV、OGV です。動画は再生を押すまで隠れていて、ブラウザがデコードできないものはダウンロードを案内します。

受け取り回数を一回使うのは、実際に受け取ったときです。転送全体で一回だけ数えます。ダウンロードはリクエスト一つではありません。再開した転送や、切れた接続のリトライでリクエストは増えますが、どれも追加では数えません。

許可は転送が続くあいだ有効

許可が切れるのは、時間が経ったときではなく、使われなくなったときです。デフォルトは無操作 1 時間で、使うたびに延びます。まだ続いている転送は必要なだけ許可を保ち、終わった転送の許可は 1 時間以内に切れます。その上限が share.ticket_ttl_hours で、デフォルトは 1 日です。

寿命を固定すると、いちばん遅い回線でいちばん大きなファイルを落とし切れる長さが必要になります。それだけ長いと、許可を他人に渡す価値が出てしまいます。

インスタンスがアップロードをスキャンしている場合、ファイルの確認が終わるまで共有は受け取れません。試しても回数は減りません。

テキスト共有は、タイトルを名前にしたテキストファイルとしてダウンロードされます。タイトルがなければコードが名前になります。

複数ファイルの共有は一つのアーカイブとして届きます。デフォルトは zip で、どのデスクトップでも追加のソフトなしで開けるのはこれだけです。選べるクライアント向けに tar と 7z もあります。ファイルが一つならそのまま届きます。

アップロード時に名乗った種類のまま配信することはない

メディアタイプは記録しますが、返すことはありません。返すと、text/html のアップロードが、全員のセッション Cookie を持つオリジン上の Stored XSS になります。

パスワード

共有にはパスワードをかけられます。4 文字以上です。アカウントのパスワードより短くてよいのは、もともと推測できないリンクにかける二つ目の鍵であり、電話で読み上げることも多いからです。

鍵のかかった共有が訪問者に伝えるのは、存在することと、パスワードが必要なことだけです。ファイル名、サイズ、期限は、パスワードを入れるまで見えません。三つとも中身を説明してしまうからです。

同じ送信元から同じコードへの誤入力が多すぎると、しばらく拒否されます。

期限と回数

受け取り可能 期限切れか上限到達 次の掃除で中身を削除 retain_after_death_hours のあとリンク自体が消える

共有は、別の期間を指定しない限り 1 週間で切れ、最長は 30 日です。受け取り回数にも上限をかけられます。上限を 1 にすると、一度読んだら消える共有になります。

切れた共有はすぐには消えません。記録が残っているあいだ、リンクを開くと「コードが見つかりません」ではなく「期限切れです」と表示されます。人に伝える内容としてはまったく違い、打ち直す価値があるのは片方だけです。中身は切れたあと最初の掃除で消えます。一度読んだら消える共有が、受け取るべき人がもう受け取ったあとで、1 週間も容量を使い続けることはありません。

掃除は 1 時間ごとに動きます。

あとから変える

作った共有には、新しい期限、新しい残り回数を設定でき、パスワードを外すこともできます。中身とコードは変わりません。

回数は最初からではなく、今から数えます。すでに 2 回受け取られた共有に 1 を設定すると、残りは 0 ではなく 1 回です。

中身の置き場所

テキストはデータベースの一行なので、データベースのバックアップがそのままテキストのバックアップになります。ファイルは一つずつオブジェクトとして、年、月、ランダムな ID の下に保存されます。ファイルの保存先を見てください。

容量制限

上限は三つあり、当てはまるうちでいちばん厳しいものが効きます。

  • インスタンス。 storage.max_total_bytes。デフォルトは未設定です。
  • ロール。 そのロールの全員で合わせて保存できる量と、1 ファイルの大きさ。
  • アカウント。 どちらの上限も、一人だけ個別に変えられます。

どれも、まだ残っている中身を数えます。データベースのテキストも含みます。中身がもう片付けられた、切れた共有は数えません。

会計係ではなく、見張り番

同時に進むアップロードは、それぞれ残りの容量を一度だけ読むので、合わせると上限を超えることがあります。その後に来るアップロードは断られます。ディスクと同じように余裕を残しておいてください。

使う量を減らしたいなら、容量制限よりデフォルトの期間を短くするほうが効きます。ディスクに載っている量はおおよそ「アップロードの速さ × 保存期間」なので、デフォルトを短くすれば、誰も断らずに平常時の量が下がります。

コマンドラインでは、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 は 1 ファイルの上限で、どちらもバイト単位です。none は値を消して上の層に任せ、0 はその層で上限なしを意味します。匿名のアップロードは guest ロールに数えられるので、匿名を受け付けるインスタンスでも量を抑えられます。

アカウントなしでアップロードする

features.anonymous_upload はデフォルトで有効です。サインインせずに作った共有には管理トークンが返ってきます。あとで削除するにはこのトークンが必要です。

管理トークンは一度しか表示されない

トークンそのものは保存されず、照合用の指紋だけが残ります。なくすと誰もその共有を削除できず、期限が切れるのを待つしかありません。

先にサインインしておけば、アカウントがトークンの代わりになり、共有は自分の一覧に出ます。

自分のものではない共有を削除しようとすると、存在しない共有と同じ反応になります。違う答えを返すと、どのコードが本物かを教えてしまうからです。

リンクプレビュー

Discord や Slack などにリンクを貼ると、画像付きのカードが出ます。カードはサーバーが描きます。展開する側は JavaScript を実行しないので、ページで組み立てた画像は誰にも見えないからです。言語はインスタンスの言語です。

描いたカードは保存しますが、書かれている内容をキーにしています。「残り 2 回」と書いたカードは、それが事実でなくなった瞬間に描き直されます。テキスト共有のカードには、最初の数行が色付きで出ます。

カードに何が出るかは共有によって違います。

共有カードに出るもの
通常タイトルかファイル名、サイズ、残り
パスワード付きパスワード付きであることだけ
エンドツーエンド暗号化そのことと、サイズだけ
リンク共有されたリンクであること。アドレスは出ない
期限切れか上限到達受け取れないこと

プレビューはチャンネルの全員に見えます。鍵のかかった共有のファイル名をそこに出したら、パスワードの意味がなくなります。プレビューを取得しても回数は減りません。

カードは自分のレイアウトに差し替えられます。デザインはインスタンス全体で一つです。レイアウトが何を求めても、鍵のかかった共有は何も明かしません。値はレイアウトに渡る前に伏せられます。

画像共有のリンクプレビュー
通常の共有
ロックされた共有のリンクプレビュー
パスワード付きの共有
テキスト共有のリンクプレビュー
テキスト共有:最初の数行を色付きで表示

設定項目

設定

型

デフォルトの期間が上限より長いと、起動しません。

次に読む

このページの内容