AWS EC2 Login using SSH public key of IAM


AWS EC2에 로그인하기 위해서는 key-pair를 이용하는 것이 일반적인 방법이다. 이 경우 다음과 같은 문제점이 있다.

  1. key-pair를 잃어버리면 로그인하기 어렵다. 방법이 아에 없는건 아니다. key-pair를 교체할 수 있기 때문이다. 하지만 번거롭다.
  2. key-pair가 있으면 누구든 로그인이 가능하다. 보안상 취약하다.
  3. 하나의 EC2에는 하나의 key-pair로 로그인을 해야한다. 작업자가 여러 명이라면 모두 같은 key-pair를 복사해서 가지고 있어야 하며, 그로인해 key-pair를 소유하고 있는 사람 중 누군가가 퇴사한 경우 key-pair를 가지고 있으므로 모든 권한 회수가 어렵다. key-pair를 새로 발급받아서 작업자들에게 새로 나눠줘야하는데 번거로운 작업이다.

이러한 불편함을 없에고 IAM에서 관리가 가능한 방법이 있다. 바로 SSH public key를 이용하여 로그인하는 방법이다. 조금 더 자세히 설명하자면 개인 PC에서 생성한 SSH public key를 AWS IAM에 등록하여 해당 user로 EC2에 로그인을 하는 방법이다.

먼저, 각 user는 개인의 SSH public key를 IAM의 SSH keys for AWS CodeCommit에 등록을 한다.

그런 뒤 EC2에서는 다음과 같은 방법으로 로그인을 하게 만든다.

  1. AWS IAM의 group을 가져와서 허용된 그룹 내의 user 리스트를 출력하여 특정 디렉토리 (/etc/sudoers.d/)에 기록 (10분 단위 cronjob)
  2. /etc/ssh/sshd_config 를 수정하여 AuthorizedKeysCommand 를 해당 user가 SSH keys for AWS Code에 저장된 SSH public key를 가져와서 검증하도록 설정 (해당 script는 root 계정으로 실행)
  3. ssh $USER@$EC2_ADDRESS 로 접속시 개인 pc에 저장된 ssh key (~/.ssh/id_rsa) 를 이용하여 접속

https://cloudonaut.io/manage-aws-ec2-ssh-access-with-iam를 참고하여 작성하였다. 여기에서는 IAM의 user를 가져오는 방법을 사용하였는데, 이번 포스팅에서는 user가 아니라 group의 목록을 읽어서 특정 group 내의 user들에게 권한을 주는 것으로 구현하였다.

이렇게 할 경우 특정 user가 퇴사를 할 경우 해당 user만 IAM에서 삭제하던지, 퇴사가 아니더라도 앞으로 해당 작업에 대한 권한을 삭제할 경우 해당 group에서 제외시키면 된다.

EC2에서 필요한 Role Policy

EC2에서 IAM의 group 목록과 user의 SSH public key를 읽을 수 있어야 한다. 위 작업에 필요한 EC2의 최소 권한은 다음과 같다.

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "iam:ListGroupsForUser",
                "iam:ListUsers",
                "iam:ListGroups"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "iam:ListSSHPublicKeys",
                "iam:GetSSHPublicKey"
            ],
            "Resource": "arn:aws:iam::${AWS_ACCOUNT}:user/*"
        }
    ]
}

EC2 구축 방법

먼저 EC2를 key-pair로 접속가능하도록 생성한다. 아직은 SSH login 작업전이므로 최초 한 번은 key-pair로 접속해야 한다. 본 예제에서는 Amazon Linux 2 AMI을 이용하여 생성하였다.

접속 후 필요한 파일을 3개 생성한다. 해당 작업에는 sudo 권한이 필요하다.

sudo touch /opt/import_users.sh
sudo chmod 755 /opt/import_users.sh
sudo touch /opt/authorized_with_iam.sh
sudo chmod 755 /opt/authorized_with_iam.sh
sudo touch /etc/cron.d/import_users
sudo chmod 644 /etc/cron.d/import_users

각각의 파일에 내용을 기록한다.

import_users.sh

#!/bin/bash
 
# Get Users with IAM
aws iam list-users --query "Users[].[UserName]" --output text | while read AWS_USER; do
  USER=`echo "$AWS_USER" | tr '[:upper:]' '[:lower:]'`
  # Get groups for an user
  aws iam list-groups-for-user --user-name="$AWS_USER" --query "Groups[].[GroupName]" --output text | while read GROUP_NAME; do
    # Check wether the user has admin role or not
    if [ "$GROUP_NAME" == "Admin" ] || [ "$GROUP_NAME" == "Ec2Worker" ] ; then
      # Add the user
      if id -u "$USER" >/dev/null 2>&1; then
        echo "$USER exists"
      else
        /usr/sbin/adduser "$USER"
        echo "$USER ALL=(ALL) NOPASSWD:ALL" > "/etc/sudoers.d/$USER"
      fi
    fi
  done
done

설명) aws cli를 이용해서 Admin, Ec2Worker 그룹내의 user들을 가져와서 ec2내의 user를 생성한다는 내용이다.

authorized_with_iam.sh

#!/bin/bash -e
 
if [ -z "$1" ]; then
  exit 1
fi
 
aws iam list-ssh-public-keys --user-name "$1" --query "SSHPublicKeys[?Status == 'Active'].[SSHPublicKeyId]" --output text | while read KeyId; do
  aws iam list-groups-for-user --user-name="$1" --query "Groups[].[GroupName]" --output text | while read GROUP_NAME; do
    if [ "$GROUP_NAME" == "Admin" ] || [ "$GROUP_NAME" == "Ec2Worker" ]; then
      aws iam get-ssh-public-key --user-name "$1" --ssh-public-key-id "$KeyId" --encoding SSH --query "SSHPublicKey.SSHPublicKeyBody" --output text
    fi
  done
done

설명) 로그인에 사용한 user를 읽어서 해당 user가 IAM에 등록한 SSH public key들의 목록을 가지고 온다는 내용이다.

etc/cron.d/import_users

*/10 * * * * root /opt/import_users.sh

설명)cronjob으로 10분마다 import_users.sh를 실행한다는 내용이다.

이제 /etc/ssh/sshd_config를 수정해야 한다.

  1. AuthorizedKeysCommand 관련 내용들을 삭제한다. (Amazon Linux 2 AMI에서는 가장 아래 2줄이었다.)
  2. 그 아래 코드를 추가한다.
# Check with IAM Role
AuthorizedKeysCommand /opt/authorized_with_iam.sh
AuthorizedKeysCommandUser root

설명) ssh 접속에 대한 key 인증 방법으로 authorized_with_iam.sh를 root권한으로 실행하라는 내용이다.

이제 모든 설정은 끝났다. 최초로 한 번 사용자 목록을 가져오도록 import_users.sh를 실행하고, sshd 서비스를 재시작하면 된다.

sudo /opt/import_users.sh
sudo service sshd restart

이제 접속을 끊고 key-pair없이 user명으로 로그인이 가능하다.

ssh seokjoonyun@ec2-address.compute.amazonaws.com

이때 주의해야 할 것은 그 전에는 key-pair를 사용해서 모두 같은 user로 작업을 했지만, 이 방법을 사용하면 모두 각자 user로 로그인이 된다. 그래서 실제 작업은 공통 사용자 (ex. ec2-user)로 하는게 편하다.


이 글이 도움이 되셨다면 공감 및 광고 클릭을 부탁드립니다 :)