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

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

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

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

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

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

Примечание: пользователь, являющийся основным для аккаунта (в случае, когда имя пользователя совпадает с номером учетной записи в панели управления), получает доступ на чтение и запись к любому бакету. Доступ основного пользователя через S3 API возможен только если в панели управления на странице Пользователи отмечен чекбокс Использовать эти данные для доступа по протоколу S3. Только основной пользователь имеет возможность создавать бакеты.

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

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

https://s3.selcdn.ru

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

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

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

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

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

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

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

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

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

Для получения подписывающего ключа:

  1. Закодировать с помощью механизма HMAC-SHA256 дату:

    DateKey = HMAC-SHA256("AWS4"+"<SecretAccessKey>", "<YYYYMMDD>")
  2. Закодировать регион с помощью закодированной на предыдущем шаге даты DataKey:

    DateRegionKey = HMAC-SHA256(<DateKey>, "<aws_region>")
  3. Закодировать сервис с помощью закодированного на предыдущем шаге региона DataRegionKey:

    DateRegionServiceKey = HMAC-SHA256(<DateRegionKey>, "<aws-service>")
  4. Закодировать ключ с помощью закодированным на предыдущем шаге региона DataRegionServiceKey:

    SigningKey = HMAC-SHA256(<DateRegionServiceKey>, "aws4_request")

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

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

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

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

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

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

signature = Hex(HMAC-SHA256(SigningKey, StringToSign))

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

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

Authorization: AWS4-HMAC-SHA256 
Credential=AKIAIOSFODNN7EXAMPLE/20130524/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 Подписанный хэш, состоящий из хеша тела запроса, секретного ключа и информации о запросе (каноническом запросе)

Канонический запрос

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

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

Где:

  • HTTPMethod — один из HTTP методов, например GET, PUT, HEAD и DELETE;
  • CanonicalURI — URI-кодированная версия пути компонента, то есть все, что начинается после “/”. Например для /examplebucket/myphoto.jpg полный путь выглядит следующим образом: https://s3.selcdn.ru/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 — привязывает полученную подпись к определенной дате, региону или сервису. В случае привязки к дате, подпись будет действовать 7 дней. В нашем случае сервис — s3.

Подробнее о способе аутентификации через 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%2Fus-east-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](), за исключением процесса создания Канонического запроса:

  • вы не включаете хэш тела запроса в Канонический запрос, так как использование подписанных URL предполагает загрузку произвольной информации и тело запроса вам не известно заранее. Вместо этого вы используете постоянную строку UNSIGNED-PAYLOAD;
  • строка 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.

Используя HTTP POST запрос

С помощью запроса POST можно загружать файлы напрямую в Облачное хранилище из браузера пользователя, минуя промежуточные серверы. Для загрузки пользователю нужно собрать валидную 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>

Кодировка формы загрузки и политики должна быть UTF-8. Вы можете установить UTF-8 кодировку с помощью заголовка Content-Type. Например, Content-Type: text/html; charset=UTF-8.

Для объявления формата 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 политики

Политика, необходимая для выполнения аутентифицированных запросов с использованием HTTP POST — это документ в кодировке UTF-8 и base64, написанный в JavaScript Object Notation (JSON), который определяет условия, которым должен соответствовать запрос.

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

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

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

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

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

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

Метод Совместимость Комментарии
Bucket CRUD ДА -
Bucket Acl Нет Работает Get 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 Нет Работает Get Tag
Bucket Versioning Нет -
Bucket Website Нет -
Object CRUD ДА -
Object Copy ДА -
Object Acl Нет Работает Get ACL
Object Content Нет -
Object Lock Configuration Нет -
Object Response Нет -
Object Retention Нет -
Object Tagging Нет Работает Get Tag
Object Torrent Нет -
Object Versions Нет -
Multipart Upload ДА -
Public Access Block Нет Все запросы по умолчанию являются Private