Skip to content
This repository was archived by the owner on Nov 8, 2021. It is now read-only.

Commit bd9ff5d

Browse files
committed
prepare v1 release
1 parent 5831d02 commit bd9ff5d

17 files changed

+672
-208
lines changed

DEV.md

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# Developer notes
2+
3+
## RegionMap
4+
To update the region map execute the following lines in your terminal:
5+
6+
```
7+
$ regions=$(aws ec2 describe-regions --query "Regions[].RegionName" --output text)
8+
$ for region in $regions; do ami=$(aws --region $region ec2 describe-images --filters "Name=name,Values=amzn-ami-hvm-2016.09.1.20161221-x86_64-gp2" --query "Images[0].ImageId" --output "text"); printf "'$region':\n AMI: '$ami'\n"; done
9+
```

LICENSE

-1
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,3 @@ Permission is hereby granted, free of charge, to any person obtaining a copy of
77
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
88

99
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
10-

README.md

+69-32
Original file line numberDiff line numberDiff line change
@@ -1,57 +1,53 @@
11
# Manage AWS EC2 SSH access with IAM
22

3-
This showcase demonstrates how you can use your IAM user's public SSH key to get access via SSH to an EC2 instance.
3+
Use your IAM user's public SSH key to get access via SSH to an EC2 instance.
44

55
## How does it work
66

77
A picture is worth a thousand words:
88

99
![Architecture](./docs/architecture.png?raw=true "Architecture")
1010

11-
* On first start all IAM users are imported and local users are created
12-
* The import also runs every 10 minutes (via cron - calls import_users.sh)
13-
* You can control which users are given sudo access as:
11+
* On first start, all IAM users are imported and local UNIX users are created
12+
* The import also runs every 10 minutes (via cron - calls `import_users.sh`)
13+
* You can control which IAM users get a local UNIX user and are therefore able to login
14+
* all (default)
15+
* only those in specific IAM groups
16+
* You can control which IAM users are given sudo access
1417
* none (default)
1518
* all
16-
* only those in a specific IAM group.
17-
* On every SSH login the EC2 instance tries to fetch the public key(s) from IAM using sshd's `AuthorizedKeysCommand`
18-
* You can restrict that the EC2 instance is only allowed to download public keys from certain IAM users instead of `*`. This way you can restrict SSH access within your account
19+
* only those in a specific IAM group
20+
* You can specify the local UNIX groups for the local UNIX users
21+
* You can assume a role before contacting AWS IAM to get users and keys (e.g. if your IAM users are in another AWS account)
22+
* On every SSH login, the EC2 instance tries to fetch the public key(s) from IAM using sshd's `AuthorizedKeysCommand`
1923
* As soon as the public SSH key is deleted from the IAM user a login is no longer possible
2024

21-
## How to run this showcase (CloudFormation)
25+
### Demo with CloudFormation
2226

2327
1. Upload your public SSH key to IAM:
2428
1. Open the Users section in the [IAM Management Console](https://console.aws.amazon.com/iam/home#users)
2529
1. Click the row with your user
26-
1. Click the "Upload SSH public key" button at the bottom of the page
27-
1. Paste your public SSH key into the textarea and click the "Upload SSH public key" button to save
28-
1. Create a stack based on the `showcase.yaml` template
30+
1. Select the **Security Credentials** tab
31+
1. Click the **Upload SSH public key** button at the bottom of the page
32+
1. Paste your public SSH key into the text-area and click the **Upload SSH public key** button to save
33+
1. Create a CloudFormation stack based on the `showcase.yaml` template
2934
1. Wait until the stack status is `CREATE_COMPLETE`
3035
1. Copy the `PublicName` from the stack's outputs
31-
1. Connect via ssh `ssh $Username@$PublicName` replace `$Username` with your IAM user and `$PublicName` with the stack's output
36+
1. Connect to the EC2 instance via `ssh $Username@$PublicName` with `$Username` being your IAM user, and `$PublicName` with the stack's output
3237

33-
## How to integrate this system into your environment (non-CloudFormation)
38+
## How to integrate this system into your environment
3439

35-
1. Upload your public SSH key to IAM as above
36-
1. Make sure any instances you want to ssh into contain the correct IAM permissions
37-
(usually based on IAM Profile, but also possibly based on an IAM user and their credentials).
38-
Look at the `iam_ssh_policy.json` for an example policy that will permit login.
39-
1. Make sure those instances automatically run a script similar to `install.sh` (note - that script assumes `git` is installed _and_ instances have access to the Internet; feel free to modify it to instead install from a tarball or using any other mechanism such as Chef or Puppet).
40-
* If you want to control sudo access, you should modify the value of ‘SudoersGroup’ in import_users.sh
41-
1. Connect to your instances now using `ssh $Username@$PublicName` with `$Username` being your IAM user, and `$PublicName` being your server's name or IP address.
42-
43-
## Limitations
44-
45-
* your EC2 instances need access to the AWS API either via an Internet Gateway + public IP or a Nat Gatetway / instance.
46-
* it can take up to 10 minutes until a new IAM user can log in
47-
* if you delete the IAM user / ssh public key and the user is already logged in, the SSH session will not be closed
48-
* uid's and gid's across multiple servers might not line up correctly (due to when a server was booted, and what users existed at that time). Could affect NFS mounts or Amazon EFS.
49-
* this solution will work for ~100 IAM users and ~100 EC2 instances. If your setup is much larger (e.g. 10 times more users or 10 times more EC2 instances) you may run into two issues:
50-
* IAM API limitations
51-
* Disk space issues
52-
* not all IAM user names are allowed in Linux user names. See section [IAM user names and Linux user names](#iam-user-names-and-linux-user-names) for further details.
40+
1. Upload your public SSH key to IAM:
41+
1. Open the Users section in the [IAM Management Console](https://console.aws.amazon.com/iam/home#users)
42+
1. Click the row with your user
43+
1. Select the **Security Credentials** tab
44+
1. Click the **Upload SSH public key** button at the bottom of the page
45+
1. Paste your public SSH key into the text-area and click the **Upload SSH public key** button to save
46+
1. Attach the IAM permissions defined in `iam_ssh_policy.json` to the EC2 instances (by creating an IAM role and an Instance Profile)
47+
1. Run the `install.sh` script as `root` on the EC2 instances
48+
1. Connect to your EC2 instances now using `ssh $Username@$PublicName` with `$Username` being your IAM user, and `$PublicName` being your server's name or IP address
5349

54-
### IAM user names and Linux user names
50+
## IAM user names and Linux user names
5551

5652
Allowed characters for IAM user names are:
5753
> alphanumeric, including the following common characters: plus (+), equal (=), comma (,), period (.), at (@), underscore (_), and hyphen (-).
@@ -69,3 +65,44 @@ This solution will use the following mapping for those special characters when c
6965
* `@` => `.at.`
7066

7167
So instead of `[email protected]` you will need to use `name.at.email.com` when login via SSH.
68+
69+
## Using a multi account strategy with a central IAM user account
70+
71+
If you are using multiple AWS accounts you probably have one AWS account with all the IAM users (I will call it **users account**), and separate AWS accounts for your environments (I will call it **dev account**). Support for this is provided using the AssumeRole functionality in AWS.
72+
73+
### Setup users account
74+
75+
1. In the **users account**, create a new IAM role
76+
1. Select Role Type **Role for Cross-Account Access** and select the option **Provide access between AWS accounts you own**
77+
1. Put the **users account** number in **Account ID** and leave **Require MFA** unchecked
78+
1. Skip attaching a policy (we will do this soon)
79+
1. Review the new role and create it
80+
1. Select the newly created role
81+
1. In the **Permissions** tab, expand **Inline Policies** and create a new inline policy
82+
1. Select **Custom Policy**
83+
1. Paste the content of the `iam_ssh_policy.json` file and replace `<YOUR_USERS_ACCOUNT_ID_HERE>` with the AWS Account ID of the **users account**.
84+
85+
### Setup dev account
86+
87+
For your EC2 instances, you need a IAM role that allows the `sts:AssumeRole` action
88+
89+
1. In the **dev account**, create a new IAM role
90+
1. Select ROle Type **AWS Service Roles** and select the option **Amazon EC2**
91+
1. Skip attaching a policy (we will do this soon)
92+
1. Review the new role and create it
93+
1. Select the newly created role
94+
1. In the **Permissions** tab, expand **Inline Policies** and create a new inline policy
95+
1. Select **Custom Policy**
96+
1. Paste the content of the `iam_crossaccount_policy.json` file and replace `<YOUR_USERS_ACCOUNT_ID_HERE>` with the AWS Account ID of the **users account** and `<YOUR_USERS_ACCOUNT_ROLE_NAME_HERE>` with the IAM rol name that you created in the **users account**
97+
1. Replace the `ASSUMEROLE` placeholder with the ARN of the IAM role in `import_users.sh` and `authorized_keys_command.sh`
98+
99+
## Limitations
100+
101+
* your EC2 instances need access to the AWS API either via an Internet Gateway + public IP or a Nat Gatetway / instance.
102+
* it can take up to 10 minutes until a new IAM user can log in
103+
* if you delete the IAM user / ssh public key and the user is already logged in, the SSH session will not be closed
104+
* uid's and gid's across multiple servers might not line up correctly (due to when a server was booted, and what users existed at that time). Could affect NFS mounts or Amazon EFS.
105+
* this solution will work for ~100 IAM users and ~100 EC2 instances. If your setup is much larger (e.g. 10 times more users or 10 times more EC2 instances) you may run into two issues:
106+
* IAM API limitations
107+
* Disk space issues
108+
* not all IAM user names are allowed in Linux user names. See section [IAM user names and Linux user names](#iam-user-names-and-linux-user-names) for further details.

docs/multiawsaccount.md

-25
This file was deleted.

iam_crossaccount_policy.json

+12-5
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,15 @@
11
{
2-
"Version": "2012-10-17",
3-
"Statement": {
4-
"Effect": "Allow",
5-
"Action": "sts:AssumeRole",
6-
"Resource": "arn:aws:iam::<IAM ACCOUNT ID WITH IAM USERS>:role/<ROLE WITH IAM ACCESS>"
2+
"Version": "2012-10-17",
3+
"Statement": [
4+
{
5+
"Sid": "Stmt1471562879000",
6+
"Effect": "Allow",
7+
"Action": [
8+
"sts:AssumeRole"
9+
],
10+
"Resource": [
11+
"arn:aws:iam::<YOUR_USERS_ACCOUNT_ID_HERE>:role/<YOUR_USERS_ACCOUNT_ROLE_NAME_HERE>"
12+
]
713
}
14+
]
815
}

iam_ssh_policy.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
"iam:ListSSHPublicKeys"
2121
],
2222
"Resource": [
23-
"arn:aws:iam::<YOUR_ACCOUNT_ID_HERE>:user/*"
23+
"arn:aws:iam::<YOUR_USERS_ACCOUNT_ID_HERE>:user/*"
2424
]
2525
}
2626
]

import_users.sh

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#!/bin/bash
1+
#!/bin/bash -e
22

33
# Which IAM groups have access to this instance
44
# Comma seperated list of IAM groups. Leave empty for all available IAM users

install.sh

+8-10
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,12 @@
1-
#!/bin/bash
1+
#!/bin/bash -e
22

33
tmpdir=$(mktemp -d)
44

5-
cd "${tmpdir}" || exit 1
5+
cd "$tmpdir"
66

7-
# yum install -y git # if necessary
8-
# or download a tarball and decompress it instead
97
git clone https://github.com/widdix/aws-ec2-ssh.git
108

11-
cd "${tmpdir}/aws-ec2-ssh" || exit 1
9+
cd "$tmpdir/aws-ec2-ssh"
1210

1311
cp authorized_keys_command.sh /opt/authorized_keys_command.sh
1412
cp import_users.sh /opt/import_users.sh
@@ -17,24 +15,24 @@ cp import_users.sh /opt/import_users.sh
1715
# changing GROUPNAMES to a comma seperated list of IAM groups you want to sync.
1816
# You can specify 1 or more groups, comma seperated, without spaces.
1917
# If you leave it blank, all IAM users will be synced.
20-
#sudo sed -i 's/IAM_AUTHORIZED_GROUPS=""/IAM_AUTHORIZED_GROUPS="GROUPNAMES"/' /opt/import_users.sh
18+
#sed -i 's/IAM_AUTHORIZED_GROUPS=""/IAM_AUTHORIZED_GROUPS="GROUPNAMES"/' /opt/import_users.sh
2119

2220
# To control which users are given sudo privileges, uncomment the line below
2321
# changing GROUPNAME to either the name of the IAM group for sudo users, or
2422
# to ##ALL## to give all users sudo access. If you leave it blank, no users will
2523
# be given sudo access.
26-
#sudo sed -i 's/SUDOERSGROUP=""/SUDOERSGROUP="GROUPNAME"/' /opt/import_users.sh
24+
#sed -i 's/SUDOERSGROUP=""/SUDOERSGROUP="GROUPNAME"/' /opt/import_users.sh
2725

2826
# To control which local groups a user will get, uncomment the line belong
2927
# changing GROUPNAMES to a comma seperated list of local UNIX groups.
3028
# If you live it blank, this setting will be ignored
31-
#sudo sed -i 's/LOCAL_GROUPS=""/LOCAL_GROUPS="GROUPNAMES"/' /opt/import_users.sh
29+
#sed -i 's/LOCAL_GROUPS=""/LOCAL_GROUPS="GROUPNAMES"/' /opt/import_users.sh
3230

3331
# If your IAM users are in another AWS account, put the AssumeRole ARN here.
3432
# replace the word ASSUMEROLEARN with the full arn. eg 'arn:aws:iam::$accountid:role/$role'
3533
# See docs/multiawsaccount.md on how to make this work
36-
#sudo sed -i 's/ASSUMEROLE=""/ASSUMEROLE="ASSUMEROLEARN"/' /opt/import_users.sh
37-
#sudo sed -i 's/ASSUMEROLE=""/ASSUMEROLE="ASSUMEROLEARN"/' /opt/authorized_keys_command.sh
34+
#sed -i 's/ASSUMEROLE=""/ASSUMEROLE="ASSUMEROLEARN"/' /opt/import_users.sh
35+
#sed -i 's/ASSUMEROLE=""/ASSUMEROLE="ASSUMEROLEARN"/' /opt/authorized_keys_command.sh
3836

3937
sed -i 's:#AuthorizedKeysCommand none:AuthorizedKeysCommand /opt/authorized_keys_command.sh:g' /etc/ssh/sshd_config
4038
sed -i 's:#AuthorizedKeysCommandUser nobody:AuthorizedKeysCommandUser nobody:g' /etc/ssh/sshd_config

0 commit comments

Comments
 (0)