otterio

command module
v0.0.0-...-3d7f943 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 9, 2026 License: Apache-2.0 Imports: 3 Imported by: 0

README

OtterIO

S3-Compatible Object StorageStore freely. Scale endlessly.

License Go GitHub

English · 简体中文

OtterIO is a high-performance, S3-compatible object storage server. It is suitable for building infrastructure for machine learning, analytics, backup, and general application data workloads.

This README covers running OtterIO on bare metal, Docker, and from source. For deeper topics (erasure coding, distributed mode, KMS, replication, etc.) see the docs/ folder.

[!IMPORTANT] OtterIO is an independent, community-maintained fork of the upstream Apache-licensed MinIO codebase. It is not affiliated with, endorsed by, or sponsored by MinIO, Inc. See Trademark & Upstream Notice and the Security Advisory before deploying.


What is OtterIO

OtterIO is a customized fork of the last Apache License 2.0 release of MinIO (≈ RELEASE.2021-04-22T15-44-28Z). It differs from upstream in the following ways:

  • HTTP layer — request router built on gofiber/fiber/v3 instead of gorilla/mux.
  • Bucket notification targets — only elasticsearch, mysql, postgresql, redis, and webhook are supported. The message-queue targets (Kafka, NATS, NATS Streaming, NSQ, AMQP, MQTT) have been removed.
  • Gateways — only nas and s3 remain. The azure, gcs, and hdfs gateways have been removed.
  • Toolchain — requires Go 1.26 or newer (see go.mod).
  • Container images — published at soulteary/otterio (Docker Hub) and ghcr.io/soulteary/otterio (GitHub Container Registry).

OtterIO continues to be distributed under the Apache License, Version 2.0. All original copyright notices are retained — see NOTICE.


Quick Start

Run a single-node OtterIO instance with Docker:

docker run -p 9000:9000 -p 9001:9001 \
  -v /mnt/data:/data \
  soulteary/otterio:latest server /data --console-address ":9001"

Default root credentials are otterioadmin:otterioadmin. Once running, see Verify to connect via the web console or mc.

[!NOTE] Standalone OtterIO servers are best suited for development and evaluation. Production deployments should run distributed mode with Erasure Coding enabled — at least 4 drives per server. See docs/erasure/README.md and docs/distributed/README.md.


Installation

Docker

OtterIO publishes container images to both Docker Hub and the GitHub Container Registry:

# Docker Hub
docker pull soulteary/otterio:latest

# GitHub Container Registry
docker pull ghcr.io/soulteary/otterio:latest
Tag Description
latest Latest stable release.
edge Bleeding-edge build from main — for testing only.

Run a standalone server with an ephemeral volume:

docker run -p 9000:9000 soulteary/otterio:latest server /data

For persistent storage, map a host directory to /data:

docker run -p 9000:9000 -v /mnt/data:/data soulteary/otterio:latest server /data
macOS
brew install otterio/stable/otterio
otterio server /data

If you previously installed OtterIO from a different tap, reinstall from the official tap:

brew uninstall otterio
brew install otterio/stable/otterio
Binary

Pre-built macOS binaries are published on GitHub Releases. Download the appropriate archive, then:

chmod +x otterio
./otterio server /data
Linux

Pre-built Linux binaries are published on GitHub Releases. Download the asset that matches your architecture and run it as otterio:

chmod +x otterio
./otterio server /data

The release pipeline (.goreleaser.yml) currently produces Linux binaries for the following architectures:

Architecture goarch
64-bit Intel/AMD amd64
64-bit ARM arm64
64-bit PowerPC LE ppc64le

.deb and .rpm packages are also produced for the supported architectures.

Windows

Pre-built Windows binaries (amd64) are published on GitHub Releases. After downloading otterio.exe, run it from the directory where it lives, or add that directory to the system PATH:

otterio.exe server D:\
FreeBSD

OtterIO does not currently provide an official FreeBSD package. Build from source on FreeBSD using the Build from Source instructions below.

Build from Source

Source builds are intended for developers and advanced users. Make sure you have a working Go toolchain (Go 1.26 or newer — see How to install Go).

git clone https://github.com/soulteary/otterio.git
cd otterio
make build
./otterio server /data

[!WARNING] We strongly recommend against running compiled-from-source binaries in production. Use a tagged release for production deployments.


Configuration

Run S3 and Web Console on separate ports

By default the web console and the S3 API share the listener bound to --address. OtterIO can serve the web UI and admin API on a dedicated port so that reverse proxies, firewalls, and network policies can govern S3 traffic and console traffic independently.

Enable the dedicated console listener via the --console-address flag or the OTTERIO_BROWSER_ADDRESS environment variable:

# CLI flag
otterio server --address ":9000" --console-address ":9001" /data

# Environment variable (equivalent)
export OTTERIO_BROWSER_ADDRESS=":9001"
otterio server --address ":9000" /data

When the dedicated console listener is enabled:

  • :9000 only serves the S3 API, STS, health, and metrics. Browser requests are no longer redirected to the web UI.
  • :9001 serves the web console (/otterio/) and the admin API (/otterio/admin/v3/*).
  • The console port must differ from the S3 port; otherwise startup fails fast.
  • Ctrl+C / SIGTERM shuts down both listeners gracefully.

[!NOTE] The admin API (used by mc admin ...) is served from the console port in this mode. Configure your mc alias to point at the console URL when issuing admin commands. Regular S3 operations (mc cp, mc ls, etc.) continue to use the S3 port.

If --console-address is not provided, both surfaces share a single port (the original behaviour).

Dedicated TLS certificates for the console listener

When you split listeners, you can also point the console at its own TLS keypair so the S3 API and the web console can use different certificates (e.g. an internal CA-signed cert for :9000 and a public cert for :9001). Use --console-certs-dir or OTTERIO_BROWSER_CERTS_DIR:

otterio server \
  --address ":9000" \
  --console-address ":9001" \
  --certs-dir /etc/otterio/certs/s3 \
  --console-certs-dir /etc/otterio/certs/console \
  /data

The directory pointed to by --console-certs-dir must contain public.crt and private.key, the same layout used by --certs-dir. Notes:

  • --console-certs-dir requires --console-address; otherwise startup fails fast.
  • If --console-certs-dir is not set, the console listener reuses the certificates loaded from --certs-dir (the legacy behaviour).
  • The S3 listener always uses --certs-dir; only the console listener honours --console-certs-dir.
  • Both keypairs are watched and hot-reloaded by the same certificate manager used for --certs-dir.
Firewall

By default OtterIO listens on port 9000 for S3 traffic (and 9001 if the console listener is split out). Some platforms block these ports until you explicitly open them.

ufw (Debian / Ubuntu)
ufw allow 9000

# Range
ufw allow 9000:9010/tcp
firewall-cmd (CentOS / RHEL)
firewall-cmd --get-active-zones
firewall-cmd --zone=public --add-port=9000/tcp --permanent
firewall-cmd --reload

--permanent makes the rule persist across reboots and reloads.

iptables (RHEL, CentOS, etc.)
iptables -A INPUT -p tcp --dport 9000 -j ACCEPT
service iptables restart

# Range
iptables -A INPUT -p tcp --dport 9000:9010 -j ACCEPT
service iptables restart
Pre-existing data

When deployed on a single drive, OtterIO server lets clients access any pre-existing data in the data directory. For example, if OtterIO is started with otterio server /mnt/data, any pre-existing data in /mnt/data is accessible to clients. The same applies to all gateway backends.


Verify

Once OtterIO is running, the deployment uses default root credentials otterioadmin:otterioadmin (override via OTTERIO_ROOT_USER / OTTERIO_ROOT_PASSWORD environment variables in production).

Web console

Point a browser at http://127.0.0.1:9000 (or the console port if you split listeners). Log in with the root credentials to create buckets, upload objects, and browse contents.

mc client

mc is a modern command-line client that speaks S3 and local filesystem URIs (similar to ls, cp, mirror, diff, etc.). Configure an alias against your OtterIO endpoint:

mc alias set local http://127.0.0.1:9000 otterioadmin otterioadmin
mc mb local/test-bucket
mc cp ./somefile local/test-bucket/
mc ls local/test-bucket/

OtterIO is wire-compatible with the AWS S3 API, so aws-cli, s3cmd, and the various AWS SDKs all work out of the box — point them at your OtterIO endpoint with the root credentials (or an IAM-issued access key).


Further Reading

Project documentation (this repository)
Upstream references (third-party)

The links below point to the original upstream MinIO project's documentation. They remain useful as background reading on S3-compatible workflows, but they describe upstream MinIO behaviour and are not maintained by OtterIO:


Contributing

Contributions are welcome via the project repository at https://github.com/soulteary/otterio. For coding conventions inherited from the upstream baseline, see the original Contributor's Guide.


Security Advisory

Click to expand — please read before deploying.

Because OtterIO is forked from the last Apache 2.0 release of MinIO (≈ RELEASE.2021-04-22T15-44-28Z), every CVE / GHSA published against upstream minio/minio after that date must be evaluated and back-ported separately. OtterIO does not automatically inherit those fixes.

Backlog status (as of 2026-06): 14 closed, 2 not-applicable, 0 open. Every advisory currently triaged against the post-2021-04 baseline has been resolved on main — see docs/security/upstream-cve-backlog.md for the per-item table with the OtterIO codepath, the upstream reference, and the regression tests pinning each fix. New upstream advisories will be added with status Pending and tracked from there.

Operators upgrading from a previous OtterIO build that used LDAP should consult docs/security/ldap-dn-normalization-migration.md before rolling out: the new release canonicalises every LDAP DN before it touches the IAM policy map, which is a one-shot breaking change for deployments that happened to rely on case-only DN differences.

Before adopting OtterIO, please evaluate fitness against your own deployment context — workload profile, capacity / throughput targets, compliance and data-residency requirements, supported-version policy, and your organisation's change-management expectations. As with any infrastructure component, we recommend a staged rollout (lab → staging → production) and validating the relevant codepaths against your own regression suite. See SECURITY.md for the disclosure policy and the supported-versions matrix.

Hardening highlights

Relative to the 2021-04-22 Apache-licensed MinIO baseline OtterIO has back-ported and (where applicable) hardened the following upstream advisories — full per-item context, codepaths, and regression tests live in docs/security/upstream-cve-backlog.md:

  • SSE metadata injection (GHSA-3rh2-v3gr-35p9 class) — reserved-prefix metadata is rejected at both the router edge and extractMetadata.
  • Precondition GET / HEAD metadata disclosure (GHSA-95fr-cm4m-q5p9 / CVE-2024-36107) — s3:ExistingObjectTag/* and s3:RequestObjectTag/* are now first-class condition keys, and the precondition path re-runs auth before writing ETag / Last-Modified so a tag-gated deny no longer leaks object state.
  • SSE-KMS context binding (multiple post-2022 CVEs) — bucket / object AAD is reconstructed from the runtime (bucket, object) on every seal and unseal, hostile or tampered MetaContext blobs are rejected with a dedicated 403 sentinel before the KMS is ever called, and the seven legacy ErrNotImplemented PUT-handler stubs have been replaced with a single enforceSSEKMSRequest security gate covering single-PUT, multipart, copy and post-policy paths.
  • Service-account privilege escalationGHSA-jjjj-jwhf-8rgr (own-account create-SA bypass), the RELEASE.2025-10-15 sub-policy escalation, and GHSA-xx8w-mq23-29g4 / CVE-2024-24747 (admin:UpdateServiceAccount) are all closed; sub-policies must be a subset of the caller's capability.
  • AddUser PolicyName privilege escalation (CVE-2021-43858) — defence-in-depth at both the handler (HTTP 400) and IAM-layer (silent strip).
  • LDAP DN normalisation family (2022–2024 advisories) — RFC 4514 + RFC 4518 canonicalisation at every DN egress and at the IAM boundary, with a one-shot persisted-data migration; see the migration note linked above.
  • Bucket / IAM policy parsingPrincipal / Resource / Action unmarshal panics fixed, attacker-controlled input no longer reflected into error messages, fuzz corpus added.
  • SigV4 signed-headers and chunked-upload hardening — empty X-Amz-Content-Sha256 is treated as "not provided" instead of coercing the canonicaliser, SignedHeaders is case-folded, and aws-chunked uploads must sign x-amz-decoded-content-length.
  • Replication-header IAM gate — fork-private X-Otterio-Source-* headers now require the s3:ReplicateObject action via enforceSourceHeaderIAM, closing a forge path that could rewrite object mtime / ETag or force delete-markers under ordinary s3:PutObject / s3:DeleteObject permissions.
  • CVE-2023-28432 bootstrap info disclosureVerifyHandler is now gated on the same inter-node JWT validator used by peer-rest / storage-rest / lock-rest; only HealthHandler remains anonymous.
  • Multi-value Host header smuggle (fork-introduced concern) — audited and pinned: both fasthttp and net/http collapse or reject duplicate Host headers before any handler runs, and SigV4 reads only the scalar r.Host, so the two-header smuggle is not constructible.

Two further upstream advisories (CVE-2021-41137 regular-user policy bypass and GHSA-cwq8-g58r-32hg ImportIAM privilege escalation) are not applicable to the 2021-04 baseline — see the backlog for the audit trail and the negative-pinning regression tests.


Trademark & Upstream Notice

Click to expand

OtterIO is an independent, community-maintained fork of the upstream Apache-licensed MinIO codebase. This project is not affiliated with, endorsed by, or sponsored by MinIO, Inc.

"MinIO" is a trademark of MinIO, Inc., used here solely to identify the upstream project from which this fork is derived. No trademark rights are granted by the Apache License 2.0 (see Section 6 of the license).

OtterIO is based on the last Apache License 2.0 release of MinIO, prior to MinIO's relicensing to the GNU AGPLv3, and remains distributed under the Apache License, Version 2.0. The original copyright notices of MinIO, Inc. and all third-party subcomponents are retained — see NOTICE.

OtterIO publishes its own container images at soulteary/otterio (Docker Hub) and ghcr.io/soulteary/otterio (GitHub Container Registry). Other links in this guide pointing to docs.min.io, dl.min.io, etc. still refer to the original upstream project, not to OtterIO. Build OtterIO from source (see Build from Source) to use the OtterIO customizations.

Project home: https://github.com/soulteary/otterio


License

OtterIO logo

OtterIO is governed by the Apache License, Version 2.0, found at LICENSE. Attribution and third-party notices are listed in NOTICE.

"MinIO" is a trademark of MinIO, Inc. OtterIO is not affiliated with, endorsed by, or sponsored by MinIO, Inc.

Documentation

The Go Gopher

There is no documentation for this package.

Directories

Path Synopsis
cmd
Package cmd This file implements helper functions to validate AWS Signature Version '4' authorization header.
Package cmd This file implements helper functions to validate AWS Signature Version '4' authorization header.
config/identity/ldap
Package ldap provides DN normalization in addition to the legacy LDAP configuration helpers defined alongside this file.
Package ldap provides DN normalization in addition to the legacy LDAP configuration helpers defined alongside this file.
crypto
Package crypto implements AWS S3 related cryptographic building blocks for implementing Server-Side-Encryption (SSE-S3) and Server-Side-Encryption with customer provided keys (SSE-C).
Package crypto implements AWS S3 related cryptographic building blocks for implementing Server-Side-Encryption (SSE-S3) and Server-Side-Encryption with customer provided keys (SSE-C).
jwt
docs
pkg
argon2
Package argon2 implements the key derivation function Argon2.
Package argon2 implements the key derivation function Argon2.
cgroup
Package cgroup implements parsing for all the cgroup categories and functionality in a simple way.
Package cgroup implements parsing for all the cgroup categories and functionality in a simple way.
console
Package console implements console printing helpers
Package console implements console printing helpers
csvparser
Package csv reads and writes comma-separated values (CSV) files.
Package csv reads and writes comma-separated values (CSV) files.
env
etag
Package etag provides an implementation of S3 ETags.
Package etag provides an implementation of S3 ETags.
fips
Package fips provides functionality to configure cryptographic implementations compliant with FIPS 140.
Package fips provides functionality to configure cryptographic implementations compliant with FIPS 140.
ioutil
Package ioutil implements some I/O utility functions which are not covered by the standard library.
Package ioutil implements some I/O utility functions which are not covered by the standard library.
kms
licverifier
Package licverifier implements a simple library to verify OtterIO Subnet license keys.
Package licverifier implements a simple library to verify OtterIO Subnet license keys.
lock
Package lock - implements filesystem locking wrappers around an open file descriptor.
Package lock - implements filesystem locking wrappers around an open file descriptor.
madmin/examples command
mimedb
Package mimedb is a database of file extension to mime content-type.
Package mimedb is a database of file extension to mime content-type.
mimedb/util command
net
rpc
sys
trie
Package trie implements a simple trie tree for otterio server/tools borrows idea from - https://godoc.org/golang.org/x/text/internal/triegen.
Package trie implements a simple trie tree for otterio server/tools borrows idea from - https://godoc.org/golang.org/x/text/internal/triegen.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL