AWS Transit网关路由

时间:2019-10-02 14:54:11

标签: amazon-web-services

我正在使用专用的Transit Gateway帐户实现Transit Gateway。然后,我打算从不同的帐户连接最多6个AWS VPC。我相信我需要将所有6个Transit Gateway附件添加到同一Transit Gateway路由表中,以允许它们之间的连接-因为AWS不允许您将TGW附件与多个TGW路由表相关联。

这可行,并且所有VPC都可以互相通信-但是控制VPC之间访问的最佳实践是什么。可以说D是公交网关帐户。

VPC A / B / C / D都在TGW路由表上。如果我不希望VPC A与VPC B对话,但允许VPC A与VPC C对话,该怎么办。我知道除非将子网VPC路由添加/传播它们,但我希望获得更多控制权,否则不会发生这种情况。

例如,两个TGW路由表,一个带有TGW附件(D),VPC A,VPCB。另一个TGW路由表带有TGW附件(D),VPC A,VPC C。

我想一种方法是将NACL添加到Transit Gateway子网中,但这只会阻塞整个VPC。

5 个答案:

答案 0 :(得分:1)

您必须根据需要设计网络。

例如,我们有4个VPC-VPC A,B,C,D。

要求:

如果我不希望VPC A与VPC B对话,但允许VPC A与VPC C对话,该怎么办。我知道除非将子网VPC路由添加/传播它们,否则这种情况不会发生,但我想更多控制权。

在设计中:

VPC A <-> VPC C VPC A <-> VPC D

您需要创建一些东西:

  1. 公交网关-tgw

  2. 传输网关附件:将所有VPC A,C,D附加到您创建的传输网关。附件A(VPC A)-> tgw附件C(VPC C)-> tgw附件D(VPC D)-> tgw

  3. 运输网关路由表(tgw-rt1):创建运输网关路由表并与所有附件(A,C和D)关联。创建传播并添加所有附件A,C和D。这将自动生成路由。

这是流量从VPC A到VPC C的流。VPC A中的子网应该具有到tgw的路由,因此流量达到tgw。 tgw查找流量来自哪个附件及其附件A(即VPC A),并找到相应的路由表tgw-rt1。现在,tgw-rt1具有将流量传播到相应附件(即VPC C)的路由。这只是一种方法,为了使流量流回VPC A,您还应该在VPC C中具有路由。

答案 1 :(得分:0)

为回答该问题,模式应如下所示……

每个VPC应该具有一个Transit Gateway附件。 每个VPC都应创建一个“传输网关路由表”。 每个Transit Gateway路由表都应与该Transit Gateway附件关联。 然后应将路由规则作为出口规则添加到Transit Gateway路由表中。

在此示例中,VPC A和B可以与A和C进行通信。但是B只能与A进行通信。

<?php

namespace App\Entity;

use Doctrine\Common\Collections\ArrayCollection;
use Symfony\Component\HttpFoundation\File\File;
use Vich\UploaderBundle\Mapping\Annotation as Vich;
use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity(repositoryClass="App\Repository\FournisseursRepository")
 * @Vich\Uploadable
 */
class Fournisseur
{
    /**
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type="integer")
     */
    private $id;

    /**
     * @ORM\Column(type="string", length=255)
     *
     * @var string
     */
    private $category;

    /**
     * @ORM\Column(type="string", length=255)
     *
     * @var string
     */
    private $civility;

    /**
     * @ORM\Column(type="text")
     *
     */
    private $name;

    /**
     * @ORM\Column(type="string", length=255)
     *
     * @var string
     */
    private $company;

    /**
     * @ORM\Column(type="string", length=255, nullable=true)
     *
     * @var string
     */
    private $named;

    /**
     * @ORM\Column(type="string", length=255)
     *
     * @var string
     */
    private $surname;

    /**
     * @ORM\Column(type="string", length=255)
     *
     * @var string
     */
    private $building;

    /**
     * @ORM\Column(type="string", length=255)
     *
     * @var string
     */
    private $street;

    /**
     * @ORM\Column(type="string", length=255)
     *
     * @var string
     */
    private $other;

    /**
     * @ORM\Column(type="integer", length=5)
     *
     * @var integer
     */
    private $zipcode;

    /**
     * @ORM\Column(type="string", length=255)
     *
     * @var string
     */
    private $city;

    /**
     * @ORM\Column(type="string", length=255)
     *
     * @var string
     */
    private $country;

    /**
     * @ORM\Column(type="string", length=255)
     *
     * @var string
     */
    private $url;

    /**
     * @ORM\Column(type="string", length=255)
     *
     * @var string
     */
    private $login;

    /**
     * @ORM\Column(type="string", length=255)
     *
     * @var string
     */
    private $passwordSite;

    /**
     * NOTE: This is not a mapped field of entity metadata, just a simple property.
     *
     * @Vich\UploadableField(mapping="fournisseur_image", fileNameProperty="imageName", size="imageSize")
     *
     * @var File
     */
    private $imageFile;

    /**
     * @ORM\Column(type="string", length=255)
     *
     * @var string
     */
    private $imageName;

    /**
     * @ORM\Column(type="integer")
     *
     * @var integer
     */
    private $imageSize;

    /**
     * @ORM\Column(type="string", length=255)
     */
    private $title;

    /**
     * @ORM\Column(type="string", length=255)
     */
    private $type;

    /**
     * @ORM\Column(type="string", length=255)
     */
    private $phone1;

    /**
     * @ORM\Column(type="string", length=255)
     */
    private $phone2;

    /**
     * @ORM\Column(type="string", length=255)
     */
    private $fax;

    /**
     * @ORM\Column(type="string", length=255)
     */
    private $email;

    /**
     * @ORM\Column(type="text")
     */
    private $note;

    /**
     * @ORM\ManyToMany(targetEntity="Article", mappedBy="fournisseurs")
     */
    private $articles;

    public function __construct() {
        $this->articles = new ArrayCollection();
    }

    public function getId(): ?int
    {
        return $this->id;
    }

    /**
     * @return string
     */
    public function getCategory(): ?string
    {
        return $this->category;
    }

    /**
     * @param string $category
     */
    public function setCategory(string $category): void
    {
        $this->category = $category;
    }

    /**
     * @return string
     */
    public function getCivility(): ?string
    {
        return $this->civility;
    }

    /**
     * @param string $civility
     */
    public function setCivility(string $civility): void
    {
        $this->civility = $civility;
    }

    /**
     * @return mixed
     */
    public function getName()
    {
        return $this->name;
    }

    /**
     * @param mixed $name
     */
    public function setName($name): void
    {
        $this->name = $name;
    }

    /**
     * @return string
     */
    public function getCompany(): ?string
    {
        return $this->company;
    }

    /**
     * @param string $company
     */
    public function setCompany(string $company): void
    {
        $this->company = $company;
    }

    /**
     * @return string
     */
    public function getNamed(): ?string
    {
        return $this->named;
    }

    /**
     * @param string $named
     */
    public function setNamed(string $named): void
    {
        $this->named = $named;
    }

    /**
     * @return string
     */
    public function getSurname(): ?string
    {
        return $this->surname;
    }

    /**
     * @param string $surname
     */
    public function setSurname(string $surname): void
    {
        $this->surname = $surname;
    }

    /**
     * @return string
     */
    public function getBuilding(): ?string
    {
        return $this->building;
    }

    /**
     * @param string $building
     */
    public function setBuilding(string $building): void
    {
        $this->building = $building;
    }

    /**
     * @return string
     */
    public function getStreet(): ?string
    {
        return $this->street;
    }

    /**
     * @param string $street
     */
    public function setStreet(string $street): void
    {
        $this->street = $street;
    }

    /**
     * @return string
     */
    public function getOther(): ?string
    {
        return $this->other;
    }

    /**
     * @param string $other
     */
    public function setOther(string $other): void
    {
        $this->other = $other;
    }

    /**
     * @return int
     */
    public function getZipcode(): ?int
    {
        return $this->zipcode;
    }

    /**
     * @param int $zipcode
     */
    public function setZipcode(int $zipcode): void
    {
        $this->zipcode = $zipcode;
    }

    /**
     * @return string
     */
    public function getCity(): ?string
    {
        return $this->city;
    }

    /**
     * @param string $city
     */
    public function setCity(string $city): void
    {
        $this->city = $city;
    }

    /**
     * @return string
     */
    public function getCountry(): ?string
    {
        return $this->country;
    }

    /**
     * @param string $country
     */
    public function setCountry(string $country): void
    {
        $this->country = $country;
    }

    /**
     * @return string
     */
    public function getUrl(): ?string
    {
        return $this->url;
    }

    /**
     * @param string $url
     */
    public function setUrl(string $url): void
    {
        $this->url = $url;
    }

    /**
     * @return string
     */
    public function getLogin(): ?string
    {
        return $this->login;
    }

    /**
     * @param string $login
     */
    public function setLogin(string $login): void
    {
        $this->login = $login;
    }

    /**
     * @return string
     */
    public function getPasswordSite(): ?string
    {
        return $this->passwordSite;
    }

    /**
     * @param string $passwordSite
     */
    public function setPasswordSite(string $passwordSite): void
    {
        $this->passwordSite = $passwordSite;
    }

    /**
     * @param File|\Symfony\Component\HttpFoundation\File\UploadedFile $imageFile
     */
    public function setImageFile(?File $imageFile = null): void
    {
        $this->imageFile = $imageFile;
    }

    public function getImageFile(): ?File
    {
        return $this->imageFile;
    }

    public function setImageName(?string $imageName): void
    {
        $this->imageName = $imageName;
    }

    public function getImageName(): ?string
    {
        return $this->imageName;
    }

    public function setImageSize(?int $imageSize): void
    {
        $this->imageSize = $imageSize;
    }

    public function getImageSize(): ?int
    {
        return $this->imageSize;
    }

    public function getTitle(): ?string
    {
        return $this->title;
    }

    public function setTitle(string $title): self
    {
        $this->title = $title;

        return $this;
    }

    public function getType(): ?string
    {
        return $this->type;
    }

    public function setType(string $type): self
    {
        $this->type = $type;

        return $this;
    }

    public function getPhone1(): ?string
    {
        return $this->phone1;
    }

    public function setPhone1(string $phone1): self
    {
        $this->phone1 = $phone1;

        return $this;
    }

    public function getPhone2(): ?string
    {
        return $this->phone2;
    }

    public function setPhone2(string $phone2): self
    {
        $this->phone2 = $phone2;

        return $this;
    }

    public function getFax(): ?string
    {
        return $this->fax;
    }

    public function setFax(string $fax): self
    {
        $this->fax = $fax;

        return $this;
    }

    public function getEmail(): ?string
    {
        return $this->email;
    }

    public function setEmail(string $email): self
    {
        $this->email = $email;

        return $this;
    }

    public function getNote(): ?string
    {
        return $this->note;
    }

    public function setNote(string $note): self
    {
        $this->note = $note;

        return $this;
    }
}

此外,还需要将子网路由规则添加到打开的VPC和SG。

答案 2 :(得分:0)

您必须根据需要设计网络。

例如,我们有4个VPC-VPC A,B,C,D。

要求:

如果我不希望VPC A与VPC B对话,但允许VPC A与VPC C对话,该怎么办。我知道除非将子网VPC路由添加/传播它们,否则这种情况不会发生,但是我想更多控制权。

在设计中:

(home_id, status)

您需要创建一些东西:

1)运输网关-tgw

2)运输网关附件: 将所有VPC A,C,D附加到您创建的传输网关。 附件A(VPC A)-> tgw 附件C(VPC C)-> tgw 附件D(VPC D)-> tgw

3)运输网关路由表(tgw-rt1): 创建转接网关路由表,并将其与所有附件(A,C和D)关联。 创建传播并添加所有附件A,C和D。这将自动生成路由。

这是流量从VPC A到VPC C的流。VPC A中的子网应该具有到tgw的路由,因此流量达到tgw。 tgw查找流量来自哪个附件及其附件A(即VPC A),并找到相应的路由表tgw-rt1。现在,tgw-rt1具有将流量传播到相应附件(即VPC C)的路由。这只是一种方法,为了使流量流回VPC A,您还应该在VPC C中具有路由。

答案 3 :(得分:0)

在中心辐射模式中: 帐户A =集线器 帐户B,C和D =轮辐

用例1-帐户B,C和D可以与帐户A通信。

用例2-帐户B和C可以直接相互通信

路由表之间唯一的区别在于设置了TGW。 VPC路由表: 帐户B VPC将具有到帐户C CIDR和TGW ID(在帐户A中定义的TGW)的路由 帐户C VPC将具有到帐户B CIDR和TGW ID(在帐户A中定义的TGW)的路由

TGW路线表: 帐户B TGW路由表传播到帐户C附件 帐户C TGW路由表传播到帐户B附件

在这种情况下,帐户B和C无法与A通信,因为没有VPC路由表,也没有TGW路由传播到VPC A附件。

有关此场景的完整Terraform代码和说明,请参阅此文档

http://i-cloudconsulting.com/aws-transit-gateway-hub-and-spoke-model/

答案 4 :(得分:0)

截至2020年9月,TGW配置进行了很多更改,因此在此处进行更新可能会有所帮助。

我们部署了与TGW和3个路由表类似的东西(如前所述,Hub和Spoke模型)。

TGW附件

  • TransitVPC
  • VPC A
  • VPC B
  • 本地VPN

路由表:

  • 隔离(默认关联表)
    • 0.0.0.0/0,带有下一跳TransitVPC
  • 本地(关联:附件VPN)
    • 具有下一跳TransitVPC的所有连接的VPC的静态路由条目。 BGP传播所需的路由条目
  • TransitVPC(默认传播表)
    • 包含所有已连接VPC的路由,并将相关VPC作为下一跳

TransitVPC现在包含一个NVA(网络虚拟设备,例如Fortigate,Barracuda,Palo Alto)。 NVA有两个用于专用和公用连接的接口,因此有两个路由表:

  • 专用子网(连接到Transit网关!)
    • 第一个防火墙节点的0.0.0.0/0私有eni(当群集故障转移到第二个节点时,路由表将被重写。请参阅供应商的相关文件。)
  • 公共子网(可选,在对VPC进行inet访问时需要)
    • 0.0.0.0/0 IGW / NatGW(取决于您的需求)

NVA将使用其自己的内置路由表,将中转网关eni IP地址作为下一跳,否则它将在专用子网路由表中循环。

通过此设置,您可以部署有效的访问控制/ IDS / IPS / AV / xxx解决方案,并根据防火墙策略隔离所有流量。

此设置还可以在route53的帮助下托管共享服务(VPC端点)VPC。