Начало работы

Создание сервисного пользователя и настройка доступа

Для работы с S3 в Облачном хранилище в панели управления:

  1. Создайте отдельного пользователя.
  2. Назначьте созданному пользователю права на работу с нужными контейнерами согласно инструкции Создание и настройка контейнера. Чтобы дать пользователю полный доступ к необходимому контейнеру выберите значение Чтение и запись.
  3. Отметьте Использовать эти данные для доступа по протоколу S3.

Для работы в конфигурационном файле используйте логин и пароль созданного пользователя:

  • в качестве Access Key используется формат <Номер аккаунта>_<Имя пользователя>;
  • в качестве Secret Key используется пароль пользователя;
  • в качестве Region используется ru-1.

Администратор по умолчанию имеет доступ на чтение и запись к любому бакету. Доступ администратора через S3 API возможен только если отмечено «Использовать эти данные для доступа по протоколу S3» в панели управления в разделе Пользователи.

Бакет (bucket) — это логическая сущность, которая помогает организовать хранение объектов.

URL для доступа (endpoint_url):

https://s3.selcdn.ru

Аутентификация

Мы поддерживаем как AWS Signature V4, так и AWS Signature V2 для совместимости с более старыми версиями клиентов.

Все описанное ниже относится только к AWS Signature V4.

Для подтверждения личности запрашивающего все запросы должны иметь подпись, которую можно создать с помощью Access Key и Secret Key.

Вычисление подписи

Вычисление подписи состоит из трех шагов:

  1. Получение ключа подписи (SigningKey)
  2. Получение строки для подписи (StringToSign)
  3. Подпись строки с помощью ключа

Получение ключа для подписи (SigningKey)

Для получения подписывающего ключа понадобится Access Key и Secret Key. Подробнее о том, где их найти в разделе Создание сервисного пользователя и настройка доступа.

Для получения подписывающего ключа закодируйте с помощью алгоритма HMAC-SHA256 следующие данные:

DateKey = HMAC-SHA256("AWS4"+"<SecretKey>", "<YYYYMMDD>")
DateRegionKey = HMAC-SHA256(<DateKey>, "<aws-region>")
DateRegionServiceKey = HMAC-SHA256(<DateRegionKey>, "<aws-service>")
SigningKey = HMAC-SHA256(<DateRegionServiceKey>, "aws4_request")

Получение строки для подписи

Получение строки для подписи зависит от используемого метода аутентификации и описано в соответствующем разделе.

Мы поддерживаем три метода подписи запросов:

  1. Через HTTP-заголовок Authorization
  2. Используя query-параметры
  3. Используя HTTP POST запрос

Подпись строки с помощью ключа

Для создания подписи закодируйте строку подписи полученным ранее ключом и переведите результат в шестнадцатеричное представление.

signature = HMAC-SHA256(SigningKey, StringToSign)

Через HTTP-заголовок Authorization

Использование заголовка Authorization является наиболее частным методом аутентификации пользователя. Общий вид запроса:

Authorization: AWS4-HMAC-SHA256 
Credential=12345_USER/20180524/ru-1/s3/aws4_request, 
SignedHeaders=host;range;x-amz-date,
Signature=fe5f80f77d5fa3beca038a248ff027d0445342fe2855ddc963176630326f1024

Описание параметров запроса

Параметр Описание
AWS4-HMAC-SHA256 Подпись AWS версии 4 (AWS4) и алгоритм подписи (HMAC-SHA256)
Credential Содержит ключ доступа и информацию о запросе в формате: ${ACCESS_KEY}/${YYYYMMDD}/${REGION}/s3/aws4_request
SignedHeaders Список в нижнем регистре имен заголовков запроса, используемых при вычислении подписи
Signature Подписанный хэш, состоящий из хеша тела запроса, секретного ключа и информации о запросе (каноническом запросе)

Канонический запрос (Canonical Request)

Для того, чтобы получить строку для подписи необходимо сделать канонический запрос следующего вида:

<HTTPMethod>\n
<CanonicalURI>\n
<CanonicalQueryString>\n
<CanonicalHeaders>\n
<SignedHeaders>\n
<HashedPayload>

Где:

  • HTTPMethod — один из HTTP методов, например GET, PUT, HEAD и DELETE;
  • CanonicalURI — URI-кодированная часть адреса, которая начинается] после домена, с первым «/», например для https://s3.selcdn.ru/examplebucket/myphoto.jpg будет выглядеть следующим образом: /examplebucket/myphoto.jpg;
  • CanonicalQueryString — параметры строки запроса;
  • CanonicalHeaders — список заголовков и их значений, разделенных новой строкой, в нижнем регистре и без пробелов;
  • SignedHeaders — список имен заголовков без значений, отсортированных по алфавиту, в нижнем регистре и через точку с запятой. Например: host;x-amz-content-sha256;x-amz-date;
  • HashedPayload — хэш SHA256 тела запроса Hex(SHA256Hash()). В случае, если тела запроса нет, хэш необходимо посчитать от пустой строки Hex(SHA256Hash(“”)).

Получение строки для подписи

Строка для подписи представляет собой конкатенацию следующих строк:

"AWS4-HMAC-SHA256" + "\n" +
timeStampISO8601Format + "\n" +
<Scope> + "\n" +
Hex(SHA256Hash(<CanonicalRequest>))

Где:

  • AWS4-HMAC-SHA256 — данная строка определяет алгоритм шифрования, который вы используете;
  • timeStampISO8601Format — текущее UTC-время в ISO 8601 формате (например, 20130524T000000Z);
  • Scope — строка формата date.Format(<YYYYMMDD>) + "/" + <region> + "/" + <service> + "/aws4_request", например “20130606/ru-1/s3/aws4_request”, привязывает полученную подпись к определенной дате, региону или сервису. В случае привязки к дате, подпись будет действовать 15 минут.

Подробнее о способе аутентификации через Authorization заголовок читайте в официальной документации Amazon S3 API.

Используя query-параметры

Аутентификация через query-параметры используется как правило тогда, когда вы хотите указать все параметры запроса непосредственно в URL. Этот метод так же обозначается как подписанный URL (Presigned URL).

Пример подписанной URL:

https://s3.selcdn.ru/examplebucket/test.txt
?X-Amz-Algorithm=AWS4-HMAC-SHA256
&X-Amz-Credential=<your-access-key-id>%2F20130721%2Fru-1%2Fs3%2Faws4_request
&X-Amz-Date=20130721T201207Z
&X-Amz-Expires=86400
&X-Amz-SignedHeaders=host
&X-Amz-Signature=<signature-value>  

Описание параметров запроса

Query-Параметр Значение
X-Amz-Algorithm Подпись AWS версии 4 (AWS4) и алгоритм подписи (AWS4-HMAC-SHA256)
X-Amz-Credential Содержит ключ доступа и информацию о запросе в формате: ${ACCESS_KEY}/${YYYYMMDD}/${REGION}/s3/aws4_request
X-Amz-Date Дата и время в формате “yyyyMMddTHHmmssZ” в соответствии со стандартом ISO 8601. Например, дата и время “08/01/2016 15:32:41.982-700” должна быть сначала приведена к UTC и представлена как “20160801T083241Z”
X-Amz-Expires Указывается временной период, в секундах, в течении которого сгенерированная ссылка будет действительна. Например, 86400 секунд (24 часа). Допустимые значения: целые числа от 1 до 604800 (7 дней)
X-Amz-SignedHeaders Список заголовков, используемых для вычисления подписи. Следующие заголовки обязательны: host и любой x-amz-*, который планируется добавить в запрос
X-Amz-Signature Подпись, необходимая для аутентификации запроса. Если подпись не соответствует ранее вычисленной запрос будет отклонен. Пример подписи: 733255ef022bec3f2a8701cd61d4b371f3f28c9f193a1f02279211d48d5193d7

Получение строки для подписи

Получение строки для подписи аналогично получению в строки для подписи в [методе аутентификации через HTTP-заголовок Authorization](), за исключением процесса создания Канонического запроса:

  • в качестве хэша нагрузки используйте значение UNSIGNED-PAYLOAD, так как подписанная URL используется для загрузки произвольного контента и нет возможности заранее посчитать его хэш;
  • строка CanonicalQueryString должна включать следующие заголовки: X-Amz-Algorithm; X-Amz-Credential, X-Amz-Date, X-Amz-Expires, X-Amz-SignedHeaders, X-Amz-Security-Token;
  • строка CanonicalHeaders должна включать заголовок host.

Подробнее о способе авторизации через query-параметры читайте в официальной документации Amazon S3 API.

Используя HTML-форму

С помощью специально сформированной HTML-формы можно загружать файлы напрямую в Облачное хранилище из браузера пользователя, минуя промежуточные серверы. Для загрузки пользователю нужно собрать валидную HTML-форму формата multipart/form-data. Сделать это можно как вручную, так и с помощью python-библиотеки boto3 (или других, которые позволяют генерировать подписи для форм).

Ограничения:

  • не поддерживается анонимная загрузка, то есть все запросы должны быть подписаны;
  • максимальное значение expiration в Policy ограничено одним годом.

Использование данного метода предполагает:

  1. Создание HTML-формы
  2. Создание POST политики

Создание HTML-формы

Общий вид html формы:

<html>
  <head>
    ...
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    ...
  </head>
  <body>

Для объявления формата HTML формы необходимо указать следующие атрибуты:

  • action — URL к которому идет обращение и содержащий имя бакета;
  • method — в данном случае должен быть указан метод POST;
  • enctype — должно быть указано multipart/form-data.

Например для бакета examplebucket:

<form action="http://s3.selcdn.ru/examplebucket" method="post"
enctype="multipart/form-data">

Можно указать дополнительные параметры загрузки с помощью специальных полей в форме. Описание этих полей в официальной документации Amazon S3 API.

Создание POST политики

Политики POST запроса - это закодированный в base64 JSON-документ, который определяет условия, которым должен соответствовать запрос.

С помощью политик можно более детально разграничить доступ и условия загружаемых объектов. В зависимости от разработки документа политики, можно контролировать гранулярность доступа для каждой загрузки, для каждого пользователя, для всех загрузок или в соответствии с той архитектурой доступа, которая соответствует вашим потребностям.

Пример POST политики:

{ "expiration": "2007-12-01T12:00:00.000Z",
  "conditions": [
    {"bucket": "johnsmith" },
    ["starts-with", "$key", "user/eric/"],
  ]
}

Политика POST обязательно должна содержать следующие элементы:

  • Expiration — определяет дату и время окончания действия данной политики в формате ISO8601 GMT;
  • Conditions — описывает условия и критерии, которым должен соответствовать запрос.
Тип условия Описание
Exact Matches Поле формы должно соответствовать указанным параметрам. В примере значение bucket должно соответствовать “johnsmith”:{"bucket": “johnsmith”}
Starts With Определяет значение, с которого должно начинаться значение для загрузки. В примере объект должен начинаться с user/user1:["starts-with", "$key", "user/user1/"]
Specifying Ranges Определяет диапазон размера данных для загрузки. В этом примере допускается размер файла от 1 до 10 МБ:["content-length-range", 1048576, 10485760]

Совместимость

Метод Совместимость Комментарии
Bucket CRUD ДА -
Bucket Acl Нет
Bucket Cors Нет -
Bucket Encryption Нет Поддерживается Client-side encryption (AWS SDK)
Bucket Lifecycle Нет -
Bucket Location ДА -
Bucket Logging Нет -
Bucket Metrics Configuration Нет -
Bucket Notification Нет -
Bucket Ownership Controls Нет -
Bucket Policy Нет -
Bucket Replication Нет -
Bucket Request Payment Нет -
Bucket Tagging Нет
Bucket Versioning Нет -
Bucket Website Нет -
Object CRUD ДА -
Object Copy ДА -
Object Acl Нет Работает Get ACL
Object Content Нет -
Object Lock Configuration Нет -
Object Response Нет -
Object Retention Нет -
Object Tagging Нет
Object Torrent Нет -
Object Versions Нет -
Multipart Upload ДА -
Public Access Block Нет Все запросы по умолчанию являются Private