mirror of
https://github.com/trailofbits/algo.git
synced 2025-06-05 22:54:01 +02:00
CF tested and working for EC2 deployment (#431)
* AWS CloudFormation #132 * IPv6 EC2 draft * CF tested and working for EC2 deployment * IPv6 Implementation, EC2, Cloudformation * Fixed ipv6 networking * adding ip6tables rule for DHCP on AWS
This commit is contained in:
parent
0e4aace6b6
commit
76cdc69548
5 changed files with 221 additions and 95 deletions
18
roles/cloud-ec2/tasks/cloudformation.yml
Normal file
18
roles/cloud-ec2/tasks/cloudformation.yml
Normal file
|
@ -0,0 +1,18 @@
|
|||
---
|
||||
|
||||
- name: Make a cloudformation template
|
||||
template:
|
||||
src: stack.yml.j2
|
||||
dest: "configs/{{ aws_server_name }}.yml"
|
||||
|
||||
- name: Deploy the template
|
||||
cloudformation:
|
||||
aws_access_key: "{{ aws_access_key | default(lookup('env','AWS_ACCESS_KEY_ID'), true)}}"
|
||||
aws_secret_key: "{{ aws_secret_key | default(lookup('env','AWS_SECRET_ACCESS_KEY'), true)}}"
|
||||
stack_name: "{{ stack_name }}"
|
||||
state: "present"
|
||||
region: "{{ region }}"
|
||||
template: "configs/{{ aws_server_name }}.yml"
|
||||
tags:
|
||||
Environment: Algo
|
||||
register: stack
|
|
@ -1,7 +1,7 @@
|
|||
- name: Check if the encrypted image already exist
|
||||
ec2_ami_find:
|
||||
aws_access_key: "{{ aws_access_key | default(lookup('env','AWS_ACCESS_KEY_ID'))}}"
|
||||
aws_secret_key: "{{ aws_secret_key | default(lookup('env','AWS_SECRET_ACCESS_KEY'))}}"
|
||||
aws_access_key: "{{ aws_access_key | default(lookup('env','AWS_ACCESS_KEY_ID'), true)}}"
|
||||
aws_secret_key: "{{ aws_secret_key | default(lookup('env','AWS_SECRET_ACCESS_KEY'), true)}}"
|
||||
owner: self
|
||||
sort: creationDate
|
||||
sort_order: descending
|
||||
|
@ -18,8 +18,8 @@
|
|||
|
||||
- name: Copy to an encrypted image
|
||||
ec2_ami_copy:
|
||||
aws_access_key: "{{ aws_access_key | default(lookup('env','AWS_ACCESS_KEY_ID'))}}"
|
||||
aws_secret_key: "{{ aws_secret_key | default(lookup('env','AWS_SECRET_ACCESS_KEY'))}}"
|
||||
aws_access_key: "{{ aws_access_key | default(lookup('env','AWS_ACCESS_KEY_ID'), true)}}"
|
||||
aws_secret_key: "{{ aws_secret_key | default(lookup('env','AWS_SECRET_ACCESS_KEY'), true)}}"
|
||||
encrypted: yes
|
||||
name: algo
|
||||
kms_key_id: "{{ kms_key_id | default(omit) }}"
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
- set_fact:
|
||||
access_key: "{{ aws_access_key | default(lookup('env','AWS_ACCESS_KEY_ID'), true) }}"
|
||||
secret_key: "{{ aws_secret_key | default(lookup('env','AWS_SECRET_ACCESS_KEY'), true) }}"
|
||||
stack_name: "{{ aws_server_name | replace('.', '-') }}"
|
||||
|
||||
- name: Locate official Ubuntu 16.04 AMI for region
|
||||
ec2_ami_find:
|
||||
|
@ -20,107 +21,20 @@
|
|||
- include: encrypt_image.yml
|
||||
tags: [encrypted]
|
||||
|
||||
- name: Add ssh public key
|
||||
ec2_key:
|
||||
aws_access_key: "{{ access_key }}"
|
||||
aws_secret_key: "{{ secret_key }}"
|
||||
name: VPNKEY
|
||||
region: "{{ region }}"
|
||||
key_material: "{{ item }}"
|
||||
with_file: "{{ SSH_keys.public }}"
|
||||
register: keypair
|
||||
|
||||
- name: Configure EC2 virtual private clouds
|
||||
ec2_vpc:
|
||||
aws_access_key: "{{ access_key }}"
|
||||
aws_secret_key: "{{ secret_key }}"
|
||||
state: present
|
||||
resource_tags: { "Environment":"Algo" }
|
||||
region: "{{ region }}"
|
||||
cidr_block: "{{ ec2_vpc_nets.cidr_block }}"
|
||||
internet_gateway: yes
|
||||
subnets:
|
||||
- cidr: "{{ ec2_vpc_nets.subnet_cidr }}"
|
||||
resource_tags: { "Environment":"Algo" }
|
||||
register: vpc
|
||||
|
||||
- name: Set up Public Subnets Route Table
|
||||
ec2_vpc_route_table:
|
||||
aws_access_key: "{{ access_key }}"
|
||||
aws_secret_key: "{{ secret_key }}"
|
||||
vpc_id: "{{ vpc.vpc_id }}"
|
||||
region: "{{ region }}"
|
||||
state: present
|
||||
tags:
|
||||
Environment: Algo
|
||||
subnets:
|
||||
- "{{ ec2_vpc_nets.subnet_cidr }}"
|
||||
routes:
|
||||
- dest: 0.0.0.0/0
|
||||
gateway_id: "{{ vpc.igw_id }}"
|
||||
register: public_rt
|
||||
|
||||
- name: Configure EC2 security group
|
||||
ec2_group:
|
||||
aws_access_key: "{{ access_key }}"
|
||||
aws_secret_key: "{{ secret_key }}"
|
||||
name: vpn-secgroup
|
||||
description: Security group for VPN servers
|
||||
region: "{{ region }}"
|
||||
vpc_id: "{{ vpc.vpc_id }}"
|
||||
rules:
|
||||
- proto: udp
|
||||
from_port: 4500
|
||||
to_port: 4500
|
||||
cidr_ip: 0.0.0.0/0
|
||||
- proto: udp
|
||||
from_port: 500
|
||||
to_port: 500
|
||||
cidr_ip: 0.0.0.0/0
|
||||
- proto: tcp
|
||||
from_port: 22
|
||||
to_port: 22
|
||||
cidr_ip: 0.0.0.0/0
|
||||
rules_egress:
|
||||
- proto: all
|
||||
from_port: 0-65535
|
||||
to_port: 0-65535
|
||||
cidr_ip: 0.0.0.0/0
|
||||
|
||||
- name: Launch instance
|
||||
ec2:
|
||||
aws_access_key: "{{ access_key }}"
|
||||
aws_secret_key: "{{ secret_key }}"
|
||||
keypair: "VPNKEY"
|
||||
vpc_subnet_id: "{{ vpc.subnets[0].id }}"
|
||||
group: vpn-secgroup
|
||||
instance_type: "{{ cloud_providers.ec2.size }}"
|
||||
image: "{{ ami_image }}"
|
||||
wait: true
|
||||
region: "{{ region }}"
|
||||
instance_tags:
|
||||
Name: "{{ aws_server_name }}"
|
||||
Environment: Algo
|
||||
exact_count: 1
|
||||
count_tag:
|
||||
Name: "{{ aws_server_name }}"
|
||||
assign_public_ip: yes
|
||||
instance_initiated_shutdown_behavior: terminate
|
||||
register: ec2
|
||||
- include: cloudformation.yml
|
||||
|
||||
- name: Add new instance to host group
|
||||
add_host:
|
||||
hostname: "{{ item.public_ip }}"
|
||||
hostname: "{{ stack.stack_outputs.PublicIP }}"
|
||||
groupname: vpn-host
|
||||
ansible_ssh_user: ubuntu
|
||||
ansible_python_interpreter: "/usr/bin/python2.7"
|
||||
ansible_ssh_private_key_file: "{{ SSH_keys.private }}"
|
||||
cloud_provider: ec2
|
||||
ipv6_support: no
|
||||
with_items: "{{ ec2.tagged_instances }}"
|
||||
ipv6_support: yes
|
||||
|
||||
- set_fact:
|
||||
cloud_instance_ip: "{{ ec2.tagged_instances[0].public_ip }}"
|
||||
cloud_instance_ip: "{{ stack.stack_outputs.PublicIP }}"
|
||||
|
||||
- name: Get EC2 instances
|
||||
ec2_remote_facts:
|
||||
|
|
192
roles/cloud-ec2/templates/stack.yml.j2
Normal file
192
roles/cloud-ec2/templates/stack.yml.j2
Normal file
|
@ -0,0 +1,192 @@
|
|||
---
|
||||
|
||||
AWSTemplateFormatVersion: '2010-09-09'
|
||||
Description: 'Algo VPN stack'
|
||||
Resources:
|
||||
|
||||
VPC:
|
||||
Type: AWS::EC2::VPC
|
||||
Properties:
|
||||
CidrBlock: {{ ec2_vpc_nets.cidr_block }}
|
||||
EnableDnsSupport: true
|
||||
EnableDnsHostnames: true
|
||||
InstanceTenancy: default
|
||||
Tags:
|
||||
- Key: Name
|
||||
Value: Algo
|
||||
- Key: Environment
|
||||
Value: Algo
|
||||
|
||||
VPCIPv6:
|
||||
Type: AWS::EC2::VPCCidrBlock
|
||||
Properties:
|
||||
AmazonProvidedIpv6CidrBlock: true
|
||||
VpcId: !Ref VPC
|
||||
|
||||
InternetGateway:
|
||||
Type: AWS::EC2::InternetGateway
|
||||
Properties:
|
||||
Tags:
|
||||
- Key: Environment
|
||||
Value: Algo
|
||||
- Key: Name
|
||||
Value: Algo
|
||||
|
||||
Subnet:
|
||||
Type: AWS::EC2::Subnet
|
||||
Properties:
|
||||
CidrBlock: {{ ec2_vpc_nets.subnet_cidr }}
|
||||
MapPublicIpOnLaunch: true
|
||||
Tags:
|
||||
- Key: Environment
|
||||
Value: Algo
|
||||
- Key: Name
|
||||
Value: Algo
|
||||
VpcId: !Ref VPC
|
||||
|
||||
VPCGatewayAttachment:
|
||||
Type: AWS::EC2::VPCGatewayAttachment
|
||||
Properties:
|
||||
VpcId: !Ref VPC
|
||||
InternetGatewayId: !Ref InternetGateway
|
||||
|
||||
RouteTable:
|
||||
Type: AWS::EC2::RouteTable
|
||||
Properties:
|
||||
VpcId: !Ref VPC
|
||||
Tags:
|
||||
- Key: Environment
|
||||
Value: Algo
|
||||
- Key: Name
|
||||
Value: Algo
|
||||
|
||||
Route:
|
||||
Type: AWS::EC2::Route
|
||||
DependsOn:
|
||||
- InternetGateway
|
||||
- RouteTable
|
||||
- VPCGatewayAttachment
|
||||
Properties:
|
||||
RouteTableId: !Ref RouteTable
|
||||
DestinationCidrBlock: 0.0.0.0/0
|
||||
GatewayId: !Ref InternetGateway
|
||||
|
||||
RouteIPv6:
|
||||
Type: AWS::EC2::Route
|
||||
DependsOn:
|
||||
- InternetGateway
|
||||
- RouteTable
|
||||
- VPCGatewayAttachment
|
||||
Properties:
|
||||
RouteTableId: !Ref RouteTable
|
||||
DestinationIpv6CidrBlock: "::/0"
|
||||
GatewayId: !Ref InternetGateway
|
||||
|
||||
SubnetIPv6:
|
||||
Type: AWS::EC2::SubnetCidrBlock
|
||||
DependsOn:
|
||||
- RouteIPv6
|
||||
- VPC
|
||||
- VPCIPv6
|
||||
Properties:
|
||||
Ipv6CidrBlock:
|
||||
"Fn::Join":
|
||||
- ""
|
||||
- - !Select [0, !Split [ "::", !Select [0, !GetAtt VPC.Ipv6CidrBlocks] ]]
|
||||
- "::dead:beef/64"
|
||||
SubnetId: !Ref Subnet
|
||||
|
||||
RouteSubnet:
|
||||
Type: "AWS::EC2::SubnetRouteTableAssociation"
|
||||
DependsOn:
|
||||
- RouteTable
|
||||
- Subnet
|
||||
- Route
|
||||
Properties:
|
||||
RouteTableId: !Ref RouteTable
|
||||
SubnetId: !Ref Subnet
|
||||
|
||||
InstanceSecurityGroup:
|
||||
Type: AWS::EC2::SecurityGroup
|
||||
DependsOn:
|
||||
- Subnet
|
||||
Properties:
|
||||
VpcId: !Ref VPC
|
||||
GroupDescription: Enable SSH and IPsec
|
||||
SecurityGroupIngress:
|
||||
- IpProtocol: tcp
|
||||
FromPort: '22'
|
||||
ToPort: '22'
|
||||
CidrIp: 0.0.0.0/0
|
||||
- IpProtocol: udp
|
||||
FromPort: '500'
|
||||
ToPort: '500'
|
||||
CidrIp: 0.0.0.0/0
|
||||
- IpProtocol: udp
|
||||
FromPort: '4500'
|
||||
ToPort: '4500'
|
||||
CidrIp: 0.0.0.0/0
|
||||
Tags:
|
||||
- Key: Name
|
||||
Value: Algo
|
||||
- Key: Environment
|
||||
Value: Algo
|
||||
|
||||
EC2Instance:
|
||||
Type: AWS::EC2::Instance
|
||||
DependsOn:
|
||||
- SubnetIPv6
|
||||
- Subnet
|
||||
- InstanceSecurityGroup
|
||||
Metadata:
|
||||
AWS::CloudFormation::Init:
|
||||
config:
|
||||
users:
|
||||
ubuntu:
|
||||
groups:
|
||||
- "sudo"
|
||||
homeDir: "/home/ubuntu/"
|
||||
files:
|
||||
/home/ubuntu/.ssh/authorized_keys:
|
||||
content: {{ lookup('file', SSH_keys.public) }}
|
||||
mode: "000644"
|
||||
owner: "ubuntu"
|
||||
group: "ubuntu"
|
||||
Properties:
|
||||
InstanceType: {{ cloud_providers.ec2.size }}
|
||||
InstanceInitiatedShutdownBehavior: terminate
|
||||
SecurityGroupIds:
|
||||
- Ref: InstanceSecurityGroup
|
||||
ImageId: {{ ami_image }}
|
||||
SubnetId: !Ref Subnet
|
||||
Ipv6AddressCount: 1
|
||||
UserData:
|
||||
"Fn::Base64":
|
||||
!Sub |
|
||||
#!/bin/bash -xe
|
||||
# http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/vpc-migrate-ipv6.html
|
||||
# https://bugs.launchpad.net/ubuntu/+source/ifupdown/+bug/1013597
|
||||
cat <<EOF > /etc/network/interfaces.d/60-default-with-ipv6.cfg
|
||||
iface eth0 inet6 dhcp
|
||||
up sysctl net.ipv6.conf.\$IFACE.accept_ra=2
|
||||
pre-down ip link set dev \$IFACE up
|
||||
EOF
|
||||
ifdown eth0; ifup eth0
|
||||
dhclient -6
|
||||
apt-get update
|
||||
apt-get -y install python-setuptools
|
||||
easy_install https://s3.amazonaws.com/cloudformation-examples/aws-cfn-bootstrap-latest.tar.gz
|
||||
cfn-init -v --stack {{ stack_name }} --resource EC2Instance --region {{ region }}
|
||||
cfn-signal -e $? --stack {{ stack_name }} --resource EC2Instance --region {{ region }}
|
||||
Tags:
|
||||
- Key: Name
|
||||
Value: Algo
|
||||
- Key: Environment
|
||||
Value: Algo
|
||||
|
||||
Outputs:
|
||||
PublicIP:
|
||||
Value:
|
||||
Fn::GetAtt:
|
||||
- EC2Instance
|
||||
- PublicIp
|
|
@ -31,6 +31,8 @@ COMMIT
|
|||
-A INPUT -p icmpv6 --icmpv6-type neighbor-solicitation -m hl --hl-eq 255 -j ACCEPT
|
||||
-A INPUT -p icmpv6 --icmpv6-type neighbor-advertisement -m hl --hl-eq 255 -j ACCEPT
|
||||
-A INPUT -p icmpv6 --icmpv6-type redirect -m hl --hl-eq 255 -j ACCEPT
|
||||
# DHCP in AWS
|
||||
-A INPUT -m state --state NEW -m udp -p udp --dport 546 -d fe80::/64 -j ACCEPT
|
||||
# TODO:
|
||||
# The IP of the resolver should be bound to a DUMMY interface.
|
||||
# DUMMY interfaces are the proper way to install IPs without assigning them any
|
||||
|
|
Loading…
Add table
Reference in a new issue