把 Storage Server 用在自己的网站上:图片、下载、归档

发布于 阅读时间 10 分钟

Web 服务器上的硬盘空间很贵,Storage Server 上的不贵。本文说明哪些东西可以挪出去,从 Web 服务器出发哪个协议能用,以及文件怎么安全地到达访客手里。

在 Web 服务器上,硬盘空间是最贵的那样东西。它坐在为数据库和 PHP 而生的高速 NVMe SSD 上,每多一个 GB 都会明显更贵。而同时躺在那里的,却是些根本用不上这种速度的东西:原始照片、视频文件、下载归档、旧的备份。

Storage Server 的价钱只是其中一个零头,而它接下的正是这部分负担。本文说明哪些东西挪出去才有意义、从 Web 服务器出发哪个协议能用、文件怎么安全地到达访客手里,以及界限在哪里。

哪些值得挪出去,哪些不值得

该放到存储上留在 Web 服务器上
图片和视频的原件缩略图和裁剪过的版本
下载归档、ISO 文件、PDF 合集CSS、JavaScript、字体
原始数据、导出文件、日志归档数据库
网站的备份每次打开页面都要用到的一切

分界线很简单:很少被读取、一次要传很大的,该放到存储上。每次打开页面都要跟着加载的,就留在快的地方。

Storage Server 是什么,又不是什么

Storage Server 是带用户账户的网络存储。您用凭据连上去,然后读写文件。它不是带公开地址的对象存储,也不是 CDN。

这在实际中意味着:您没法在页面里把图片直接链到存储上,因为每一次访问都要登录。要么由您的 Web 服务器把文件取来再转发出去,要么您自己生成有时效的下载链接。怎么做得干净,下面会讲。

听起来像是个限制,但它有个好处:谁也没法靠猜地址或者转发一个链接就把您的文件拿走。访问永远要经过您的应用,也就要经过您的规则。

实践中真能用的那个模式

三步,就这么多:

  1. 原件放在存储上。它们上传一次,之后很少再碰。
  2. 派生出来的版本生成一次,放在 Web 服务器上。也就是缩略图、裁剪过的变体、压缩过的版本。它们很小,而且每次打开页面都要用。
  3. 下载走您的应用。一个小脚本检查权限、从存储取文件、再输出出去。

反过来做、每次打开页面都去存储现取缩略图的,等于给自己造了一个慢网站。每个文件的网络往返时间会累加起来,一个有四十张图的相册就要等四十次。

哪种情形用哪个协议

协议端口适合需要
SMB / CIFS445挂载为目录服务器上的 root 权限
SSHFS23挂载为目录,带加密服务器上的 root 权限
SFTP23从 PHP 访问、脚本、传输出方向的 23 端口
WebDAV 走 HTTPS443共享主机、受限环境只要 HTTPS
rsync23大目录的同步出方向的 23 端口
BorgBackup23带去重的备份出方向的 23 端口

最重要的那个决定不取决于口味,而取决于您的权限:在自己的服务器上,您把存储挂载成一个目录,于是每个应用都能用它,而完全不必知道它是什么。具体做法见将 Storage Server 挂载为网络驱动器。

在共享主机上您没有 root 权限,挂载也就谈不上了。那里的路是从应用里走 WebDAV 或 SFTP,而 WebDAV 通常阻力更小,因为 443 端口几乎从不被封。

在 PHP 里配好访问

用 SFTP 只需要一个纯 PHP 的库,服务器上不必装扩展:

composer require phpseclib/phpseclib:~3.0
use phpseclib3\Net\SFTP;

$sftp = new SFTP('u123456.storage.kernelhost.net', 23);
if (!$sftp->login('u123456-sub1', $passwort)) {
    throw new RuntimeException('登录失败');
}

// 上传文件
$sftp->put('/bilder/2026/original.jpg', '/tmp/upload.jpg', SFTP::SOURCE_LOCAL_FILE);

// 读取文件
$inhalt = $sftp->get('/bilder/2026/original.jpg');

至于 WebDAV,内置的 curl 扩展就够了:

$ch = curl_init('https://u123456.storage.kernelhost.net/bilder/2026/original.jpg');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_USERPWD        => 'u123456-sub1:' . $passwort,
    CURLOPT_TIMEOUT        => 30,
]);
$inhalt = curl_exec($ch);
curl_close($ch);

两个例子用的都是子账户,不是主账户。原因见下一节。

每个用途各配一个子账户

每台 Storage Server 都允许最多 100 个子账户,而且每个套餐都如此。每个子账户都有:

  • 自己的起始目录,出不去;
  • 自己的密码;
  • 自己的协议开关,例如只开 SFTP、不开 Samba。

对一个网站来说这意味着:给 Web 服务器一个子账户,只能用 SFTP,也只看得见 /web;给备份第二个,只看得见 /backup。万一 Web 服务器哪天被拿下,攻击者也碰不到备份,因为那个账户根本不知道它们的存在。

有一个界限:子账户拿不到自己的空间配额。它出不了自己的目录,但在那里面可以把整个套餐的存储填满。真想限制单个用户的,就需要在前面放一个应用来接管这件事。把 Nextcloud 连到 Storage Server 讲的正是这种搭法。

安全地分发下载

最常见的错误是把凭据放进浏览器,比如做成一个带用户名和密码的链接。正确的做法是由您的服务器建立连接并把文件转发出去:

<?php
// 在任何事情发生之前先检查权限
if (!nutzer_darf_datei($_GET['id'])) {
    http_response_code(403);
    exit;
}

$sftp = neue_verbindung();
$datei = $sftp->get(pfad_zu($_GET['id']));

header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="dokument.pdf"');
header('Content-Length: ' . strlen($datei));
echo $datei;

文件非常大的时候,最好分块读取,而不是全部装进内存,否则会撞上 PHP 的内存上限。为此要用 ob_end_flush(),然后一段一段地把文件输出出去。

预计会有很多并发下载的,还要想到每个正在进行的下载都会占住一个 PHP 进程。到了一定规模,这种东西就该放在一台自己的服务器后面,而不是共享主机后面。

把网站备份到存储上

这是最简单的入门方式,而且立刻就有收获。用 rsync 只传输变化的部分:

rsync -az --delete -e "ssh -p 23" \
      /var/www/example.com/ \
      u123456-sub2@u123456.storage.kernelhost.net:/backup/web/

要做带去重和加密的备份,BorgBackup 是更好的选择,它在存储上原生就有。再加上存储自己的快照作为第二层:按套餐不同是 10、20、30 或 40 个手动快照,另有同样数量的自动快照,分日、周、月三种节奏。

和备份到同一台服务器上相比,差别恰恰是决定性的:硬盘被删掉或者被加密时,本地备份会跟着一起没,放在独立存储上的备份不会。

动手之前:两个开关

在客户中心的 Storage Server 处,您会找到“访问设置”按钮。有两件事必须对:

  • 外部可访问性必须开着,否则您的 Web 服务器从互联网上到不了存储。
  • 需要用的那个协议必须放开,也就是 SMB 要开 Samba,SFTP 和 rsync 要开 SSH,走 HTTPS 的那条路要开 WebDAV。

新订购的服务器上这些都是开着的。出于安全考虑把用不到的关掉的人,请记住:日后“怎么又不行了”最常见的原因,恰恰就是这个。

哪个套餐合适

套餐空间子账户快照价格
Storage-11 TB10010 个,另加 10 个自动9.99 EUR
Storage-25 TB10020 个,另加 20 个自动29.99 EUR
Storage-310 TB10030 个,另加 30 个自动39.99 EUR
Storage-420 TB10040 个,另加 40 个自动69.99 EUR

所有 Storage Server 都在德国,支持 FTP、FTPS、SFTP、SCP、Samba、WebDAV 和 WebDAVs,原生带 rsync 和 BorgBackup,并且有 IPv4 和 IPv6。没有安装费,按预付方式结算,无最短合约期。所以您可以先从 1 TB 开始,以后再扩,不用搬家。

举个算账的例子:在 Web 服务器上多买 1 TB 空间,按服务商不同要花每月 9.99 欧元的好几倍,而且它还和网站躺在同一台机器上。旁边的存储不只是更便宜,它还是分开的。

常见问题

可以把图片直接从 Storage Server 引到我的网站里吗?
不能用图片标签里的直链。Storage Server 不是公开的 Web 服务器,每一次访问都要登录。要么由您的 Web 服务器把文件取来再转发出去,要么您自己生成有时效的下载链接。至于缩略图,更好的办法是生成一次,然后缓存在 Web 服务器上。
从 Web 服务器出发该选哪个协议?
在有 root 权限的自有服务器上,SMB 或 SSHFS 最省事,存储会直接显示为一个普通目录。在没有 root 权限的共享主机上这条路走不通,那里阻力最小的是走 HTTPS 的 WebDAV,因为 443 端口几乎从不被封。
Storage Server 能代替 CDN 吗?
不能。CDN 把副本分布到多个节点,并直接分发给访客。Storage Server 是单个机房里的一个存放点,访问都需要登录。两者是互补的:原件放在存储上,对外分发的版本走 Web 服务器或 CDN。
可以建多少个子账户?
最多 100 个,每个套餐都一样。每个子账户有自己的起始目录、自己的密码和自己的协议开关。这样网站拿到一个只能用 SFTP、也只看得见自己目录的账户,备份则另有一个。
可以给某个子账户单独分配空间吗?
不行,没有按子账户设置的配额。子账户出不了自己的目录,但在那里面可以把整个套餐的空间占满。想限制单个用户的,必须在自己的应用里做。
访问速度怎么样?
整块传输的大文件非常好,瓶颈在您 Web 服务器的网络接入。而很多小文件一个接一个访问时,每个文件都要再加上一次网络往返的时间。所以原件和归档该放到存储上,而缩略图这类频繁加载的小东西要放进 Web 服务器上的缓存里。
凭据会在浏览器里暴露吗?
只有在做法不对的时候才会。正确的做法是由 Web 服务器建立连接并把文件转发出去。这样凭据就留在服务器上,既不会出现在源代码里,也不会出现在地址里。
也可以用它来备份我的网站吗?
可以,而且这是最简单的入门方式。用 rsync 或 BorgBackup 只传输变化的部分,再加上存储自己的快照作为第二层。按套餐不同可做 10 到 40 个快照,另有同样数量的自动快照。
这需要一台自己的服务器吗?
不需要。从共享主机上也能用,走 WebDAV 或者从 PHP 里走 SFTP。只有把存储挂载成驱动器才需要 root 权限,也就需要一台自己的服务器。
这要花多少钱?
1 TB 的 Storage-1 每月 9.99 欧元,5 TB 的 Storage-2 是 29.99,10 TB 的 Storage-3 是 39.99,20 TB 的 Storage-4 是 69.99。无安装费,按预付方式结算,无最短合约期,机房在德国。

Storage Server Webserver WebDAV SFTP Mediendateien Downloads Backup