Files
minio-storage/SECURITY.md
Frank John Begornia c3c3e38f28 first commit
2026-01-06 09:41:27 +08:00

6.2 KiB

MinIO Security Guide

Console Access Security

Production Console Access Options

Don't expose console to internet at all. Access via SSH tunnel:

# From your local machine
ssh -L 9001:localhost:9001 user@your-server

# Then access: http://localhost:9001

Pros:

  • No public exposure
  • No additional authentication needed
  • Protected by SSH security

Cons:

  • Requires SSH access
  • Not convenient for multiple team members

Expose console via HTTPS with double authentication:

Setup Steps:

  1. Generate BasicAuth credentials:
# Install htpasswd (if not installed)
sudo apt-get install apache2-utils  # Ubuntu/Debian
# OR
brew install httpd  # macOS

# Generate password hash
htpasswd -nb admin YourStrongPassword123

# Output example:
# admin:$apr1$xyz123$abc...def
  1. Add to production .env:
# Double authentication: BasicAuth + MinIO login
TRAEFIK_CONSOLE_AUTH='admin:$$apr1$$xyz123$$abc...def'  # Note: $$ for docker-compose
  1. Update docker-compose.prod.yml (already done):
- "traefik.http.routers.minio-console.middlewares=minio-auth"
- "traefik.http.middlewares.minio-auth.basicauth.users=${TRAEFIK_CONSOLE_AUTH}"
  1. Access: https://console.crewsportswear.com
    • First: Browser BasicAuth prompt (admin/YourStrongPassword123)
    • Second: MinIO login (your MINIO_ROOT_USER/PASSWORD)

Pros:

  • Double authentication layer
  • Works from anywhere
  • Can share with team

Cons:

  • Console still publicly accessible (but protected)
  • Need to manage two sets of credentials

⚠️ Option 3: IP Whitelist (For Fixed IPs)

Add IP restriction to BasicAuth:

# In docker-compose.prod.yml labels
- "traefik.http.middlewares.minio-ipwhitelist.ipwhitelist.sourcerange=YOUR_IP/32,OFFICE_IP/32"
- "traefik.http.routers.minio-console.middlewares=minio-auth,minio-ipwhitelist"

Never do this in production:

  • Exposed to brute force attacks
  • Admin panel publicly accessible
  • Single point of failure if credentials leaked

S3 API Endpoint Security

The S3 API endpoint (minio.crewsportswear.com) should remain public for:

  • Application file uploads/downloads
  • Direct image access
  • S3 API operations

Why it's safe:

  • Requires valid access keys
  • Bucket policies control access
  • Can't browse/delete without credentials

Example public URL:

https://minio.crewsportswear.com/crewsportswear/images/product.jpg

Only publicly readable paths (like /images/) are accessible. Private uploads require auth.


Production Security Checklist

1. Strong Credentials

# Generate strong password
openssl rand -base64 32

# Update .env
MINIO_ROOT_USER=admin_$(date +%s)  # Unique username
MINIO_ROOT_PASSWORD=<generated_password>

2. Console Access

  • Use SSH tunnel OR
  • Enable Traefik BasicAuth
  • Consider IP whitelist
  • Never expose without protection

3. Bucket Policies

# Only make necessary paths public
mc anonymous set download crewminio/crewsportswear/images/

# Keep uploads private
mc anonymous set none crewminio/crewsportswear/uploads/

4. Application Access Keys

Create separate access keys per app (don't use root credentials):

# Access MinIO console → Administrator → Users → Create User
# Or via mc:
mc admin user add crewminio crewsportswear-app <password>
mc admin policy attach crewminio readwrite --user crewsportswear-app

Then use in app:

MINIO_KEY=crewsportswear-app
MINIO_SECRET=<password>

5. Network Segmentation

# Apps should access MinIO via internal network
MINIO_ENDPOINT=http://crew-minio:9000  # Internal
# Not: https://minio.crewsportswear.com (external)

6. HTTPS Only

environment:
  - MINIO_SERVER_URL=https://minio.crewsportswear.com  # Force HTTPS

7. Regular Backups

# Automated daily backup
mc mirror crewminio/ /var/backups/minio/$(date +%Y%m%d)/

8. Monitor Access Logs

# Enable audit logging
docker exec crew-minio-prod mc admin trace crewminio

For Solo Developer:

# Don't expose console publicly
# Remove console Traefik labels
# Access via SSH tunnel only

For Small Team (2-5 people):

# Use BasicAuth + MinIO login (double auth)
# IP whitelist to office/VPN
# Strong passwords (32+ chars)

For Larger Team:

# Use VPN (Tailscale/WireGuard) + internal console
# Separate access keys per app/user
# Audit logging enabled
# Regular security reviews

Quick Setup Commands

Secure Console (BasicAuth)

# 1. Generate password
htpasswd -nb admin $(openssl rand -base64 16)

# Output: admin:$apr1$xyz...
# Copy this to .env

# 2. Update .env
cat >> .env << EOF
TRAEFIK_CONSOLE_AUTH='admin:\$\$apr1\$\$xyz...'  # Escape $ with $$
EOF

# 3. Restart
docker-compose -f docker-compose.prod.yml up -d

SSH Tunnel (No Public Console)

# 1. Remove console Traefik labels from docker-compose.prod.yml
# 2. Don't expose port 9001
# 3. Access via SSH:
ssh -L 9001:localhost:9001 user@server
# Then: http://localhost:9001

Emergency: Credentials Compromised

# 1. Immediately change root password
docker exec crew-minio-prod mc admin user update crewminio minioadmin --password NewPassword123

# 2. Revoke leaked access keys
docker exec crew-minio-prod mc admin user disable crewminio leaked-user

# 3. Review access logs
docker exec crew-minio-prod mc admin trace crewminio

# 4. Rotate application keys
# Update all apps with new credentials

# 5. Check for unauthorized files
docker exec crew-minio-prod mc ls --recursive crewminio/

Summary

Access Method Security Level Use Case
SSH Tunnel Solo dev, maximum security
BasicAuth + IP Small team, fixed IPs
BasicAuth Only Remote team, can't use VPN
Public Console NEVER USE

Recommendation: Start with SSH tunnel. Add BasicAuth only if multiple people need access.