1- # Purpose
1+ # Using AWS SSM commands from a docker container to restrict credentials scope
22
3- AWS SSM has been sufficient to achieve virtually all ssh type needs for some time. However, it has two
4- issues we should address.
3+ NB This is a worked example, not a production-ready solution. It is intended to demonstrate how to use AWS SSM commands
54
6- ## AWS CLI is more powerful
7-
8- When it was first written, in 2018, by the then security team, fifty percent of whom are now back on the security team,
9- SSM Scala closed a gap in the AWS CLI. It required instances to be permitted access via the ssh port (22) and managed
10- discovery, then it created an ssh key, and put it on the instance, allowing the user to ssh in. It also allowed for
11- port forwarding, and other useful ssh features.
12-
13- The AWS CLI has since been updated to include almost the same functionality, but better. Instances no longer need to
14- be permitted access via the ssh port, and the AWS CLI can now do port forwarding by host name.
15-
16- SSM Scala is no longer worth the maintenance cost. It won't be deleted, but you should consider moving away from it.
17-
18- ![ ssm-scala-tombstone.png] ( ssm-scala-tombstone.png )
19-
20- ## More paranoia around credentials
21-
22- The AWS credentials used to get a session on a remote instance inherently provide a lot of power. Once you have a
23- session on an instance, you can use the instance's profile to access quite a lot of information, and any secrets
24- the instance can read.
25-
26- For example:
27- ```
28- # Fetch the user data script
29- TOKEN=$(curl -s -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600")
30- curl -s -H "X-aws-ec2-metadata-token: $TOKEN" \
31- http://169.254.169.254/latest/user-data
32- ```
33- or even
34- ```
35- # Fetch the private cert
36- aws --region eu-west-1 s3 cp s3://my-bucket-of-secrets/my-stack/PROD/my-secure-app/secret-cert.json
37- ```
38- or EVEN
39- ```
40- curl -H "X-aws-ec2-metadata-token: $TOKEN" \
41- http://169.254.169.254/latest/meta-data/iam/security-credentials/[role-name]
42- ```
43-
44- Incidentally, there is now a dedicated ` .ssh ` permission in Janus, which gives just enough permissions to discover
45- and access an instance within the account, without providing the excessive power of ` .dev `
46-
47- Even with those reduced credentials, we should aim use the same approach as devcontainers, and not put "bare"
48- credentials on our laptops (where they can potentially be exfiltrated by attackers) at all.
49-
50- This is a simple setup to deliver containerised ssh to instances, with discover built in. You can use this, or take
51- the principles and build your own, but the important thing is to avoid putting credentials on your laptop.
52-
53- # Setup
5+ ## Setup
546
557Build a small docker image which includes some scripts, the AWS cli tool and, crucially, the SSM session manager plugin for AWS.
568
579```
5810docker build -t aws-shell .
5911```
6012
61- # Run
13+ ## Run
6214
6315```
6416docker run -it aws-shell bash
6517```
6618
6719These can be done in one clean step using the ` scripts/container ` script.
6820
69- # Configuring
21+ ## Configuring
7022
7123Grab your AWS credentials as ` aws configure ` commands. Make sure the profile name is ` default ` or set ` AWS_PROFILE ` .
7224Paste them into the docker shell. The region is already set to eu-west-1, but can be overridden on the command line.
7325
74- # Examples
26+ ## Examples
7527
76- ## Starting a remote SSM session
28+ ### Starting a remote SSM session
7729
7830```
7931docker run -it aws-shell bash
@@ -87,9 +39,9 @@ Connecting to i-0c7f9cb1234567890
8739Starting session with SessionId: justin.rowles-rycskjdsfjkgflkbgdflksdfakl
8840```
8941
90- ## Starting a tunnel to a remote host
42+ ### Starting a tunnel to a remote host
9143
92- ### Ports
44+ #### Ports
9345
9446There will be three ports in play.
9547
@@ -109,7 +61,7 @@ host-tunnel myApp myStack myStage theirHostName
10961```
11062to open a tunnel on the oldest instance with those tags from SSM_PORT to < ; theirHostName> ; : REMOTE_PORT
11163
112- A similar approach can be used to get to remote RDS hosts, looking them up with tags, using `rds-tunnel.
64+ A similar approach can be used to get to remote RDS hosts, looking them up with tags, using ` rds-tunnel ` .
11365
11466At this point, you can run a client to the remote host communicating on localhost: CONTAINER_PORT . This
11567client can be anything - psql, curl, ftp...
0 commit comments