Коротко. S3-фронт слушает 443 и терминирует TLS на узле. Клиент «не подключается» по трём независимым причинам: сертификат без subjectAltName (handshake отбивается на имени хоста), выбран virtual-hosted стиль без wildcard-DNS, либо запрос уходит не в S3, а в IAM из-за карты доменов. Лечится не отключением проверки, а сертификатом с SAN на apex и wildcard, wildcard-записью в DNS и корректной картой доменов.
1. Что где стоит
клиент → DNS → внешний адрес (DNAT/балансировщик) → узел :443 (haproxy) → scalerd (S3)
443— единственная точка входа S3. Порты11000–11003— внутренние порты DSS, не S3.- TLS терминируется на узле; дальше трафик идёт во внутренний S3-шлюз.
- Сертификат фронта — не файл «на память»: продукт рендерит его из ConfigRule
haproxy_ssl(ресурсный типscalerd) в файл видаscalerd.pem. Поэтому правка файла руками бессмысленна — при следующем применении конфигурации он будет перезаписан. - Сертификат GUI — отдельное правило (
samurai_ssl); его браузерные предупреждения лечатся независимо от S3.
Внешний доступ — это DNS + проброс порта. Продукт не знает, какой внешний адрес и порт вы используете; он видит только запрос, пришедший на узел. Поэтому «изнутри работает, снаружи нет» — почти всегда история про DNAT, DNS или сертификат, выданный на другое имя.
2. Два стиля адресации
| Стиль | Формат | Что нужно |
|---|---|---|
| Path-style | https://s3.<DOMAIN>/<BUCKET>/<KEY> |
apex-имя в DNS, SAN на apex |
| Virtual-hosted | https://<BUCKET>.s3.<DOMAIN>/<KEY> |
wildcard *.s3.<DOMAIN> в DNS, SAN на wildcard |
Path-style работает всегда и является безопасным выбором для проверки. Virtual-hosted требует, чтобы каждый бакет резолвился как имя хоста: без wildcard-записи клиент падает ещё на DNS, до TLS.
Список доменов, которые шлюз понимает как суффиксы, задаётся в конфигурации шлюза
(domain_suffix_set). Это отдельная настройка от сертификата: сертификат может быть wildcard, а
DNS — без wildcard, и наоборот.
3. Симптомы и что они значат
| Симптом клиента | Причина |
|---|---|
hostname '...' doesn't match 'scalerd' |
сертификат по умолчанию: CN=scalerd, без SAN |
Handshake не проходит, HTTP 000 при --cacert |
та же причина: доверие не спасает, если имя не совпадает |
Не резолвится <BUCKET>.s3.<DOMAIN> |
нет wildcard-DNS, а клиент настаивает на virtual-hosted |
400 InvalidAction ... NO_VERSION_SPECIFIED |
запрос ушёл в службу IAM: S3-хост попал в карту IAM-доменов |
307 без ошибки |
штатный ответ S3-фронта; признак, что фронт жив |
403 SignatureDoesNotMatch |
подпись/время/кодирование ключа, не сертификат |
Важно: «добавить сертификат в доверенные» не лечит S3, если в сертификате нет SAN. Браузер предлагает «принять исключение», а библиотеки (aws-cli, boto3, s3cmd, rclone) сравнивают имя хоста и отказывают. Импорт в доверенные оправдан для браузеров и внутренних служб — но не как решение для S3-клиентов.
4. Сертификат с SAN: штатный путь
Нужны оба имени в SAN: apex (для path-style и вызовов API) и wildcard (для virtual-hosted). Wildcard-сертификат сам по себе apex не покрывает.
Выпуск (у себя или на узле; приватный ключ — вне каталогов продукта, права не шире 600):
cat > san.cnf <<'EOF'
[req]
distinguished_name = dn
req_extensions = v3
prompt = no
[dn]
CN = s3.<DOMAIN>
[v3]
subjectAltName = @alt
basicConstraints = critical, CA:FALSE
keyUsage = critical, digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth
[alt]
DNS.1 = s3.<DOMAIN>
DNS.2 = *.s3.<DOMAIN>
EOF
openssl req -new -newkey rsa:2048 -nodes -keyout s3.key -out s3.csr -config san.cnf
openssl x509 -req -in s3.csr -signkey s3.key -days 3650 \
-extfile san.cnf -extensions v3 -out s3.crt
cat s3.crt s3.key > s3-fullchain.pem
Установка — только через модель или GUI, не копированием файла:
- GUI: Configuration → SSL-сертификаты → раздел S3 SSL; загрузить
s3-fullchain.pem(сертификат + ключ одним файлом) и подтвердить операцию. Право на это действие —UPDATE_SYSTEMCONFIG_S3SSL. - Model API (эквивалент): изменить содержимое настройки
ssl_pem_contentв ConfigRulehaproxy_ssl(ресурсный типscalerd), затем применить конфигурацию приложенияscalerdштатнымconfigure. Форматsettings— массив по узлам/локациям: смотреть живой документ, а не угадывать. Как читать и менять модель — Model API.
Альтернатива для парка сервисов — свой CA: клиентам ставится один корневой сертификат, продление
идёт без правок на клиентах. Публичный ACME-сертификат возможен, но требует DNS-01 для wildcard
(обновление TXT-записи каждые 90 дней) или HTTP-01 с открытым 80 на терминаторе; для закрытого
контура это лишняя зависимость.
5. DNS и внешний доступ
- Apex:
s3.<DOMAIN>→ внешний адрес (или CNAME на балансировщик). - Wildcard:
*.s3.<DOMAIN>→ тот же адрес, если нужен virtual-hosted. Без него — только path-style. - Проброс порта: наружу публикуется ровно один порт S3; он обслуживает любой хост, поэтому при смене сертификата DNAT менять не нужно.
- IAM-домен: для IAM-вызовов нужен отдельный FQDN (см. IAM и resource policy); по IP IAM не работает.
Проверка снаружи — тем же инструментом, что видит клиент: curl, openssl s_client, клиентский
SDK. Локальные проверки на узле доказывают только, что служба жива, но не что клиент дойдёт.
6. Проверка после установки сертификата
# 1) какой сертификат реально отдаётся и есть ли SAN
echo | openssl s_client -connect s3.<DOMAIN>:443 -servername s3.<DOMAIN> 2>/dev/null \
| openssl x509 -noout -subject -ext subjectAltName
# 2) фронт отвечает без отключения проверки
curl -sS -o /dev/null -w '%{http_code}\n' https://s3.<DOMAIN>/
# 3) клиент без --no-verify-ssl
aws --endpoint-url https://s3.<DOMAIN> s3 ls
Ожидается: в SAN — s3.<DOMAIN> и *.s3.<DOMAIN>; curl → 307; aws s3 ls → список бакетов
или AccessDenied при валидных ключах (это уже права, не TLS).
Для virtual-hosted дополнительно:
getent hosts <BUCKET>.s3.<DOMAIN>
Ожидается адрес, а не пустой ответ. Если пусто — wildcard-записи нет.
7. Продление и откат
- Перед заменой сохранить текущий PEM вне каталога продукта и зафиксировать содержимое
ssl_pem_content(guid правилаhaproxy_ssl). - Продление = новая пара «сертификат + ключ» в модель тем же путём, в окно обслуживания. Для самоподписанного/своего CA — по календарю; срок можно ставить длинный, но правило «продление = новая пара через модель» остаётся.
- Откат = вернуть прежний PEM в то же правило и применить
configureприложенияscalerd. - Не забыть GUI-сертификат (
samurai_ssl): браузерные предупреждения на порту GUI лечатся им же. - Каталог
ssl.<hash>ротируется продуктом; путь брать через симлинкssl.
8. Границы
- Конкретные имена DNS-зон, внешние адреса и порты проброса — инфраструктура заказчика, не продукта: в статье они не приводятся.
- Поведение клиента при не-ASCII ключах и неизвестных query-параметрах — отдельная тема совместимости, см. S3-совместимость.
- «Сертификат без SAN — штатное поведение по умолчанию» подтверждено на нашей практике; в других
сборках проверять фактический вывод
openssl s_client, а не предполагать.
9. Источники
- Quantum Software Documentation Center (7.3) (2026-11-07)
- Release Notes 7.3 — загрузка цепочки SSL через GUI по документированному порядку PEM, предупреждение об истечении сертификата за 6 месяцев
- Наша практика (обезличенно): сертификат без SAN, path-style, wildcard-DNS и проверка
307на кластере из трёх нод, ActiveScale 7.3.1.2; замена через ConfigRulehaproxy_ssl. - Обновлено: 2026-11-07.