istio api безопасность

Безопасность Istio API в Kubernetes с JWT

Раньше мы установили Istio и развернули наш эхо-сервис vecho в K8s.

Это должно быть запущено, если мы вызовем конечную точку.

curl -i vadal.local / echo

Теперь мы хотим обезопасить доступ к этой услуге, как это было с Kong.

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

kubectl edit svc / vecho -n vadal

Убедитесь, что для него установлено имя: http.

ports:
  - name: http
    port: 80
    protocol: TCP
    targetPort: 8080

Добавьте следующую политику авторизации. Это обеспечивает соблюдение правила, согласно которому только запросы GET могут получить доступ к службе.

cat <<EOF | kubectl apply -f -
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: vecho-get
  namespace: vadal
spec:
  selector:
    matchLabels:
      app: vecho
  action: ALLOW
  rules:
  - to:
    - operation:
        methods: ["GET"]
EOF

curl -i vadal.local / echo -X POST
HTTP / 1.1 403 Запрещено
content-length: 19
content-type: text / plain
date: Sun , 12 июл 2020 23:05:03 GMT
сервер: istio-envoy
x-envoy-upstream-service-time: 3
RBAC: доступ запрещен

curl -i vadal.local / echo -X GET
HTTP / 1.1 200 OK
content-type: application / json
date: вс, 12 июля 2020 г., 23:05:38 GMT
x-envoy-upstream-service-time: 8
сервер: istio-envoy
кодировка передачи: фрагментирована
{«timestamp»: »2020–07–12T23: 05: 38.318 ', "заголовки": {"host": "vadal.local", "user-agent": "curl / 7.64.1'," accept ":"
/ "," x-b3-sampled »:« 1 ', «x-forwarded-proto»: «http», «x-request-id»: «6c0ded60–6b20–9eea-b599–1392d1053e56',» x-envoy-original- path »:» / echo »,« content-length »:« 0 »,« x-envoy-internal »:« true »,« x-forwarded-client-cert »:« By = spiffe: //cluster.local /ns/vadal/sa/default;Hash=aae1e29c7a34b9f1f614d868f212f936019bd2caa7560221224ef70578705c31; traceid »:» c11e0dcd7b8727b19adf3e7a5dd5b589 ', «x-b3-spanid»: «294e70a066ee29a7», «x-b3-parentpanid»: «9adf3e7a5dd5b589'}}

Все хорошо.

Доступ к ключевому заголовку

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

cat <<EOF | kubectl apply -f -
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: vecho-get
  namespace: vadal
spec:
  selector:
    matchLabels:
      app: vecho
  action: ALLOW
  rules:
  - to:
    - operation:
        methods: ["GET"]
    when:
      - key: request.headers[x-vadal-key]
        values: ["secret"]
EOF

В доступе будет отказано, если вы не укажете правильный заголовок и значение.

curl -i http: //vadal.local/echo -H x-vadal-key: secret

JWT доступ

В Istio JWT Access состоит из двух частей: RequestAuthentication и AuthorizationPolicy, как указано выше. Параметры JWT определяются с помощью наборов веб-ключей JSON (JWKS).

Сначала мы создаем тестовый токен JWT (RS256), который мы будем использовать для защиты нашего API.

Https://jwt.io/#debugger-io?token=eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJ2YWRhbCIsImlhdCI6MTUxNjIzOTAyMn0.fZjUjMZA4Zk06HMwUhWWyN_9390eyPq1NHc8PkCD_9ZX2N6hqoPyoKeoUJlz2-914F-zSYa31YF1Z0tLPkf8oUCoC-8NaUmgcpB178g957b0ugg39mZGRi2DDiJSPPaQ1S_0xfHjQQwl46S0UoNnDDzcFuEngZ_Rnpviyoi-LZ4CcwamYP19N-WmXOZvESnPJ9MhSzudBWArLAarFQ74tg6Lmf3GWRuTKzdECd29IBq-CdQvdP6YxsMvceoxZXfy76jrRLbFkjfEn6fT_SWPL-FN3zX-emaiYGyfFGB9nmOjgCph0F20oy5Gf5ffEVxM4uzMerzheawqtg3HDResYQ&publicKey=-----BEGIN PUBLIC KEY - - - MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnzyis1ZjfNB0bBgKFMSv vkTtwlvBsaJq7S5wA% 2BkzeVOVpVWwkWdVha4s38XM% 2Fpa% 2Fyr47av7% 2Bz3VTmvDRyAHc aT92whREFpLv9cj5lTeJSibyr% 2FMrm% 2FYtjCZVWgaOYIhwrXwKLqPr% 2F11inWsAkfIy tvHWTxZYEcXLgAXFuUuaS3uF9gEiNQwzGTU1v0FqkqTBr4B8nW3HCN47XUu0t8Y0 е% 2Blf4s4OxQawWD79J9% 2F5d3Ry0vbV3Am1FtGJiJvOwRsIfVChDpYStTcHTCMqtvWb V6L11BWkpzGXSW4Hv43qa% 2BGSYOD2QU68Mb59oSk2OB% 2BBtOLpJofmbGEGgvmwyCI9 MwIDAQAB - - -End PUBLIC KEY - - - https://russelldavies.github.io/jwk -creator /

Теперь нам нужен соответствующий JWK, скопируйте открытый ключ на этот сайт:

Https://russelldavies.github.io/jwk-creator/

Скопируйте преобразованный JWK в блок ниже в пределах keys: [], как показано, а также определите AuthorizationPolicy, чтобы теперь ожидать, что iss будет vadal.

cat <<EOF | kubectl apply -f -
apiVersion: security.istio.io/v1beta1
kind: "RequestAuthentication"
metadata:
  name: vecho-jwt
  namespace: vadal
spec:
  selector:
    matchLabels:
      app: vecho
  jwtRules:
    - outputPayloadToHeader: vadaltoken
      issuer: "vadal"
      jwks: |
        {
          keys: [
            {
              "kty": "RSA",
              "n": "nzyis1ZjfNB0bBgKFMSvvkTtwlvBsaJq7S5wA-kzeVOVpVWwkWdVha4s38XM_pa_yr47av7-z3VTmvDRyAHcaT92whREFpLv9cj5lTeJSibyr_Mrm_YtjCZVWgaOYIhwrXwKLqPr_11inWsAkfIytvHWTxZYEcXLgAXFuUuaS3uF9gEiNQwzGTU1v0FqkqTBr4B8nW3HCN47XUu0t8Y0e-lf4s4OxQawWD79J9_5d3Ry0vbV3Am1FtGJiJvOwRsIfVChDpYStTcHTCMqtvWbV6L11BWkpzGXSW4Hv43qa-GSYOD2QU68Mb59oSk2OB-BtOLpJofmbGEGgvmwyCI9Mw",
              "e": "AQAB",
              "alg": "RS256",
              "use": "sig"
            }
          ]
        }

---
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: vecho-get
  namespace: vadal
spec:
  selector:
    matchLabels:
      app: vecho
  action: ALLOW
  rules:
  - to:
    - operation:
        methods: ["GET"]
    when:
      - key: request.auth.claims[iss]
        values: ["vadal"]
EOF

Мы добавили RequestAuthentication и добавили в AuthorizationPolicy предложение when, которое ожидает, что iss будет равно vadal.

curl -i vadal.local / echo
HTTP / 1.1 403 Запрещено
content-length: 19
content-type: text / plain
date: вс, 12 июля 2020 23:08:17 GMT
сервер: istio-envoy
x-envoy-upstream-service-time: 6

RBAC: доступ запрещен

Теперь используйте токен выше:

ЗНАК = eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJ2YWRhbCIsImlhdCI6MTUxNjIzOTAyMn0.fZjUjMZA4Zk06HMwUhWWyN_9390eyPq1NHc8PkCD_9ZX2N6hqoPyoKeoUJlz2-914F-zSYa31YF1Z0tLPkf8oUCoC-8NaUmgcpB178g957b0ugg39mZGRi2DDiJSPPaQ1S_0xfHjQQwl46S0UoNnDDzcFuEngZ_Rnpviyoi-LZ4CcwamYP19N-WmXOZvESnPJ9MhSzudBWArLAarFQ74tg6Lmf3GWRuTKzdECd29IBq-CdQvdP6YxsMvceoxZXfy76jrRLbFkjfEn6fT_SWPL-FN3zX-emaiYGyfFGB9nmOjgCph0F20oy5Gf5ffEVxM4uzMerzheawqtg3HDResYQ

curl -i http: //vadal.local/echo -H Авторизация: Bearer $ TOKEN

HTTP / 1.1 200 OK
content-type: application / json
date: Mon, 13 Jul 2020 00:12:59 GMT
x-envoy-upstream-service-time: 8
сервер: istio-envoy
кодировка передачи: фрагментирована

{«timestamp»: «2020–07–13T00: 32: 42.107 ',« headers »: {« host »:« vadal.local »,« user-agent »:« curl / 7.64.1', » принять»:» / »,» разрешение»:» Знаменосец eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJ2YWRhbCIsImlhdCI6MTUxNjIzOTAyMn0.fZjUjMZA4Zk06HMwUhWWyN_9390eyPq1NHc8PkCD_9ZX2N6hqoPyoKeoUJlz2-914F-zSYa31YF1Z0tLPkf8oUCoC-8NaUmgcpB178g957b0ugg39mZGRi2DDiJSPPaQ1S_0xfHjQQwl46S0UoNnDDzcFuEngZ_Rnpviyoi-LZ4CcwamYP19N-WmXOZvESnPJ9MhSzudBWArLAarFQ74tg6Lmf3GWRuTKzdECd29IBq-CdQvdP6YxsMvceoxZXfy76jrRLbFkjfEn6fT_SWPL-FN3zX-emaiYGyfFGB9nmOjgCph0F20oy5Gf5ffEVxM4uzMerzheawqtg3HDResYQ»,» х-b3-пробы» : "1 '," x-forwarded-proto ":" http "," x-request-id ":" 54b2bab0–8b7b-90d5-ad4d-d5c61ddb5c17', "x-envoy-original-path": "/ echo ”,” Content-length ”:” 0 ', ”x-envoy-internal”: ”true”, “x-forwarded-client-cert”: ”By = spiffe: //cluster.local/ns/vadal/sa /default;Hash=aae1e29c7a34b9f1f614d868f212f936019bd2caa7560221224ef70578705c31;Subject=$$$************************************************************************************************************** adaltoken ”:” eyJpc3MiOiJ2YWRhbCIsIsImlhdCI6MTUxNjIzOTAyMn0 ', ”x-b3-traceid”: ”df7bf539adf2fe23035466d917e4b60c”, ”x-613” -b435e / x-613 ”-b435e / x-61317435e / x-61317435e / x-61317435e / xpanid em>

Доступ теперь контролируется JWT RS256.

Мы также можем использовать HS256 JWT аналогичным образом.

Создайте JWK отсюда https://mkjwk.org/

Добавьте новый RequestAuthentication с именем метаданных vadal-jwt-oct и следующими ключами, скопированными с указанного выше сайта.

{
    "keys": [
        {
            "kty": "oct",
            "use": "sig",
            "kid": "vadal",
            "k": "_kR1V8tTZ6z4-u2sQ3B4BfAx96773EHZQMi5g6baUQXsxHfSLU5EucNDycQqW3QkA2V0oXOLn4zoj6nSehJz-pidWVjP3-QGOZcj4lU5B2bU0nzjUNwgvTQM0h2ooyhlG8zOgaSPbmXYRh9eXlLVK2Zn8GFBk-YRciTejrkMpP1bLw70LB5rHtMwSY-hUJ-xEx1v7GeibNCglVp5BnAqXZM47fEhFxxcz1vw7sNnBM-s_sV58Hg4tY0nSKO7-iMCuCs2XAPfcxVY8JaVwZjrN9hLITsqJsvQlDj48uB6W1f4T94Xydc5cCjKsXkSk169ii5gNJLZFaWPCNupk1FFSA",
            "alg": "HS256"
        }
    ]
}

Чтобы получить соответствующий HS256 JWT, нам нужно получить значение K.

Https://jwt.io/#debugger-io?token=eyJhbGciOiJIUzI1NiIsImtpZCI6InZhZGFsIiwidHlwIjoiSldUIn0.eyJpc3MiOiJ2YWRhbCIsImlhdCI6MTUxNjIzOTAyMn0.wKGe7fJG4Vp0ZDXtf0RaHyXTUL0tnWGA10ptGlB1Cp4

Значение k - ›_kR1V… необходимо ввести в поле секрета по ссылке ниже (и выбрана опция« секрет на основе 64 »).

Установите новую переменную с полученным токеном.

TOKENH = eyJhbGciOiJIUzI1NiIsImtpZCI6InZhZGFsIiwidHlwIjoiSldUIn0.eyJpc3MiOiJ2YWRhbCIsImlhdCI6MTUxNjIzOTAyGeMn0.ua







curl -i http: //vadal.local/echo -H Авторизация: токен на предъявителя $ TOKENH

HTTP / 1.1 200 OK
content-type: application / json
date: Mon, 13 Jul 2020 01:07:04 GMT
x-envoy-upstream-service-time: 6
сервер: istio-envoy
кодировка передачи: фрагментирована

{«timestamp»: «2020–07–13T01: 07: 04.348 ',« headers »: {« host »:« vadal.local »,« user-agent »:« curl / 7.64.1', » accept ”:” / ”,” x-b3-sampled ”:” 1 ', ”x-forwarded-proto”: “http”, “x-request-id”: ”097c3aa6–5284 –993b-89be-167556119b13 ', «x-envoy-original-path»: «/ echo», «content-length»: «0», «x-envoy-internal»: «true», «x-forwarded- client-cert ”:” By = spiffe: //cluster.local/ns/vadal/sa/default; Hash = aae1e29c7a34b9f1f614d868f212f936019bd2caa7560221224ef70578705c31; Subject = ””; URI = spiffelocal/sa/system: //cluster / istio-ingressgateway-service-account ”,” vadaltoken ”:” eyJpc3MiOiJ2YWRhbCIsImlhdCI6MTUxNjIzOTAyMn0 ', ”x-b3-traceid”: ”c658d2e664c825a74357cab” -freedeff ”x-b2e664c825a74357cab” -bid9 ”435899abdefffd7c”}}

Теперь у нас есть доступ к JWT HS256.

Как видно выше, одна политика авторизации может иметь несколько отдельных определений аутентификации запроса.

Заключение

Мы добавили ключ заголовка API, RS256, а также HS256 JWT для управления доступом к нашему сервису.

Это немного сложнее, чем Kong из-за использования JWKS, но работает точно так же. Мы увидели, как политики авторизации могут применяться напрямую к рабочим нагрузкам.

Дальнейшие подробности

Https://istio.io/latest/docs/concepts/security/ https://tools.ietf.org/html/rfc7517#section-4.3 https://mkjwk.org/ https: //russelldavies.github.io/jwk-creator/ https://www.keycloak.org/

Первоначально опубликовано на https://blog.ramjee.uk 13 июля 2020 г.