2016-03-06 18 views
9

AKTUALIZACJA: Pracowałem nad tym i między innymi. Nie można uzyskać działającej konfiguracji w/dwóch podsieci i bastionu SSH. Umieszczenie nagrody za pełną konfigurację pliku tt: * tworzy dwie prywatne podsieci * tworzy bastion * obraca instancję ec2 w każdej podsieci skonfigurowanej przez bastion (uruchamiaj dowolne polecenie powłoki przez bastion) * ma Internet bramka skonfigurowany * ma NAT dla gospodarzy na prywatnych podsieci * ma trasy i grupy zabezpieczeń odpowiednio skonfigurowanyJak routować między dwiema podsieciami w AWS VPC w/Terraform?

Original post: próbuję nauczyć Terraform i zbudować prototyp. Posiadam VPC AWS skonfigurowany przez Terraform. Oprócz podsieci DMZ, mam publiczną podsieć "sieć", która odbiera ruch z Internetu. Mam prywatną "aplikację" podsieci, która nie jest dostępna z internetu. Próbuję skonfigurować hosta bastionu, aby terraform mógł dostarczać instancje w prywatnej podsieci aplikacji. Nie udało mi się jeszcze tego uruchomić.

Kiedy wejdę do bastionu, nie mogę SSH od hosta bastionu do żadnych instancji w prywatnej podsieci. Podejrzewam, że istnieje problem z routingiem. Budowałem ten prototyp przez kilka dostępnych przykładów i dokumentację. Wiele przykładów używa nieco innych technik i definicji trasowania terraform za pośrednictwem dostawcy aws.

Czy ktoś może podać idealny lub właściwy sposób zdefiniowania tych trzech podsieci (publiczna "sieć", publiczna "dmz" w/bastion i prywatna "aplikacja"), aby instancje w podsieci internetowej miały dostęp podsieć "app" i czy host bastionu w strefie DMZ może dostarczać instancje w prywatnej podsieci "app"?

wycinek z moich configs są poniżej:

resource "aws_subnet" "dmz" { 
    vpc_id = "${aws_vpc.vpc-poc.id}" 
    cidr_block = "${var.cidr_block_dmz}" 
} 

resource "aws_route_table" "dmz" { 
    vpc_id = "${aws_vpc.vpc-poc.id}" 
    route { 
     cidr_block = "0.0.0.0/0" 
     gateway_id = "${aws_internet_gateway.gateway.id}" 
    } 
} 

resource "aws_route_table_association" "dmz" { 
    subnet_id = "${aws_subnet.dmz.id}" 
    route_table_id = "${aws_route_table.dmz.id}" 
} 

resource "aws_subnet" "web" { 
    vpc_id = "${aws_vpc.vpc-poc.id}" 
    cidr_block = "10.200.2.0/24" 
} 

resource "aws_route_table" "web" { 
    vpc_id = "${aws_vpc.vpc-poc.id}" 
    route { 
     cidr_block = "0.0.0.0/0" 
     instance_id = "${aws_instance.bastion.id}" 
    } 
} 

resource "aws_route_table_association" "web" { 
    subnet_id = "${aws_subnet.web.id}" 
    route_table_id = "${aws_route_table.web.id}" 
} 

resource "aws_subnet" "app" { 
    vpc_id = "${aws_vpc.vpc-poc.id}" 
    cidr_block = "10.200.3.0/24" 
} 

resource "aws_route_table" "app" { 
    vpc_id = "${aws_vpc.vpc-poc.id}" 
    route { 
     cidr_block = "0.0.0.0/0" 
     instance_id = "${aws_instance.bastion.id}" 
    } 
} 

resource "aws_route_table_association" "app" { 
    subnet_id = "${aws_subnet.app.id}" 
    route_table_id = "${aws_route_table.app.id}" 
} 
+1

Jeśli potrzebujesz dodatkowej pomocy, musisz rozwinąć plik TF, aby pokazać również grupy zabezpieczeń/NACL itp., Ponieważ nie uważam, że tutaj problemem są trasy (inne niż brak wychodzących dostęp do sieci w prywatnych podsieciach, chyba że twoja bastionowa skrzynka działa również jako brama NAT) – ydaetskcoR

Odpowiedz

3

Oto fragment, który może ci pomóc. Zostało to niesprawdzone, ale zostało wyciągnięte z jednego z moich plików terraform, w którym udostępniam maszyny wirtualne w prywatnej podsieci. Wiem, że działa to z jedną prywatną podsiecią, próbowałem zaimplementować dwa tutaj, tak jak twoje pierwotne pytanie.

Przeskakuję przez moje wystąpienia NAT, aby trafić i udostępnić prywatne pola podsieci Terraform. Jeśli twoje grupy zabezpieczeń są poprawnie skonfigurowane, to działa. Zajęło mi to trochę eksperymentów.

/* VPC creation */ 
resource "aws_vpc" "vpc_poc" { 
    cidr_block = "10.200.0.0/16" 
} 

/* Internet gateway for the public subnets */ 
resource "aws_internet_gateway" "gateway" { 
    vpc_id = "${aws_vpc.vpc_poc.id}" 
} 

/* DMZ subnet - public */ 
resource "aws_subnet" "dmz" { 
    vpc_id = "${aws_vpc.vpc_poc.id}" 
    cidr_block = "10.200.1.0/24" 
    /* may help to be explicit here */ 
    map_public_ip_on_launch = true 
    /* this is recommended in the docs */ 
    depends_on = ["aws_internet_gateway.gateway"] 
} 

resource "aws_route_table" "dmz" { 
    vpc_id = "${aws_vpc.vpc_poc.id}" 
    route { 
     cidr_block = "0.0.0.0/0" 
     gateway_id = "${aws_internet_gateway.gateway.id}" 
    } 
} 

resource "aws_route_table_association" "dmz" { 
    subnet_id = "${aws_subnet.dmz.id}" 
    route_table_id = "${aws_route_table.dmz.id}" 
} 

/* Web subnet - public */ 
resource "aws_subnet" "web" { 
    vpc_id = "${aws_vpc.vpc_poc.id}" 
    cidr_block = "10.200.2.0/24" 
    map_public_ip_on_launch = true 
    depends_on = ["aws_internet_gateway.gateway"] 
} 

resource "aws_route_table" "web" { 
    vpc_id = "${aws_vpc.vpc_poc.id}" 
    route { 
     cidr_block = "0.0.0.0/0" 
     /* your public web subnet needs access to the gateway */ 
     /* this was set to bastion before so you had a circular arg */ 
     gateway_id = "${aws_internet_gateway.gateway.id}" 
    } 
} 

resource "aws_route_table_association" "web" { 
    subnet_id = "${aws_subnet.web.id}" 
    route_table_id = "${aws_route_table.web.id}" 
} 

/* App subnet - private */ 
resource "aws_subnet" "app" { 
    vpc_id = "${aws_vpc.vpc_poc.id}" 
    cidr_block = "10.200.3.0/24" 
} 

/* Create route for DMZ Bastion */ 
resource "aws_route_table" "app" { 
    vpc_id = "${aws_vpc.vpc_poc.id}" 
    route { 
     cidr_block = "0.0.0.0/0" 
     /* this send traffic to the bastion to pass off */ 
     instance_id = "${aws_instance.nat_dmz.id}" 
    } 
} 

/* Create route for App Bastion */ 
resource "aws_route_table" "app" { 
    vpc_id = "${aws_vpc.vpc_poc.id}" 
    route { 
     cidr_block = "0.0.0.0/0" 
     /* this send traffic to the bastion to pass off */ 
     instance_id = "${aws_instance.nat_web.id}" 
    } 
} 

resource "aws_route_table_association" "app" { 
    subnet_id = "${aws_subnet.app.id}" 
    route_table_id = "${aws_route_table.app.id}" 
} 

/* Default security group */ 
resource "aws_security_group" "default" { 
    name = "default-sg" 
    description = "Default security group that allows inbound and outbound traffic from all instances in the VPC" 
    vpc_id = "${aws_vpc.vpc_poc.id}" 

    ingress { 
    from_port = "0" 
    to_port  = "0" 
    protocol = "-1" 
    self  = true 
    } 

    egress { 
    from_port = "0" 
    to_port  = "0" 
    protocol = "-1" 
    self  = true 
    } 
} 

/* Security group for the nat server */ 
resource "aws_security_group" "nat" { 
    name  = "nat-sg" 
    description = "Security group for nat instances that allows SSH and VPN traffic from internet. Also allows outbound HTTP[S]" 
    vpc_id  = "${aws_vpc.vpc_poc.id}" 

    ingress { 
    from_port = 80 
    to_port  = 80 
    protocol = "tcp" 
    /* this your private subnet cidr */ 
    cidr_blocks = ["10.200.3.0/24"] 
    } 
    ingress { 
    from_port = 443 
    to_port  = 443 
    protocol = "tcp" 
    /* this is your private subnet cidr */ 
    cidr_blocks = ["10.200.3.0/24"] 
    } 
    ingress { 
    from_port = 22 
    to_port  = 22 
    protocol = "tcp" 
    cidr_blocks = ["0.0.0.0/0"] 
    } 
    ingress { 
    from_port = -1 
    to_port  = -1 
    protocol = "icmp" 
    cidr_blocks = ["0.0.0.0/0"] 
    } 

    egress { 
    from_port = 80 
    to_port  = 80 
    protocol = "tcp" 
    cidr_blocks = ["0.0.0.0/0"] 
    } 
    egress { 
    from_port = 443 
    to_port  = 443 
    protocol = "tcp" 
    cidr_blocks = ["0.0.0.0/0"] 
    } 
    egress { 
    from_port = 22 
    to_port  = 22 
    protocol = "tcp" 
    /* this is the vpc cidr block */ 
    cidr_blocks = ["10.200.0.0/16"] 
    } 
    egress { 
    from_port = -1 
    to_port  = -1 
    protocol = "icmp" 
    cidr_blocks = ["0.0.0.0/0"] 
    } 
} 

/* Security group for the web */ 
resource "aws_security_group" "web" { 
    name = "web-sg" 
    description = "Security group for web that allows web traffic from internet" 
    vpc_id = "${aws_vpc.vpc_poc.id}" 

    ingress { 
    from_port = 80 
    to_port = 80 
    protocol = "tcp" 
    cidr_blocks = ["0.0.0.0/0"] 
    } 

    ingress { 
    from_port = 443 
    to_port = 443 
    protocol = "tcp" 
    cidr_blocks = ["0.0.0.0/0"] 
    } 
} 

/* Install deploy key for use with all of our provisioners */ 
resource "aws_key_pair" "deployer" { 
    key_name = "deployer-key" 
    public_key = "${file("~/.ssh/id_rsa")}" 
} 

/* Setup NAT in DMZ subnet */ 
resource "aws_instance" "nat_dmz" { 
    ami    = "ami-67a54423" 
    availability_zone = "us-west-1a" 
    instance_type  = "m1.small" 
    key_name   = "${aws_key_pair.deployer.id}" 
    /* Notice we are assigning the security group here */ 
    security_groups = ["${aws_security_group.nat.id}"] 

    /* this puts the instance in your public subnet, but translate to the private one */ 
    subnet_id   = "${aws_subnet.dmz.id}" 

    /* this is really important for nat instance */ 
    source_dest_check = false 
    associate_public_ip_address = true 
} 

/* Give NAT EIP In DMZ */ 
resource "aws_eip" "nat_dmz" { 
    instance = "${aws_instance.nat_dmz.id}" 
    vpc  = true 
} 

/* Setup NAT in Web subnet */ 
resource "aws_instance" "nat_web" { 
    ami    = "ami-67a54423" 
    availability_zone = "us-west-1a" 
    instance_type  = "m1.small" 
    key_name   = "${aws_key_pair.deployer.id}" 
    /* Notice we are assigning the security group here */ 
    security_groups = ["${aws_security_group.nat.id}"] 

    /* this puts the instance in your public subnet, but translate to the private one */ 
    subnet_id   = "${aws_subnet.web.id}" 

    /* this is really important for nat instance */ 
    source_dest_check = false 
    associate_public_ip_address = true 
} 

/* Give NAT EIP In DMZ */ 
resource "aws_eip" "nat_web" { 
    instance = "${aws_instance.nat_web.id}" 
    vpc  = true 
} 

/* Install server in private subnet and jump host to it with terraform */ 
resource "aws_instance" "private_box" { 
    ami   = "ami-d1315fb1" 
    instance_type = "t2.large" 
    key_name  = "${aws_key_pair.deployer.id}" 
    subnet_id  = "${aws_subnet.api.id}" 
    associate_public_ip_address = false 

    /* this is what gives the box access to talk to the nat */ 
    security_groups = ["${aws_security_group.nat.id}"] 

    connection { 
    /* connect through the nat instance to reach this box */ 
    bastion_host = "${aws_eip.nat_dmz.public_ip}" 
    bastion_user = "ec2-user" 
    bastion_private_key = "${file("keys/terraform_rsa")}" 

    /* connect to box here */ 
    user = "ec2-user" 
    host = "${self.private_ip}" 
    private_key = "${file("~/.ssh/id_rsa")}" 
    } 
} 
3

Chyba że gospodarz bastion działa również jako NAT (nie radzę ci się połączyć role na tej samej instancji), a następnie internetowych i aplikacji podsieci nie będzie miał żadnego wychodzącego dostępu do sieci, ale poza tym wygląda na dobrze routing mądry, ponieważ TF automatycznie doda lokalny rekord routingu dla VPC.

Dopóki masz lokalny rekord trasy, który obejmuje twój zakres VPC, routing powinien być dobry. Przeniesienie pliku konfiguracyjnego Terraform (i dodanie minimalnych niezbędnych zasobów) pozwala mi utworzyć kilka podstawowych instancji we wszystkich 3 podsieciach i pomyślnie przejść między nimi, więc prawdopodobnie brakuje czegoś innego, takiego jak grupy zabezpieczeń lub NACL.

+0

Dzięki. Ponownie, mam problem z tym, że terraform nie może SSH do instancji w prywatnej podsieci za pośrednictwem bastionu. Pomyślałem, że to routing, ale będę kopać głębiej i publikować aktualizacje tutaj. – n8gard

2

Nie dały swój pełny Terraform, ale trzeba, aby umożliwić SSH do wystąpień „app” VPC z obu bastionu IP lub bloku CIDR swojego hosta bastion, więc coś takiego:

resource "aws_security_group" "allow_ssh" { 
    name = "allow_ssh" 
    description = "Allow inbound SSH traffic" 

    ingress { 
     from_port = 22 
     to_port = 22 
     protocol = "tcp" 
     cidr_blocks = ["${aws_instance.bastion.private_ip}/32"] 
    } 
} 

Następnie w „app” zasobów instancji, będziemy chcieli, aby dodać grupę zabezpieczeń:

... 
vpc_security_group_ids = ["${aws_security_group.allow_ssh.id}"] 
... 

https://www.terraform.io/docs/providers/aws/r/security_group_rule.html

+0

To było pomocne, ponieważ pokazało mi nowy sposób wyrażenia tego, ale niestety nie było to poprawką. Musi być coś jeszcze. – n8gard

+0

Jeśli potrzebujesz konkretnej pomocy, podaj resztę szablonu. Tutaj nie ma wystarczającego kontekstu. – Nathan

2

należy sprawdzić problemy z siecią z tcpdump i inne narzędzia do debugowania. Sprawdź, czy:

  1. Ips są reacheble, a ustawienia sieciowe są poprawne (np. 10.200.2.X może dotrzeć IP hosta bastion)
  2. To iptables/inna zapora nie blokuje ruchu
  3. serwer
  4. ssh jest słuchać (SSH do IP tych przyjmujących od tych host)
  5. masz prawo bezpieczeństwa grupy dla gospodarzy (widać to w proterties instancji EC2)
  6. Spróbuj powąchać ruchu z tcpdump
2

nie widzę powodu, dla hosta Bastion.

Mam coś podobnego przy użyciu saltstack, ja po prostu kontroluję resztę za pomocą serwera głównego w VPC, przypisuję do niego określoną grupę zabezpieczeń, aby umożliwić dostęp.

CIDR X/24 
subnetX.0/26- subnet for control server. <aster server ip EC2-subnet1/32 
subnetX.64/26 - private minions 
subentX.128/26 - public minions 
subnetX.192/26- private minions 

następnie utworzyć jedną tabelę trasy dla każdej podsieci dla swojej miłości do izolacji Dołącz każdą trasę do indywidualnych podsieci. Na przykład.

rt-1 - subnetX.0/26 
rt-2 - subnetX.64/26 
rt-3 - subnetX.128/26 
rt-4 - subnetX.192/26 

upewnić się, że stół trasa ma coś takiego to więc trasa jest możliwe dla rt-1 przykład podłączyć do każdego

destination: CIDR X/24 Target: local 

Następnie ograniczyć łączność poprzez grupy zabezpieczeń inbound.e.g. zezwól na SSH z podsieci EC21/32

Po zakończeniu pracy z serwerem sterującym mogę usunąć określoną trasę, która mówi CIDR X/24 Target: local w mojej publicznej podsieci, więc nie jest już w stanie kieruj ruch do mojego lokalnego CIDR.

Nie ma powodu, dla któregobym tworzył skomplikowany bastion, skoro już dałam moc, by usunąć trasę z serwera sterowania.

Powiązane problemy