artykuły

VPC – wprowadzenie do sieci w AWS

Brak komentarzy

Czego się dowiesz

W tym artykule stworzę topologię sieci, która odwzorowuje tą dostarczaną domyślnie przez AWS dla każdego nowego konta (Default VPC). Podczas tworzenia opiszę działanie poszczególnych elementów i funkcjonalność, którą dostarczają.

Całość opiszę za pomocą CloudFormation by usprawnić wdrożenie i późniejsze utrzymanie. Opis szablonu podzielę na sekcje, które opiszę, tak by łatwo dowiedzieć się co w nich zadeklarowałem.

Na samym końcu pochylę się nad tematem kosztu wykonanej przeze mnie sieci.

Po co mi to wszystko?

Virtual Private Cloud czyli VPC, to wirtualne sieci. Używając ich zyskuję pełną kontrolę nad ruchem sieciowym. Dzięki temu jestem w stanie ukryć moje wrażliwe zasoby(np. baza danych, maszyna wirtualna, etc.) w prywatnych subnetach, z którymi nie ma połączenia z internetem. Z kolei w przypadku w którym moi klienci komunikują się ze mną poprzez publiczny internet zasoby które muszę im udostępnić, ulokuję w publicznych subnetach. Jeżeli natomiast komunikacja z klientem odbywa się za pomocą np. VPN’a (może jest to system on-prem) to ruch mogę przekierować do konkretnego subnetu!
Jak widzisz opcji na wykorzystanie VPC i jego składników jest bardzo, bardzo dużo.

VPC – wymagania

Zacznę od ogólnego opisu funkcjonalnego. W mojej sieci chcę:

  • korzystać z usług o wysokiej dostępności, w tym celu stworzę subnety w różnych strefach dostępności,
  • by we wszystkich subnetach mojego VPC był dostęp do Internetu oraz by zasoby w nich umieszczone mogły być z niego dostępne. W skrócie, by wszystkie subnety były publiczne.

Końcowa topologia mojej sieci jest widoczna na diagramie poniżej. Widać na nim trzy subnety, które mają możliwość komunikowania się z Internetem, ich tablicę routingu oraz NACL – namiastkę sieciowego firewalla.

Docelowa topologia VPC

Anatomia sieci w AWS

VPC

VPC jest fundamentem na którym opiera się cała infrastruktura sieciowa którą tworzy się w AWS. Jako wirtualna sieć pozwala na lokowanie zasobów w dowolnej availability zone, jeśli tylko utworzymy w niej subnet. To z kolei pozwala na tworzenie rozwiązań które maja wysoką dostępność(High Availability).

Podczas tworzenia VPC określa się blok CIDR, w którym będą znajdować się wszystkie zasoby przypisane do naszej sieci.

Subnet

Określa logiczny podział sieci. Adresy dostępne wewnątrz subnetu określa się za pomocą bloku CIDR. Określa on również rozmiar naszej przestrzeni adresowej, czyli to jak wiele zasobów może znaleźć się w opisywanym subnecie.
Na poziomie subnetu określa się tablice routingu(route table) oraz listy kontroli dostępu (NACL).

Route table

Tablica trasowania – jest to mapa mówiąca o tym gdzie każdy z pakietów wychodzących z naszego subnetu powinien zostać przekierowany.

Adres docelowy Kolejny cel
10.4.0.0/16local
192.168.0.0/16virtual-private-gateway
0.0.0.0/0internet-gateway

Załóżmy, że do naszego subnetu przypinamy powyższą tablicę routingu. W takim przypadku kolejny cel pakietu wychodzącego określamy patrząc na adres docelowy. Jeżeli znajduje się wewnątrz bloku:

  • 10.4.0.0/16 to przekieruj pakiet wewnątrz VPC
  • 192.168.0.0/16 to jest to pakiet przeznaczony do sieci naszego klienta i przekieruj go do połączenia VPN
  • Adres nie pasuje do żadnej poprzedniej reguły przekieruj do internet gateway’a

Podczas routingu przeglądana jest cała tablica, z której jest wybierany najlepiej dopasowany wpis, na podstawie docelowego adresu. Najlepiej dopasowaną będzie reguła dla konkretnego adresu (maska /32).

Internet gateway

Jest to komponent który pozwala na komunikację między zasobami w VPC a Internetem. Komunikacja jest możliwa tylko jeśli zasób posiada publiczny adres IP.
Internet Gateway jest skalowalny i ma wysoką dostępność. Dzięki temu nie muszę martwić się czy da radę obsłużyć ruch między moją siecią a Internetem. Jeżeli subnet ma trasę prowadzącą bezpośrednio do Internet Gateway’a nazywa się go subnetem publicznym.

W sytuacji w której zasoby nie mogą mieć lub zwyczajnie nie chcę przypisać im publicznych adresów IP muszę wykorzystać NAT Gateway. Subnet, który nie ma trasy do Internet Gateway’a nazywa się subnetem prywatnym.

NAT Gateway

Podobnie jak Internet Gateway pozwala na komunikację między zasobami wewnątrz subnetu a Internetem. Zasadniczą różnicą jest to, że dokonuje translacji adresów przez co nie wymaga aby zasoby, które z niego korzystają miały przypisany publiczny adres IP. Brak tego wymogu oznacza również, że zasoby które korzystają z NAT Gateway jako bramy na świat nie są osiągalne z publicznego Internetu.

Network ACL

To nic innego jak listy dostępu do subneta – firewall. W domyślnej konfiguracji przepuszcza cały ruch wejściowy i wyjściowy.

NACL działa na podstawie zdefiniowanych reguł. Wpisy rozpatrywane są w odpowiedniej kolejności – od najniższej do najwyższej.
Jako decydująca brana jest pierwsza z reguł która pasuje do rozpatrywanego adresu IP.
Każdy NACL posiada regułę, oznaczoną za pomocą znaku *. Reguła ta rozpatrywana jest jako ostatnia i odrzuca ruch, który nie został dopasowany do poprzednich.

Wykonanie

W celu ułatwienia wielokrotnego tworzenia naszego VPC zostanie opisane za pomocą CloudFormation. Całość podzielę na cztery kroki.

VPC

  AWSTemplateFormatVersion: "2010-09-09"
  Description: Basic Network Structure
  Resources:
    Vpc:
      Type: AWS::EC2::VPC
      Properties:
        CidrBlock: '10.0.0.0/16'
        EnableDnsHostnames: true

Dodaję tutaj jedynie VPC. Ustalam blok adresów na 10.0.0.0-10.0.255.255. Moim celem jest odwzorowanie domyślnie tworzonego VPC więc ustawiam EnableDnsHostnames na true by każdemu zasobowi z publicznym adresem IP przydzielać jednocześnie publicznie rozwiązywalny adres w DNS. Dla przykładu jeśli nasza EC2 dostanie adres 176.34.138.87 to równocześnie zostanie jej przydzielona domena ec2-176-34-138-87.eu-west-1.compute.amazonaws.com

Internet Gateway

  AWSTemplateFormatVersion: "2010-09-09"
  Description: Basic Network Structure
  Resources:
    Vpc:
      Type: AWS::EC2::VPC
      Properties:
        CidrBlock: '10.0.0.0/16'
        EnableDnsHostnames: true
    InternetGateway:
      Type: AWS::EC2::InternetGateway
    InternetGatewayAttachment:
      Type: AWS::EC2::VPCGatewayAttachment
      Properties:
        InternetGatewayId: !Ref InternetGateway
        VpcId: !Ref Vpc

Następnie w liniach 9-10 tworzę Internet Gateway a później(11-15) przypisuję do wcześniej utworzonego VPC.

Tablica routingu

  AWSTemplateFormatVersion: "2010-09-09"
  Description: Basic Network Structure
  Resources:
    Vpc:
      Type: AWS::EC2::VPC
      Properties:
        CidrBlock: '10.0.0.0/16'
        EnableDnsHostnames: true
    InternetGateway:
      Type: AWS::EC2::InternetGateway
    InternetGatewayAttachment:
      Type: AWS::EC2::VPCGatewayAttachment
      Properties:
        InternetGatewayId: !Ref InternetGateway
        VpcId: !Ref Vpc
    RouteTable:
      Type: AWS::EC2::RouteTable
      Properties:
        VpcId: !Ref Vpc
    InternetRoute:
      Type: AWS::EC2::Route
      Properties:
        DestinationCidrBlock: '0.0.0.0/0'
        RouteTableId: !Ref RouteTable
        GatewayId: !Ref InternetGateway

Kolejnym krokiem jest stworzenie RouteTable(17-20) oraz jednej trasy dla każdego pakietu(0.0.0.0/0) wskazującej na wcześniej utworzony Internet Gateway.
Każda tablica routingu ma domyślny wpis dla ruchu lokalnego. W tym przypadku jest to 10.0.0.0/16.

Stworzona tablica w rezultacie wygląda w ten sposób:

Route table used in the vpc
Wynikowa tablica routingu

Subnety

Teraz pozostaje mi dodać ostatnie brakujące części sieci, subnety. Każdy z nich będzie wyglądał podobnie, tak jak na poniższym listingu.

SubnetA:
  Type: AWS::EC2::Subnet
  Properties:
    CidrBlock: '10.0.1.0/24'
    VpcId: !Ref Vpc
    AvailabilityZone: eu-west-1a
    MapPublicIpOnLaunch: true

Dla każdego z subnetów muszę podać blok CIDR oraz VPC w którym ma się znaleźć.

W moim przypadku chcę lokować subnet w konkretnym availability zone by łatwo je nazywać(SubnetA). Kolejną rzeczą którą muszę zrobić to przypisywać publiczne IP tworzonym zasobom by mogły one korzystać z dostępu do internetu przez Interet Gatway.

Dla każdego subnetu muszę też wskazać z której tablicy routingu korzysta – stworzyć asocjację. Listing poniżej pokazuje jak to zrobić:

SubnetATableAssociation:
      Type: AWS::EC2::SubnetRouteTableAssociation
      Properties:
        RouteTableId: !Ref RouteTable
        SubnetId: !Ref SubnetA        

Finalny CloudFormation ze wszystkimi elementami:

  AWSTemplateFormatVersion: "2010-09-09"
  Description: Basic Network Structure
  Resources:
    Vpc:
      Type: AWS::EC2::VPC
      Properties:
        CidrBlock: '10.0.0.0/16'
        EnableDnsHostnames: true
    InternetGateway:
      Type: AWS::EC2::InternetGateway
    InternetGatewayAttachment:
      Type: AWS::EC2::VPCGatewayAttachment
      Properties:
        InternetGatewayId: !Ref InternetGateway
        VpcId: !Ref Vpc
    RouteTable:
      Type: AWS::EC2::RouteTable
      Properties:
        VpcId: !Ref Vpc
    InternetRoute:
      Type: AWS::EC2::Route
      Properties:
        DestinationCidrBlock: '0.0.0.0/0'
        RouteTableId: !Ref RouteTable
        GatewayId: !Ref InternetGateway
    SubnetA:
      Type: AWS::EC2::Subnet
      Properties:
        AvailabilityZone: eu-west-1a
        CidrBlock: '10.0.1.0/24'
        MapPublicIpOnLaunch: true
        VpcId: !Ref Vpc
    SubnetATableAssociation:
      Type: AWS::EC2::SubnetRouteTableAssociation
      Properties:
        RouteTableId: !Ref RouteTable
        SubnetId: !Ref SubnetA        
    SubnetB:
      Type: AWS::EC2::Subnet
      Properties:
        AvailabilityZone: eu-west-1b
        CidrBlock: '10.0.2.0/24'
        MapPublicIpOnLaunch: true
        VpcId: !Ref Vpc
    SubnetBTableAssociation:
      Type: AWS::EC2::SubnetRouteTableAssociation
      Properties:
        RouteTableId: !Ref RouteTable
        SubnetId: !Ref SubnetB
    SubnetC:
      Type: AWS::EC2::Subnet
      Properties:
        AvailabilityZone: eu-west-1c
        CidrBlock: '10.0.3.0/24'
        MapPublicIpOnLaunch: true
        VpcId: !Ref Vpc
    SubnetCTableAssociation:
      Type: AWS::EC2::SubnetRouteTableAssociation
      Properties:
        RouteTableId: !Ref RouteTable
        SubnetId: !Ref SubnetC  

Deploy mojego rozwiązania mogę wykonać na dwa podstawowe sposoby albo za pomocą konsoli webowej albo z użyciem linii poleceń i programu aws cloudformation deploy.

Ale czegoś tu brakuje?

Jeśli dobrze się przyjrzysz brakuje tutaj jednej z opisanych wcześniej rzeczy – NACL. Jest tak ponieważ jest ona tworzona automatycznie, razem z tworzeniem VPC i domyślnie przypisywana do każdego subnetu. Możesz ją zmienić jawnie tworząc listę a później wiążąc ją z konkretnymi subnetami. W dokładnie taki sam sposób jak przy tworzeniu tablic routingu.

Tak się jednak składa, że domyślne NACL jest takie dokładnie takie jakie mam w założeniu, czyli zezwala na cały ruch do i z sieci.

Koszt

Dobra wiadomość jest taka, że stworzenie powyższego VPC i jego komponentów nie jest obarczone żadnymi dodatkowymi opłatami! Trzeba natomiast uważać na koszta dodatkowego monitorowania, użycia innych elementów, jak NAT Gateway czy połączenia VPN.

Z opisanych przeze mnie zasobów jedynie wykorzystanie NAT Gateway’a wprowadza dodatkowy koszt. W przypadku rejonu eu-west-1( Irlandia) jest to $0.048 za każdą godzinę działania oraz $0.048 za każdy przetworzony GB . Więcej szczegółów na temat dodatkowych kosztów związanych z VPC znajduje się tutaj.

Tags: , , , , ,

Powiązane artykuły

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *

Wypełnij to pole
Wypełnij to pole
Proszę wprowadzić prawidłowy adres email.
You need to agree with the terms to proceed

Menu