7

I have two instances in a VPC distinct security groups, each with their own public IP. I would like instance one to be able to connect to instance two on it's Public IP. I discovered that granting access to the security group, only allows access to the private IP, not the Public IP.

I have now defined my Security Group to allow access to the Public IP of the instance which resides in the other Security Group. However, this is inconvenient, as I can't easily automate this (think Ansible), since I will first need to perform a lookup of the DNS name, before I can add it to the group.

Does anyone know of a simpler way of doing this?

To summarize:

  • Instance 1 -> 1.2.3.4
  • Instance 2 -> 5.6.7.8

Instance 1 is required to access Instance 2 on it's Public IP. I currenty end up having to manually lookup what the IP of instance 1 is and in turn add that to the security group of Instance 2.

MLu
  • 23,798
  • 5
  • 54
  • 81
darkl0rd
  • 79
  • 1
  • 4
  • Hi @darkl0rd, if the below responses answer your question please accept one of them. It's the way to say thanks to people who spent their free time helping others on ServerFault. Thanks! – MLu Nov 21 '18 at 00:23

3 Answers3

7

I'm afraid that as soon as you go out to the Public IPs you no longer can use the Security Group ID as the Source in the target SG. That only works for Private IPs.

However if you create the Instance 1 through Ansible you can then use the Ansible facts for the instance to obtain its Public IP and set it as a source in the Instance 2 SG. Something like this should do:

- name: Create Instance 1
  ec2:
    key_name: mykey
    instance_type: t2.micro
    image: ami-123456
    wait: yes
    assign_public_ip: yes             <<< Assign Public IP
  register: ec2

And then you can add it as a source to the Instance 2 Security Group:

- name: Instance 2 SG
  ec2_group:
    name: ...
    rules:
    - proto: tcp
      ports:
      - 80
      cidr_ip: "{{ ec2.instances.public_ip }}"   <<< Use it here

Something along these lines should let you do the automation with Ansible.

Hope that helps :)

MLu
  • 23,798
  • 5
  • 54
  • 81
  • Thank you for that information, I wasn't aware of that limitation with security groups. Likely because we rarely use public IP's on instance level. – hargut Nov 06 '18 at 06:12
4

Requests from an instance's public IP address are not treated as if they are coming from the instance's Security Groups. That only works from requests using private IP addresses.

I recommend that the source instance use a DNS address for the target instance that resolves to the target instance's private IP. For example: you create a CNAME record my-service.example.com that points to the target instance's public DNS name that is provided by AWS. The public DNS name will look something like ec2-public-ipv4-address.compute-1.amazonaws.com.

AWS provides split-horizon DNS resolution. When my-service.example.com is resolved on the public internet, the public IP is returned. When my-service.example.com is resolved in your VPC, the private IP is returned. Therefore your source instance will connect to the target instance using a private IP and your Security Group rules will work as expected.

This sort of DNS configuration isn't always possible or practical, so you may need to whitelist the source instance's public IP address. In this case, make sure that it is an Elastic IP Address - otherwise the public IP will change if the server shuts down.

Greg
  • 141
  • 4
  • 2
    Bonus with this solution: data transfer between instances in the same VPC using public IPs incurs an additonal per-GB charge because the traffic passes through more AWS network infrastructure. This configuration avoids that charge. – Michael - sqlbot Nov 06 '18 at 03:12
  • Thanks, however I really need to use the Public IP, as I need to come in through the ALB which does SSL termination. I can make it work, as I pointed out by adding the Public IP of the other instance in the security group. I was hoping that there was another way of doing it, mainly because having to do this complicates the playbook I'm building to set this up. – darkl0rd Nov 06 '18 at 06:11
  • I've had the same situation. In my case I created an internal load balancer in parallel to the public load balancer. I then created a private route53 zone (for the same domain name as the public site) associated with the vpc and created records in that private zone that pointed to the internal load balancer instead of the public load balancer. – Greg Nov 06 '18 at 16:42
  • The downside is paying for another load balancer. The upside is that internal traffic stays on the private network. – Greg Nov 06 '18 at 16:43
3

Typically you'd create a named security group, attach it to those instances, and add a rule which references this security group as a source and allow the needed destination ports.

Final picture:

  • All instances needed to communicate with each other have the created security group attached.
  • The created security group contains rules which state inbound from created security group to destination port you need
  • Often there are no outbound rules included, as secutity groups are stateful. But feel free to add what is needed.

So basically not even a single ip is needed, and allow/deny can be controlled by attaching the security group to resources where access is needed. This method also works nicely with dynamic environments (e.g. autoscaled).

hargut
  • 3,848
  • 6
  • 10
  • 1
    I'm not sure if *Security Group ID* works as a *source for traffic* over *Public IPs*. I don't think so, but I may be wrong. – MLu Nov 05 '18 at 22:10
  • 1
    @MLu you are correct. Security Group ID does not work as a source for traffic over Public IPs – Greg Nov 06 '18 at 03:12