Skip to content

Commit 4f1f0e1

Browse files
author
Mike Morris
committed
Allow private IP address and tags for SSM targets
EC2 instance private IPv4 addresses and instance tags can now be used to specify a target instance when using runas for sessions and port forwarding. This is in addition to providing the instance ID directly, and using DNS TXT records.
1 parent 8bc2163 commit 4f1f0e1

File tree

2 files changed

+50
-3
lines changed

2 files changed

+50
-3
lines changed

docs/ssm.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,10 @@ Starting with version 1.5, the tool supports integration with the SSM Session Ma
77
a shell, or port-forwarding, session with appropriately configured EC2 instances.
88

99
Starting with version 2.2, the tool supports the ability to specify the target instance as an EC2 instance identifier,
10-
or using a DNS TXT record which contains the instance ID.
10+
or using a DNS TXT record which contains the instance ID. As of version 2.2.1 you can also provide the target instance
11+
as the instance's private IPv4 address, or as a tag key and tag value pair in the format `tag_key:tag_value`. Both
12+
formats will perform a DescribeInstances EC2 API call, and if multiple instance IDs are returned, the first one in the
13+
list is used.
1114

1215
### Prerequisites
1316
In addition to having a target EC2 instance registered with an SSM agent version supporting the desired functionality,

main.go

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import (
1818
"github.com/aws/aws-sdk-go/aws/credentials"
1919
"github.com/aws/aws-sdk-go/aws/defaults"
2020
"github.com/aws/aws-sdk-go/aws/session"
21+
"github.com/aws/aws-sdk-go/service/ec2"
2122
"github.com/aws/aws-sdk-go/service/iam"
2223
"github.com/aws/aws-sdk-go/service/iam/iamiface"
2324
"github.com/aws/aws-sdk-go/service/sts"
@@ -910,17 +911,40 @@ func getSamlPassword() (string, error) {
910911
func checkTarget(target string) string {
911912
matched, err := regexp.MatchString(`^i-[[:xdigit:]]{8,}$`, target)
912913
if err != nil {
913-
log.Fatalf("error checking target host", err)
914+
log.Fatalf("error checking target host: %s", err)
914915
}
915916

916917
if matched {
917918
log.Debugln("detected EC2 instance id target")
918919
return target
919920
}
920921

922+
matched, err = regexp.MatchString(`^.+:.+$`, target)
923+
if err != nil {
924+
log.Fatalf("error checking target host: %s", err)
925+
}
926+
927+
if matched {
928+
log.Debugln("detected EC2 instance tag spec")
929+
spec := strings.SplitN(target, `:`, 2)
930+
f := new(ec2.Filter).SetName(fmt.Sprintf(`tag:%s`, spec[0])).SetValues(aws.StringSlice([]string{spec[1]}))
931+
return describeInstance(f)
932+
}
933+
934+
matched, err = regexp.MatchString(`^\d{1,3}\.\d{1,3}\.\d{1,3}.\d{1,3}$`, target)
935+
if err != nil {
936+
log.Fatalf("error checking target host: %s", err)
937+
}
938+
939+
if matched {
940+
log.Debugln("detected EC2 instance IPv4 address")
941+
f := new(ec2.Filter).SetName(`private-ip-address`).SetValues(aws.StringSlice([]string{target}))
942+
return describeInstance(f)
943+
}
944+
921945
rr, err := net.LookupTXT(target)
922946
if err != nil {
923-
log.Fatalf("error looking up target host", err)
947+
log.Fatalf("error looking up target host: %s", err)
924948
}
925949

926950
for _, r := range rr {
@@ -938,3 +962,23 @@ func checkTarget(target string) string {
938962
log.Fatal("unable to determine target host type")
939963
return ""
940964
}
965+
966+
func describeInstance(filter *ec2.Filter) string {
967+
o, err := ec2.New(ses).DescribeInstances(new(ec2.DescribeInstancesInput).SetFilters([]*ec2.Filter{filter}))
968+
if err != nil {
969+
log.Fatalf("error describing instance: %s", err)
970+
}
971+
972+
for _, r := range o.Reservations {
973+
if len(r.Instances) > 0 {
974+
if len(r.Instances) > 1 {
975+
log.Warn("more than 1 instance found, using 1st value")
976+
}
977+
978+
return *r.Instances[0].InstanceId
979+
}
980+
}
981+
982+
log.Fatal("no instances returned from lookup")
983+
return ""
984+
}

0 commit comments

Comments
 (0)