Zpět k mikroslužbám spolu s Istio. Část 3

Zpět k mikroslužbám spolu s Istio. Část 3

Pozn. přek.: První část Tento cyklus byl věnován seznámení s možnostmi Istio a jejich demonstraci v praxi, druhá — jemně laděnému směrování a správě síťového provozu. Nyní se zaměříme na bezpečnost: pro demonstraci základních funkcí s ní souvisejících autor používá identity službu Auth0, nicméně analogicky lze nastavit i jiné poskytovatele.

Nastavili jsme Kubernetes klastr, na kterém jsme nasadili Istio a příklad mikroslužbové aplikace Sentiment Analysis, — tak byly demonstrovány možnosti Istio.

Díky Istio se nám podařilo udržet malé rozměry služeb, protože nepotřebují implementaci takových "vrstev" jako opakování pokusů (Retries), časové limity (Timeouts), automatické pojistky (Circuit Breakers), trasování (Tracing), monitorování (Monitoring). Kromě toho jsme použili techniky pokročilého testování a nasazení: A/B testování, zrcadlení a kanárkové nasazení.

Zpět k mikroslužbám spolu s Istio. Část 3

V novém materiálu se zaměříme na finální vrstvy na cestě k business value: autentizaci a autorizaci — a v Istio je to skutečně radost!

Autentizace a autorizace v Istio

Nikdy bych nevěřil, že se nechám inspirovat autentizací a autorizací. Co může s technologického hlediska nabídnout Istio, aby udělalo tato témata fascinující a dokonce vás také inspirovala?

Odpověď je jednoduchá: Istio převádí odpovědnost za tyto funkce z vašich služeb na proxy Envoy. Když požadavky dorazí k službám, jsou již autentizovány a autorizovány, takže vám zbývá pouze psát užitečný obchodní kód.

Zní to dobře? Podívejme se dovnitř!

Autentizace s Auth0

Jako server pro správu identit a přístupu budeme používat Auth0, který má zkušební verzi, je intuitivní na používání a jednoduše se mi líbí. Nicméně, stejné principy lze aplikovat i na jakoukoli jinou realizaci OpenID Connect: KeyCloak, IdentityServer a mnohé další.

Pro začátek se přihlaste na Auth0 Portal se svým účtem, vytvořte tenant (tenant — „nájemce“, logická jednotka izolace, podrobnosti viz dokumentaci — pozn. překl.) a přejděte do Applications > Default App, vyberte Doména, jak je znázorněno na obrázku níže:

Zpět k mikroslužbám spolu s Istio. Část 3

Uveďte tuto doménu v souboru resource-manifests/istio/security/auth-policy.yaml (zdroj):

apiVersion: authentication.istio.io/v1alpha1
kind: Policy
metadata:
  name: auth-policy
spec:
  targets:
  - name: sa-web-app
  - name: sa-feedback
  origins:
  - jwt:
      issuer: "https://{YOUR_DOMAIN}/"
      jwksUri: "https://{YOUR_DOMAIN}/.well-known/jwks.json"
  principalBinding: USE_ORIGIN

S využitím tohoto zdroje Pilot (jeden ze tří základních komponentů Control Plane v Istio — pozn. překl.) konfiguruje Envoy pro autentizaci požadavků před tím, než je přesměruje na služby: sa-web-app a sa-feedback. Zároveň konfigurace není aplikována na Envoy služby sa-frontend, což nám umožňuje ponechat frontend neautentizovaný. Pro aplikování politiky (Policy) proveďte příkaz:

$ kubectl apply -f resource-manifests/istio/security/auth-policy.yaml
policy.authentication.istio.io “auth-policy” vytvořena

Vraťte se na stránku a proveďte požadavek — uvidíte, že skončí stavem 401 Neautorizováno. Nyní přesměrujeme uživatele frontendu na autentizaci pomocí Auth0.

Autentizace požadavků pomocí Auth0

Abyste autentizovali požadavky koncového uživatele, je nutné vytvořit API v Auth0, které bude představovat autentizované služby (reviews, details a ratings). Pro vytvoření API přejděte na Auth0 Portal > APIs > Create API a vyplňte formulář:

Zpět k mikroslužbám spolu s Istio. Část 3

Důležitou informací zde je Identifier, který později použijeme ve skriptu. Zapište si ho takto:

  • Audience: {YOUR_AUDIENCE}

Zbývající potřebné detaily se nachází na Auth0 Portal v sekci Applications — vyberte Test Application (vytváří se automaticky spolu s API).

Zde si zapíšeme:

  • Doména: {YOUR_DOMAIN}
  • Client Id: {YOUR_CLIENT_ID}

Posuňte se do Test Application do textového pole Allowed Callback URLs (povolené URL pro callback), kde uvedeme URL, na kterou by měl být požadavek odeslán po dokončení autentizace. V našem případě je to:

http://{EXTERNAL_IP}/callback

A pro Allowed Logout URLs (povolené URL pro odhlášení) přidáme:

http://{EXTERNAL_IP}/logout

Přejdeme k frontendu.

Aktualizace frontendu

Přepněte se na větev auth0 repozitáře [istio-mastery]. V této větvi byl kód frontendu změněn tak, aby přesměrovával uživatele do Auth0 pro autentizaci a používal JWT token v požadavcích na ostatní služby. To bylo realizováno následujícím způsobem (App.js):

analyzeSentence() {
    fetch('/sentiment', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
            'Authorization': `Bearer ${auth.getAccessToken()}` // Access Token
        },
        body: JSON.stringify({ sentence: this.textField.getValue() })
    })
        .then(response => response.json())
        .then(data => this.setState(data));
}

Aby bylo možné převést frontend na použití dat tenantů v Auth0, otevřete sa-frontend/src/services/Auth.js a nahraďte v něm hodnoty, které jsme si zapsali výše (Auth.js):

const Config = {
    clientID: '{YOUR_CLIENT_ID}',
    domain:'{YOUR_DOMAIN}',
    audience: '{YOUR_AUDIENCE}',
    ingressIP: '{EXTERNAL_IP}' // Používá se pro přesměrování po autentizaci
}

Aplikace je připravena. Uveďte své Docker ID v následujících příkazech při sestavování a nasazení provedených změn:

$ docker build -f sa-frontend/Dockerfile 
 -t $DOCKER_USER_ID/sentiment-analysis-frontend:istio-auth0 
 sa-frontend

$ docker push $DOCKER_USER_ID/sentiment-analysis-frontend:istio-auth0

$ kubectl set image deployment/sa-frontend 
 sa-frontend=$DOCKER_USER_ID/sentiment-analysis-frontend:istio-auth0

Vyzkoušejte aplikaci! Budete přesměrováni na Auth0, kde se musíte přihlásit (nebo zaregistrovat), po čemž budete posláni zpět na stránku, ze které budou prováděny již autentizované požadavky. Pokud však vyzkoušíte zmíněné příkazy z prvních částí článku s curl, obdržíte kód 401 Stavový kód, který signalizuje, že požadavek není autorizován.

Uděláme další krok - autorizujeme požadavky.

Autorizace s Auth0

Autentizace nám umožňuje pochopit, kdo uživatel je, ale abychom zjistili, k čemu má přístup, je třeba autorizace. Istio nabízí nástroje i pro toto.

Jako příklad vytvoříme dvě skupiny uživatelů (viz schéma níže):

  • Uživatelé (uživatelé) — s přístupem pouze k službám SA-WebApp a SA-Frontend;
  • Moderátoři (moderátoři) — s přístupem ke všem třem službám.

Zpět k mikroslužbám spolu s Istio. Část 3
Koncept autorizace

Pro vytvoření těchto skupin využijeme rozšíření Auth0 Authorization a pomocí Istio jim poskytneme různé úrovně přístupu.

Instalace a konfigurace Auth0 Authorization

Na portálu Auth0 přejděte k rozšířením (Rozšíření) a nainstalujte Auth0 Authorization. Po instalaci přejděte k Authorization Extension, a tam - k konfiguraci tenant’a kliknutím vpravo nahoře a výběrem příslušné možnosti menu (Konfigurace). Aktivujte skupiny (Skupiny) a klikněte na tlačítko publikování pravidla (Publikovat pravidlo).

Zpět k mikroslužbám spolu s Istio. Část 3

Vytváření skupin

V Authorization Extension přejděte na Skupiny a vytvořte skupinu Moderátoři. Protože budeme považovat všechny autentizované uživatele za běžné, není potřeba vytvářet pro ně další skupinu.

Vyberte skupinu Moderátoři, klikněte na Přidat členy, přidejte svůj hlavní účet. Některé uživatele nechte bez jakékoli skupiny, abyste se ujistili, že jim je přístup zakázán. (Nové uživatele lze vytvořit ručně přes Auth0 Portal > Uživatelé > Vytvořit uživatele.)

Přidejte Group Claim do Access Tokenu

Uživatelé byli přidáni do skupin, ale tato informace by měla být také odrazena v přístupových tokenech. Aby byla splněna pravidla OpenID Connect a zároveň se vrátily požadované skupiny, token bude muset přidávat svůj vlastní klam. Implementuje se prostřednictvím pravidel Auth0.

Pro vytvoření pravidla přejděte na portál Auth0 k Pravidla, klikněte na Vytvořit pravidlo a vyberte prázdné pravidlo z šablon.

Zpět k mikroslužbám spolu s Istio. Část 3

Zkopírujte níže uvedený kód a uložte ho jako nové pravidlo Přidat klam skupiny (namespacedGroup.js):

function (user, context, callback) {
    context.accessToken['https://sa.io/group'] = user.groups[0];
    return callback(null, user, context);
}

Poznámka: tento kód bere první skupinu uživatele, která je definována v rozšíření pro autorizaci, a přidává ji do přístupového tokenu jako vlastní klam (pod jeho jmenným prostorem, jak to vyžaduje Auth0).

Vraťte se na stránku Pravidla a zkontrolujte, že máte dvě pravidla, zapsaná v následujícím pořadí:

  • auth0-authorization-extension
  • Přidat klam skupiny

Pořadí je důležité, protože pole skupiny asynchronně dostane pravidlo auth0-authorization-extension a poté je přidáno jako klam druhým pravidlem. Výsledkem je takový přístupový token:

{
 "https://sa.io/group": "Moderators",
 "iss": "https://sentiment-analysis.eu.auth0.com/",
 "sub": "google-oauth2|196405271625531691872"
 // [zkraťeno pro přehlednost]
}

Nyní je třeba nastavit proxy Envoy pro ověřování přístupu uživatelů, proto bude skupina získána z klamu (https://sa.io/group) ve vraceném přístupovém tokenu. To je téma pro další část článku.

Konfigurace autorizace v Istio

Aby autorizace fungovala, je nutné zapnout RBAC pro Istio. K tomu využijeme následující konfiguraci:

apiVersion: "rbac.istio.io/v1alpha1"
kind: RbacConfig
metadata:
  name: default
spec:
  mode: 'ON_WITH_INCLUSION'                     # 1
  inclusion:
    services:                                   # 2
    - "sa-frontend.default.svc.cluster.local"
    - "sa-web-app.default.svc.cluster.local"
    - "sa-feedback.default.svc.cluster.local" 

Vysvětlení:

  • 1 — zapínáme RBAC pouze pro služby a jmenné prostory uvedené v poli Inclusion;
  • 2 — uvádíme seznam našich služeb.

Aplikujeme konfiguraci pomocí následujícího příkazu:

$ kubectl apply -f resource-manifests/istio/security/enable-rbac.yaml
rbacconfig.rbac.istio.io/default vytvořeno

Nyní všechny služby vyžadují řízení přístupu založené na rolích (Role-Based Access Control). Jinými slovy, přístup ke všem službám je zakázán a povede k odpovědi RBAC: přístup odepřen. Nyní povolíme přístup autorizovaným uživatelům.

Konfigurace přístupu pro běžné uživatele

Všichni uživatelé by měli mít přístup ke službám SA-Frontend a SA-WebApp. To se realizuje pomocí následujících zdrojů Istio:

  • ServiceRole — určuje práva, která má uživatel;
  • ServiceRoleBinding — určuje, ke komu se tato ServiceRole vztahuje.

Pro běžné uživatele povolíme přístup k určitým službám (servicerole.yaml):

apiVersion: "rbac.istio.io/v1alpha1"
kind: ServiceRole
metadata:
  name: regular-user
  namespace: default
spec:
  rules:
  - services: 
    - "sa-frontend.default.svc.cluster.local" 
    - "sa-web-app.default.svc.cluster.local"
    paths: ["*"]
    methods: ["*"]

A pomocí regular-user-binding aplikujeme ServiceRole na všechny návštěvníky stránky (regular-user-service-role-binding.yaml):

apiVersion: "rbac.istio.io/v1alpha1"
kind: ServiceRoleBinding
metadata:
  name: regular-user-binding
  namespace: default
spec:
  subjects:
  - user: "*"
  roleRef:
    kind: ServiceRole
    name: "regular-user"

Znamená „všichni uživatelé“, že i neautentizovaní uživatelé získají přístup k SA WebApp? Ne, politika zkontroluje platnost JWT tokenu.

Aplikujeme konfigurace:

$ kubectl apply -f resource-manifests/istio/security/user-role.yaml
servicerole.rbac.istio.io/regular-user created
servicerolebinding.rbac.istio.io/regular-user-binding created

Konfigurace přístupu pro moderátory

Pro moderátory chceme povolit přístup ke všem službám (mod-service-role.yaml):

apiVersion: "rbac.istio.io/v1alpha1"
kind: ServiceRole
metadata:
  name: mod-user
  namespace: default
spec:
  rules:
  - services: ["*"]
    paths: ["*"]
    methods: ["*"]

Ale taková práva chceme pouze pro ty uživatele, jejichž access token obsahuje claim https://sa.io/group s hodnotou Moderátoři (mod-service-role-binding.yaml):

apiVersion: "rbac.istio.io/v1alpha1"
kind: ServiceRoleBinding
metadata:
  name: mod-user-binding
  namespace: default
spec:
  subjects:
  - properties:
      request.auth.claims[https://sa.io/group]: "Moderators"
  roleRef:
    kind: ServiceRole
name: "mod-user" 

Aplikujeme konfigurace:

$ kubectl apply -f resource-manifests/istio/security/mod-role.yaml
servicerole.rbac.istio.io/mod-user created
servicerolebinding.rbac.istio.io/mod-user-binding created

Kvůli ukládání do mezipaměti v envoyích může implementace pravidel autorizace trvat pár minut. Poté se můžete ujistit, že uživatelé a moderátoři mají různé úrovně přístupu.

Závěr této části

Seriozně: Viděli jste někdy jednodušší, snadno škálovatelní a bezpečný přístup k autentizaci a autorizaci?

Pouze tři zdroje Istio (RbacConfig, ServiceRole a ServiceRoleBinding) byly potřeba k dosažení jemné kontroly nad autentizací a autorizací přístupu koncových uživatelů k službám.

Navíc jsme přenesli starost o tyto problémy z našich služeb do envoyí, čímž jsme dosáhli:

  • snížení množství běžného kódu, ve kterém mohou být bezpečnostní problémy a chyby;
  • snížení počtu hloupých situací, kdy byl jeden endpoint dostupný zvenčí a zapomněl o tom informovat;
  • zrušení potřeby aktualizovat všechny služby při každém přidání nové role nebo práva;
  • toho, aby nové služby zůstávaly jednoduché, bezpečné a rychlé.

Výstup

Istio umožňuje týmům soustředit své zdroje na důležité obchodní úkoly, aniž by zvyšovaly režijní náklady službám, vracejíce je k statusu "mikro".

Článek (ve třech částech) poskytl základní znalosti a připravený praktický návod pro zahájení práce s Istio v reálných projektech.

P.S. od překladatele

Přečtěte si také náš blog:

Zdroj: habr.com

Koupit spolehlivý hosting pro webové stránky s ochranou proti DDoS, VPS VDS servery 🔥 Koupit spolehlivý hosting pro webové stránky s ochranou proti DDoS, VPS VDS servery | ProHoster