본문 바로가기
BackEnd

SSH 접속 불가

by oncerun 2023. 3. 15.
반응형

 

NCloud 서버의 접속이 안된다!

 

오늘은 NCloud 서버의 ssh 접속이 안 되는 경우를 해결하는 방법이다. ( 온프레미스의 경우이다.)

 

내가 만든 프로젝트는 아니지만 운영관련해서 일이 하나 있었다. 

 

애플리케이션이 동작하는 서버가 있었는데, 어느 순간부터 ssh 접속이 안된다는 것이다. 이를 맡은 개발자가 여러 시도를 해보고 NCloud 문의도 많이 한 것으로 보인다. 

 

우선 살펴보기로 했다. 

 

 

putty로 해당 서버의 접속하려고 시도했지만 다음과 같이 Remote side unexpetedly closed network connection이라는 문구가 나오면서 접속이 되지 않았다. 

 

NCloud AVG 설정을 보니 우선 보안적으로 취약한 점을 찾았다. ssh에 대한 접속권한이 public으로 전부 열려있었다. 

 

무한한 공격이 들어왔다고 생각했고 2021년 사용된 서버니까 다음과 같이 생각했다.

 

리눅스에는 로그인 관련된 auth.log가 존재한다.  이는 인증과 관련된 로그 파일이 작성되는데, 2년 동안 수많은 공격의 로그가 담겨있기 때문에 해당 파일이 비대해졌고 기본 제공되는 SSD 용량인 50GB가 가득 차서 연결을 위한 파일 생성이 불가능해졌고 로그인 시도에 대한 auth.log 파일을 쓸 공간이 없어 ssh 접속이 안될 수 있다고 생각했다. 

 

우선 NCloud는 이러한 상황을 대비해 서버 접속 콘솔이라는 기능을 제공해준다. 

전화 문의를 통해 매우 친절하게 설명 받아 사용했다. 

 

담당자분은 이를 싱글모드로 접속해 해당 관련 작업을 진행하는 것을 권했고 다음과 같이 진행했다.

 

GRUB의 부트로더에서 "ro"부분을 다음과 같이 rw init=/bin/bash로 변경하여 로딩하면 싱글모드로 접속이 된다. 

 

접속 후 전체 디스크 용량을 확인했다. 가득찼을 것이라고 생각했지만 그렇지 않았다. 

 

auth.log 파일을 살펴보았다. 예상대로 수 많은 공격이 들어왔었고 용량이 3GB 정도 됐던 것 같다.

 

auth.log 파일을 보니 재밌는 로그가 하나 있었다.

 

 

UNPROTECTED PRIVATE KEY FILE

로그를 읽어보면 ssh 클라이언트가 사용하는 개인 키 파일의 권한이 너무 넓게 설정되어 있다는 것을 말한다. 
따라서 해당 개인 키가 무시되었다라고 나옵니다. 

 

 

잠시 SSH 프로토콜에 대해 다시 한 번 생각해 봅니다.

 

로그인, 원격 시스템의 명령을 실행, 파일을 복사할 수 있도록 해주는 프로토콜.

 

기존의 원격 접속 프로토콜에 보안을 추가한 프로토콜이다. 

 

SSH 프로토콜은 클라이언트 - 서버 모델로 동작한다. 

 

예를 들어 putty를 사용하면 우리는 ssh 클라이언트이며, 보통 AWS EC2나, NCloud Server를 할당받으면 openssh-server가 설치되어 있다. 

 

systemctl status sshd

 

SSH 프로토콜은 대칭키, 비대칭키, 해시알고리즘을 지원하며 이를 통해 인증 및 암호화를 진행한다. 

 

대칭키 방식은 클라이언트 - 서버 간 전체 연결을 암호화에 사용한다.

비대칭키 방식은 키 교환, 클라이언트 인증, 서버 인증에 사용된다. 

해시 알고리즘은 패킷의 무결성을 확인하기 위해 사용한다. 

 

 

SSH 동작 과정

 

 

1. 클라이언트가 서버와 연결하기 위해 요청을 보낸다.

 

2. 서버는 응답을 받고 서버의 공개키를 전달한다.

 

3. 클라이언트는 접속하려는 SSH 서버가 올바른 서버인지 검증한다.

 

이를 위해 클라이언트는 전달받은 공개키를 통해 정상 서버를 검증한다. 이 과정은 다음과 같다.

 

1. 클라이언트에서 난수 생성, 난수 해시값 생성 및 저장한다.

 

2. 이 난수를 서버의 공개키로 암호화하여 서버로 전송한다.

 

3. 서버에서 서버의 개인키로 데이터를 복호화하여 난수를 추출한다. 

 

4. 복호화된 난수 값의 해시값을 생성 후 서버의 개인키로 암호화 후 클라이언트에게 전송한다. 

 

5. 클라이언트는 이를 복호화한 후 자신이 가지고 있던 난수 해시값과 서버가 보낸 난수 해시값을 비교하여 값이 일치하는지 확인합니다. 

 

6. 동일할 시 해당 서버가 올바른 서버임을 확인하고 통신을 지속합니다.

 

더보기

해시 함수는 임의의 길이의 데이터를 고정된 길이의 데이터로 매핑하는 함수입니다. 즉, 입력 데이터의 특정한 형태를 고정된 길이의 데이터로 변환합니다. 예를 들어, "hello world"라는 문자열을 SHA-256 해시 함수를 사용하여 해시값을 계산하면 다음과 같은 결과가 나옵니다.

입력 데이터: "hello world"
해시값: 2ef7bde608ce5404e97d5f042f95f89f1c232871a9fbf9e5c0851bc0e1ca0
출력 길이: 256비트 (32바이트)

해시 함수는 입력 데이터가 조금이라도 변경되면 출력값이 크게 달라집니다. 예를 들어, "hello world!"라는 문자열을 SHA-256 해시 함수를 사용하여 해시값을 계산하면 다음과 같은 결과가 나옵니다.

입력 데이터: "hello world!"
해시값: b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9
출력 길이: 256비트 (32바이트)

이렇게 입력 데이터가 조금이라도 변경되면 출력값이 크게 바뀌는 특성 때문에 해시 함수는 데이터의 무결성 검증 등에 널리 사용됩니다.

 

이제 대칭키로 통신을 하는 것이 더 효율적이므로 세션 키를 생성한다. 

(이때 Difiie-Hellman 알고리즘을 사용한다. 이는 공개키와 개인키를 통해 대칭키를 교환하는 방식)

* 여기서 대칭키 교환에 사용하는 키 쌍은 서버와 클라이언트 인증에 사용되는 SSH 키 쌍과 다릅니다. 

 

 

 

오류를 파악해 봅시다. 

 

보통 openssh -server 패키지를 직접 설치하지 않는 경우 /etc/ssh 경로에 설치됩니다.

 

여기서는 다음과 같은 파일들이 openssh-server가 설치될 때 자동으로 생성됩니다.

 

  • ssh_host_ecdsa_key: ECDSA 알고리즘을 사용하는 호스트 키의 개인키 파일
  • ssh_host_ecdsa_key.pub: ECDSA 알고리즘을 사용하는 호스트 키의 공개키 파일
  • ssh_host_ed25519_key: Ed25519 알고리즘을 사용하는 호스트 키의 개인키 파일
  • ssh_host_ed25519_key.pub: Ed25519 알고리즘을 사용하는 호스트 키의 공개키 파일
  • ssh_host_rsa_key: RSA 알고리즘을 사용하는 호스트 키의 개인키 파일
  • ssh_host_rsa_key.pub: RSA 알고리즘을 사용하는 호스트 키의 공개키 파일

( 특정 알고리즘을 사용하도록 구성하면 해당 알고리즘 호스트 키 쌍을 사용하여 인증을 진행합니다. 기본 3개가 설치되는군요.)

 

위 파일들은 SSH 서버에서 사용되는 호스트 키파일로 SSH 서버는 호스트 키를 사용하여 서버 인증을 수행하고 클라이언트가 SSH 서버에 접속할 때 호스트 키를 사용하여 서버의 신원을 검증합니다. 

 

SSH 동작 과정 중에는 클라이언트가 서버를 검증하는 과정이 있다고 했다. 

 

접속이 안 되는 서버를 싱글모드로 들어가 해당 파일의 권한을 확인했을 때 모든 호스트 키파일의 권한이 777이었다. 

 

따라서 클라이언트가 공개키로 암호화하여 전송된 난수를 복호화하는 과정에서 호스트 개인키를 사용하려고 했지만 해당 개인키의 권한이 777로 설정되어 있어 해당 개인키를 믿지 못하여 연결을 끊어버리는 상황이 나타난 것으로 보인다.

 

openssh server 설치 시 적절한 권한으로 호스트 키파일을 생성해준다고 한다. 다른 서버의 권한을 확인했을 때 다음과 같았다.

 

따라서 해당 권한에 맞게 접속 불가 서버도 변경해 주었다.

 

이후 서버를 재시작한 후 원격으로 접속을 시도하니 성공했다. 

 

 

왜 해당 파일들의 권한이 777로 설정됐는지는 알 수 없다. 

 

stat 명령어로 언제 변경됐는지 확인했어야 했는데, 권한을 수정해 버려서 시간이 덮어써졌다. 과거 다른 분이 어떤 의도로 변경하셨는지는 몰라 조금은 찝찝하다. 

 

내가 관리하는 서버가 아니기 때문에 다음과 같이 권장사항을 제공하고 마무리하려고 한다.

 

NCloud는 서버 접속용 공인 IP를 제공합니다.

이에 대해 포트 포워딩을 통해 외부 특정 포트를 열고 서버의 22번 포트로 포워딩할 수 있습니다. 

따라서 서버 AVG(보안) 설정에서 기본적으로 22번 ssh 요청을 화이트리스트로 관리하시거나 접속하지 못하게 막고 서버 접속용 공인 ip와 지정한 port로만 접속할 수 있도록 하는 것을 권장드립니다. 

 

또한 root 계정으로 접속하는 것은 보안상 위험하니 별도의 사용자를 생성하여 접속하도록 할 수 있습니다. ( 해당 과정은 별도의 키쌍이 필요하며 https://manvscloud.com/?p=713  다음 링크에서 자세히 설명합니다. )

위 링크를 통하면 id와 password 접속을 막고 키 쌍을 기반으로만 로그인할 수 있도록 변경할 수 있습니다.

 

 

ps - 왜 스토리지 붙였는데 마운트 안 하신 거죠?... 

 

 

 

https://velog.io/@ragnarok_code/SSH-%EB% 8F%99% EC% 9E%91% EC% 9B%90% EB% A6% AC-%EC% 9D% B4% ED%95% B4% ED%95%98% EA% B8% B0

https://ko.wikipedia.org/wiki/%EC%8B%9C%ED%81%90%EC%96%B4_%EC%85%B8

 

반응형

'BackEnd' 카테고리의 다른 글

JSR 303, 380, @Valid, @Validated  (0) 2023.07.23
🛠️ Swagger ?  (0) 2023.07.12
Prometheus & Grafana  (0) 2023.02.17
Monitoring  (0) 2023.02.16
CQRS Pattern  (0) 2023.02.02

댓글