如何在Ubuntu 24.04 VPS上自托管MinIO
在一台 Ubuntu 24.04 VPS 上构建 MinIO S3 服务,涵盖验证源码、systemd、mc、预签名 URL 和 restic。注意:Community Edition 预编译文件路径已返回 410 Gone。
MinIO 自托管对象存储能提供什么
MinIO 是支持 Amazon S3 API 的自托管对象存储。将 restic 或 S3 SDK 指向您自己的服务器,只需修改 endpoint 设置,即可完成日常对象读取、写入、列举和预签名链接操作。不过,兼容并不等同于完全一致。例如,MinIO 不实现 Amazon 的对象 ACL,其维护者也表示无意实现该功能。因此,依赖 ACL 行为的应用不能只更换 endpoint。本指南将在 Ubuntu 24.04 上构建单节点服务:使用经验证源码编译的二进制文件、专用系统用户、避免将 root 凭据写入 unit 文件的 systemd unit,以及供 restic 备份数据的 bucket。
S3(simple storage service)是 HTTP API,而不是文件系统。您可以使用 PUT 将对象按 key 写入 bucket,再使用 GET 获取对象。在标准 bucket 中,不支持部分写入,也不支持重命名。Amazon 的 S3 Express One Zone 目录 bucket 是例外,它们提供专用的追加和重命名调用。但这只适用于一种存储类别,本指南不依赖这些功能。备份工具偏好这种标准模型,因为对象要么完整到达,要么根本没有到达。
单个节点只保存一份数据副本。这就是您作出的取舍。您可以以 VPS 的成本获得一个由自己控制的 S3 endpoint,同时也要承担云服务商原本负责的全部工作,包括更换故障磁盘和修补服务器软件。接近本文末尾的章节会明确说明这种取舍在何时合理。
2026 年 10 月 MinIO 社区版的状态
在基于此构建之前,请先阅读本部分,因为近期情况已发生变化。2025 年 5 月,MinIO 移除了社区版 Web 控制台中的管理功能。浏览器中仅保留了对象浏览器,因此存储桶和访问密钥现在需使用 mc 命令行客户端进行管理。
2025 年晚些时候,MinIO 停止发布预编译的社区版二进制文件。项目 README 指出社区版仅以源代码形式分发,且自 2026 年 4 月起,minio/minio 仓库已被归档,并附带 THIS REPOSITORY IS NO LONGER MAINTAINED 通知。旧的下载服务器也已停止提供社区版文件。经 2026 年 10 月 20 日核实,本指南曾用于下载服务器二进制文件、客户端二进制文件及其校验和文件的每个 dl.min.io 路径,现在均返回 410 Gone,这属于刻意移除而非服务中断。该服务器上唯一保留的 mc 二进制文件是位于 /aistor/mc/release/ 下的 AIStor Client,它属于商业产品线。min.io 上的下载页面现在列出了 AIStor Server、AIStor Client、AIStor SDK 以及一些 AIStor 插件,此外还有一个面向开发者、研究人员和运行独立部署的小型组织的免费 AIStor 层级,不再提供社区构建版本。
源代码依然存在,且比最后一个二进制版本更新。最终的社区版本是 RELEASE.2025-10-15T17-29-55Z,于 2025 年 10 月 16 日作为安全版本发布:它修复了服务账户和 STS 中通过会话策略绕过导致的权限提升漏洞,发布说明建议所有用户立即升级。最后一个预编译二进制文件是 2025 年 9 月的版本,因此它从未获得该修复。本指南将编译 10 月份的版本,由于仓库已被归档,这也将是社区版获得的最后一个修复。
这一事实决定了本指南后续的内容。这就是为什么此处的 MinIO 监听 127.0.0.1,并且仅通过您控制的代理访问互联网的原因。
安装 MinIO 二进制文件并验证下载
MinIO 使用 Go 语言编写。根据厂商 README,构建该程序只需一条 go install 命令,但要求 Go 1.24 或更高版本。请先从官方 tarball 安装 Go。截至 2026 年 10 月 20 日,go.dev/dl 上的当前稳定版本为 go1.27.3,该版本于 2026 年 10 月 19 日发布,修复了 crypto/x509 包的一个安全漏洞。下方哈希值是该页面为 linux-amd64 归档文件发布的哈希。若您选择更新的 Go 版本,请从同一页面获取其哈希值。-f 标志可确保 curl 在遇到 HTTP 错误时直接失败,而不是将错误页面保存为您指定的文件名;否则,用户最终会解压出一个 404 页面,并困惑为何它不是归档文件。
cd /tmp
GOVER=go1.27.3
curl -fsSL "https://go.dev/dl/$GOVER.linux-amd64.tar.gz" -o go.tar.gz比较这两个哈希值,且仅比较哈希值。
published=65efbc80fdc1fa2cd2631cad5b481777a68e8725f34e89f50fc6ac714e379b40
downloaded=$(sha256sum go.tar.gz | awk '{print $1}')
[ "$published" = "$downloaded" ] && echo "checksum ok"请明确此检查的意义。哈希匹配仅证明下载完整,且在传输过程中未损坏或被篡改。它不能证明厂商是可信的。这是另一个层面的问题,没有任何 sha256sum 命令可以解决。
sudo rm -rf /usr/local/go
sudo tar -C /usr/local -xzf go.tar.gz
export PATH=$PATH:/usr/local/go/bin
go version现在以普通用户身份构建最终的社区版本。go install 会将下载的每个模块(包括 MinIO 自身的源代码)与 sum.golang.org 上的 Go 公共校验和数据库进行比对。因此,如果模块被篡改或替换,构建过程会因安全错误而停止,不会生成二进制文件。
go install github.com/minio/minio@RELEASE.2025-10-15T17-29-55Z
sudo install -o root -g root -m 755 ~/go/bin/minio /usr/local/bin/minio
minio --version
go version -m /usr/local/bin/minio | head -n 3minio --version 会输出 DEVELOPMENT.GOGET,而不是版本名称,因为 go install 没有应用厂商用于标记其二进制文件的构建标志。go version -m 会读取 Go 嵌入在每个二进制文件中的模块信息,其 mod github.com/minio/minio 行显示了您构建时所用的提交记录。如果此处显示 Permission denied,说明模式错误;如果显示 command not found,说明 /usr/local/bin 不在您的 PATH 中。如果 VPS 内存不足以进行编译,请在另一台相同架构的 Linux 机器上运行相同的 go install,然后将生成的二进制文件复制过来。
创建系统用户和数据目录
MinIO 接受来自网络的上传请求,因此不应以 root 身份运行。为它创建一个没有主目录且没有登录 shell 的账户。
sudo groupadd -r minio-user
sudo useradd -M -r -g minio-user -s /usr/sbin/nologin minio-user
sudo mkdir -p /var/lib/minio/data
sudo chown -R minio-user:minio-user /var/lib/minio
sudo chmod 750 /var/lib/minio-r 创建 UID 小于 1000 的系统账户,使其不在普通用户使用的范围内。-M 不创建主目录,因为从不登录的账户无需保存文件。使用 id minio-user 检查结果,并使用 stat -c '%U %a' /var/lib/minio 检查;后者应输出 minio-user 750。
数据目录必须允许该用户写入,而不仅是读取。MinIO 首次启动时会在卷中创建 .minio.sys 目录,用于保存自身的配置。因此,如果目录归 root 所有,MinIO 会在启动期间退出,并显示以 permission denied 结尾的消息。以这种方式运行的每项服务都适用同一规则;VPS 上的最小权限服务用户对此有详细说明。
将 root 凭据放入环境文件
root 凭据可以访问每个存储桶,因此不应放在所有用户都可读的单元文件中。先以正确的模式创建文件,再写入内容。这样即使在极短时间内,密码也不会存在于可读文件中。
sudo install -o root -g root -m 600 /dev/null /etc/default/minio
printf 'MINIO_ROOT_USER=minio-root\nMINIO_ROOT_PASSWORD=%s\nMINIO_VOLUMES="/var/lib/minio/data"\nMINIO_OPTS="--address 127.0.0.1:9000 --console-address 127.0.0.1:9001"\n' "$(openssl rand -base64 24)" | sudo tee /etc/default/minio > /dev/null
sudo sed -n 's/^MINIO_ROOT_PASSWORD=//p' /etc/default/miniotee 会截断现有文件,而不是重新创建文件,因此文件模式保持为 600,所有者保持为 root。这是有意为之的。systemd 会在降权为 User= 之前以 root 身份读取 EnvironmentFile,因此服务账户无需读取自己的凭据。服务运行后,使用 sudo -u minio-user cat /etc/default/minio 验证。该命令必须输出 Permission denied。
启动 MinIO 前,需要了解它的两个行为。在环境中既没有 MINIO_ROOT_USER,也没有 MINIO_ROOT_PASSWORD 时,MinIO 不会拒绝启动。它会使用文档中所述的默认凭据 minioadmin:minioadmin 启动。这是扫描器首先尝试的凭据对,MinIO 在使用它们时看起来完全正常。密码少于 8 个字符时则会被拒绝:MinIO 会在启动时退出,并报告凭据无效,因为访问密钥至少需要 3 个字符,密钥至少需要 8 个字符。
MINIO_VOLUMES 是数据路径,MINIO_OPTS 保存选项。绑定到 127.0.0.1 意味着此 VPS 外部的任何设备都无法访问 S3 API,这是正确的默认设置。稍后通过持有证书的代理按需开放访问。
编写 systemd 单元
创建 /etc/systemd/system/minio.service:
[Unit]
Description=MinIO object storage
Documentation=https://github.com/minio/minio
Wants=network-online.target
After=network-online.target
[Service]
User=minio-user
Group=minio-user
EnvironmentFile=/etc/default/minio
ExecStart=/usr/local/bin/minio server $MINIO_VOLUMES $MINIO_OPTS
Restart=always
RestartSec=5
LimitNOFILE=65536
NoNewPrivileges=true
[Install]
WantedBy=multi-user.targetEnvironmentFile 前没有前导 -,这是有意的,不是拼写错误。使用连字符时,systemd 会忽略缺失的文件,并继续启动 MinIO。因此,文件被删除或路径拼写错误时,系统会悄然启动一个使用 minioadmin:minioadmin 的服务器。不使用连字符时,缺失文件会在 MinIO 运行前使单元启动失败,journalctl -u minio 会显示 Failed to load environment files: No such file or directory。拒绝启动的单元比悄然接受默认密码的服务器更容易被发现。
$MINIO_VOLUMES 和 $MINIO_OPTS 有意不加引号,因为 systemd 会将未加引号的变量按空白字符拆分为独立参数。这样,MINIO_OPTS 中的四个单词会成为传递给 minio server 的四个参数。LimitNOFILE=65536 会提高文件描述符限制,因为每个打开的连接和每个打开的数据文件都会占用一个描述符,而默认值 1024 在高负载下会耗尽。
sudo systemctl daemon-reload
sudo systemctl enable --now minio
systemctl is-active minio
curl -fsS -o /dev/null -w '%{http_code}\n' http://127.0.0.1:9000/minio/health/liveis-active 应输出 active,健康检查端点应返回 200。journalctl -u minio -n 20 --no-pager 会显示服务器正在监听的 API 地址。如果单元持续重启,systemd 会放弃并记录 Start request repeated too quickly。这表示 MinIO 每次尝试都会退出。原因会显示在该消息上方的几行中,因此请向上查看。
如需进一步隔离,请将 ProtectSystem=full 和 ProtectHome=true 添加到 [Service] 部分。这两项都需要主机内核提供挂载命名空间。在共享主机内核的容器虚拟化环境中,例如 OpenVZ 或 LXC,它们可能会失败,此时单元会报告 status=226/NAMESPACE。删除这两行后,单元即可启动。该单元本身是普通单元,VPS 上的 systemd 服务和计时器介绍了其余指令。
安装 mc 并验证往返通信
MinIO 客户端是 mc。请勿使用 apt install mc 安装。该软件包是 Midnight Commander,一个与 MinIO 无关的文件管理器。
dl.min.io 仍然提供 mc 二进制文件,但不再是社区版本。旧的社区路径 https://dl.min.io/client/mc/release/linux-amd64/mc 现在返回 410 Gone。MinIO 目前在该路径下提供的是 https://dl.min.io/aistor/mc/release/linux-amd64/mc 处的 AIStor Client,其 AIStor CLI 参考文档指出该工具仅具备授权 AIStor Server 部署的专属功能。该参考文档未提及将其用于社区版服务器,因此本指南继续使用社区版客户端。minio/mc 仓库已于 2026 年 7 月归档,因此请使用相同的 Go 工具链构建其最后一个版本 RELEASE.2025-08-13T08-35-41Z。校验和数据库也涵盖了此下载内容。
go install github.com/minio/mc@RELEASE.2025-08-13T08-35-41Z
sudo install -o root -g root -m 755 ~/go/bin/mc /usr/local/bin/mc将服务器注册为别名,然后通过它传输一个对象。
MINIO_PASS=$(sudo sed -n 's/^MINIO_ROOT_PASSWORD=//p' /etc/default/minio)
mc alias set local http://127.0.0.1:9000 minio-root "$MINIO_PASS"
mc mb local/backups
echo "hello object storage" > /tmp/hello.txt
mc cp /tmp/hello.txt local/backups/hello.txt
mc ls local/backups
mc cat local/backups/hello.txtmc ls 应列出 hello.txt 及其大小,mc cat 应输出 hello object storage。这次往返通信是服务器正常工作的确凿证据,因为它执行了与其他所有客户端相同的签名 S3 请求。如果您需要二次确认,mc admin info local 可以打印服务器状态。
现在,趁存储桶还是空的,再执行一次检查。
mc alias set defaultcheck http://127.0.0.1:9000 minioadmin minioadmin此命令必须失败。如果它成功了,说明环境变量文件未传递给进程,且您的服务器正在使用默认凭据运行。在任何其他操作接触该机器之前,请务必修复此问题。
mc 以明文形式将别名存储在 ~/.mc/config.json 中,因此这些凭据会保存在执行该命令的用户的主目录下。在 sudo 下运行 mc 会将 root 凭据放入 /root/.mc/config.json。请将 root 别名保留在一个管理员账户中,并为每个应用程序分配其专属密钥。
使用预签名 URL 分发单个对象
预签名 URL 是一个附带签名和有效期的普通 HTTPS 链接。持有该链接的任何人都可以获取这个对象,无需账户,也无需客户端。
mc share download --expire 12h local/backups/hello.txt输出会在查询字符串中包含 X-Amz-Signature 和 X-Amz-Expires。其中有两点容易让人意外。链接根据所用别名中的端点生成,因此在 127.0.0.1 上使用的别名会生成只能由本机打开的链接。对于计划发送的链接,应在公网主机名上创建另一个别名。其次,没有用于撤销单个链接的按钮。签名会一直有效,直到链接过期,或用于签名的密钥被删除或更改。对于使用 root 凭据签名的链接,这意味着轮换 root 凭据。因此,设置较短的有效期是实际可行的控制措施。S3 签名格式允许的最长有效期为 7 天。
为 restic 创建专用密钥和存储桶
root 凭据可以读取和删除所有存储桶,因此备份作业不能持有这些凭据。创建一个存储桶、一个仅限该存储桶的策略,以及一个不具备其他权限的用户。
mc mb local/restic
cat > /tmp/restic-rw.json <<'EOF'
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": ["s3:ListBucket", "s3:GetBucketLocation"],
"Resource": ["arn:aws:s3:::restic"]
},
{
"Effect": "Allow",
"Action": ["s3:GetObject", "s3:PutObject", "s3:DeleteObject"],
"Resource": ["arn:aws:s3:::restic/*"]
}
]
}
EOF
RESTIC_KEY=$(openssl rand -base64 24)
mc admin policy create local restic-rw /tmp/restic-rw.json
mc admin user add local restic-backup "$RESTIC_KEY"
mc admin policy attach local restic-rw --user restic-backupMinIO 提供内置的 readwrite 策略。使用它可以少执行一个命令,但它会授予对服务器上所有存储桶的完全访问权限。上面的策略有意将存储桶名称写了两次:一次写作 arn:aws:s3:::restic,用于列出存储桶;另一次写作 arn:aws:s3:::restic/*,用于访问其中的对象。在 S3 中,存储桶和其中的对象是不同的资源,因此策略只指定其中一个时会失败,而且错误表现得像客户端损坏。
在信任该限制之前先进行测试。
mc alias set resticuser http://127.0.0.1:9000 restic-backup "$RESTIC_KEY"
mc ls resticuser/restic
mc ls resticuser/backups第一个 ls 会成功,第二个会因 Access Denied 失败。未经测试的策略只是猜测。
现在让 restic 使用该存储桶。restic 从标准 AWS 环境变量读取 S3 凭据,因此不需要使用 restic 专用的凭据文件。
sudo apt install -y restic
export AWS_ACCESS_KEY_ID=restic-backup
export AWS_SECRET_ACCESS_KEY="$RESTIC_KEY"
restic -r s3:http://127.0.0.1:9000/restic init
restic -r s3:http://127.0.0.1:9000/restic backup /etc
restic -r s3:http://127.0.0.1:9000/restic snapshotsrestic init 会要求输入存储库密码。该密码会加密存储库,因此 MinIO 始终只保存密文;如果密码丢失,备份也会丢失。由 systemd 计时器启动的任务没有终端可供输入,因此应将 RESTIC_PASSWORD_FILE 设置为权限模式为 600 的文件,以便执行计划备份。
有一条部署规则比上面的任何命令都重要。将 restic 存储库放在与受保护数据相同的 VPS 上,只能避免糟糕的 rm,无法避免其他问题。MinIO 节点应位于另一台机器上,最好位于不同的区域。VPS 上的 restic 备份介绍了如何在此基础上配置计划任务和保留策略。
使用 nginx 终止 TLS
MinIO 运行在 localhost 上,因此 nginx 是对外提供服务的入口。先按 使用 certbot 和 nginx 配置 Let's Encrypt 证书 中的说明签发证书,然后使用以下 server 块。
server {
listen 443 ssl;
server_name s3.example.com;
ignore_invalid_headers off;
client_max_body_size 0;
proxy_buffering off;
proxy_request_buffering off;
location / {
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_connect_timeout 300;
proxy_http_version 1.1;
proxy_set_header Connection "";
chunked_transfer_encoding off;
proxy_pass http://127.0.0.1:9000;
}
}其中几行配置是必需的。client_max_body_size 0 会取消默认的 1 MB 请求体大小限制;否则,任何更大的上传都会在 MinIO 收到请求之前被 413 Request Entity Too Large 拒绝。proxy_request_buffering off 会直接转发上传内容,因为默认配置会先将整个请求写入临时文件,大型对象会因此占用两份磁盘空间。proxy_set_header Host $http_host 容易被忽略:S3 签名包含 Host 请求头,因此代理如果重写该请求头,每个请求都会因 SignatureDoesNotMatch 失败,即使访问日志显示请求已正常到达。
还要将 MinIO 的公开名称告知它,这样它生成的链接才会指向代理,而不是 localhost。
echo 'MINIO_SERVER_URL=https://s3.example.com' | sudo tee -a /etc/default/minio
sudo systemctl restart minio防火墙规则应保持精简。允许 SSH 和 HTTPS,不要为端口 9000 和 9001 添加任何规则,因为绑定到 127.0.0.1 的地址无论防火墙如何配置,都无法从其他机器访问。VPS 上的 ufw 防火墙基础包含相关命令。
何时使用单节点 MinIO,以及何时需要真正的 S3
此处的单节点指单盘部署,因此部署内部不存在奇偶校验或冗余副本,每个对象的持久性等同于单台 VPS 磁盘的持久性。MinIO 的官方文档自 2025 年 10 月社区托管文档下线后,仅以源码形式存在于 minio/docs 仓库中。该文档将独立部署模式描述为用于早期开发和评估,并指出 MinIO 不建议在生产环境中使用该模式。虽然可以为存储桶开启对象锁定(Object Locking),但在单台 VPS 上,这仅能阻止通过 S3 API 进行的删除操作。任何拥有该机器 root 权限的用户仍可直接删除磁盘上的文件,因此不要在此架构下向他人承诺不可篡改的保留策略。
该方案适合作为异地第二台 VPS 上的 restic 备份目标,也适合作为开发工作和 CI 构建产物的 S3 端点,因为丢失存储桶仅会导致重新构建,不会造成其他损失。对于小型应用的用户上传功能,只要你掌握恢复方案并已实际测试过恢复流程,该方案也是合理的。
当合同或监管机构要求对象锁定或多区域持久性时,或者当你不想成为凌晨 3 点因磁盘空间耗尽而被呼叫的人时,请选择托管式 S3。代码冻结是另一个客观原因。截至 2026 年 10 月 20 日,社区版已归档并不再维护,其最后一个版本 RELEASE.2025-10-15T17-29-55Z 即为本指南所编译的版本。此后的任何问题都不会得到修复,因此运行该版本意味着你需要接受这一现状,或者迁移至 MinIO 的商业版 AIStor 产品,亦或是其他自托管存储方案,相关对比可参考 自托管 MinIO 的替代方案。
有一个界限值得说明,因为它经常被提及。对象存储不是数据库。在标准存储桶中,每次写入都会替换整个对象,即使是亚马逊为 S3 Express One Zone 添加的追加(append)调用也仅能将数据添加到末尾,因此在 S3 存储桶上直接运行 SQL 文件既缓慢又不安全。请将数据库保留在本地磁盘上,并将其备份到存储桶中:在 VPS 上生产环境运行 SQLite 一文对此类分离架构进行了说明。
故障模式及对应消息
systemctl enable --now 后单元立即失败。 查看 journalctl -u minio -n 30 --no-pager。Failed to load environment files: No such file or directory 表示单元中缺少 /etc/default/minio,或其路径拼写错误。以 permission denied 结尾的消息表示服务账户无权写入数据目录,因此请检查 stat -c '%U' /var/lib/minio/data 是否输出 minio-user。
minioadmin:minioadmin 仍然可以登录。 环境文件从未传递给进程。确认单元包含 EnvironmentFile=/etc/default/minio,运行 sudo systemctl daemon-reload,然后重启服务。MinIO 只会在启动时读取一次根凭据,因此编辑该文件但不重启不会产生任何变化。
启动时出现 Address already in use。 其他进程占用了端口 9000。修改 MinIO 端口前,使用 sudo ss -ltnp | grep :9000 查找该进程。
通过代理上传超过 1 MB 的文件失败。 nginx 返回了 413 Request Entity Too Large,MinIO 从未收到该请求。在 server block 中设置 client_max_body_size 0。
SignatureDoesNotMatch。 密钥不正确,或者客户端与 MinIO 之间的某个组件重写了 Host 标头,而签名涵盖了该标头。
RequestTimeTooSkewed。 客户端或服务器的时钟不正确。每个经过签名的 S3 请求都包含时间戳。与 Amazon S3 一样,MinIO 会拒绝时间戳与自身时钟相差超过 15 分钟的标头签名请求。预签名链接则根据其过期时间进行检查。检查 timedatectl,并确认时间同步处于活动状态。
对确认存在的存储桶出现 Access Denied。 此密钥的作用域属于其他存储桶。使用 mc admin policy info local restic-rw 输出策略实际允许的内容,并比较资源行中的存储桶名称。
FAQ
单节点 MinIO 是否足以用于实际备份?
如果将其作为 restic 的备份目标,且运行在与受保护数据不同的机器上,它是可用的。但它不能作为唯一的备份副本。单盘部署不具备奇偶校验,MinIO 内部没有第二份副本;如果 VPS 磁盘发生数据丢失,对象将无法恢复。请在其他位置保留第二个备份目标,并至少进行一次恢复测试,以确保流程有效。
为什么 sha256sum -c 在校验 MinIO 的校验和文件时会失败?
你只会在较早保存的副本中遇到该文件,因为 dl.min.io 已在 2026 年 10 月 20 日对所有社区版二进制文件和校验和文件回答了 410 Gone。该文件内部哈希值后的标签标明了版本,例如 minio.RELEASE.2025-09-07T16-13-09Z,而下载的文件通常命名为 minio。sha256sum -c 会寻找校验和文件中记录名称的文件,由于找不到,它会报告 No such file or directory 和 WARNING: 1 listed file could not be read。下载本身没有问题。请直接比较哈希字符串并忽略该标签,因为它不具备安全含义。
MinIO 管理 Web 控制台去哪了?
MinIO 在 2025 年 5 月移除了社区版控制台中的管理功能,Web 界面仅保留了对象浏览器。存储桶和用户现在需使用 mc 客户端进行管理,使用如 mc admin user add 和 mc admin policy attach 等命令。这是社区版的预期使用方式,而非变通方案,这也是本指南全程使用命令行操作的原因。
如何将 restic 指向 MinIO 作为 S3 后端?
将 AWS_ACCESS_KEY_ID 和 AWS_SECRET_ACCESS_KEY 设置为 MinIO 的访问密钥(Access Key)及其密钥(Secret),然后使用格式为 s3:https://s3.example.com/restic 的存储库字符串,其中路径的最后一部分为存储桶名称。请先使用 mc mb 创建存储桶,因为仅限于单个存储桶权限的密钥没有创建存储桶的权限。restic 在上传前会使用其存储库密码加密所有内容,因此 MinIO 存储的是密文,无法查看你的文件。
我必须在 nginx 后运行 MinIO 吗?
当客户端不在同一台机器上时,你需要 TLS(传输层安全协议)。否则,每个对象都会以明文形式在网络上传输,访问密钥 ID 和请求签名也是如此。密钥本身不会离开客户端,因为 S3 签名仅在本地使用它来计算签名,但路径上的任何人仍可读取你的数据,并在时间戳有效期间重放捕获的请求。在 443 端口上使用带有 certbot 证书的代理是实现 TLS 最简单的方法,它将证书续期与 MinIO 分离开来。如果将 --certs-dir 指向存放 public.crt 和 private.key 的目录,MinIO 也可以自行终止 TLS,但这样服务账户需要读取已续期私钥的权限,这会增加额外工作量且结果相同。