
Przyp. tłum.: Ten cykl był poświęcony możliwościom Istio oraz ich prezentacji w działaniu, — precyzyjnie dostosowanej trasowaniu i zarządzaniu ruchem sieciowym. Teraz porozmawiamy o bezpieczeństwie: do demonstracji podstawowych funkcji związanych z tym tematem autor wykorzystuje usługę tożsamości Auth0, jednak podobnie można skonfigurować innych dostawców.
Skonfigurowaliśmy klaster Kubernetes, w którym uruchomiliśmy Istio i przykładową aplikację mikroserwisową Sentiment Analysis, ilustrując możliwości Istio.
Dzięki Istio udało nam się zachować niewielki rozmiar usług, ponieważ nie wymagają one wdrożenia takich „warstw”, jak ponowne próby połączenia (Retries), limity czasowe (Timeouts), automatyczne wyłączniki (Circuit Breakers), śledzenie (Tracing), monitorowanie (Monitoring). Ponadto zastosowaliśmy zaawansowane techniki testowania i wdrażania: A/B-testy, mirroring i kanaryczne wypuszczenia.

W nowym materiale przyjrzymy się ostatnim warstwom na drodze do wartości biznesowej: autoryzacji i uwierzytelnieniu — a w Istio to czysta przyjemność!
Uwierzytelnienie i autoryzacja w Istio
Nigdy bym nie pomyślał, że zainspiruje mnie autoryzacja i uwierzytelnienie. Co takiego może technologicznie zaoferować Istio, aby te tematy były frapujące, a nawet więcej — aby zainspirowały i Was?
Odpowiedź jest prosta: Istio przenosi odpowiedzialność za te możliwości z Twoich usług na proxy Envoy. W momencie, gdy zapytania docierają do usług, są już uwierzytelnione i autoryzowane, więc pozostaje Ci tylko pisać przydatny kod biznesowy.
Brzmi dobrze? Zajrzyjmy więc do środka!
Uwierzytelnienie z Auth0
Jako serwer do zarządzania tożsamością i dostępem użyjemy Auth0, który ma wersję próbną, jest intuicyjny w użyciu i po prostu mi się podoba. Jednak te same zasady można zastosować wobec każdej innej : KeyCloak, IdentityServer i wielu innych.
Na początek wejdź na ze swoim kontem, utwórz tenant (tenant — „wynajmujący”, logiczna jednostka izolacji, szczegóły w — przyp. tłum.) i przejdź do Applications > Default App, wybierając Domena, jak pokazano na zrzucie ekranu poniżej:

Podaj tę domenę w pliku resource-manifests/istio/security/auth-policy.yaml ():
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 Mając takie zasoby, Pilot (jeden z trzech podstawowych komponentów Control Plane w Istio — przyp. tłum.) konfiguruje Envoy'e do autoryzacji żądań przed ich przekierowaniem do usług: sa-web-app i sa-feedback. W tym samym czasie konfiguracja nie jest stosowana do Envoy'ów usługi sa-frontend, co pozwala nam zachować frontend nieuwierzytelniony. Aby zastosować politykę (Policy), wykonaj polecenie:
$ kubectl apply -f resource-manifests/istio/security/auth-policy.yaml
policy.authentication.istio.io “auth-policy” utworzonaWróć na stronę i dokonaj żądania — zobaczysz, że zakończy się ono statusem 401 Nieautoryzowany. Teraz przekierujemy użytkowników frontendu do autoryzacji z Auth0.
Autoryzacja żądań z Auth0
Aby uwierzytelnić żądania końcowego użytkownika, należy utworzyć API w Auth0, które będzie reprezentować uwierzytelnione usługi (recenzje, szczegóły i oceny). Aby utworzyć API, przejdź do Auth0 Portal > APIs > Create API i wypełnij formularz:

Ważną informacją tutaj jest Identifier, który później użyjemy w skrypcie. Zapiszmy go sobie tak:
- Audience: {YOUR_AUDIENCE}
Pozostałe potrzebne nam szczegóły znajdują się w Auth0 Portal w sekcji Applications — wybierz Test Application (tworzone automatycznie wraz z API).
Tutaj zapiszemy:
- Domena: {YOUR_DOMAIN}
- Client Id: {YOUR_CLIENT_ID}
Przewiń do Test Application do pola tekstowego Allowed Callback URLs (dozwolone URL'e dla callback'u), w którym wskażemy URL, do którego powinno być wysyłane wywołanie po zakończeniu autoryzacji. W naszym przypadku to:
http://{EXTERNAL_IP}/callbackA dla Allowed Logout URLs (dozwolone URL'e dla wylogowania) dodamy:
http://{EXTERNAL_IP}/logoutPrzejdźmy do frontendu.
Aktualizacja frontendu
Przełącz się na gałąź auth0 repozytorium [istio-mastery]. W tej gałęzi kod frontendu został zmieniony w taki sposób, aby przekierowywać użytkowników do Auth0 w celu autoryzacji i używać tokena JWT w żądaniach do innych usług. Ostatnie zostało zrealizowane w następujący sposób ():
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 przenieść frontend na korzystanie z danych tenants w Auth0, otwórz sa-frontend/src/services/Auth.js i zamień w nim wartości, które zapisaliśmy powyżej ():
const Config = {
clientID: '{YOUR_CLIENT_ID}',
domain:'{YOUR_DOMAIN}',
audience: '{YOUR_AUDIENCE}',
ingressIP: '{EXTERNAL_IP}' // Używane do przekierowania po uwierzytelnieniu
}Aplikacja jest gotowa. Podaj swoje Docker ID w poniższych poleceniach podczas budowania 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-auth0Wypróbuj aplikację! Zostaniesz przekierowany na Auth0, gdzie musisz się zalogować (lub zarejestrować), a następnie zostaniesz odesłany z powrotem na stronę, z której będą już wykonywane uwierzytelnione zapytania. Jeśli spróbujesz wymienionych we wczesniejszych częściach artykułu poleceń za pomocą curl — otrzymasz kod 401 Status Code, sygnalizujący, że zapytanie nie jest autoryzowane.
Zróbmy kolejny krok — autoryzujemy zapytania.
Autoryzacja z Auth0
Uwierzytelnienie pozwala nam zrozumieć, kim jest użytkownik, ale aby dowiedzieć się, do czego ma dostęp, potrzebna jest autoryzacja. Istio oferuje również narzędzia do tego.
Na przykład stwórzmy dwie grupy użytkowników (patrz na schemat poniżej):
- Użytkownicy (users) — z dostępem tylko do usług SA-WebApp i SA-Frontend;
- Moderatorzy (moderators) — z dostępem do wszystkich trzech usług.

Koncepcja autoryzacji
Aby stworzyć te grupy, skorzystamy z rozszerzenia Auth0 Authorization i za pomocą Istio zapewnimy im różne poziomy dostępu.
Instalacja i konfiguracja Auth0 Authorization
Na portalu Auth0 przejdź do rozszerzeń (Extensions) i zainstaluj Auth0 Authorization. Po instalacji przejdź do Authorization Extension, a następnie do konfiguracji najemcy poprzez kliknięcie w prawym górnym rogu i wybór odpowiedniej opcji menu (Configuration). Aktywuj grupy (Groups) i kliknij przycisk publikacji reguły (Publish rule).

Tworzenie grup
W Authorization Extension przejdź do Groups i stwórz grupę Moderators. Ponieważ będziemy traktować wszystkich uwierzytelnionych użytkowników jako zwykłych, nie ma potrzeby tworzenia dla nich dodatkowej grupy.
Wybierz grupę Moderators, kliknij na Add Members, dodaj swoje główne konto. Pozostaw niektórych użytkowników bez żadnej grupy, aby upewnić się, że dostęp dla nich jest zabroniony. (Nowych użytkowników można stworzyć ręcznie przez Auth0 Portal > Users > Create User.)
Dodaj Group Claim do Access Token
Użytkownicy zostali dodani do grup, jednak ta informacja musi być również odzwierciedlona w tokenach dostępu. Aby spełnić wymagania OpenID Connect i jednocześnie zwrócić potrzebne grupy, token będzie musiał dodać swoje . Realizowane jest poprzez zasady Auth0.
Aby stworzyć zasadę, przejdź do Portalu Auth0 do Reguły, kliknij na Utwórz Regułę i wybierz pustą zasadę z szablonów.

Skopiuj poniższy kod i zapisz go jako nową zasadę Dodaj Klauzulę Grupy ():
function (user, context, callback) {
context.accessToken['https://sa.io/group'] = user.groups[0];
return callback(null, user, context);
}Uwaga: ten kod bierze pierwszą grupę użytkownika, określoną w Rozszerzeniu Autoryzacji, i dodaje ją do access-tokenu jako custom claim (pod własną przestrzenią nazw, jak wymagane przez Auth0).
Wróć do strony Reguły i upewnij się, że masz dwie zasady zapisane w następującej kolejności:
- auth0-authorization-extension
- Dodaj Klauzulę Grupy
Kolejność ma znaczenie, ponieważ pole grupy asynchronicznie otrzymuje zasadę auth0-authorization-extension i jest następnie dodawane jako claim drugą zasadą. W rezultacie otrzymujemy taki access-token:
{
"https://sa.io/group": "Moderators",
"iss": "https://sentiment-analysis.eu.auth0.com/",
"sub": "google-oauth2|196405271625531691872"
// [skrócone dla czytelności]
} Teraz należy skonfigurować proxy Envoy, aby sprawdzało dostęp użytkownika, zatem grupa będzie wyciągana z claim (https://sa.io/group) w zwracanym access-tokenie. To temat na kolejny rozdział artykułu.
Konfiguracja autoryzacji w Istio
Aby autoryzacja działała, należy włączyć RBAC dla Istio. W tym celu skorzystamy z 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śnienia:
- 1 — włączamy RBAC tylko dla usług i przestrzeni nazw wymienionych w polu
Inclusion; - 2 — wymieniamy listę naszych usług.
Zastosujemy konfigurację takim poleceniem:
$ kubectl apply -f resource-manifests/istio/security/enable-rbac.yaml
rbacconfig.rbac.istio.io/default created Teraz wszystkie usługi wymagają kontroli dostępu opartej na rolach (Role-Based Access Control). Innymi słowy, dostęp do wszystkich usług jest zabroniony i skutkuje odpowiedzią RBAC: dostęp zabroniony. Teraz zezwolimy na dostęp autoryzowanym użytkownikom.
Konfiguracja dostępu dla zwykłych użytkowników
Wszyscy użytkownicy powinni mieć dostęp do usług SA-Frontend i SA-WebApp. Może być to zrealizowane przy pomocy następujących zasobów Istio:
- ServiceRole — określa prawa, które przysługują użytkownikowi;
- ServiceRoleBinding — określa, do kogo odnosi się ta ServiceRole.
Dla zwykłych użytkowników umożliwimy dostęp do określonych usług ():
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 przez regular-user-binding zastosujemy ServiceRole do wszystkich odwiedzających stronę ():
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" oznacza, że także nieuwierzytelnieni użytkownicy uzyskają dostęp do SA WebApp? Nie, polityka sprawdzi ważność tokenu JWT.
Zastosujemy konfiguracje:
$ kubectl apply -f resource-manifests/istio/security/user-role.yaml
servicerole.rbac.istio.io/regular-user utworzony
servicerolebinding.rbac.istio.io/regular-user-binding utworzonyKonfiguracja dostępu dla moderatorów
Dla moderatorów chcemy umożliwić dostęp do wszystkich usług ():
apiVersion: "rbac.istio.io/v1alpha1"
kind: ServiceRole
metadata:
name: mod-user
namespace: default
spec:
rules:
- services: ["*"]
paths: ["*"]
methods: ["*"] Ale chcemy mieć takie prawa tylko dla tych użytkowników, w których access-tokenie znajduje się claim https://sa.io/group o wartości Moderators ():
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" Zastosujemy konfiguracje:
$ kubectl apply -f resource-manifests/istio/security/mod-role.yaml
servicerole.rbac.istio.io/mod-user utworzony
servicerolebinding.rbac.istio.io/mod-user-binding utworzonyZ powodu buforowania w envoyach, aby nowe zasady autoryzacji zaczęły obowiązywać, może być potrzebne kilka minut. Po tym czasie upewnisz się, że użytkownicy i moderatorzy mają różne poziomy dostępu.
Podsumowanie tej części
No serio: czy kiedykolwiek widziałeś prostsze, bezwysiłkowe, skalowalne i bezpieczne podejście do autoryzacji i uwierzytelniania?
Tylko trzy zasoby Istio (RbacConfig, ServiceRole i ServiceRoleBinding) były potrzebne, aby uzyskać szczegółową kontrolę nad autoryzacją i uwierzytelnianiem dostępu użytkowników końcowych do usług.
Dodatkowo przenieśliśmy troskę o te problemy z naszych usług do envoy, osiągając:
- zmniejszenie ilości typowego kodu, w którym mogą pojawić się problemy z bezpieczeństwem i błędy;
- zmniejszenie liczby głupich sytuacji, w których jeden punkt końcowy był dostępny z zewnątrz i zapomniał o tym poinformować;
- eliminacji potrzeby aktualizacji wszystkich usług przy każdym dodaniu nowej roli lub uprawnienia;
- tego, że nowe usługi pozostają proste, bezpieczne i szybkie.
Wnioski
Istio pozwala zespołom skupić swoje zasoby na kluczowych zadaniach biznesowych, nie dodając obciążeń do usług, przywracając je do statusu 'mikro'.
Artykuł (w trzech częściach) dostarczył podstawową wiedzę oraz gotową praktyczną instrukcję do rozpoczęcia pracy z Istio w rzeczywistych projektach.
P.S. od tłumacza
Przeczytaj także na naszym blogu:
- „Powrót do mikroserwisów z Istio”: , ;
- «»;
- «».
Źródło: habr.com
