minio-init: add a public bucket with a put-only uploader
There was no way to share a file by link: both buckets are private and the bootstrap forces anonymous access off on every run. Add a bucket named public whose objects anyone can GET by key, with no anonymous listing or writes, and an optional user that may only put and delete there, so a leaked uploader key reads nothing and reaches no other bucket. Assisted-by: Claude:fable-5-2
This commit is contained in:
parent
d009d2c3d2
commit
10c620e796
4 changed files with 76 additions and 1 deletions
|
|
@ -38,11 +38,13 @@ jobs:
|
|||
BINGO_DB_PASSWORD: ${{ secrets.BINGO_DB_PASSWORD }}
|
||||
BINGO_S3_ACCESS_KEY: ${{ secrets.BINGO_S3_ACCESS_KEY }}
|
||||
BINGO_S3_SECRET_KEY: ${{ secrets.BINGO_S3_SECRET_KEY }}
|
||||
PUBLIC_S3_ACCESS_KEY: ${{ secrets.PUBLIC_S3_ACCESS_KEY }}
|
||||
PUBLIC_S3_SECRET_KEY: ${{ secrets.PUBLIC_S3_SECRET_KEY }}
|
||||
with:
|
||||
host: ${{ secrets.DEPLOY_IP }}
|
||||
username: ${{ secrets.DEPLOY_USER }}
|
||||
key: ${{ secrets.DEPLOY_SSH_KEY }}
|
||||
envs: POSTGRES_PASSWORD,MINIO_ROOT_USER,MINIO_ROOT_PASSWORD,ASXPIO_DB_PASSWORD,ASXPIO_S3_ACCESS_KEY,ASXPIO_S3_SECRET_KEY,BINGO_DB_PASSWORD,BINGO_S3_ACCESS_KEY,BINGO_S3_SECRET_KEY
|
||||
envs: POSTGRES_PASSWORD,MINIO_ROOT_USER,MINIO_ROOT_PASSWORD,ASXPIO_DB_PASSWORD,ASXPIO_S3_ACCESS_KEY,ASXPIO_S3_SECRET_KEY,BINGO_DB_PASSWORD,BINGO_S3_ACCESS_KEY,BINGO_S3_SECRET_KEY,PUBLIC_S3_ACCESS_KEY,PUBLIC_S3_SECRET_KEY
|
||||
script_stop: true
|
||||
script: |
|
||||
umask 077
|
||||
|
|
@ -57,6 +59,8 @@ jobs:
|
|||
BINGO_DB_PASSWORD=${BINGO_DB_PASSWORD}
|
||||
BINGO_S3_ACCESS_KEY=${BINGO_S3_ACCESS_KEY}
|
||||
BINGO_S3_SECRET_KEY=${BINGO_S3_SECRET_KEY}
|
||||
PUBLIC_S3_ACCESS_KEY=${PUBLIC_S3_ACCESS_KEY}
|
||||
PUBLIC_S3_SECRET_KEY=${PUBLIC_S3_SECRET_KEY}
|
||||
EOF
|
||||
chmod 600 /opt/storage/.env
|
||||
chmod +x /opt/storage/init/postgres-init.sh /opt/storage/init/minio-bootstrap.sh
|
||||
|
|
|
|||
16
SECRETS.md
16
SECRETS.md
|
|
@ -75,6 +75,22 @@ The same values go on the **datacenterbingo repo**.
|
|||
| `BINGO_S3_ACCESS_KEY` | 20-char alphanumeric. |
|
||||
| `BINGO_S3_SECRET_KEY` | 40-char alphanumeric. |
|
||||
|
||||
### Uploader for the `public` bucket
|
||||
|
||||
Objects in `public` are readable by anyone at `https://s3.asxp.io/public/<key>`
|
||||
(no anonymous listing). This user may only put and delete there. Optional:
|
||||
without the secrets the bucket exists and only root can upload.
|
||||
|
||||
| Secret | Value |
|
||||
|-------------------------|-----------------------|
|
||||
| `PUBLIC_S3_ACCESS_KEY` | 20-char alphanumeric. |
|
||||
| `PUBLIC_S3_SECRET_KEY` | 40-char alphanumeric. |
|
||||
|
||||
```sh
|
||||
aws --endpoint-url https://s3.asxp.io --profile asxp-public \
|
||||
s3 cp shot.png s3://public/shot.png
|
||||
```
|
||||
|
||||
The table grants need asxpio's migrations to have run. On a fresh install,
|
||||
deploy storage again after asxpio's first boot.
|
||||
|
||||
|
|
|
|||
|
|
@ -78,6 +78,8 @@ services:
|
|||
ASXPIO_S3_SECRET_KEY: ${ASXPIO_S3_SECRET_KEY}
|
||||
BINGO_S3_ACCESS_KEY: ${BINGO_S3_ACCESS_KEY}
|
||||
BINGO_S3_SECRET_KEY: ${BINGO_S3_SECRET_KEY}
|
||||
PUBLIC_S3_ACCESS_KEY: ${PUBLIC_S3_ACCESS_KEY}
|
||||
PUBLIC_S3_SECRET_KEY: ${PUBLIC_S3_SECRET_KEY}
|
||||
volumes:
|
||||
- ./init/minio-bootstrap.sh:/bootstrap.sh:ro
|
||||
entrypoint: ["/bin/sh", "/bootstrap.sh"]
|
||||
|
|
|
|||
|
|
@ -58,6 +58,48 @@ EOF
|
|||
|| mc admin policy update local "${name}" "/tmp/${name}.json"
|
||||
}
|
||||
|
||||
# World-readable by object key; no anonymous listing or writes.
|
||||
ensure_public_bucket() {
|
||||
bucket="$1"
|
||||
if ! mc ls "local/${bucket}" >/dev/null 2>&1; then
|
||||
mc mb "local/${bucket}"
|
||||
fi
|
||||
cat > "/tmp/${bucket}-anonymous.json" <<EOF
|
||||
{
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [
|
||||
{
|
||||
"Effect": "Allow",
|
||||
"Principal": {"AWS": ["*"]},
|
||||
"Action": ["s3:GetObject"],
|
||||
"Resource": ["arn:aws:s3:::${bucket}/*"]
|
||||
}
|
||||
]
|
||||
}
|
||||
EOF
|
||||
mc anonymous set-json "/tmp/${bucket}-anonymous.json" "local/${bucket}" >/dev/null
|
||||
}
|
||||
|
||||
# Put and delete only: the holder can publish and retract, not read or list.
|
||||
write_upload_policy() {
|
||||
name="$1"
|
||||
bucket="$2"
|
||||
cat > "/tmp/${name}.json" <<EOF
|
||||
{
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [
|
||||
{
|
||||
"Effect": "Allow",
|
||||
"Action": ["s3:PutObject", "s3:DeleteObject"],
|
||||
"Resource": ["arn:aws:s3:::${bucket}/*"]
|
||||
}
|
||||
]
|
||||
}
|
||||
EOF
|
||||
mc admin policy create local "${name}" "/tmp/${name}.json" 2>/dev/null \
|
||||
|| mc admin policy update local "${name}" "/tmp/${name}.json"
|
||||
}
|
||||
|
||||
# $3: one or more policy names, space-separated.
|
||||
ensure_user() {
|
||||
access="$1"
|
||||
|
|
@ -89,6 +131,17 @@ else
|
|||
echo "minio-init: BINGO_S3_* unset, skipping bingo user"
|
||||
fi
|
||||
|
||||
# Files shared by link: https://s3.asxp.io/public/<key>. Everything in this
|
||||
# bucket is readable by anyone who knows the key.
|
||||
ensure_public_bucket "public"
|
||||
write_upload_policy "public-upload" "public"
|
||||
|
||||
if [ -n "${PUBLIC_S3_ACCESS_KEY:-}" ] && [ -n "${PUBLIC_S3_SECRET_KEY:-}" ]; then
|
||||
ensure_user "${PUBLIC_S3_ACCESS_KEY}" "${PUBLIC_S3_SECRET_KEY}" "public-upload"
|
||||
else
|
||||
echo "minio-init: PUBLIC_S3_* unset, skipping public uploader"
|
||||
fi
|
||||
|
||||
# Leftover from before the photos had their own bucket.
|
||||
mc admin policy remove local "asxpio-invoices-bingo-ro" >/dev/null 2>&1 || true
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue