[EC2] EC2 인스턴스 SSH 접속 연결 오류 해결하기

Nurrung·2023년 6월 4일
0
post-thumbnail

SSH을 통해 인스턴스에 연결하려고 할때 "Connection Refused" 또는 "Connection timed out"이 발생하는 경우가 종종 있을 것이다. 오늘 포스팅에서는 각각의 에러가 발생하는 경우를 알아보고 이에 대한 해결 방법에 대하여 정리해보겠다.

해당 포스팅은 AWS의 Re:post에서 가이드하는 내용을 기반으로 이를 조금 더 자세하게 풀어내는 방향을 목표로 하였다. 기존의 가이드는 아래에 링크를 참고하면 된다.
(* AWS Link: https://repost.aws/ko/knowledge-center/ec2-linux-resolve-ssh-connection-errors )


글의 목차를 설명한 뒤 바로 위의 에러를 해결하는 방법에 대하여 설명해보겠다.

목차
(1). Connection time out 이 발생하는 원인 및 해결 방법
(2). Connection refused 가 발생하는 원인 및 해결 방법
(3). 네 가지 해결 방법에 대한 가이드

  • 방법 1: Linux용 EC2 직렬 콘솔 사용.
  • 방법 2: AWS Systems Manager Session Manager 사용.
  • 방법 3: 사용자 데이터 스크립트 사용.

1. Connection time out 이 발생하는 원인 및 해결 방법

원인

: Connection timed out 메시지는 SSH 클라이언트측에서 발생하며, 해당 오류는 서버가 클라이언트에 응답하지 않고 클라이언트 프로그램이 시간 초과 되었다는 것을 알려줍니다.

  1. 보안 그룹 또는 네트워크 ACL이 액세스를 허용하지 않습니다.
  2. 인스턴스의 운영 체제에 방화벽이 있습니다.
  3. 클라이언트와 서버 사이에 방화벽이 있습니다.
  4. 호스트가 존재하지 않습니다.

해결방법

: Connection timed out 오류의 경우 다음을 확인합니다.

  1. 인스턴스의 IP 주소 또는 호스트 이름이 정확합니다.
  2. 인스턴스가 상태 확인을 통과하고 있습니다.
  3. 인스턴스의 보안 그룹이 TCP 포트 22에서 수신되는 트래픽을 허용합니다.
  4. 인스턴스 서브넷의 네트워크 ACL은 TCP 포트 22에서 수신되는 트래픽을 허용하고 발신 트래픽에 대해 임시 포트를 허용합니다.
  5. 인스턴스 서브넷의 라우팅 테이블이 EC2 인스턴스와 SSH 클라이언트 간의 연결을 제공하도록 올바르게 구성되어 있습니다.
  6. SSH 클라이언트와 EC2 인스턴스 간의 연결을 차단하는 방화벽은 없습니다.
  7. SSH는 인스턴스에서 TCP 래퍼에 의해 차단되지 않습니다.

참고 : 마지막 두 개의 확인 단계에서는 인스턴스에 대한 OS 수준 액세스가 필요합니다.


2. Connection refused 가 발생하는 원인 및 해결 방법

원인

: Connection refused 메시지는 호스트에서 전송되며, 해당 오류의 일반적인 원인은 다음과 같다.

  1. 호스트가 인스턴스에 도달했지만 SSH 포트에서 수신 대기 중인 서비스가 없습니다.
  2. 방화벽이 패키지를 차단했으며 패키지를 삭제하는 대신 거부하도록 설정되었습니다.

해결 방법

: Connection refused 오류의 경우 다음을 확인 합니다.

  1. SSH 연결을 거부하는 인스턴스에는 방화벽이 없습니다.
  2. SSH 대몬(daemon)(sshd)이 포트 22에서 실행 및 수신 중입니다.

참고: 두 확인 단계 모두 인스턴스에 대한 OS 수준 액세스가 필요합니다.


3. 세 가지 해결 방법에 대한 가이드

인스턴스가 2가지 상태 확인 검사에 모두 통과했을 경우 아래의 방법을 사용하여 "Connection Time out" and "Connection refused" 등의 오류를 해결할 수 있다.

  • 방법 1: Linux용 EC2 직렬 콘솔 사용.
  • 방법 2: AWS Systems Manager Session Manager 사용.
  • 방법 3: 사용자 데이터 스크립트 사용.

방법 1 : Linux용 EC2 직렬 콘솔 사용

EC2 직렬 콘솔을 사용하기 위한 사전 조건

참고: EC2 직렬 콘솔 사전 조건

1). Nitro 기반 인스턴스 유형 : 해당 기능은 Nitro 시스템에 구축된 모든 인스턴스에 대해 지원됩니다.

2). 액세스 권한 부여 : EC2 직렬 콘솔에 대한 액세스 권한을 부여하는 구성 작업을 완료해야합니다.
참고 : EC2 직렬 콘솔 액세스 관리

-> 직렬 콘솔을 사용하기 전 계정 수준에 대한 액세스 권한을 부여하고, IAM 사용자 수준에서 액세스 권한을 부여하는 정책을 생성해야합니다.

3). 인스턴스 상태 : 인스턴스 상태가 "running" 여야 합니다.

-> $ amazon-ssm-agent --version

4). EC2 Systems Manager : 인스턴스에서 SSM을 사용할 경우 SSM Agent 버전 3.0.854.0 이상이 설치되어 있어야 합니다.

-> 직렬 콘솔을 사용하는 각 인스턴스에는 sudo 액세스 권한이 있는 암호 기반 Linux 사용자가 포함되어야 합니다. 때문에 로그인 비밀번호가 구성된 Linux 계정이 없는 경우 ssm-user을 실행하여 sudo 액세스 권한이 있는 계정의 비밀번호를 재설정해야 합니다.

참고 : SSM의 Run Command을 사용하여 ssm-user sudo 권한 수정

_ 방법 A) Run Command을 사용하여 ssm-user sudo 권한 수정(콘솔)

a) System Manager 콘솔 접속
b) Run command 탭으로 이동
c) 사용할 명령 문서(command document)에서 "AWS-RunShellScript" 선택
d) sudo 액세스 권한을 허락 하려면 아래의 명령어를 명령 파라미터 영역에 붙여넣고 실행합니다.

cd /etc/sudoers.d
echo "ssm-user ALL=(ALL) NOPASSWD:ALL" > ssm-agent-users

f) sudo 액세스 권한을 제거 (Sudo가 불가능하도록) 하려면 아래의 명령어를 명령 파라미터 영역에 붙여넣고 실행합니다.

cd /etc/sudoers.d
echo "#User rules for ssm-user" > ssm-agent-users


EC2 직렬 콘솔에 접속할 수 있는 사전 조건 충족 후 직렬 콘솔을 사용하여 접속

: 직렬 콘솔 접속에 성공하였다면 아래의 명령어를 통해 SSH 연결이 OS 방화벽 또는 TCP 래퍼에 의해 차단되지 않았는지 확인합니다. 또한 sshd 서비스가 제대로 실행되고 있는지 확인합니다.

  1. iptables을 통해 OS단에서 방화벽 규칙을 구성한 경우 다음 명령어를 이용하여 ssh 기본 포트 22의 모든 연결을 허용하는 규칙을 추가합니다.

$ sudo iptables -I INPUT 1 -p tcp --dport 22 -j ACCEPT

참고 : AWS는 OS기반 방확벽 대신 Security Group과 Nacl 이용한 보안 설정이 가능하며, 이러한 방식을 권장하기 때문에 방화벽을 완전히 비활성화 합니다.

아래의 명령어를 활용하여 모든 방화벽 관련 모든 규칙을 플러시 합니다.

  • UFW(Ubuntu, Debian)를 사용하는 배포판

$ sudo iptables -F
$ sudo iptables -P INPUT ACCEPT
$ sudo ufw disable

  • 방화벽(Red Hat, CentOS)을 사용하는 배포판

$ sudo iptables -F
$ sudo iptables -P INPUT ACCEPT
$ sudo systemctl disable firewalld

  1. sshd 서비스가 실행 중인지 확인하고 SSH TCP 포트가 수신 대기 상태인지 확인합니다.

$ sudo systemctl restart sshd
$ sudo ss -tpln | grep -iE '22|ssh'

  1. OS단에서 ACL을 확인합니다. 즉, TCP 래퍼가 SSH 연결을 차단하고 있지 않은지 확인합니다.

$cat /etc/hosts.[ad]* | grep -vE '^#' | awk 'NF' | wc -l

0이 아닌 경우 /etc/hosts.allow 경로를 확인합니다.


방법 2 : AWS Systems Manager Session Manager 사용

: AWS System Manager을 사용하려면 인스턴스가 "SSM 관리형 인스턴스"여야 하며, 인스턴스에 설치된 SSM 에이전트 핑 상태가 Online(온라인) 여야 합니다.

AWS Systems Manager에서 Session Manager을 사용하기 위한 사전 조건

참고 : Session Manager 사전 조건

1) 지원되는 운영 체제 :

  • Linux 및 mac OS 등 모든 Linux 버전을 지원합니다.
  • Session Manager는 Windows Server 2012부터 Windows Server 2022까지 지원합니다.

2) SSM Agent : 세션을 통해 연결하려는 관리형 노드에 AWS Systems Manager SSM Agent 버전 2.3.68.0 이상이 설치되어 있어야 합니다.

3) 엔드포인트에 연결 : 연결하려는 관리형 노드는 다음 엔드포인트에 대한 HTTPS(포트 443) 아웃바운드 트래픽도 허용해야 합니다.

4) IAM 서비스 역할 : 아래의 문서를 참고하여 올바른 형태의 역할을 추가 또는 생성해줍니다.

참고 : Session Manager 권한을 사용하는 IAM 역할 확인 또는 생성

Session Manager 사전 조건 충족 후 이슈 해결 방법

  1. AWS System Manager 콘솔로 이동

  2. Session Manager 탭 으로 이동 후 Session 시작

  3. 위의 방법이 1 ~ 4 단계 (EC2 직렬 콘솔 사용)의 명령어를 실행합니다.


방법 3 : 사용자 데이터 스크립트 (User data scipts) 사용

: 위의 방법 1, 2이 실행 불가능한 경우 EC2 사용자 데이터 스크립트를 사용하여 해결할 수 있습니다. 다만 해당 방법은 인스턴스 중지와 같은 제약이 있기 때문에 인스턴스를 중지했을때 발생할 수 있는 상황을 확인하고 진행해야 한다.

  • 확인 해야하는 사항
    1. 이 절차를 수행하려면 EC2 인스턴스를 중지했다가 다시 시작해야 합니다. 인스턴스 스토어 볼륨에 저장된 데이터가 인스턴스에 있는 경우 해당 데이터는 인스턴스를 중지한 후 삭제됩니다.
    2. 인스턴스가 Amazon EC2 Auto Scaling 그룹에 속한 경우 인스턴스를 종료하면 Auto Scaling 그룹 내 인스턴스도 중지될 수 있습니다.
    3. AWS Auto Scaling을 사용하는 서비스에서 인스턴스를 시작한 경우 인스턴스를 종료하면 Auto Scaling 그룹 내 인스턴스도 중지될 수 있습니다.
    4. 인스턴스 종료는 Auto Scaling 그룹에 대한 인스턴스 확장 보호 설정에 따라 달라집니다. 인스턴스가 Auto Scaling 그룹의 일부인 경우, 문제 해결 단계를 시작하기 전에 Auto Scaling 그룹에서 일시적으로 인스턴스 제거합니다.
    5. 인스턴스를 중지하고 다시 시작하면 인스턴스의 퍼블릭 IP 주소가 변경됩니다. 외부 트래픽을 인스턴스로 라우팅할 때는 퍼블릭 IP 주소 대신 탄력적 IP 주소를 사용하는 것이 좋습니다.

사용자 데이터 스크립트를 사용하여 이슈 해결 방법

  1. Amazon EC2 콘솔로 이동

  2. 인스턴스 탭으로 이동, 목표로 하는 대상 인스턴스 선택

  3. 해당 인스턴스 중지

  • 중지 작업은 데이터 유실 및 공인 IP 변경을 발생시킬 수 있기 때문에 신중히 작업한다.
  1. 해당 인스턴스 선택 후 작업 -> 인스턴스 설정 -> 사용자 데이터 편집 선택

  2. 아래의 유저 데이터 스크립트를 "사용자 데이터 편집"에 붙여 넣고 저장한다.

Content-Type: multipart/mixed; boundary="//"
MIME-Version: 1.0

--//
Content-Type: text/cloud-config; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename="cloud-config.txt"

#cloud-config
cloud_final_modules:

  • [scripts-user, always]

--//
Content-Type:
text/x-shellscript; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename="userdata.txt"

#!/bin/bash
iptables -P INPUT ACCEPT
iptables -F
systemctl restart sshd.service || service sshd restart
if [[ $( cat /etc/hosts.[ad]* | grep -vE '^#' | awk 'NF' | wc -l) -ne 0 ]];\
then sudo sed -i '1i sshd2 sshd : ALL: allow' /etc/hosts.allow; fi
--//

  1. 인스턴스 시작 및 SSH 연결

  2. 앞의 사용자 데이터 스크립트는 인스턴스를 재부팅할 때마다 실행되도록 설정되어 있습니다. 인스턴스에 대한 액세스 권한을 다시 얻은 후에는 사용자 데이터 스크립트를 제거합니다.

사용자 데이터를 제거하려면 다음을 수행합니다.

  1. 방법 4: 사용자 데이터 스크립트 사용 섹션의 1~4단계를 완료합니다.

  2. [사용자 데이터 편집] 대화 상자에서 사용자 데이터 스크립트를 삭제합니다.


SSH을 통해 원격 호스트에 접속하는 도중 위와 같은 에러를 겪은 적은 모두들 한번쯤은 있을 것이라 생각한다. AWS에서 SSH 접속 이외에 어떻게 우회하여 인스턴스를 접속할 수 있는지 접속 후 어떠한 부분을 확인하고 수정해야하는지를 해당 포스팅을 통해 정리해 보았으며, 결국은 OS 레벨의 방화벽 ACL을 확인하고 sshd이 정상적으로 작동하고 있는지 확인하는 것이 해당 이슈를 해결하는 가장 정석적인 방법임을 알 수 있었다.

profile
Good to see you guys

0개의 댓글

관련 채용 정보