SSL/TLS for buckets

See what we're up to: Runway is here! 🚀

Public buckets with a custom domain and SSL #

Using our object storage for internals, is one thing — but using it for assets is another. Usually, you would want to access your files using a custom domain — e.g. https://test-storage.staging.planetary-quantum.com with TLS enabled. The following guide walks you through the setup of a bucket on our object storage with files that are accessible (readable) to the public.

In order to use this, your objects have to be created using `acl: public-read` or (**our recommendation**) you use a [add a bucket policy](/multi-node/s3-object-storage/policies/). Adding the `public-read` ACL or a policy implies that the objects are accessible to anyone. Be careful, when uploading backups or log files to the object storage, as anyone can download them when `public-read` is enabled.

For brevity, we will use the Minio Client (mc) to create a bucket and copy a file. Read on for installation and configuration.

Create a bucket #

$ mc mb pn-storage/test-storage.staging.planetary-quantum.com
Bucket created successfully `pn-storage/test-storage.staging.planetary-quantum.com`.

Setup DNS record #

Point the host to your cluster (via your DNS provider):

# zone: staging.planetary-quantum.com
test-storage   CNAME   IN  $endpoint.customer.planetary-quantum.net.
DNS changes can always take a bit of time.

Upload a file #

Explained, step by step:

  1. Create a file hello-world.txt (with contents, “Hallo Welt”)
  2. Copy the file to the object storage
  3. Use curl to access the file
$ echo "Hallo Welt" > ./hello-world.txt
$ mc cp \
  hello-world.txt \
  pn-storage/test-storage.staging.planetary-quantum.com/hello-world.txt
hello-world.txt:         11 B / 11 B  â–“â–“â–“â–“â–“â–“â–“â–“â–“â–“â–“â–“â–“â–“â–“â–“â–“â–“â–“â–“â–“â–“â–“â–“â–“â–“â–“â–“â–“â–“â–“â–“â–“â–“â–“â–“â–“â–“â–“â–“â–“â–“â–“â–“â–“â–“â–“â–“â–“â–“â–“â–“â–“â–“â–“â–“â–“â–“â–“â–“â–“â–“â–“â–“â–“â–“â–“â–“â–“â–“â–“â–“â–“â–“â–“â–“â–“â–“â–“â–“â–“â–“â–“â–“â–“â–“â–“â–“â–“  92 B/s 0s
$ curl \
  https://s3.storage.planetary-networks.de/test-storage.staging.planetary-quantum.com/hello-world.txt
Hallo Welt
For larger files, please add `--disable-multipart`, as this is currently not supported.
We recommend using bucket policies to manage the access to objects. If you don't want to do this, you can run `mc cp` with the parameter `--attr x-amz-acl=public-read` to set the ACL on an individual file.

Setup a proxy #

Since we made the file accessible, it’s time to serve it on our own domain. In order to achieve that you need a small nginx proxy, which runs on your cluster. Traefik will take care of the SSL/TLS and nginx can improve the performance by caching files.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
server {
  listen 80;
  server_name localhost;

  # To 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;

  # To disable buffering
  proxy_buffering off;

  location / {
    # Proxy headers
    proxy_redirect off;

    proxy_set_header Authorization     '';
    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 https://s3.storage.planetary-networks.de;
  }
}

Caching #

Optionally, add caching to the mix:

  • cache for 10 minutes
  • up to 500 MB
  • cache eviction is 60 minutes
http {
  proxy_cache_path   /tmp/ levels=1:2 keys_zone=object_storage_cache:10m max_size=500m
                    inactive=60m use_temp_path=off;

  // ...
  server {
    // ...
    location / {
      proxy_cache            object_storage_cache;
      proxy_hide_header      x-amz-id-2;
      proxy_hide_header      x-amz-request-id;
      proxy_hide_header      x-amz-meta-server-side-encryption;
      proxy_hide_header      x-amz-server-side-encryption;
      proxy_hide_header      Set-Cookie;
      proxy_ignore_headers   Set-Cookie;
      proxy_cache_revalidate on;
      proxy_intercept_errors on;
      proxy_cache_use_stale  error timeout updating http_500 http_502 http_503 http_504;
      proxy_cache_lock       on;
      proxy_cache_valid      200 304 60m;
      add_header             Cache-Control max-age=31536000;
      add_header             X-Cache-Status $upstream_cache_status;
      // ...
}

Done #

Deploy the proxy to your cluster, and verify it is working as expected:

$ curl https://test-storage.staging.planetary-quantum.com/hello-world.txt
Hallo Welt
To re-emphasize: This example works well and requires next to no changes/maintenance, because the bucket has a **DNS-style name: test-storage.staging.planetary-quantum.com**

Appendix #

A complete working example (which requires minimal changes) is available on Github: https://github.com/hostwithquantum/object-storage-proxy-stack

Advantages:

  • take advantage of our managed Traefik (with Let’s Encrypt)
  • deployment workflow using quantum-cli