Skip to content

Commit

Permalink
Merge updates from public repo (#1)
Browse files Browse the repository at this point in the history
* if iam returns no users at all, it is likey down (implementation merged from https://github.com/packetfairy/aws-ec2-ssh/blob/condoms/import_users.sh#L285) fixes widdix#96

* Fix typo (widdix#125)

* Fix typo in rpm install output text
* Fix file name

* fix

* fix

* improved check

* re added creation policy

* changing aws command line detection to make it silent (widdix#127)

* fix RHEL

* increase timeout

* allow parallel tests

* fix RHEL showcase

* re-add creation policy

* Update README.md

bump version

* added license to templates

* Install from latest release instead of master (widdix#133)

Add argument to install script to specify release

* document ##ALL##

* fix tag enabled groups in multi account setup (widdix#136)

* added hint to AWS Systems Manager Session Manager

* Changed URI for RPM to latest release version (widdix#140)

* fix IAM SSH access

* fix

* Update README.md
  • Loading branch information
labkey-stuartm authored and labkey-ians committed Feb 22, 2019
1 parent 5553cc8 commit 8257618
Show file tree
Hide file tree
Showing 13 changed files with 137 additions and 63 deletions.
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Manage AWS EC2 SSH access with IAM

> You might want to checkout the newly launched [AWS Systems Manager Session Manager for Shell Access to EC2 Instances](https://aws.amazon.com/de/blogs/aws/new-session-manager/)
Use your IAM user's public SSH key to get access via SSH to an **EC2 instance** running
* Amazon Linux 2017.09
* Amazon Linux 2 2017.12
Expand Down Expand Up @@ -54,7 +56,7 @@ A picture is worth a thousand words:
4. Click the **Upload SSH public key** button at the bottom of the page
5. Paste your public SSH key into the text-area and click the **Upload SSH public key** button to save
2. Attach the IAM permissions defined in [`iam_ssh_policy.json`](./iam_ssh_policy.json) to the EC2 instances (by creating an IAM role and an Instance Profile)
3. Install the RPM<sup>1</sup>: `rpm -i https://s3-eu-west-1.amazonaws.com/widdix-aws-ec2-ssh-releases-eu-west-1/aws-ec2-ssh-1.7.0-1.el7.centos.noarch.rpm`
3. Install the RPM<sup>1</sup>: `rpm -i https://s3-eu-west-1.amazonaws.com/widdix-aws-ec2-ssh-releases-eu-west-1/aws-ec2-ssh-1.9.2-1.el7.centos.noarch.rpm`
4. The configuration file is placed into `/etc/aws-ec2-ssh.conf`
5. The RPM creates a crontab file to run import_users.sh every 10 minutes. This file is placed in `/etc/cron.d/import_users`

Expand Down Expand Up @@ -102,7 +104,7 @@ one or more of the following lines:
```
ASSUMEROLE="IAM-role-arn" # IAM Role ARN for multi account. See below for more info
IAM_AUTHORIZED_GROUPS="GROUPNAMES" # Comma separated list of IAM groups to import
SUDOERS_GROUPS="GROUPNAMES" # Comma seperated list of IAM groups that should have sudo access
SUDOERS_GROUPS="GROUPNAMES" # Comma seperated list of IAM groups that should have sudo access or `##ALL##` to allow all users
IAM_AUTHORIZED_GROUPS_TAG="KeyTag" # Key Tag of EC2 that contains a Comma separated list of IAM groups to import - IAM_AUTHORIZED_GROUPS_TAG will override IAM_AUTHORIZED_GROUPS, you can use only one of them
SUDOERS_GROUPS_TAG="KeyTag" # Key Tag of EC2 that contains a Comma separated list of IAM groups that should have sudo access - SUDOERS_GROUPS_TAG will override SUDOERS_GROUPS, you can use only one of them
SUDOERSGROUP="GROUPNAME" # Deprecated! IAM group that should have sudo access. Please use SUDOERS_GROUPS as this variable will be removed in future release.
Expand Down
2 changes: 1 addition & 1 deletion authorized_keys_command.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ if [ -z "$1" ]; then
fi

# check if AWS CLI exists
if ! which aws; then
if ! [ -x "$(which aws)" ]; then
echo "aws executable not found - exiting!"
exit 1
fi
Expand Down
2 changes: 1 addition & 1 deletion aws-ec2-ssh.conf
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,5 @@ ASSUMEROLE=""

# Remove or set to 0 if you are done with configuration
# To change the interval of the sync change the file
# /etc/cron.d/aws-ec2-ssh
# /etc/cron.d/import_users
DONOTSYNC=0
2 changes: 1 addition & 1 deletion aws-ec2-ssh.spec
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ chmod 0644 ${RPM_BUILD_ROOT}%{_sysconfdir}/cron.d/import_users
%include install_configure_sshd.sh
%include install_configure_selinux.sh
%include install_restart_sshd.sh
echo "To configure the aws-ec2-ssh package, edit /etc/aws-ec-ssh.conf. No users will be synchronized before you did this."
echo "To configure the aws-ec2-ssh package, edit /etc/aws-ec2-ssh.conf. No users will be synchronized before you did this."


%postun
Expand Down
4 changes: 4 additions & 0 deletions iam_crossaccount_policy.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,9 @@
"Resource": [
"arn:aws:iam::<YOUR_USERS_ACCOUNT_ID_HERE>:role/<YOUR_USERS_ACCOUNT_ROLE_NAME_HERE>"
]
},{
"Effect": "Allow",
"Action": "ec2:DescribeTags",
"Resource": "*"
}]
}
38 changes: 25 additions & 13 deletions import_users.sh
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
#!/bin/bash -e

function log() {
/usr/bin/logger -i -p auth.info -t aws-ec2-ssh "$@"
}

# check if AWS CLI exists
if ! which aws; then
echo "aws executable not found - exiting!"
if ! [ -x "$(which aws)" ]; then
log "aws executable not found - exiting!"
exit 1
fi

Expand All @@ -14,7 +18,7 @@ fi

if [ ${DONOTSYNC} -eq 1 ]
then
echo "Please configure aws-ec2-ssh by editing /etc/aws-ec2-ssh.conf"
log "Please configure aws-ec2-ssh by editing /etc/aws-ec2-ssh.conf"
exit 1
fi

Expand Down Expand Up @@ -54,10 +58,6 @@ fi
INSTANCE_ID=$(curl -s http://169.254.169.254/latest/meta-data/instance-id)
REGION=$(curl -s http://169.254.169.254/latest/dynamic/instance-identity/document | grep region | awk -F\" '{print $4}')

function log() {
/usr/bin/logger -i -p auth.info -t aws-ec2-ssh "$@"
}

function setup_aws_credentials() {
local stscredentials
if [[ ! -z "${ASSUMEROLE}" ]]
Expand Down Expand Up @@ -171,7 +171,7 @@ function create_or_update_local_user() {
# check that username contains only alphanumeric, period (.), underscore (_), and hyphen (-) for a safe eval
if [[ ! "${username}" =~ ^[0-9a-zA-Z\._\-]{1,32}$ ]]
then
echo "Local user name ${username} contains illegal characters"
log "Local user name ${username} contains illegal characters"
exit 1
fi

Expand Down Expand Up @@ -227,16 +227,13 @@ function clean_iam_username() {
function sync_accounts() {
if [ -z "${LOCAL_MARKER_GROUP}" ]
then
echo "Please specify a local group to mark imported users. eg iam-synced-users"
log "Please specify a local group to mark imported users. eg iam-synced-users"
exit 1
fi

# Check if local marker group exists, if not, create it
/usr/bin/getent group "${LOCAL_MARKER_GROUP}" >/dev/null 2>&1 || /usr/sbin/groupadd "${LOCAL_MARKER_GROUP}"

# setup the aws credentials if needed
setup_aws_credentials

# declare and set some variables
local iam_users
local sudo_users
Expand All @@ -249,8 +246,23 @@ function sync_accounts() {
get_iam_groups_from_tag
get_sudoers_groups_from_tag

# setup the aws credentials if needed
setup_aws_credentials

iam_users=$(get_clean_iam_users | sort | uniq)
if [[ -z "${iam_users}" ]]
then
log "we just got back an empty iam_users user list which is likely caused by an IAM outage!"
exit 1
fi

sudo_users=$(get_clean_sudoers_users | sort | uniq)
if [[ ! -z "${SUDOERS_GROUPS}" ]] && [[ ! "${SUDOERS_GROUPS}" == "##ALL##" ]] && [[ -z "${sudo_users}" ]]
then
log "we just got back an empty sudo_users user list which is likely caused by an IAM outage!"
exit 1
fi

local_users=$(get_local_users | sort | uniq)

intersection=$(echo ${local_users} ${iam_users} | tr " " "\n" | sort | uniq -D | uniq)
Expand All @@ -262,7 +274,7 @@ function sync_accounts() {
then
create_or_update_local_user "${user}" "$sudo_users"
else
echo "Can not import IAM user ${user}. User name is longer than 32 characters."
log "Can not import IAM user ${user}. User name is longer than 32 characters."
fi
done

Expand Down
21 changes: 17 additions & 4 deletions install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

show_help() {
cat << EOF
Usage: ${0##*/} [-hv] [-a ARN] [-i GROUP,GROUP,...] [-l GROUP,GROUP,...] [-s GROUP] [-p PROGRAM] [-u "ARGUMENTS"]
Usage: ${0##*/} [-hv] [-a ARN] [-i GROUP,GROUP,...] [-l GROUP,GROUP,...] [-s GROUP] [-p PROGRAM] [-u "ARGUMENTS"] [-r RELEASE]
Install import_users.sh and authorized_key_commands.
-h display this help and exit
Expand All @@ -23,6 +23,9 @@ Install import_users.sh and authorized_key_commands.
Defaults to '/usr/sbin/useradd'
-u "useradd args" Specify arguments to use with useradd.
Defaults to '--create-home --shell /bin/bash'
-r release Specify a release of aws-ec2-ssh to download from GitHub. This argument is
passed to \`git clone -b\` and so works with branches and tags.
Defaults to 'master'
EOF
Expand All @@ -39,8 +42,9 @@ LOCAL_GROUPS=""
ASSUME_ROLE=""
USERADD_PROGRAM=""
USERADD_ARGS=""
RELEASE="master"

while getopts :hva:i:l:s: opt
while getopts :hva:i:l:s:p:u:r: opt
do
case $opt in
h)
Expand Down Expand Up @@ -68,6 +72,9 @@ do
u)
USERADD_ARGS="$OPTARG"
;;
r)
RELEASE="$OPTARG"
;;
\?)
echo "Invalid option: -$OPTARG" >&2
show_help
Expand All @@ -88,16 +95,22 @@ export USERADD_PROGRAM
export USERADD_ARGS

# check if AWS CLI exists
if ! which aws; then
if ! [ -x "$(which aws)" ]; then
echo "aws executable not found - exiting!"
exit 1
fi

# check if git exists
if ! [ -x "$(which git)" ]; then
echo "git executable not found - exiting!"
exit 1
fi

tmpdir=$(mktemp -d)

cd "$tmpdir"

git clone -b master https://github.com/widdix/aws-ec2-ssh.git
git clone -b "$RELEASE" https://github.com/widdix/aws-ec2-ssh.git

cd "$tmpdir/aws-ec2-ssh"

Expand Down
21 changes: 9 additions & 12 deletions install_configure_sshd.sh
Original file line number Diff line number Diff line change
@@ -1,17 +1,14 @@
#!/bin/bash -e

if grep -q '#AuthorizedKeysCommand none' "$SSHD_CONFIG_FILE"; then
sed -i "s:#AuthorizedKeysCommand none:AuthorizedKeysCommand ${AUTHORIZED_KEYS_COMMAND_FILE}:g" "$SSHD_CONFIG_FILE"
else
if ! grep -q "AuthorizedKeysCommand ${AUTHORIZED_KEYS_COMMAND_FILE}" "$SSHD_CONFIG_FILE"; then
echo "AuthorizedKeysCommand ${AUTHORIZED_KEYS_COMMAND_FILE}" >> "$SSHD_CONFIG_FILE"
fi
# add new line if file does not end with new line
if [ -n "$(tail -c1 ${SSHD_CONFIG_FILE})" ]; then
echo >> ${SSHD_CONFIG_FILE}
fi

if grep -q '#AuthorizedKeysCommandUser nobody' "$SSHD_CONFIG_FILE"; then
sed -i "s:#AuthorizedKeysCommandUser nobody:AuthorizedKeysCommandUser nobody:g" "$SSHD_CONFIG_FILE"
else
if ! grep -q 'AuthorizedKeysCommandUser nobody' "$SSHD_CONFIG_FILE"; then
echo "AuthorizedKeysCommandUser nobody" >> "$SSHD_CONFIG_FILE"
fi
if ! grep -q '^AuthorizedKeysCommand /opt/authorized_keys_command.sh' ${SSHD_CONFIG_FILE}; then
sed -e '/AuthorizedKeysCommand / s/^#*/#/' -i ${SSHD_CONFIG_FILE}; echo "AuthorizedKeysCommand ${AUTHORIZED_KEYS_COMMAND_FILE}" >> ${SSHD_CONFIG_FILE}
fi

if ! grep -q '^AuthorizedKeysCommandUser nobody' ${SSHD_CONFIG_FILE}; then
sed -e '/AuthorizedKeysCommandUser / s/^#*/#/' -i ${SSHD_CONFIG_FILE}; echo 'AuthorizedKeysCommandUser nobody' >> ${SSHD_CONFIG_FILE}
fi
33 changes: 26 additions & 7 deletions showcase-rpm.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,13 @@
---
# The MIT License (MIT)
#
# Copyright (c) 2016 widdix GmbH
#
# Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
#
# 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.
AWSTemplateFormatVersion: '2010-09-09'
Description: 'AWS EC2 SSH access with IAM showcase using RPM'
Parameters:
Expand Down Expand Up @@ -35,16 +44,19 @@ Mappings:
AmazonLinux:
RegionMap: RegionMapAmazonLinux
UserData: |
trap '/opt/aws/bin/cfn-signal -e 1 --stack=${STACKNAME} --region=${REGION} --resource=Instance' ERR
/opt/aws/bin/cfn-init --verbose --stack=${STACKNAME} --region=${REGION} --resource=Instance
/opt/aws/bin/cfn-signal -e 0 --stack=${STACKNAME} --region=${REGION} --resource=Instance
AmazonLinux2:
RegionMap: RegionMapAmazonLinux2
UserData: |
trap '/opt/aws/bin/cfn-signal -e 1 --stack=${STACKNAME} --region=${REGION} --resource=Instance' ERR
/opt/aws/bin/cfn-init --verbose --stack=${STACKNAME} --region=${REGION} --resource=Instance
/opt/aws/bin/cfn-signal -e 0 --stack=${STACKNAME} --region=${REGION} --resource=Instance
SUSELinuxEnterpriseServer:
RegionMap: RegionMapSUSELinuxEnterpriseServer
UserData: |
trap '/usr/bin/cfn-signal -e 1 --stack=${STACKNAME} --region=${REGION} --resource=Instance' ERR
mkdir aws-cfn-bootstrap-latest
curl -s -m 60 https://s3.amazonaws.com/cloudformation-examples/aws-cfn-bootstrap-latest.tar.gz | tar xz -C aws-cfn-bootstrap-latest --strip-components 1
easy_install aws-cfn-bootstrap-latest
Expand All @@ -53,6 +65,7 @@ Mappings:
RHEL:
RegionMap: RegionMapRHEL
UserData: |
trap '/bin/cfn-signal -e 1 --stack=${STACKNAME} --region=${REGION} --resource=Instance' ERR
mkdir aws-cfn-bootstrap-latest
curl -s -m 60 https://s3.amazonaws.com/cloudformation-examples/aws-cfn-bootstrap-latest.tar.gz | tar xz -C aws-cfn-bootstrap-latest --strip-components 1
easy_install aws-cfn-bootstrap-latest
Expand All @@ -61,6 +74,7 @@ Mappings:
CentOS:
RegionMap: RegionMapCentOS
UserData: |
trap '/bin/cfn-signal -e 1 --stack=${STACKNAME} --region=${REGION} --resource=Instance' ERR
mkdir aws-cfn-bootstrap-latest
curl -s -m 60 https://s3.amazonaws.com/cloudformation-examples/aws-cfn-bootstrap-latest.tar.gz | tar xz -C aws-cfn-bootstrap-latest --strip-components 1
easy_install aws-cfn-bootstrap-latest
Expand Down Expand Up @@ -299,13 +313,19 @@ Resources:
prepareSUSELinuxEnterpriseServer: {}
prepareRHEL:
packages:
rpm:
epel: 'http://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm'
yum:
git: []
python2-pip: []
python:
awscli: []
unzip: []
commands:
a_download:
command: 'curl "https://s3.amazonaws.com/aws-cli/awscli-bundle.zip" -o "awscli-bundle.zip"'
cwd: '/tmp'
b_extract:
command: 'unzip awscli-bundle.zip'
cwd: '/tmp'
c_install:
command: './awscli-bundle/install -i /usr/local/aws -b /bin/aws'
cwd: '/tmp'
prepareCentOS:
packages:
rpm:
Expand All @@ -330,7 +350,6 @@ Resources:
'Fn::Base64': !Sub
- |
#!/bin/bash -ex
trap '/opt/aws/bin/cfn-signal -e 1 --stack=${AWS::StackName} --region=${AWS::Region} --resource=Instance' ERR
export REGION=${AWS::Region}
export STACKNAME=${AWS::StackName}
${UserData}
Expand All @@ -348,7 +367,7 @@ Resources:
CreationPolicy:
ResourceSignal:
Count: 1
Timeout: PT15M
Timeout: PT20M
Outputs:
PublicName:
Description: 'The public name of the EC2 instance.'
Expand Down
Loading

0 comments on commit 8257618

Please sign in to comment.