Amazon AWS udostępnia szeroką gamę serwisów, które możemy wykorzystać do udostępnienia światu usługi, na którą czeka. Wśrod nich jest serwis AWS Identity Access Management, zdecydowanie najmniej ‘sexy’, ale być może najważniejszy z nich. Bez względu na to, którą usługę się decydujemy, bez odwołania się do IAM będzie prawdopodobnie bezużyteczna. Jak sama nazwa wskazuje IAM jest miejscem, w którym zarządza się uprawnieniami w ramach naszego konta AWS.
Zgodnie z zaleceniami AWS odradza się korzystanie z konta roota (użytkownika podanego podczas rejestracji w AWS) do codziennej pracy, gdyż w przypadku jego przejęcia może nas to narazić na ogromne koszty. Użytkownik root ma nieograniczone uprawnienia i może tworzyć dowolne zasoby, co w połączeniu z naszą kartą kredytową oznacza prostą drogę do katastrofy. Dlatego konto root powinno się charakteryzować bardzo silnymi zabezpieczeniami i powinno być używane jedynie w szczególnych sytuacjach. Do codziennej pracy powinniśmy wykorzystywać użytkownika, który ma wystarczające uprawnienia do zarządzania serwisami, które nas interesują.
Korzystając z serwisów AWS uprawnienia przydziela się także poszczególnym usługom, jeżeli konieczne jest by ta komunikowała się z inną w ramach naszego konta. Na przykład funkcja lambda, której działania polega na odczytywaniu zawartości kubełka S3 potrzebuje pozwolenia na dostęp do konkretnych zasobów. Jeżeli funkcja zawsze odczytuje ten sam obiekt, definiując uprawnienie możemy ograniczyć je do konkretnie wskazanej lokalizacji. W innym przypadku bardziej sensowna może być zgoda na odczyt ze wszystkich kubełków w regionie.
Od poprawnego użycia serwisu AWS IAM zależy, czy nasza aplikacja będzie bezpieczna dla nas i dla naszych klientów, dlatego zabezpieczenie dostępu do używanych zasobów w ramach konta AWS powinno być kluczową kwestią. W tym momencie warto przypomnieć, czym IAM nie jest. Ta usługa nie nadaje się do zabezpieczania dostępu do aplikacji, którą tworzymy albo zarządzania danymi naszych klientów.
Zarządzanie uprawnieniami
Każdy z serwisów AWS udostępnia szereg akcji, które można wykonywać za pośrednictwem konsoli WWW, lini poleceń albo SDK. W każdym przypadku do wykonania akcji jest niezbędne uprawnienie zdefiniowane w serwisie AWS IAM. Pojedyncze uprawnienia w ramach jednego serwisu można połączyć policy (po polsku policy to polityka, co brzmi nienaturalnie, więc w tym przypadku będę używał angielskiego terminu). Jeżeli tą samą grupę uprawnień zamierzamy przydzielić wielu użytkownikom warto zdefiniować policy jeden raz pod wybraną nazwą. W takim przypadku mówimy o Managed Policy. Jeżeli na to się nie zdecydujemy, to określając uprawnienia dla każdego użytkownika będzie to trzeba robić jedno po drugim. W tej sytuacji będziemy mówić o inline policy.
Definiowanie policy
Jak w przypadku każdego serwisu AWS z IAM możemy korzystać używając konsoli WWW, lini poleceń albo SDK. Bez względu na to, jaką metodę użyjemy warto pamiętać, że uniwersalną reprezentacją policy jest dokument JSON, który zawiera listę akcji, które łączy, listę zasobów, do których stosuje się policy i (opcjonalnie) listę dodatkowych warunków, kiedy uprawnienia zdefiniowane w policy mają moc. W zależności od tego, jak używamy IAM możemy policy “wyklikać” (w konsoli WWW), albo napisać ręcznie. Pierwsza metoda ma tą przewagę, że nie musimy znać na pamięć wszystkich akcji danego serwisu albo szukać ich w odmętach dokumentacji. Dlatego osobiście polecam podejście utworzenie pierwszej wersji w konsoli WWW, a następnie “dopieścić” ją w dowolnym edytorze tekstowym.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "DostepDoS3",
"Effect": "Allow",
"Action": [
"s3:PutObject",
"s3:GetObject",
"s3:CreateBucket"
],
"Resource": [
"arn:aws:s3:::kubelek-s3",
"arn:aws:s3:::inny-kubelek-s3/test/*"
],
"Condition": {
"BoolIfExists": {
"aws:MultiFactorAuthPresent": "true"
}
}
}
]
}
Przykładowe policy z jedną deklaracją o nazwie DostepDoS3
określa grupę uprawnień do wykonywania akcji w serwisie S3. Akcje które można wykonać jest określone parametrem Action
. Lista zasobów, do których jest ograniczone jest policy, jest zdefiniowana parametrem Resources
. Jeżeli to policy przypisać użytkownikowi, to będzie miał prawo wstawić obiekt (s3:PutObject
) albo odczytać obiekt (s3:GetObject
) z kubełka inny-kubelek-s3
. Ścieżka obiektu musi się rozpoczynać od test
. A więc do kubełka możemy zapisać na przykład obiekt test/w-chmurze/readme.txt
albo odczytać test/pobierz/start.exe
. Z kolei próba odczytu obiektu katalog/w-chmurze/odczyt
zakończy się niepowodzeniem z powodu braku odpowiednich uprawnień. Analogicznie uprawnienie s3:CreateBucket
oznacza zgodę na utowrzenie kubełka o nazwie kubelek-s3
. Jako dodatkowy warunek określamy metodę dwuskładnikową metodę uwierzytelnienia (Multi Factor Authentication). Jeżeli użytkownik, który ma przypisane policy nie zaloguje się przy pomocy MFA, to policy nie będzie miało mocy.
W policy powyżej użyliśmy oświadczenia, w którym dajemy zgodę ("Effect": "Allow"
) na wykonanie określonych akcji. Czasami więcej sensu ma jednak określenie, których akcji użytkownik nie może wykonać.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "PelenDostepDoS3",
"Effect": "Allow",
"Action": "s3:*",
"Resource": "*"
},
{
"Sid": "ZakazUsuwania",
"Effect": "Deny",
"Action": [
"s3:DeleteBucket",
"s3:DeleteObject"
],
"Resource": "*",
}
]
}
Policy zawiera dwa oświadczenia: PelnyDostepDoS3
daje pełny dostęp do S3 i wyszystkich zasobów i ZakazUsuwania
, które wyłącza usuwanie obiektów i kubełków. W rezultacie użytkownik, któremu przypiszemy takie policy może zrobić wszystko, ale nie może usunąć żadnego zasobu. Alternatywą dla tak skonstruowanego policy byłaby lista wszystkich dozwolonych akcji, co by zdecydowanie uczyniło dokument dużo mniej czytelnym.