Powrót do mikroserwisów z Istio. Część 3

Powrót do mikroserwisów z Istio. Część 3

Notatka. przeł.: Pierwsza część ta seria poświęcona była poznaniu możliwości Istio i zademonstrowaniu ich w działaniu, drugi — precyzyjnie dostrojone zarządzanie routingiem i ruchem sieciowym. Teraz porozmawiamy o bezpieczeństwie: aby zademonstrować podstawowe funkcje z nim związane, autor korzysta z usługi tożsamości Auth0, ale innych dostawców można skonfigurować w podobny sposób.

Stworzyliśmy klaster Kubernetes, w którym wdrożyliśmy Istio oraz przykładową aplikację mikrousługową Sentiment Analysis, aby zademonstrować możliwości Istio.

Dzięki Istio udało nam się utrzymać niewielkie rozmiary naszych usług, ponieważ nie wymagały one wdrażania warstw takich jak ponowne próby, przekroczenia limitu czasu, wyłączniki automatyczne, śledzenie i monitorowanie. Dodatkowo zastosowaliśmy zaawansowane techniki testowania i wdrażania: testy A/B, Mirroring i Canary Rollouts.

Powrót do mikroserwisów z Istio. Część 3

W nowym materiale zajmiemy się ostatnimi warstwami na drodze do wartości biznesowej: uwierzytelnianiem i autoryzacją – a w Istio to prawdziwa przyjemność!

Uwierzytelnianie i autoryzacja w Istio

Nigdy bym nie uwierzyła, że ​​zainspiruje mnie uwierzytelnianie i autoryzacja. Co Istio może zaoferować z technologicznego punktu widzenia, aby tematy te były zabawne, a jeszcze bardziej inspirujące?

Odpowiedź jest prosta: Istio przenosi odpowiedzialność za te możliwości z Twoich usług na serwer proxy Envoy. Zanim żądania dotrą do usług, zostały już uwierzytelnione i autoryzowane, więc jedyne, co musisz zrobić, to napisać kod przydatny w biznesie.

Brzmi dobrze? Zajrzyjmy do środka!

Uwierzytelnianie za pomocą Auth0

Jako serwer do zarządzania tożsamością i dostępem wykorzystamy Auth0, który ma wersję próbną, jest intuicyjny w obsłudze i po prostu mi się podoba. Jednak te same zasady można zastosować do każdego innego Wdrożenia OpenID Connect: KeyCloak, IdentityServer i wiele innych.

Aby rozpocząć, przejdź do Portal Auth0 za pomocą swojego konta utwórz najemcę (najemca - „najemca”, logiczna jednostka izolacji, więcej szczegółów patrz dokumentacja - około. tłumacz.) i idź do Aplikacje > Aplikacja domyślnawybór Domena, jak pokazano na zrzucie ekranu poniżej:

Powrót do mikroserwisów z Istio. Część 3

Określ tę domenę w pliku resource-manifests/istio/security/auth-policy.yaml (źródło):

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

Z takim zasobem, Pilocie (jeden z trzech podstawowych komponentów Control Plane w Istio – ok. tłum.) konfiguruje Envoy tak, aby uwierzytelniał żądania przed przekazaniem ich do usług: sa-web-app и sa-feedback. Jednocześnie konfiguracja nie dotyczy obsługi Envoyów sa-frontend, co pozwala nam pozostawić frontend bez uwierzytelnienia. Aby zastosować Politykę, uruchom komendę:

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

Wróć na stronę i złóż wniosek - zobaczysz, że kończy się to statusem 401 Nieautoryzowane. Teraz przekierujmy użytkowników frontendu do uwierzytelnienia za pomocą Auth0.

Uwierzytelnianie żądań za pomocą Auth0

Aby uwierzytelniać żądania użytkowników końcowych, musisz utworzyć interfejs API w Auth0, który będzie reprezentował uwierzytelnione usługi (opinie, szczegóły i oceny). Aby utworzyć API przejdź do Portal Auth0 > Interfejsy API > Utwórz interfejs API i wypełnij formularz:

Powrót do mikroserwisów z Istio. Część 3

Istotną informacją jest tutaj identyfikator, którego użyjemy w dalszej części skryptu. Zapiszmy to w ten sposób:

  • Publiczność: {TWOJA_ODBIORCY}

Pozostałe potrzebne nam dane znajdują się na Portalu Auth0 w sekcji Zastosowania - wybierać Aplikacja testowa (tworzony automatycznie wraz z API).

Tutaj napiszemy:

  • Domena: {TWOJA DOMENA}
  • Identyfikator klienta: {YOUR_CLIENT_ID}

Przewiń do Aplikacja testowa do pola tekstowego Dozwolone adresy URL wywołania zwrotnego (rozwiązane adresy URL dla wywołania zwrotnego), w którym podajemy adres URL, pod który połączenie ma zostać wysłane po zakończeniu uwierzytelnienia. W naszym przypadku jest to:

http://{EXTERNAL_IP}/callback

I dla Dozwolone adresy URL wylogowania (dozwolone adresy URL do wylogowania) dodaj:

http://{EXTERNAL_IP}/logout

Przejdźmy do frontendu.

Aktualizacja frontendu

Przejdź do oddziału auth0 magazyn [istio-mastery]. W tej gałęzi kod frontendu jest zmieniany tak, aby przekierowywał użytkowników do Auth0 w celu uwierzytelnienia i użycia tokena JWT w żądaniach do innych usług. Ten ostatni jest realizowany w następujący sposób (Aplikacja.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 zmienić interfejs użytkownika tak, aby korzystał z danych dzierżawy w Auth0, otwórz sa-frontend/src/services/Auth.js i zamień w nim wartości, które napisaliśmy powyżej (Autoryzacja.js):

const Config = {
    clientID: '{YOUR_CLIENT_ID}',
    domain:'{YOUR_DOMAIN}',
    audience: '{YOUR_AUDIENCE}',
    ingressIP: '{EXTERNAL_IP}' // Используется для редиректа после аутентификации
}

Aplikacja jest gotowa. Określ swój identyfikator Dockera w poniższych poleceniach podczas kompilowania i wdrażania wprowadzonych zmian:

$ 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

Wypróbuj aplikację! Zostaniesz przekierowany do Auth0, gdzie musisz się zalogować (lub zarejestrować), po czym zostaniesz odesłany do strony, z której będą wysyłane już uwierzytelnione żądania. Jeśli wypróbujesz polecenia wymienione w pierwszych częściach artykułu za pomocą curl, otrzymasz kod 401 Kod stanu, sygnalizując, że żądanie nie jest autoryzowane.

Zróbmy kolejny krok - autoryzuj żądania.

Autoryzacja z Auth0

Uwierzytelnianie pozwala nam zrozumieć, kim jest użytkownik, ale wymagana jest autoryzacja, aby wiedzieć, do czego ma on dostęp. Istio oferuje również do tego narzędzia.

Jako przykład utwórzmy dwie grupy użytkowników (patrz diagram poniżej):

  • użytkowników (użytkownicy) — z dostępem wyłącznie do usług SA-WebApp i SA-Frontend;
  • Moderatorzy (moderatorzy) — z dostępem do wszystkich trzech usług.

Powrót do mikroserwisów z Istio. Część 3
Koncepcja autoryzacji

Aby utworzyć te grupy, skorzystamy z rozszerzenia Auth0 Authorization i wykorzystamy Istio, aby zapewnić im różne poziomy dostępu.

Instalacja i konfiguracja Autoryzacji Auth0

W portalu Auth0 przejdź do rozszerzeń (Rozszerzenia) i zainstaluj Autoryzacja0. Po instalacji przejdź do Rozszerzenie autoryzacji, a tam - do konfiguracji najemcy klikając w prawym górnym rogu i wybierając odpowiednią opcję menu (Konfiguracja). Aktywuj grupy (Grupy) i kliknij przycisk publikowania reguły (Reguła publikowania).

Powrót do mikroserwisów z Istio. Część 3

Twórz grupy

W rozszerzeniu autoryzacji przejdź do Grupy i utwórz grupę Moderatorzy. Ponieważ wszystkich uwierzytelnionych użytkowników będziemy traktować jak zwykłych użytkowników, nie ma potrzeby tworzenia dla nich dodatkowej grupy.

Wybierz grupę Moderatorzy, Naciskać Dodaj członków, dodaj swoje konto główne. Pozostaw niektórych użytkowników bez żadnej grupy, aby mieć pewność, że odmówią im dostępu. (Nowych użytkowników można tworzyć ręcznie za pomocą Portal Auth0 > Użytkownicy > Utwórz użytkownika.)

Dodaj oświadczenie grupy do tokenu dostępu

Użytkownicy zostali dodani do grup, ale ta informacja musi być także odzwierciedlona w tokenach dostępu. Aby zachować zgodność z OpenID Connect i jednocześnie zwrócić potrzebne nam grupy, token będzie musiał dodać własne roszczenie niestandardowe. Zaimplementowano poprzez reguły Auth0.

Aby utworzyć regułę, przejdź do portalu Auth0 Zasady, Naciskać Stwórz zasadę i wybierz pustą regułę z szablonów.

Powrót do mikroserwisów z Istio. Część 3

Skopiuj poniższy kod i zapisz go jako nową regułę Dodaj roszczenie grupowe (namespacedGroup.js):

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

Operacja: Ten kod pobiera pierwszą grupę użytkowników zdefiniowaną w rozszerzeniu autoryzacji i dodaje ją do tokenu dostępu jako niestandardowe oświadczenie (w swojej przestrzeni nazw, zgodnie z wymaganiami Auth0).

Wróć do strony Zasady i sprawdź, czy masz dwie reguły zapisane w następującej kolejności:

  • auth0-rozszerzenie-autoryzacji
  • Dodaj roszczenie grupowe

Kolejność jest ważna, ponieważ pole grupy otrzymuje regułę asynchronicznie auth0-rozszerzenie-autoryzacji a następnie jest dodawany jako twierdzenie przez drugą regułę. Rezultatem jest token dostępu taki jak ten:

{
 "https://sa.io/group": "Moderators",
 "iss": "https://sentiment-analysis.eu.auth0.com/",
 "sub": "google-oauth2|196405271625531691872"
 // [сокращено для наглядности]
}

Teraz musisz skonfigurować proxy Envoy, aby sprawdzał dostęp użytkowników, dla których grupa zostanie wyciągnięta z roszczenia (https://sa.io/group) w zwróconym tokenie dostępu. To temat na kolejną część artykułu.

Konfiguracja autoryzacji w Istio

Aby autoryzacja działała, musisz włączyć RBAC dla Istio. W tym celu użyjemy następującej konfiguracji:

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" 

Wyjaśnienie:

  • 1 — włącz RBAC tylko dla usług i przestrzeni nazw wymienionych w polu Inclusion;
  • 2 — podajemy listę naszych usług.

Zastosujmy konfigurację za pomocą następującego polecenia:

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

Wszystkie usługi wymagają teraz kontroli dostępu opartej na rolach. Innymi słowy, dostęp do wszystkich usług jest zabroniony i skutkuje odpowiedzią RBAC: access denied. Teraz zezwólmy na dostęp autoryzowanym użytkownikom.

Konfiguracja dostępu dla zwykłych użytkowników

Wszyscy użytkownicy muszą mieć dostęp do usług SA-Frontend i SA-WebApp. Wdrożono przy użyciu następujących zasobów Istio:

  • Rola usługi — określa uprawnienia przysługujące użytkownikowi;
  • Wiązanie roli usługi — określa, do kogo należy ta rola usługi.

Zwykłym użytkownikom umożliwimy dostęp do niektórych usług (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: ["*"]

I przez regular-user-binding zastosuj ServiceRole do wszystkich odwiedzających stronę (powiązanie roli usługi zwykłego użytkownika.yaml):

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

Czy „wszyscy użytkownicy” oznaczają, że nieuwierzytelnieni użytkownicy będą również mieli dostęp do aplikacji SA WebApp? Nie, polityka sprawdzi ważność tokena JWT.

Zastosujmy konfiguracje:

$ 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

Konfiguracja dostępu dla moderatorów

Moderatorom chcemy umożliwić dostęp do wszystkich usług (mod-service-role.yaml):

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

Ale chcemy takich praw tylko dla tych użytkowników, których token dostępu zawiera roszczenie https://sa.io/group ze znaczeniem Moderators (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" 

Zastosujmy konfiguracje:

$ 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

Ze względu na buforowanie w wysłannikach zastosowanie reguł autoryzacji może zająć kilka minut. Następnie możesz upewnić się, że użytkownicy i moderatorzy mają różne poziomy dostępu.

Wniosek w tej części

A tak na serio, czy widziałeś kiedyś prostsze, łatwe, skalowalne i bezpieczne podejście do uwierzytelniania i autoryzacji?

Aby uzyskać precyzyjną kontrolę nad uwierzytelnianiem i autoryzacją dostępu użytkownika końcowego do usług, potrzebne były tylko trzy zasoby Istio (RbacConfig, ServiceRole i ServiceRoleBinding).

Dodatkowo zajęliśmy się tymi zagadnieniami w ramach usług poselskich, osiągając:

  • zmniejszenie ilości kodu ogólnego, który może zawierać problemy i błędy bezpieczeństwa;
  • ograniczenie liczby głupich sytuacji, w których jeden punkt końcowy okazał się dostępny z zewnątrz i zapomniał o tym zgłosić;
  • wyeliminowanie konieczności aktualizacji wszystkich usług po każdym dodaniu nowej roli lub uprawnienia;
  • aby nowe usługi pozostały proste, bezpieczne i szybkie.

Wniosek

Istio pozwala zespołom skoncentrować swoje zasoby na zadaniach o znaczeniu krytycznym dla firmy bez zwiększania kosztów usług, przywracając im status mikro.

Artykuł (w trzech częściach) dostarczył podstawowej wiedzy i gotowych praktycznych wskazówek, jak rozpocząć pracę z Istio w rzeczywistych projektach.

PS od tłumacza

Przeczytaj także na naszym blogu:

Źródło: www.habr.com

Dodaj komentarz