System Engineering/Security

Security #5. SSH의 동작원리와 SSH KEY 배포

ZunoXI 2023. 7. 29.

이번 포스팅에서는 SSH의 동작원리에 대해 알아보고 서버/클라이언트 관계에서의 SSH Key를 배포하는 방법 및 절차를 기술해보고자 합니다.

 

 

 

 

SSH란?

 

SSH는 Secure SHell의 약자이며 우리가 일반적으로 서버에 접속할 때 사용하는 보안 프로토콜입니다. 과거에는 원격 서버에 접속 시 telnet을 사용하였으나 여러 보안이슈가 있었기에 현재는 암호화 통신이 가능한 ssh를 사용합니다. 

 

ssh는 대칭키 방식과 비대칭키 방식을 모두 사용하는 프로토콜입니다. 여기서 비대칭키란 암호화, 복호화를 서로 다른 키를 이용하여 진행하는 방식이고, 대칭키 방식은 동일한 키값으로 암호화, 복호화를 진행하는 방식입니다. ssh는 비대칭키를 이용하여 서버인증/사용자 인증을 진행하고, 대칭키를 이용하여 주고받은 데이터를 암호화합니다.

 

 

인증과정

 

ssh 인증과정은 아래와 같이 진행됩니다.

 

서버 인증 과정

출처 : https://www.ssh.com/academy/ssh

 

위 그림과 같이 SSH를 통한 서버인증과정은 크게 4단계로 이루어집니다.

 

  • 사용자가 원격지 서버에 접속하기 위한 연결설정
  • 서버가 클라이언트측에 서버의 공개키를 전달
  • 여러 가지 파라미터 값을 통해 인증과정을 거쳐 보안 채널을 오픈
  • 사용자가 서버 호스트의 os영역에 로그인

 

아래 내용부터 1단계씩 자세히 확인해보겠습니다.

 

1. 서버 인증과정

 

클라이언트가 특정 서버에 접속하기 위해 ssh의 well known 포트인 tcp 22번 포트를 통해 접속을 시도하게 됩니다.

 

(참고 : https://www.ssh.com/academy/ssh/port 요 글의 내용은 왜 ssh가 tcp 22번을 사용하게 되었는지에 대해 나와있으니 참고하면 좋을 것 같습니다.)

 

 

서버에 접속하려고 시도할 때 사용자 관점, 정상적인 서버인지 확인하는 과정입니다.

 

  1. 클라이언트에서 서버에 처음 접속을 시도 시 서버의 공개키를 받겠냐는 메시지에  yes를 선택하면 서버로부터 공개키를 전달받음
  2. 클라이언트는 전달받은 공개키를. ssh/known_hosts에 저장
  3. 클라이언트는 난수를 발생시키고 난수값에 대한 hash값을 생성하여 저장함
  4. 클라이언트는 발생시킨 난수값을 서버로부터 전달받았던 공개키를 이용하여 암호화
  5. 암호화된 난수값을 서버로 다시 전달
  6. 서버는 전달받은 난수값을 서버의 개인키를 이용하여 복호화
  7. 서버는 복호화된 난수값을 hash값으로 변환
  8. 서버는 변환된 hash값을 다시 클라이언트로 보냄
  9. 클라이언트는 서버로 부터 받은 hash값이 본인이 보내기 전 저장했던 hash값과 같은지 검사
  10. 비교 후 동일하다면 서버 인증 성공

 

2. 사용자 인증과정

 

사용자가 서버에 접근하고자 할 때 서버관점, 인가된 사용자인지 확인하는 과정입니다..

 

  1. 서버인증과정과 절차가 유사하지만 반대로 진행
  2. 클라이언트가 비대칭키인 개인키와 공개키를 생성함
  3. 클라이언트가 공개키를 서버에 전달
  4. 서버는. ssh/authorized_keys에 클라이언트의 공개키를 저장
  5. 서버에서는 난수를 발생시킨 후 hash값으로 저장
  6. 공개키를 이용하여 발생시킨 난수값을 암호화
  7. 암호화된 난수값을 클라이언트에 전달
  8. 클라이언트는 전달받은 난수값을 개인키를 이용하여 복호화
  9. 복호화된 난수값을 hash값으로 변환
  10. 변환된 hash값을 다시 서버에 전달
  11. 서버는 클라이언트로부터 받은 hash값이 본인이 전달했던 난수값의 hash값과 같은지 비교
  12. 비교 후 동일하다면 사용자 인증 성공

 

 

실제 서버 접속 구현

 

여기 사용자 로컬이 test-01.test, 서버가 test-02.test 라고 가정하고 테스트를 진행하겠습니다.

 

ssh key 생성

 

우선 접속을 시도하려는 로컬 (test-01.test)에서 ssh 키를 생성합니다.

ssh-keygen -t '암호화 방식' -E '해시 알고리즘'

[root@test-01.test .ssh]# ssh-keygen -t rsa -E sha512
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa): 
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
SHA512:XV77YQzxe+rlzu/WJK7HFpRlhdFYW2jgWxfDanvMgSlJQ/xn3E5esVMEsuvzfLmu/5yxYemX9+CLj/wT4jr8Pw root@test-01.test
The key's randomart image is:
+---[RSA 2048]----+
|          o.oo+%*|
|           = oBoX|
|          . BoB**|
|         . = @=X=|
|        S . *.BO=|
|           ...=*B|
|         . .o++X*|
|          o..OEO@|
|          .+*O&/^|
+----[SHA512]-----+

 

생성된 공개키와 비밀키를 확인 / 복사

 

id_rsa 가 개인키, id_rsa_pub이 공개키이다.

[root@test-01.test .ssh]# ls
id_rsa  id_rsa.pub

 

공개키(id_rsa_pub)의 내용을 서버의. ssh/authorized_keys에 복사합니다.

 

서버 접속

 

- ssh -l '계정명' 'hostname'

(이 경우 dns에 해당 hostname이 있을 때 사용하고, 보통은 IP를 입력)

[root@test-01.test .ssh]# ssh -l root test-02.test
The authenticity of host 'test-01.test (172.100.100.100)' can't be established.
ECDSA key fingerprint is SHA256:0zbkWCoYK26Ofq/1p0M92RFFog20FvZel1eMElfEB1A.
ECDSA key fingerprint is MD5:cd:05:46:c5:d6:30:d0:78:13:b3:02:8e:08:f0:fc:87.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'test-01.test,172.100.100.100' (ECDSA) to the list of known hosts.
Last login: ~~~~~~
[root@test-02.test ~]#

 

 

일반적인 key 사용

 

보통 CSP에서 제공하는 서버의 경우 (예를 들면 AWS EC2) 접속할 클라이언트의 공개키와 개인키를 미리 생성하여 서버의 authorized_keys에 공개키를 넣어두고 개인키만 알려주게 됩니다. 그러면 그 개인키를 이용하여 서버에 접속할 수 있겠죠! 윈도우 터미널에서 ssh -i '개인키'를 저장한 파일' '인가된 사용자'@'ip' 요런 명령어를 통해 접속할 수 있습니다. 

 

또한, 앞선 실습의 경우는 특정 서버를 로컬이라고 가정하고 다른 서버에 연결하는 과정을 구현해 봤는데요, 실제로 별도 접근 권한이 있는 서버끼리도 ssh로 통신하게 해야 할 경우가 있기에, 이 경우도 동일한 과정으로 설정해서 서버 대 서버 ssh 접근을 하면 되겠습니다.

 

 

 

참고 

 

https://limvo.tistory.com/21

 

[서버보안] SSH #1 - SSH 원리

SSH(Secure Shell) : 시큐어 셸 기존 Telnet, Rlogin, RSH를 대체하기 위해 만들어졌으며 네트워크 상의 다른 PC나 서버에 로그인, 원격 명령 실행, 파일 전송을 수행할 수 있는 프로토콜이다. 기존의 원격

limvo.tistory.com

 

반응형

댓글