반응형

CI/CD 설정에 의해 자동으로 생성된 AutoScalingGroup(ASG)의 인스턴스(private subnet)들은
배포 시 마다 새로운 인스턴스로 교체되기 때문에
접속 설정을 저장하고 사용하기 어렵습니다.

인스턴스 내의 로그를 확인하거나 긴급 점검을 하는 경우
쉽게 해당 인스턴스에 접속할 수 있도록
autossh를 이용한 Shell script를 작성해 봤습니다.

※ autossh: https://www.harding.motd.ca/autossh/

 

autossh

autossh - Automatically restart SSH sessions and tunnels Update: Version 1.4g most notably addresses a bug that could see an alarm signal occur without a handler, causing autossh to exit inappropriately. Previous update: Version 1.4f incorporates a number

www.harding.motd.ca

※ Autossh Port Forwarding: https://medium.com/@gary4est/autossh-port-forwarding-23088d948787

 

Autossh Port Forwarding

How to setup ssh port forwarding with autossh and systemd or launchtl

medium.com

#! /bin/bash

if [ ! ${1} ] || [ ! ${2} ]; then
  echo "tunneling.sh {PRIVATE_IP} {LOCAL_PORT}"
  exit 1
fi

SSH_PID=$(lsof -ti tcp:${2})

if [ ${SSH_PID} ]; then
  AUTOSSH_PID=$(ps -o ppid -p ${SSH_PID} | tail -1)
  echo "killing the process of autossh:${2}"
  kill -9 ${AUTOSSH_PID}
  echo "killing the process of TCP:${2}"
  kill -9 ${SSH_PID}
fi

echo "tunneling by autossh..."
autossh -f -N -M 0 -o "ServerAliveInterval 30" -o "ServerAliveCountMax 3" \
 -L ${2}:${1}:22 -i "{{Bastion_키_페어_파일}}" {{Bastion_사용자}}@{{Bastion_호스트}}

sleep 3

echo "removing ssh key of localhost:${2}"
nohup ssh-keygen -R "[localhost]:${2}" > /dev/null 2>&1

echo "connecting ${1}"
ssh -i "{{원격_키_페어_파일}}" {{원격_사용자}}@localhost -p ${2}
{{Bastion_키_페어_파일}} Bastion host 키 페어 파일
{{Bastion_사용자}} Bastion host 의 로그인 USER
{{Bastion_호스트}} Bastion host의 IP/도메인
{{원격_키_페어_파일}} 접속할 원격 인스턴스의 키 페어 파일
{{원격_사용자}} 접속할 원격 인스턴스의 로그인 USER

예) 로컬의 9222 포트를 이용하여 원격 Host 234.234.234.234 에 접속하려는 경우

./{쉘_파일명} 234.234.234.234 9222

위와 같이 쉘 스크립트를 실행하면

1) 9222 포트로 실행 중인 프로세스 있는지 확인

2) 프로세스가 있다면 해당 프로세스를 실행시킨 autossh의 프로세스를 확인하여 종료

3) 9222 포트 프로세스 종료

4) autossh를 이용하여 로컬 9522 포트 통한 Tunneling 실행

5) 해당 로컬 포트로 등록된 ssh-key 삭제

6) 지정한 로컬 포트를 통해 원격 인스턴스에 접속

의 단계로 실행됩니다.

실제로 위와 같이 쉘을 실행하면

새로운 ssh-key를 통해 접속을 계속할 거냐고 묻는 화면이 나오고
yes를 선택하면 원격 호스트에 접속할 수 있습니다.

반응형
반응형

외부에 공개되어 있지 않은 private subnet에 있는 자원에 접근하기 위해서는
Bastion host를 통해 Tunneling을 해야 하는데
Tunneling은 일반적인 ssh 접속을 통해 이루어지므로
네트워크 상태나 프로세스 비정상 종료 등으로 인해 Tunneling이 중단될 수 있습니다.

이 경우 사용 중이던 private subnet 접근도 중지되게 되는데,
Tunneling 종료로 인한 private subnet 접속 해제를 막기 위해
autossh 라는 프로그램이 있습니다.
※ autossh 웹사이트: https://www.harding.motd.ca/autossh/

 

autossh

autossh - Automatically restart SSH sessions and tunnels Update: Version 1.4g most notably addresses a bug that could see an alarm signal occur without a handler, causing autossh to exit inappropriately. Previous update: Version 1.4f incorporates a number

www.harding.motd.ca

웹사이트에 따르면 autossh는
ssh 접속하고 모니터 하며
해당 프로세스가 종료되거나 네트워크가 중단되면 ssh 접속을 재시작하는 방식으로 접속을 유지합니다.

autossh의 이러한 특성을 이용하면
Tunneling(Port forwarding)을 생성, 유지하는 데에도 적용할 수 있습니다.
※ Autossh Port Fowarding: https://medium.com/@gary4est/autossh-port-forwarding-23088d948787

 

Autossh Port Forwarding

How to setup ssh port forwarding with autossh and systemd or launchtl

medium.com

autossh를 통해 Tunneling 생성, 유지 방법을 정리하였습니다.

autossh 설치 (macOS 기준)

brew install autossh

autossh 실행

autossh -f -N -M 0 -o "ServerAliveInterval 30" -o "ServerAliveCountMax 3" \
 -L ${Local포트}:${원격인스턴스}:${원격포트} -i "${키페어파일}" ${BASTION_USER}@${BASTION_HOST}

 autossh 옵션

-f 백그라운드에서 실행
-N 원격 명령어를 실행하지 않음. 주로 포트 포워딩만 하는 경우 적용
-M 모니터 포트. 환경 설정에서 설정한 값을 override 함. 0으로 설정할 경우 off
-o ssh 접속 옵션
-L 지정한 로컬 포트를 이용하여 원격 인스턴스에 접속
-i ssh 접속 키 페어 파일 경로

예) 로컬의 9022 포트를 통해 123.123.123.123에 ssh 접속을 해야 하는 경우 터널링

autossh -f -N -M 0 -o "ServerAliveInterval 30" -o "ServerAliveCountMax 3" \
 -L 9022:123.123.123.123:22 -i "/key-pair.pem" \
 bastion-user@ec2-XXX-XXX-XXX-XXX.ap-northeast-2.compute.amazonaws.com

원격 리소스 접근

autossh 설치 후 위와 같이 실행하면 Tunneling이 생성, 유지되며
이후에는 locahost의 포트를 통해 private subnet의 자원에 접근할 수 있습니다.

ssh -i "${키페어파일}" ${원격_USER}@localhost -p ${로컬포트}

예) 원격 USER(ec2-user)가 로컬 9022 포트 통해 접속

ssh -i "/key-pair.pem" ec2-user@localhost -p 9222

 

반응형
반응형

Bastion host

Bastion이란 원래 적의 침입을 막기 위해 쌓은 시설물로 주로 성의 외부에 쌓는 성곽 등을 뜻합니다.

AWS와 같은 Cloud 환경에서 실제 운용 중인 애플리케이션을 외부의 임의 접근으로 부터 지키기 위해, 외부와 차단된 Private subnet에 위치 시키게 됩니다.

이 경우 실제 애플리케이션의 개발자도 접근할 수 없는 문제가 생기는데,
이 때 개발자가 애플리케이션에 접근하여 작업할 수 있도록 Public subnet에 Bastion host를 위치 시키고
이 Bastion host를 통해 Private subnet의 애플리케이션으로 접근하는 것이 가능합니다.

Bastion host를 통해 애플리케이션 뿐 아니라 DB 등 보안 상 Private subnet에 위치하는 다른 자원들에 대해서도 접근/통제가 가능합니다.

이렇게 Bastion host를 통해서만 접근하도록 허용하면
외부의 인가되지 않은 직접적인 접근을 차단할 수 있고,
Bastion host 역시 인가된 사용자만 접근할 수 있도록 하면
훨씬 더 높은 수준의 보안을 유지할 수 있습니다.

여기서는 Bastion host를 이용한 터널링을 통해 Private subnet 내의 자원에 접근하는 방법을 정리하였습니다.

SSH 터널링

SSH Port Forwarding(포트 포워딩)은 클라이언트(또는 점프 서버)의 특정 포트를 통해 원격 서버에 접속하는 방식이며
SSH Tunneling(터널링)이라고도 부릅니다.

터널링 방법에는 Local Forwarding(로컬 포워딩) Remote Forwarding(원격 포워딩) 2가지 방법이 있습니다.

로컬 포워딩은 클라이언트의 특정 포트 접근을 원격의 지정된 포트로 포워딩하는 방법이며,

원격 포워딩은 점프 서버의 특정 포트 접근을 원격의 지정된 포트로 포워딩하는 방법입니다.

원격 포워딩의 경우 지정하는 포트에 대한 접근을 열어줘야 하기 때문에 지정 포트가 많아지면 보안 설정도 복잡해집니다.

여기서는 로컬 포워딩을 통해 private subnet 자원에 접근하는 방법을 정리하였습니다.

SSH 터널링 시작

로컬에 있는 pem 파일을 이용하여 bastion(ec2-3-39-***-***)에 접속하고, 로컬의 9022 포트(임의 설정) 접근을 private subnet 내의 ec2 인스턴스(ip-10-0-***-***)의 22번 포트로 포워딩합니다.

로컬 포트는 사용자 임의로 설정하여 사용할 수 있습니다.

ssh -i {bastion_프라이빗_키_파일} {bastion_유저}@{bastion_호스트} \
 -L {로컬_포트}:{접속대상_호스트}:22

옵션 기능
-N 원격 명령 실행하지 않음. (터널링 용도)
-i {키_페어_파일} bastion 접속용 키 페어 파일
-L {로컬_포트}:{접속대상_호스트}:{접속대상_포트} 로컬 포트를 접속 대상의 호스트와 포트로 포워딩

SSH 접근

터널링 실행한 창을 그대로 두고, 새 창을 열어 localhost의 로컬 포트로 SSH 접근하면 대상 서버로 포워딩 됩니다.

ssh -i {접속대상_키_파일} {접속대상_유저}@localhost -p {로컬_포트}

DBMS CLI 터널링

Maria DB를 기준으로 cli를 통해 접근하는 방법입니다. (macOS 기준)

로컬에 Maria DB 설치

로컬에 Maria DB를 설치합니다.

brew install mariadb

※ Homebrew - macOS용 패키지 관리자 (https://brew.sh/index_ko)

SSH 터널링

로컬의 임의 포트로 터널링을 시작합니다.

ssh -N -i {bastion_키_파일} {bastion_계정}@{bastions_호스트} \
 -L {로컬_임의_포트}:{RDS_엔드포인트}:3306

Maria DB 접속

새 창에서 mariaDB에 접속합니다.

mysql -h localhost -P {임의_포트} -u {mariaDB_계정} -p

Redis 터널링

로컬에서 Redis 접속을 위한 Tunneling 입니다. (macOS 기준)

Redis 설치

로컬에 redis를 설치합니다.

brew install redis

SSH 터널링

Bastion을 통한 Tunneling을 시작합니다.

ssh -N -i {bastion_키_페어_파일} {bastion_계정}@{bastion_호스트} \
 -L {임의_로컬_포트}:{redis_엔드포인트}:6379

Redis 접속

redis-cli를 통해 redis에 접근합니다.

redis-cli -h localhost -p {임의_로컬_포트}

🔗 참고

https://aws.amazon.com/ko/premiumsupport/knowledge-center/systems-manager-ssh-vpc-resources/

 

AWS Systems Manager를 통해 SSH 터널을 사용하여 프라이빗 VPC 리소스에 액세스

닫기 Saud 씨의 동영상을 통해 자세히 알아보기(4:38)

aws.amazon.com

https://aws.amazon.com/ko/premiumsupport/knowledge-center/rds-connect-ec2-bastion-host/

 

EC2를 Bastion 호스트로 사용하여 프라이빗 RDS DB 인스턴스에 로컬로 연결

닫기 Karthiga 씨의 동영상을 통해 자세히 알아보기(5:53)

aws.amazon.com

 

반응형
반응형

EC2 인스턴스를 생성하면 기본 계정(ec2-user)이 생성됩니다.

기본 계정의 경우 다수에게 알려져 있기 때문에 보안에 취약할 수 있습니다.

기본 계정 외 sudo 권한이 있는 새로운 계정을 생성하고
기존의 기본 계정은 삭제하여 불법적인 접근을 막을 수 있도록 해보겠습니다.

🧑‍🔧 신규 계정 생성 및 기본 계정 설정

퍼블릭 키 확인

로컬에 저장된 기존 계정(ec2-user)의 키 페어 파일에서 퍼블릭 키를 검색하여
ssh-rsa … 로 시작하는 반환 결과를 확인합니다.

ssh-keygen -y -f {키_페어_파일}

사용자 계정 생성

EC2 인스턴스에 접속한 후 SUDO 권한이 있는 계정으로 새로운 계정을 생성하고
새로 생성한 계정으로 전환합니다.

sudo adduser {신규_계정명}
sudo su - {신규_계정명}

사용자 계정 root에 .ssh 디렉토리를 만들고 권한을 700으로 변경합니다.

mkdir .ssh
chmod 700 .ssh

.ssh/authorized_keys 파일을 생성하고 권한을 600으로 변경합니다.

cd .ssh
touch authorized_keys
chmod 600 authorized_keys

에디터로 authorized_keys 파일을 열어
앞서 확인했던 키 페어 파일의 퍼블릭 키를 붙여 넣고 저장합니다.

sudo 권한 부여

새로운 계정에 sudo 권한을 부여하고, 기존 계정(ec2-user)은 삭제하기 위해
ec2-user 계정에서 /etc/sudoers.d/90-cloud-init-users 파일에 새로운 계정을 추가하고 저장합니다.

✍️ sudoers 관련 파일들은 visudo 명령으로만 수정할 수 있습니다.

sudo visudo -f /etc/sudoers.d/90-cloud-init-users
# Created by cloud-init v. 19.3-45.amzn2 on Wed, 20 Jul 2022 04:30:09 +0000

# User rules for ec2-user
ec2-user ALL=(ALL) NOPASSWD:ALL
{신규_계정명} ALL=(ALL) NOPASSWD:ALL

새로운 계정으로 로그인 한 후 sudo 권한을 확인합니다.

기본 계정 제거

더 이상 사용하지 않을 기존 계정은 삭제합니다.

sudo userdel -r {사용자_계정}

🔗 참고 링크

https://docs.aws.amazon.com/ko_kr/AWSEC2/latest/UserGuide/managing-users.html

 

Linux 인스턴스에서 사용자 계정 관리 - Amazon Elastic Compute Cloud

퍼블릭 키를 연속된 한 줄에 붙여넣는지 확인합니다. 퍼블릭 키는 여러 줄로 분할되지 않아야 합니다.

docs.aws.amazon.com

https://blog.outsider.ne.kr/505

 

Ubuntu에서 sudo 명령어로 root권한 얻지 못할때 :: Outsider's Dev Story

메인OS는 아니지만 우분투를 사용한지도 좀 되긴 했지만 항상 X-window상에서만 사용하다가 보니 꽤 많은 부분이 자동설정되어 있이서 따로 의식하지 못하고 있었습니다. 서버에 설치된 우분투에

blog.outsider.ne.kr

https://jojoldu.tistory.com/433

 

2. Ansible (앤서블) 로 전체 서버 계정 추가하기 - CLI로 계정 추가하기

이번 시간엔 앤서블 CLI를 통해 각 호스트에 루트 권한을 가진 계정을 추가해보겠습니다. 2-1. 모듈? 실습에 들어가기 앞서 앤서블의 모듈에 대해 간단하게 소개하겠습니다. 앤서블의 공식 홈페이

jojoldu.tistory.com

 

반응형

+ Recent posts