Minio Single Node Installation

Vorwort

Die hier gezeigte Anleitung ist rudimentär und kann nicht den kompletten Funktionsumfang von Minio abdecken.
Ich werde nach und nach weitere Beispiele hinzufügen, gerade im Hinblick auf Policies für Backups, oder Bereitstellung statischer Dateien / Webseiten.

Hinweis

Docker / Compose solle bereits installiert sein! Zusätzlich wird in dieser Anleitung der Traffic durch einen Nginx geleitet, dies ist aber kein muss.
Wird Minio direkt erreichbar gemacht werden (ohne Proxy davor), sollte die Transport-Verschlüsselung von Minio bereitgestellt werden. Hierfür muss Minio Zertifikate mitgeteilt bekommen (nicht Bestandteil der Anleitung)

Docker Compose

Der Pfad /mnt/data/minio/data muss noch den lokalen Gegebenheiten angepasst werden!

version: "3"
services:
  minio:
    user: "1000:1000"
    image: quay.io/minio/minio
    container_name: minio
    environment:
      MINIO_ROOT_USER_FILE: "/run/secrets/minio_root_user"
      MINIO_ROOT_PASSWORD_FILE: "/run/secrets/minio_root_password"
    volumes:
    - /mnt/data/minio/data:/data
    restart: unless-stopped
    command: "server /data --console-address :9001"
    secrets:
    - minio_root_user
    - minio_root_password
    networks:
      default:
        ipv4_address: 172.55.1.2
    # optionales Port Forwarding, FALLS kein Firewall Forwarding konfiguriert werden soll
    ports:
    - 9001:9001
    - 9000:9000

networks:
  default:
    driver: bridge
    ipam:
      driver: default
      config:
        - subnet: 172.55.1.0/24
    driver_opts:
      com.docker.network.bridge.name: br_minio

secrets:
   minio_root_user:
     file: ./secrets/minio_root_user
   minio_root_password:
     file: ./secrets/minio_root_password

Nun werden die Secrets in Dateien abgelegt, das Passwort sollte angepasst werden und sicher sein!

USERNAME=minio
PASSWORD=$(pwgen -s 32 1)

mkdir -p secrets
cat - > secrets/minio_root_user <<EOF
${USERNAME}
EOF

cat - > secrets/minio_root_password <<EOF
${PASSWORD}
EOF

Nginx Konfiguration

Die offizielle Dokumentation ist an manchen stellen etwas wild und nach verschiedenen Loginproblemen habe ich für mich entschieden, die Konfiguration etwas abweichend vom Standard vorzunehmen. Die Dokumentation schlägt vor, eine pfadbasierte Unterscheidung zwischen S3 und Minio Admin Panel zu konfigurieren.
Dies hat bei mir und vielen anderen Benutzern auch nicht geklappt und sorgte für Probleme, weshalb ich 2 vhosts in nginx konfiguriere:

Hinweis

Die unten stehenden Snippets können nicht ohne Anpassung vorgenommen werden!
Es fehlen Einstellungen wie listen, SSL Zertifikat, Logs und andere sicherheitsrelevante Einstellungen.
Einfaches kopieren wäre copy&waste…

S3 vhost
server {
  server_name s3.domain.com

  #######################
  # listen, ssl, logs, etc pp
  #######################

  # Allow special characters in headers
  ignore_invalid_headers off;

  # Allow any size file to be uploaded.
  # Set to a value such as 1000m; to restrict file size to a specific value
  client_max_body_size 0;

  # Disable buffering
  proxy_buffering off;
  proxy_request_buffering off;

  # bestimmte IPs zulassen
  # allow   192.168.201.1;
  # deny all;

  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;

    # Default is HTTP/1, keepalive is only enabled in HTTP/1.1
    proxy_http_version 1.1;
    proxy_set_header Connection "";
    chunked_transfer_encoding off;

    proxy_pass http://172.55.1.2:9000; # This uses the upstream directive definition to load balance
  }
}
Minio Admin Panel
server {
  server_name         minio.domain.com

  #######################
  # listen, ssl, logs, etc pp
  #######################

  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_set_header X-NginX-Proxy          true;

    # This is necessary to pass the correct IP to be hashed
    real_ip_header X-Real-IP;

    proxy_connect_timeout 300;

    # To support websocket
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";

    chunked_transfer_encoding off;

    proxy_pass http://172.55.1.2:9001; # This uses the upstream directive definition to load balance
  }
}

Nach einem Nginx Reload / Restart kann Minio aufgerufen werden:

Policies

Vollzugriff auf Bucket-Namen wie Username

Hier kann der Benutzer nur auf Buckets zugreifen die wie sein Username lautet ${aws:username}.
Dieses Muster kann grundsätzlich auf verschiedene Weise genutzt werden, ist hier aber stark vereinfacht dargestellt:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "User",
            "Effect": "Allow",
            "Action": [
                "s3:*"
            ],
            "Resource": [
                "arn:aws:s3:::${aws:username}",
                "arn:aws:s3:::${aws:username}/*"
            ]
        }
    ]
}
Append Only (Restic)

Diese Regeln sorgen dafür, dass Restic (Backup Software) nur Daten anhängen und lesen darf.
Der Bucket muss dem Usernamen entsprechen:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "DeleteLocks",
            "Effect": "Allow",
            "Action": [
                "s3:DeleteObject"
            ],
            "Resource": [
                "arn:aws:s3:::${aws:username}/locks/*"
            ]
        },
        {
            "Sid": "AllowListings",
            "Effect": "Allow",
            "Action": [
                "s3:GetBucketLocation",
                "s3:ListBucket"
            ],
            "Resource": [
                "arn:aws:s3:::${aws:username}"
            ]
        },
        {
            "Sid": "User",
            "Effect": "Allow",
            "Action": [
                "s3:GetObject",
                "s3:PutObject"
            ],
            "Resource": [
                "arn:aws:s3:::${aws:username}/*"
            ]
        }
    ]
}