13

更新: とりわけこれに取り組んでいます。2 つのサブネットと 1 つの SSH 踏み台を使用して、機能する構成を取得できないようです。* 2 つのプライベート サブネットを作成する * 要塞を作成する * 要塞経由で構成された各サブネットで ec2 インスタンスをスピンする (要塞経由で任意のシェル コマンドを実行する) * インターネット ゲートウェイを構成する * 持っているプライベート サブネット上のホストの nat ゲートウェイ * ルートとセキュリティ グループが適切に構成されている

元の投稿: Terraform を学習してプロトタイプを作成しようとしています。Terraform を介して構成された AWS VPC があります。DMZ サブネットに加えて、インターネットからのトラフィックを受信するパブリック サブネット「web」があります。インターネットからアクセスできないプライベートサブネット「アプリ」があります。テラフォームがプライベート「アプリ」サブネットにインスタンスをプロビジョニングできるように、要塞ホストを構成しようとしています。私はまだこれを機能させることができませんでした。

踏み台に ssh 接続すると、踏み台ホストからプライベート サブネット内のどのインスタンスにも SSH 接続できません。ルーティングに問題があると思われます。私は、いくつかの利用可能な例とドキュメントを使用して、このプロトタイプを構築してきました。多くの例では、aws プロバイダーを介して、わずかに異なる手法と Terraform ルーティング定義を使用しています。

「web」サブネット上のインスタンスが「app」にアクセスできるように、これら 3 つのサブネット (パブリック「web」、パブリック「dmz」と要塞、およびプライベート「app」) を定義するための理想的または適切な方法を誰かが提供してください。 DMZ の踏み台ホストがプライベート「アプリ」サブネットにインスタンスをプロビジョニングできることを確認しますか?

私の設定の一部を以下に示します。

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}"
}
4

5 に答える 5

6

ここにあなたを助けるかもしれないスニペットがあります. これはテストされていませんが、プライベート サブネットで VM をプロビジョニングするテラフォーム ファイルの 1 つから取得されました。これは1つのプライベートサブネットで機能することを知っています。元の質問のように、ここで2つ実装しようとしました。

NAT インスタンスをジャンプして、Terraform でプライベート サブネット ボックスにアクセスしてプロビジョニングします。セキュリティ グループが正しく設定されていれば、機能します。私にはいくつかの実験が必要でした。

/* 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")}"
  }
}
于 2016-04-26T05:43:12.123 に答える
3

完全な Terraform を提供していませんが、踏み台 IP または踏み台ホストの CIDR ブロックから「アプリ」VPC インスタンスへの SSH を許可する必要があるため、次のようになります。

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"]
  }
}

次に、「アプリ」インスタンス リソースで、セキュリティ グループを追加します。

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

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

于 2016-04-20T02:03:22.873 に答える
3

Bastion ホストの理由がわかりません。

私はsaltstackを使用して似たようなものを持っています.VPC内のマスターサーバーを使用して残りを制御し、特定のセキュリティグループを割り当ててアクセスを許可します.

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 

次に、分離を愛するために、サブネットごとに 1 つのルート テーブルを作成します。各ルートを個々のサブネットに接続します。例えば

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

ルートテーブルにこのようなものが含まれていることを確認して、ルートが rt-1 インスタンスが全員に接続できるようにします

destination: CIDR X/24  Target: local

次に、セキュリティ グループ inbound を介して接続を制限します。たとえば、EC2-subnet1/32 からの SSH を許可します。

コントロール サーバーでのすべての作業が完了したら、CIDR X/24 ターゲット: ローカルという特定のルートをパブリック サブネットで削除できるため、ローカル CIDR にトラフィックをルーティングできなくなります。

コントロールサーバーでルートを削除する権限を既に与えているので、複雑な要塞を作成する理由はありません。

于 2016-04-22T15:59:11.073 に答える
3

その要塞ホストが NAT としても機能していない限り (同じインスタンスでロールを結合することはお勧めしません)、Web サブネットとアプリ サブネットにはアウトバウンド Web アクセスはありませんが、それ以外の場合は、TF が自動的に追加するため、ルーティングに関しては問題ないように見えます。 VPC のローカル ルーティング レコード。

VPC 範囲をカバーするローカル ルーティング レコードがある限り、ルーティングは問題ないはずです。Terraform 構成ファイルを取得 (および必要最小限のリソースを追加) することで、3 つのサブネットすべてにいくつかの基本的なインスタンスを作成し、それらの間で正常にルーティングできるようになるため、セキュリティ グループや NACL などの何かが不足している可能性があります。

于 2016-03-06T17:50:34.357 に答える
2

tcpdump およびその他のデバッグ ツールを使用して、ネットワークの問題を確認する必要があります。次のことを確認してください。

  1. IP が到達可能であり、ネットワーク設定が正しい (たとえば、10.200.2.X は踏み台ホストの IP に到達できる)
  2. iptables/別のファイアウォールがトラフィックをブロックしていないこと
  3. sshサーバーがリッスンしています(それらのホストからそれらのホストのIPにsshします)
  4. ホストに適切なセキュリティ グループがあります (これは EC2 インスタンスのプロパティで確認できます)
  5. tcpdump でトラフィックを盗聴してみてください
于 2016-04-20T20:41:44.643 に答える