wolnosciowiec/wolnosciowiec-image-repository

文件存储服务,专为超低成本共享主机构建,对性能无影响

安装: 31

依赖: 0

建议: 0

安全性: 0

星标: 25

关注者: 8

分支: 4

语言:Go

类型:项目


README

通知:遗憾的是,我们再也没有维护备份存储生态系统的电力了,因为它变得相当庞大,我们也不是全职的雇员开发团队。请随意维护一个分支。

Coverage Status Test Artifact Hub

原生云,零知识,多租户,合规性严格,安全优先的备份存储,占用最小空间。

TLDR;为端到端GPG加密文件提供原始备份存储,支持多用户、配额、版本控制,使用对象存储(S3/Min.io/GCS等)并在Kubernetes或独立部署。不包含任何花哨功能,尽可能轻量级和稳定,这是项目目标。

本地支持

  • Kubernetes(但不要求)
  • GPG端到端加密
  • 通过GitOps(配置即代码)进行配置
  • 可配置配额的多租户
  • 后端存储支持多个云提供商(所有由GO Cloud支持)
  • (安全性)具有限制范围的JWT令牌(登录端点可以应用对用户会话的额外限制)
  • (安全性)具有不同限制的额外用户名和密码对 - 用于单个用户

注意

  • 项目更注重安全性而不是性能
  • 由于端到端特性,不支持增量备份。增量备份需要在客户端实现,并在服务器上存储一些加密元数据。将来可能会实现,但不是我们的首要任务。请随意发送Pull Request

技术堆栈

要求

  • Kubernetes(如果想要使用Kubernetes)
  • PostgreSQL
  • 小规模使用约128MB内存(注意我们使用Argon2di,并对缓冲区上的文件上传和计算进行操作
  • 存储提供商(S3、GCS、Min.io、本地文件系统或其他由https://gocloud.dev/howto/blob/#services支持的)

支持

  • 任何Kubernetes 1.20+
  • K3s
  • OpenShift(支持路由、非特权、非root容器)
  • PostgreSQL 11+
  • SealedSecrets
  • Min.io

与其他备份系统的区别

选择最佳工具取决于特定用例。在Kubernetes上最常见的方式是执行云原生卷快照,Velero项目是最知名的解决方案,它集成了云提供商如AWS、Google Cloud或Azure,并使用API调用来请求云提供商的快照。

备份存储方法使用应用程序本地和更传统的备份方法 - 使用tar、pg_dump、mysqldump和其他应用程序本地工具进行备份和还原。这种选择的方法有优点和缺点如下

优点

  • 可以备份数据的一部分,例如“PostgreSQL实例中的数据库X”
  • 数据安全控制:所有数据都使用GPG加密,存储层不知道存储了什么内容。您是否100%信任您的云服务提供商?
  • 不依赖公有云
  • 体积驱动程序无感知,即使在k3s上带有本地存储提供程序也能运行

缺点

  • 成功执行过程的责任(不仅仅是向提供商发出API调用)
  • 没有进行一致的块设备快照的可能性
  • 在非常大的规模上较慢且效率低下
  • 维护和监控执行备份的脚本

成熟度

注意: 该软件目前处于预生产阶段。我们不计划对功能进行重大更改,但API接口可能仍会发生变化。我们建议使用官方的Backup Maker客户端,该客户端将始终与API更改保持同步。

星标仓库,订阅发布以获取通知。

安全/合规性演示

我的备份是在特定时间创建的吗?

每个备份集合都有一个HTTP健康检查端点,您可以对其进行监控,并在预期备份未提交或无效时触发警报。

攻击者获得了我的Kubernetes集群,并想要覆盖远程备份

  • 最佳实践是限制版本提交的频率。攻击者需要非常有耐心才能用恶意备份覆盖您的旧备份。

攻击者从目标环境中获取了我的备份存储库凭据

  • 访问密钥功能允许为同一用户生成额外的用户名和密码对,但权限较少
  • 使用Backup Maker Operator,它会在备份之前实时注入JWT凭据。这些凭据仅限于一次性上传到单个集合
  • 您可以指定可以提交备份的IP地址范围(如果服务器可以从互联网访问)

攻击者想要上传一个TB大小的文件来产生云成本或耗尽磁盘空间

备份存储库在磁盘配额下运行。每个传入的字节流都会实时计算,并在达到限制时取消

我的备份存储库服务器的存储泄露了!

端到端备份加密使得您的备份对于没有您的GPG私钥的人不可读。

运行

应用程序是用GO编写的,作为单个二进制文件分发。推荐的方法是在Kubernetes集群的Docker镜像中运行。

独立运行

export AWS_ACCESS_KEY_ID=AKIAIOSFODNN7EXAMPLE
export AWS_SECRET_ACCESS_KEY=wJaFuCKtnFEMI/CApItaliSM/bPxRfiCYEXAMPLEKEY

backup-repository \
    --db-password=postgres \
    --db-user=postgres \
    --db-password=postgres \
    --db-name=postgres \
    --jwt-secret-key="secret key" \
    --storage-url="s3://mybucket?endpoint=localhost:9000&disableSSL=true&s3ForcePathStyle=true&region=eu-central-1"

通过Helm安装

helm repo add riotkit-org https://riotkit-org.github.io/helm-of-revolution/
helm install backups riotkit-org/backup-repository-server -n backup-repository # --values ...

文档

有关文档,请查阅./docs目录

注意:您可能正在阅读main分支的文档,请考虑选择分支/标签选择器中的版本化标签。

生态系统

  • Backup Maker:带有自动GPG加密支持的备份上传和下载。CLI客户端 + BMG(备份制作程序流程生成器),用于生成可定制的备份和恢复流程。
  • RKC:Space Harbor项目的一部分,包含Space Harbor K8s集群与备份存储库的CLI集成
  • PGBR:用于与BackupMaker一起使用的PostgreSQL辅助工具,用于使用转储和恢复的本地机制进行可靠的备份

Github社区中找到更多项目。

安全性

  • 用于身份验证的是JSON Web Token
  • 由于使用性质,令牌是长期有效的
  • 支持范围化的JSON Web Tokens(单个请求的令牌可以具有比用户配置文件中定义的权限更少的权限)
  • 用户可以拥有多个用户名和密码对,每个对都有额外的限制(例如,用户名 mycluster$collection1 -> 仅上传到collection1,用户名 mycluster$collection2 -> 仅上传到collection2)
  • 所有JWT都可以随时撤销。配置中存储了生成的令牌列表(仅sha256快捷方式)
  • 密码使用 argon2di 编码(2015年密码散列竞赛的获胜者,由OWASP推荐)
  • 所有对象都由RBAC(基于角色的访问控制)和ACL(访问控制列表)管理
  • 服务器在 uid=65532 下运行,非root容器
  • 有一个单独的ServiceAccount,使用命名空间范围的角色
  • 我们使用distroless镜像
  • 默认情况下,我们为Kubernetes中的kind: Pod设置了请求和限制
  • 内置简单的请求速率限制器,以防止应用侧的DoS攻击(注意:限制是按应用实例计算的。对于更高级的限制,请正确配置您的反向代理
  • 每个BackupUser可以选择性地限制只能从允许的IP地址连接
Argon2Config{
    time:    1,
    memory:  64 * 1024,
    threads: 4,
    keyLen:  32,
}

RBAC

类型为kind: BackupUser的对象(可以登录备份存储库服务器的用户)具有一组全局角色。全局角色授予对系统给定类型所有对象的访问权限。

如果某人的个人资料中有collectionManager,则在该人所有的收藏中都是管理员,这意味着浏览、删除、编辑、创建。

---
apiVersion: backups.riotkit.org/v1alpha1
kind: BackupUser
# ...
spec:
    # ...
    roles:
        - collectionManager

范围RBAC

大多数对象类型实现了accessControl,用于在对象范围内指定给定用户的权限。

---
apiVersion: backups.riotkit.org/v1alpha1
kind: BackupCollection
# ...
spec:
    # ...
    accessControl:
        - name: admin
          roles:
              - collectionManager

代码中的RBAC

域对象应该实现一种逻辑,检查给定的Actor是否可以在特定于该对象的上下文中执行。

func (u User) CanViewMyProfile(actor User) bool {
	// rbac
	if actor.GetRoles().HasRole(security.RoleUserManager) {
		return true
	}

	// user can view self info
	return u.Spec.Email == actor.Spec.Email
}

代码中的ACL

func (c Collection) CanUploadToMe(user *users.User) bool {
	if user.GetRoles().HasRole(security.RoleBackupUploader) {
		return true
	}

	for _, permitted := range c.Spec.AccessControl {
		if permitted.UserName == user.Metadata.Name && permitted.Roles.HasRole(security.RoleBackupUploader) {
			return true
		}
	}

	return false
}

备份窗口

最佳实践是限制版本提交的频率。攻击者需要非常有耐心才能用恶意备份覆盖您的旧备份。

在紧急情况下,系统管理员或具有uploadsAnytime角色的个人可以在备份窗口之间上传备份。小心!不要使用管理员账户或具有uploadsAnytime角色的账户设置自动备份。

---
apiVersion: backups.riotkit.org/v1alpha1
kind: BackupCollection
# ...
spec:
    # ...
    window:
        # allow to send backups only everyday starting from 00:30 to 01:30
        - from: "00 30 * * *"
          duration: 1h

配额

系统管理员可以创建一个具有指定单个文件、整个收藏夹存储限制的收藏,选择一个轮换策略。

概念很简单 - 在给定的收藏中可以存储X个版本的Y大小。

此外,还有所谓的额外空间,允许上传超过限制的文件,而不会中断备份流程。这种情况立即在收藏健康检查中作为警告报告。

---
apiVersion: backups.riotkit.org/v1alpha1
kind: BackupCollection
# ...
spec:
    # ...
    maxBackupsCount: 5
    maxOneVersionSize: 1M
    maxCollectionSize: 5M

额外空间

以下示例允许正常上传1MB大小的文件,但可选地允许上传更大的文件,这些文件总计可以额外占用5MB。例如,上传的版本之一可以是一个5MB的文件,或者可以有2个2.5MB的版本 - 都超过了maxOneVersionSize的软限制。而maxCollectionSize是硬限制。

maxBackupsCount = 5
maxOneVersionSize = 1MB
maxCollectionSize = 10MB

estimatedCollectionSize = maxBackupsCount * maxOneVersionSize = 5 * 1MB = 5MB
extraSpace = maxCollectionSize - estimatedCollectionSize = 10MB - 5MB
---
apiVersion: backups.riotkit.org/v1alpha1
kind: BackupCollection
# ...
spec:
    # ...
    maxBackupsCount: 5
    maxOneVersionSize: 1M
    maxCollectionSize: 10M

轮换

轮换策略提供对备份版本管理的控制。

fifo

先进先出。添加新版本时删除最旧的版本。

---
apiVersion: backups.riotkit.org/v1alpha1
kind: BackupCollection
# ...
spec:
    # ...
    strategyName: fifo

贡献

此软件使用GoLand(开源开发许可)进行开发。特别感谢支持。

安全策略