[Ubuntu] SSH 보안설정

[Ubuntu] SSH 보안설정
Photo by Markus Spiske / Unsplash

iwinv라는 국내 업체에서 가상서버(VPS)를 하나 생성해서 다시 블로그를 시작해보려고 하다보니 오랜만에 서버셋팅을 본격적으로 하고 있다. 기존 PC에서 사용할 때와는 다르게 인터넷 상에서 운영되는 서버다보니... 서버관리를 위한 SSH 보안설정이 신경쓰여 구글링을 해보고 관련된 설정을 해봤다.(매번 호스팅업체의 콘솔서비스를 이용하는 것은 너무 불편해서...)

A. 사용환경

  • OS : Ubuntu 22.04.2 LTS (Jammy Jellyfish)
  • H/W : 1 vCPU, 1GB Memory (iwinv vCore.V2-Lite)

B. 작업할 내용

  1. ufw로 특정 IP만 접근허용
  2. root계정 접근차단 (PermitRootLogin)
  3. 특정 user만 접근허용 (AllowUsers)
  4. Session Timeout 설정 (ClientAliveInterval, ClientAliveCountMax)
  5. 암호없는 계정 로그인차단 (PermitEmptyPasswords)
  6. 로그인시도 횟수지정 (MaxAuthTries)
  7. 로그인 대기시간 조정 (LoginGraceTime)

C. 방화벽(ufw) 작업

내 경우에는 주로 PC를 이용해서 SSH로 접속하는 일은 사무실에서 이루어지다보니.. SSH에 접속하는 IP주소를 한정할 수 있는 상황이라서 Port를 변경하는 것보다 IP를 제한하는 것이 더 유리하다고 판단했다.

$ sudo ufw status
Status: inactive
$

ufw 패키지는 설치가 되어있으나 inactive 상태다. ufw를 켜준다.

$ sudo ufw enable
Command may disrupt existing ssh connections. Proceed with operation (y|n)? y
Firewall is active and enabled on system startup
$

ssh 연결이 끊어질 수 있다고 경고를 하지만... y를 입력하고 실행해준다. 이제 사무실 공인IP를 확인한다. 확인하는 가장 간단한 방법은... 네이버에서 내 공인ip로 검색을 하면, 공인ip 주소를 알려준다.

출처 : 네이버 검색화면 캡쳐

이제 아래의 명령어를 실행해서 특정 공인IP에서만 22번 포트(ssh)로 접근할 수 있도록 설정한다.

$ sudo ufw allow from [공인IP] to any port 22
Rule added
$

[공인IP]에 해당하는 부분에 네이버에서 확인한 IP주소를 입력한다.

$ sudo ufw default deny
Default incoming policy changed to 'deny'
(be sure to update your rules accordingly)
$

그리고 기본적인 inbound 정책은 deny(거절)로 설정한다. 그리고 설정한 내용을 확인해본다.

$ sudo ufw status
Status: active

To                         Action      From
--                         ------      ----
22                         ALLOW       [공인IP]

$

이제 이 서버의 SSH포트(22번)는 [공인IP]를 사용하는 클라이언트에서만 접속이 가능하다.

D. SSH서버 설정변경

이제 나머지 SSH서버와 관련된 보안설정은 설정파일(/etc/ssh/sshd_config)을 변경해서 적용한다. 개인적으로 설정파일은 항상 원본을 보관하여 어떤 부분이 변경되었는지 파악이 쉽도록 작업하는 편이다.

$ sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config_20230627

설정파일 원본을 백업한 뒤에는 선호하는 텍스트편집기를 열어서 설정파일을 변경한다.

$ sudo vim /etc/ssh/sshd_config

아래의 내용을 참고해서 설정을 변경한다.

  1. PermitRootLogin : yes -> no 설정값을 변경
  2. AllowUsers : 설정파일 가장 하단에 AllowUsers ubuntu 추가
  3. #ClientAliveInterval 0 : 주석제거 후 값을 600으로 변경
  4. #ClientAliveCountMax 3 : 주석제거
  5. #PermitEmptyPasswords no : 주석제거
  6. #MaxAuthTries 6 : 주석제거 후 값을 3으로 변경
  7. #LoginGraceTime 2m : 주석제거 후 값을 30으로 변경

변경한 설정파일과 원본설정파일을 비교해본다.

$ diff /etc/ssh/sshd_config_20230627 /etc/ssh/sshd_config
32,33c32,33
< #LoginGraceTime 2m
< PermitRootLogin yes
---
> LoginGraceTime 30
> PermitRootLogin no
35c35
< #MaxAuthTries 6
---
> MaxAuthTries 3
58c58
< #PermitEmptyPasswords no
---
> PermitEmptyPasswords no
99,100c99,100
< #ClientAliveInterval 0
< #ClientAliveCountMax 3
---
> ClientAliveInterval 600
> ClientAliveCountMax 3
122a123,124
>
> AllowUsers ubuntu
$

변경 전 설정파일(/etc/ssh/sshd_config_20230627)과 비교해서 잘 바뀐 것으로 확인된다면 ssh 서비스를 재기동하여 변경한 설정을 적용한다.

$ sudo systemctl restart ssh

E. 테스트

이제 작업한 내용을 테스트해본다.

  1. [공인IP]에서 ubuntu 계정으로 접속시도 -> Succeed (정상)
  2. [공인IP]에서 root 계정으로 접속시도 -> Failed (정상)[1]
  3. [공인IP]에서 ubuntu 계정으로 비밀번호 3회 틀림 -> Failed (정상)[2]
  4. [공인IP]가 아닌 곳에서 ubuntu 계정으로 접속시도 -> Failed (정상)[3]

나머지도 테스트를 해보고 싶은데... 테스트 케이스가 애매해서 참고문서의 가이드가 정상이라고 가정하고 마무리한다.

F. 마치면서..

대부분의 사람들이 저와 같이 사무실이 고정IP가 아닌 경우가 있어서 본 문서의 가이드가 적합하지 않을 수도 있다. 그런 경우에는 가능하면 /etc/ssh/sshd_config파일의 Port 22Port 2222와 같은 형태로 기본 포트를 변경하는 것을 권장한다. 해당 내용은 참고문서 1번을 읽어보면 확인할 수 있다.

G. 참고문서

  1. SSH 보안 설정, lesstif.com, lesstif, unknown date
  2. 우분투(Ubuntu) 환경에 방화벽(UFW) 설정하기, LINDAREX, LINDAREX, 2020/02/24
  3. [Ubuntu] 우분투 방화벽(UFW) 설정, WEBDIR, 흉내쟁이, unknown date

  1. /var/log/auth.log를 확인해보면 Jun 27 16:33:12 blog sshd[22684]: User root from [공인IP] not allowed because not listed in AllowUsers 형태로 차단된 것을 확인할 수 있다. ↩︎

  2. /var/log/auth.log를 확인해보면 설정한 횟수만큼 로그인 실패로그가 저장된 뒤에 Jun 27 16:38:29 blog sshd[22692]: error: maximum authentication attempts exceeded for ubuntu from [공인IP] port 7589 ssh2 [preauth]Jun 27 16:38:29 blog sshd[22692]: Disconnecting authenticating user ubuntu [공인IP] port 7589: Too many authentication failures [preauth] 형태의 로그가 남아있는 것을 확인할 수 있다. ↩︎

  3. [공인IP]가 아닌 putty로 로그인 시도하니 Network error: Connection timed out 오류가 발생한다. ↩︎