Keenetic: пробрасывать pre-auth куку из 401 GET /auth в POST /auth (X-Detail: no session)
This commit is contained in:
@@ -43,10 +43,28 @@ jobs:
|
||||
|
||||
- name: Сборка и публикация образа
|
||||
run: |
|
||||
# docker build/push ходят наружу (Docker Hub, при первой сборке слоя — ещё и Maven
|
||||
# Central) по тому же нестабильному пути, что раньше ронял пул образа раннера — там
|
||||
# были TCP-таймауты/обрывы, которые лечатся повтором, а не переделкой шага. Поэтому
|
||||
# оборачиваем оба во retry с паузой: 5 попыток, между ними 15с.
|
||||
retry() {
|
||||
local attempt=1
|
||||
local max=5
|
||||
until "$@"; do
|
||||
if [ "$attempt" -ge "$max" ]; then
|
||||
echo "::error::'$*' не удалось за $max попыток(ки), сдаюсь"
|
||||
return 1
|
||||
fi
|
||||
echo "'$*' — попытка $attempt из $max не удалась, жду 15с и повторяю..."
|
||||
attempt=$((attempt + 1))
|
||||
sleep 15
|
||||
done
|
||||
}
|
||||
|
||||
IMAGE="docker.io/$DOCKERHUB_USER/iot-hub"
|
||||
docker build -t "$IMAGE:${GITHUB_SHA}" -t "$IMAGE:latest" .
|
||||
docker push "$IMAGE:${GITHUB_SHA}"
|
||||
docker push "$IMAGE:latest"
|
||||
retry docker build -t "$IMAGE:${GITHUB_SHA}" -t "$IMAGE:latest" .
|
||||
retry docker push "$IMAGE:${GITHUB_SHA}"
|
||||
retry docker push "$IMAGE:latest"
|
||||
env:
|
||||
DOCKERHUB_USER: ${{ secrets.DOCKERHUB_USER }}
|
||||
|
||||
@@ -71,7 +89,11 @@ jobs:
|
||||
|
||||
- name: Установка Helm
|
||||
run: |
|
||||
curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3
|
||||
# raw.githubusercontent.com — тот же ненадёжный путь. --retry у curl умеет повторять
|
||||
# сам, без ручного цикла: 5 попыток, экспоненциальная задержка, повтор и на сетевых
|
||||
# обрывах (--retry-all-errors), не только на HTTP-кодах.
|
||||
curl -fsSL --retry 5 --retry-delay 5 --retry-all-errors \
|
||||
-o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3
|
||||
chmod +x get_helm.sh
|
||||
./get_helm.sh
|
||||
rm get_helm.sh
|
||||
|
||||
+10
-3
@@ -133,15 +133,22 @@ public class KeeneticRouterClient {
|
||||
"Keenetic RCI: роутер не прислал X-NDM-Challenge/X-NDM-Realm в ответ на GET /auth — "
|
||||
+ "формат авторизации мог снова измениться");
|
||||
}
|
||||
// Диагностика (X-Detail: "0x2021, no session") показала: 401 на GET /auth сам по себе
|
||||
// ставит pre-auth сессионную куку, к которой привязан именно этот challenge. Раньше мы
|
||||
// её игнорировали и слали POST /auth вообще без Cookie — роутер не мог сопоставить
|
||||
// решённый challenge ни с какой сессией и отвечал 400. Сохраняем куку из 401 и шлём
|
||||
// её на POST — так же, как обычный запрос уже шлёт actualную сессионную куку.
|
||||
storeCookie(challengeHeaders);
|
||||
String hash = sha256Hex(challenge + md5Hex(properties.getLogin() + ":" + realm + ":" + properties.getPassword()));
|
||||
Map<String, String> body = Map.of("login", properties.getLogin(), "password", hash);
|
||||
// Хэш — SHA-256, необратимый, логировать его безопасно (в отличие от самого пароля).
|
||||
// INFO, а не DEBUG — это временная диагностика (400 Bad Request на POST /auth не даёт
|
||||
// тела ответа, причина пока не установлена), чтобы не пришлось менять уровень логов.
|
||||
log.info("Keenetic RCI: POST {} login={} challenge={} realm={} hash={}",
|
||||
authUrl, properties.getLogin(), challenge, realm, hash);
|
||||
log.info("Keenetic RCI: POST {} login={} challenge={} realm={} hash={} cookie={}",
|
||||
authUrl, properties.getLogin(), challenge, realm, hash, sessionCookie);
|
||||
try {
|
||||
ResponseEntity<Void> authResponse = restTemplate.postForEntity(authUrl, body, Void.class);
|
||||
HttpEntity<Object> entity = new HttpEntity<>(body, authHeaders());
|
||||
ResponseEntity<Void> authResponse = restTemplate.postForEntity(authUrl, entity, Void.class);
|
||||
storeCookie(authResponse.getHeaders());
|
||||
} catch (HttpStatusCodeException authError) {
|
||||
log.error("Keenetic RCI: POST /auth -> {} ({}); заголовки ответа: {}; тело ответа: '{}'",
|
||||
|
||||
@@ -42,7 +42,7 @@ resources:
|
||||
# в то, что здесь — см. README.md, раздел "Конфигурация без Helm-редеплоя".
|
||||
adapters:
|
||||
camera:
|
||||
enabled: true
|
||||
enabled: false
|
||||
urls: []
|
||||
# - "https://example.com/stream1/master.m3u8"
|
||||
keenetic:
|
||||
|
||||
Reference in New Issue
Block a user