O konfiguracji sieci w Azure App Service Enviroment słów kilka. A może więcej niż kilka.
Jeśli czytaliście mój poprzedni artykuł o budowaniu aplikacji w chmurze bez użycia serwera to zapewne wiecie, że…App Service Enviroment to dedykowane środowisko dostarczające z jednej strony, łatwość wdrażania aplikacji, właściwe dla zwykłego App Service, ale pozwalające dużo bardziej precyzyjnie sterować ruchem sieciowym.
Banał, w dodatku wszystkie aspekty tej konfiguracji opisane są w dokumentacji Azure (trzeba przyznać, że nie w jednym a kilku artykułach) a jednak pierwsza konfiguracja i zrozumienie o co chodzi może młodemu (nie wiekiem a doświadczeniem) adeptowi sztuki nastręczyć nieco trudności.
Zróbmy więc to krok po kroku ale najpierw nieco teorii i wyjaśnień jak to działa.
Jeśli nie interesuje Cię teoria (nie rozumiem dlaczego miało by tak być:)) ale chcesz zrobić tak, by działało, przejdź od razu do zrzutów z mojej konfiguracji.
Zachęcam jednak by poświęć chwilę i zrozumieć szczegóły, grafiki zapożyczyłem od Christina Compy, która decyduje o rozwoju ASE.
- Po pierwsze, ASE zawsze powstaje w ramach dedykowanego subnet'u w ramach wybranego VNET'u.
Cała infrastruktura dedykowanych maszyn wirtualnych w ramach klastra, na których "stoi" Wasze ASE występuje właśnie w tej sieci. Cała komunikacja sieciowa, jaka wchodzi do ASE odbywa się przez tzw. VIP czyli Virtual IP, który jest publiczny i widoczny z Internetu. To stanie się niezwykle istotne w drugiej części artykułu. Dokumentacja o tym pisze tak: Architektura sieci w ramach ASE.
- Jeśli tworzycie nowe ASE, polecam wcześniej utworzyć VNET w wybranym regionie a w nim Subnet, w którym Wasze ASE będzie gościło .
Nie polegajcie na kreatorze Azure, który utworzy dużą sieć (/16 jeśli mnie pamięć nie myli) i zawsze z tą samą adresacją wewnętrzną (nie jest to problem dopóki nie chcecie korzystać z Express Route lub VNET Peering).
I tutaj kilka rekomendacji:
- Wasz Subnet musi być tak duży, by pomieścić wszystkie nody ASE, o które w przyszłości powiększycie Wasze środowisko. Jeśli dziś Wasze ASE ma tylko 2 instancje w ramach puli FE i 2 instancje w WP1 (jest to minimalny rozmiar ASE), a w przyszłości dojdziecie do maksymalnych 50 instancji to Wasza sieć musi być na to gotowa, inaczej się NIE "wyskalujecie". Proponuję by też VNET, w ramach którego tworzycie ASE miał unikalną adresację (bo patrz pkt 2.) na wypadek gdybyście kilka ASE chcieli przez ER wystawić do Waszego DC.
- Nie da się na dziś zmienić sieci (VNET, Subnet) w któym występuje Wasze ASE. Jeśli je chcecie zmienić ze względu na adresację, wielkość musicie usunąć środowisko i powołać od początku.
- Jeśli Wasze ASE ma być dostępne przez ExpressRoute to sieć, której będziecie używali nie może występować po stronie Waszego DC. Niby oczywiste prawda? ;)
- Microsoft zaleca by subnet, w którym wdrażacie ASE był pusty, inaczej w przypadku problemów Support może odmówić wsparcia . Skoro MSFT oficjalnie zaleca to nie ma co dyskutować, szkoda czasu :)
- Jeśli chcecie by Wasze ASE było dostępne tylko dla rozwiązań w ramach Azure (nie dostępne z Internetu) lub tylko przez sieć w ramach ExpressRoute wtedy zależy Wam na ILB (Internal Load Balancer) w ramach ASE. Opcja dostępna tylko przy tworzeniu ASE, potem oczywiście nie ma opcji zmiany.
I na koniec, możliwy jest również scenariusz, w którym jedno ASE jest "publiczne", drugie "dostępne tylko w Azure" i Wasza aplikacja jest rozłożona pomiędzy tymi warstwami ASE. Poglądowo wygląda to tak jak niżej. Na dziś jest to dość kosztowna opcja, jak pamiętacie, najmniejsze bazowe ASE "pochłonie" ok. 1200 banknotów z podobizną Washington'a.
Skoro już wiemy, jak utworzyć nasze ASE poprawnie, to teraz przejdźmy do naszego realnego scenariusza. To, co chcemy osiągnąć, jest zilustrowane na rysunku poniżej:
- Tylko wybrane aplikacje, wdrożone na ASE są dostępne z Internetu. Inne, "prywatne", są dostępne tylko z publicznej aplikacji w ramach ASE.
- Ruch do publicznej aplikacji, wdrożonej na ASE może przyjść tylko z WAF'a (Web nie Windows:) Application Firewall) lub innego "appliance", wdrożonego w Azure. Na rysunku poniżej brakuje wspominanego WAF - wiadomo, że stoi pomiędzy ruchem z Internetu a VIP
- I na koniec… każdy ruch, który nie przeszedł przez WAF'a, a próbuje odpytywać przez VIP naszą publiczną aplikację, powinien być terminowany na poziomie sieci Vnet (Subnet) a nie na poziomie samej aplikacji publicznej. Zaleta moim zdaniem niedoceniona, a przecież nie możliwe do zrealizowania w zwykłym AppService i takimi zapytaniami może generować niepotrzebną utylizację zasobów AppService i w szczególności doprowadzić do niedostępności usługi. AppService nie ma pojęcia sieci, którą może sterować i jedyna konfiguracja wyłączająca konkretne adresy IP może odbyć się na poziomie Web.config.
- Możecie ten scenariusz jeszcze bardziej rozbudować, a mianowicie:
1. W moim podejściu tylko jedna (publiczna co zrozumiałe) będzie miała własną nazwę / domenę i będzie dostępna pod publicznym adresem IP
2. Ponieważ ASE może być duże, możecie mieć kilka aplikacji publicznych, każda pod inną, własną domeną, ale wtedy musicie skorzystać z tzw. IP-SSL Binding i zwiększyć liczbę publicznych adresów przypisanych do waszego ASE. Jest dostępna taka opcja w głównych opcjach ASE pod nazwą IP addresses. Domyślnie macie tylko jeden taki adres, dodanie kolejnego potrafi potrwać chwilę.
Możecie postawić podchwytliwe pytanie: kiedy następuje operacja wiązania kolejnego publicznego IP z wybraną nazwą własną i czy muszę to wywołać przez portal / skrypt PowerShell? Odpowiedź: przy dodawaniu kolejnej nazwy własnej do aplikacji (co zobaczycie poniżej) następuje powiązanie tej nazwy z adresem IP (sam Azure to robi), co jest ładnie widoczne w opcji IP addresses, o której pisałem wyżej. Posiadanie wielu adresów z wieloma nazwami własnymi daje jeszcze jedną elastyczność - możecie przypisać różne reguły dla ruchu wchodzącego/wychodzącego per aplikacja (a tak naprawdę per przypisany do niej adres IP). Bierze się to stąd, że cały ruch wewnątrz ASE pomiędzy aplikacjami następuje zawsze z VIP i do VIP przypisanego do aplikacji. Ruch wewnątrz ASE nie wychodzi poza wskazany dla ASE subnet ale jest tak oznaczany w nagłówkach TCP IP i dlatego też możliwe jego rozróżnienie.
Prześledźmy zrzuty ekranu z konfiguracji, którą wykonałem.
W mojej konfiguracji dodatkowo dodałem certyfikat SSL na poziomie VIP'a w ramach ASE, zalecam jednak terminację SSL robić na WAF i nie ustawiać jej już na poziomie VIP'a. Pokażę to w kolejnym poście.
- Pierwszy krok to ustalić VIP naszego ASE, którzy przy okazji jest adresem wychodzącym, z którego wychodzi cały ruch wychodzący z ASE.
- Jeśli już powołaliście swojego WAF'a do życia i udało Wam się zalogować do konsoli (tutaj dla Barracuda) musicie dodać nowy serwis. Ważne: Żeby określić Waszą usługę przez adres IP a nie nazwę musicie włączyć w Barracuda tzw. Advanced Mode w ustawieniach konfiguracji samej Barracuda. Tutaj link jak zacząć z Barracuda WAF.
- Czas dodać własną domenę do naszej aplikacji w ramach ASE. Nic trudnego, tak samo wygląda to dla App Service.
- Dodajemy host name, potwierdzamy, że jesteśmy właścicielami domeny. U dostawcy domeny zmieniamy rekord tylko na czas ustawienia tego poświadczenia. Docelowo przecież moja nazwa dla aplikacji czyli michal.architektwchmurze.pl nie będzie rozwiązywana na VIP dla ASE a na... adres publiczny WAF lub adres publiczny Load Balancera, który "stoi" przed parą WAF'ów.
- Efekt powinien być taki jak niżej. I tu właśnie doskonale widać, że moja nazwa rozwiązuje się na adres publiczny WAF'a. Możecie zapytać - to po co ta cała zabawa z potwierdzeniami domeny? To trochę tak, jak ustawianie "custom host header" w serwerze aplikacyjnym, dzięki któremu wiemy jak rozróżnić wiele różnych żądań po porcie 80 z jednoczesnym potwierdzeniem, że macie prawa do tej właśnie publicznej nazwy.
- A teraz pobawimy się siecią. O tym jak kontrolować sieć w ramach ASE więcej tutaj Jak kontrolować ruch wchodzący do ASE. Kluczowa z całego artykułu jest tabelka jak niżej, która pokazuje porty, używane przez ASE. Na czerwono te obowiązkowe, w szczególności 454, 455, które jeśli nie są dostępne, są blokowane, to wtedy Wasze ASE pokaże w portalu, że ma wewnętrzny problem albo że jest niedostępne. I tu ciekawostka, domyślnie sieć dla ASE nie ma przypisanego NSG, kiedy dodacie do niej własne NSG to już te porty powinny być tam przez Was określone. Azure nie zrobi tego sam.
- Ja wykorzystałem jedno z NSG, które już było w mojej subskrypcji. Co tu mamy:
- Pozwalam na ruch po porcie 80 i 443 z mojego WAF.
- Pozwalam na ruch po 454 oraz 455 tu oznaczony jako Internet ale ten ruch zawsze będzie z portu VIP.
- I niepotrzebnie pozwalam na ruch po porcie 3389 - tak to jest, jak korzysta się z już dostępnego NSG.
- Aby nie popełnić mojego błędu i zrobić to w 100% profesjonalnie, waszym przyjacielem będzie PowerShell, opisany znowu w tym samym artykule: Jak kontrolować ruch wchodzący do ASE
- I teraz już tylko przyjemności: dodanie do wybranego przez Was subnetu utworzonej wcześniej Network Security Group
- Sprawdzenie, że przypisanie odbyło się poprawnie.
- I testy - najpierw staram się dostać do mojej aplikacji przez publiczny adres DNS, który jest przypisany każdej web aplikacji w ASE (o ile nie występuje z ILB)
- A teraz dostaję się do mojej aplikacji po mojej własnej nazwie i domenie i jest... Aplikacja odpowiada. Skąd mam pewność, że ruch idzie przez WAF? Bo jak widzieliście wcześniej michal.architektwchmurze.pl wskazuje właśnie na mojego WAF.
Na dziś koniec. Jak kontynuację tego postu, pokażę Wam jak do tej konfiguracji dodać certyfikaty.
Zachęcam do własnych zabaw i pytań. Temat w gruncie rzeczy jest prosty, wymaga jednak chwili, by zrozumieć teorię.